novelWriter 2.4.4__py3-none-any.whl → 2.5rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/METADATA +4 -5
  2. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/RECORD +109 -101
  3. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +33 -39
  5. novelwriter/assets/i18n/project_en_GB.json +1 -0
  6. novelwriter/assets/icons/typicons_dark/icons.conf +2 -0
  7. novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
  8. novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
  9. novelwriter/assets/icons/typicons_light/icons.conf +2 -0
  10. novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
  11. novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
  12. novelwriter/assets/manual.pdf +0 -0
  13. novelwriter/assets/sample.zip +0 -0
  14. novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
  15. novelwriter/assets/syntax/default_dark.conf +32 -18
  16. novelwriter/assets/syntax/default_light.conf +24 -10
  17. novelwriter/assets/syntax/dracula.conf +44 -0
  18. novelwriter/assets/syntax/grey_dark.conf +5 -4
  19. novelwriter/assets/syntax/grey_light.conf +5 -4
  20. novelwriter/assets/syntax/light_owl.conf +7 -6
  21. novelwriter/assets/syntax/night_owl.conf +7 -6
  22. novelwriter/assets/syntax/snazzy.conf +42 -0
  23. novelwriter/assets/syntax/solarized_dark.conf +4 -3
  24. novelwriter/assets/syntax/solarized_light.conf +4 -3
  25. novelwriter/assets/syntax/tango.conf +27 -11
  26. novelwriter/assets/syntax/tomorrow.conf +6 -5
  27. novelwriter/assets/syntax/tomorrow_night.conf +7 -6
  28. novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
  29. novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
  30. novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
  31. novelwriter/assets/text/credits_en.htm +4 -1
  32. novelwriter/assets/themes/cyberpunk_night.conf +3 -0
  33. novelwriter/assets/themes/default_dark.conf +2 -0
  34. novelwriter/assets/themes/default_light.conf +2 -0
  35. novelwriter/assets/themes/dracula.conf +48 -0
  36. novelwriter/assets/themes/solarized_dark.conf +2 -0
  37. novelwriter/assets/themes/solarized_light.conf +2 -0
  38. novelwriter/common.py +33 -12
  39. novelwriter/config.py +184 -98
  40. novelwriter/constants.py +47 -35
  41. novelwriter/core/buildsettings.py +68 -69
  42. novelwriter/core/coretools.py +5 -23
  43. novelwriter/core/docbuild.py +52 -40
  44. novelwriter/core/document.py +3 -5
  45. novelwriter/core/index.py +115 -45
  46. novelwriter/core/item.py +8 -19
  47. novelwriter/core/options.py +2 -4
  48. novelwriter/core/project.py +23 -57
  49. novelwriter/core/projectdata.py +1 -3
  50. novelwriter/core/projectxml.py +12 -15
  51. novelwriter/core/sessions.py +3 -5
  52. novelwriter/core/spellcheck.py +4 -9
  53. novelwriter/core/status.py +211 -164
  54. novelwriter/core/storage.py +0 -8
  55. novelwriter/core/tohtml.py +139 -105
  56. novelwriter/core/tokenizer.py +278 -122
  57. novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
  58. novelwriter/core/toodt.py +257 -166
  59. novelwriter/core/toqdoc.py +419 -0
  60. novelwriter/core/tree.py +5 -7
  61. novelwriter/dialogs/about.py +11 -18
  62. novelwriter/dialogs/docmerge.py +17 -19
  63. novelwriter/dialogs/docsplit.py +17 -19
  64. novelwriter/dialogs/editlabel.py +6 -10
  65. novelwriter/dialogs/preferences.py +193 -144
  66. novelwriter/dialogs/projectsettings.py +225 -189
  67. novelwriter/dialogs/quotes.py +12 -9
  68. novelwriter/dialogs/wordlist.py +9 -15
  69. novelwriter/enum.py +35 -30
  70. novelwriter/error.py +8 -15
  71. novelwriter/extensions/configlayout.py +40 -21
  72. novelwriter/extensions/eventfilters.py +1 -5
  73. novelwriter/extensions/modified.py +58 -14
  74. novelwriter/extensions/novelselector.py +1 -3
  75. novelwriter/extensions/pagedsidebar.py +9 -12
  76. novelwriter/extensions/{circularprogress.py → progressbars.py} +30 -8
  77. novelwriter/extensions/statusled.py +29 -25
  78. novelwriter/extensions/switch.py +4 -6
  79. novelwriter/extensions/switchbox.py +7 -6
  80. novelwriter/extensions/versioninfo.py +3 -9
  81. novelwriter/gui/doceditor.py +118 -137
  82. novelwriter/gui/dochighlight.py +231 -186
  83. novelwriter/gui/docviewer.py +66 -107
  84. novelwriter/gui/docviewerpanel.py +3 -10
  85. novelwriter/gui/editordocument.py +1 -3
  86. novelwriter/gui/itemdetails.py +7 -11
  87. novelwriter/gui/mainmenu.py +22 -18
  88. novelwriter/gui/noveltree.py +11 -24
  89. novelwriter/gui/outline.py +14 -26
  90. novelwriter/gui/projtree.py +35 -60
  91. novelwriter/gui/search.py +10 -3
  92. novelwriter/gui/sidebar.py +2 -6
  93. novelwriter/gui/statusbar.py +29 -37
  94. novelwriter/gui/theme.py +26 -48
  95. novelwriter/guimain.py +134 -148
  96. novelwriter/shared.py +36 -32
  97. novelwriter/text/patterns.py +113 -0
  98. novelwriter/tools/dictionaries.py +10 -20
  99. novelwriter/tools/lipsum.py +10 -16
  100. novelwriter/tools/manusbuild.py +9 -11
  101. novelwriter/tools/manuscript.py +71 -145
  102. novelwriter/tools/manussettings.py +71 -75
  103. novelwriter/tools/noveldetails.py +16 -21
  104. novelwriter/tools/welcome.py +12 -26
  105. novelwriter/tools/writingstats.py +9 -12
  106. novelwriter/types.py +49 -4
  107. novelwriter/extensions/simpleprogress.py +0 -55
  108. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/LICENSE.md +0 -0
  109. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/entry_points.txt +0 -0
  110. {novelWriter-2.4.4.dist-info → novelWriter-2.5rc1.dist-info}/top_level.txt +0 -0
@@ -25,18 +25,16 @@ from __future__ import annotations
25
25
 
26
26
  import logging
27
27
 
28
- from PyQt5.QtWidgets import (
29
- QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit, QVBoxLayout,
30
- QWidget
31
- )
28
+ from PyQt5.QtWidgets import QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit, QVBoxLayout, QWidget
32
29
 
33
30
  from novelwriter import CONFIG
34
- from novelwriter.types import QtDialogCancel, QtDialogOk
31
+ from novelwriter.extensions.modified import NDialog
32
+ from novelwriter.types import QtAccepted, QtDialogCancel, QtDialogOk
35
33
 
36
34
  logger = logging.getLogger(__name__)
37
35
 
38
36
 
39
- class GuiEditLabel(QDialog):
37
+ class GuiEditLabel(NDialog):
40
38
 
41
39
  def __init__(self, parent: QWidget, text: str = "") -> None:
42
40
  super().__init__(parent=parent)
@@ -91,8 +89,6 @@ class GuiEditLabel(QDialog):
91
89
  cls = GuiEditLabel(parent, text=text)
92
90
  cls.exec()
93
91
  label = cls.itemLabel
94
- accepted = cls.result() == QDialog.DialogCode.Accepted
95
- cls.deleteLater()
92
+ accepted = cls.result() == QtAccepted
93
+ cls.softDelete()
96
94
  return label, accepted
97
-
98
- # END Class GuiEditLabel
@@ -27,18 +27,20 @@ from __future__ import annotations
27
27
  import logging
28
28
 
29
29
  from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
30
- from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence
30
+ from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence
31
31
  from PyQt5.QtWidgets import (
32
- QAbstractButton, QApplication, QCompleter, QDialog, QDialogButtonBox,
33
- QFileDialog, QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout,
34
- QWidget
32
+ QAbstractButton, QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout,
33
+ QLineEdit, QPushButton, QVBoxLayout, QWidget
35
34
  )
36
35
 
37
36
  from novelwriter import CONFIG, SHARED
38
- from novelwriter.constants import nwConst, nwUnicode
37
+ from novelwriter.common import describeFont
38
+ from novelwriter.constants import nwUnicode
39
39
  from novelwriter.dialogs.quotes import GuiQuoteSelect
40
40
  from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
41
- from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox
41
+ from novelwriter.extensions.modified import (
42
+ NComboBox, NDialog, NDoubleSpinBox, NIconToolButton, NSpinBox
43
+ )
42
44
  from novelwriter.extensions.pagedsidebar import NPagedSideBar
43
45
  from novelwriter.extensions.switch import NSwitch
44
46
  from novelwriter.types import (
@@ -49,7 +51,7 @@ from novelwriter.types import (
49
51
  logger = logging.getLogger(__name__)
50
52
 
51
53
 
52
- class GuiPreferences(QDialog):
54
+ class GuiPreferences(NDialog):
53
55
 
54
56
  newPreferencesReady = pyqtSignal(bool, bool, bool, bool)
55
57
 
@@ -64,8 +66,8 @@ class GuiPreferences(QDialog):
64
66
 
65
67
  # Title
66
68
  self.titleLabel = NColourLabel(
67
- self.tr("Preferences"), SHARED.theme.helpText,
68
- parent=self, scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
69
+ self.tr("Preferences"), self, color=SHARED.theme.helpText,
70
+ scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
69
71
  )
70
72
 
71
73
  # Search Box
@@ -133,7 +135,13 @@ class GuiPreferences(QDialog):
133
135
  """Build the settings form."""
134
136
  section = 0
135
137
  iSz = SHARED.theme.baseIconSize
138
+ boxFixed = 5*SHARED.theme.textNWidth
136
139
  minWidth = CONFIG.pxInt(200)
140
+ fontWidth = CONFIG.pxInt(162)
141
+
142
+ # Temporary Variables
143
+ self._guiFont = CONFIG.guiFont
144
+ self._textFont = CONFIG.textFont
137
145
 
138
146
  # Label
139
147
  self.sidebar.addLabel(self.tr("General"))
@@ -173,27 +181,17 @@ class GuiPreferences(QDialog):
173
181
  # Application Font Family
174
182
  self.guiFont = QLineEdit(self)
175
183
  self.guiFont.setReadOnly(True)
176
- self.guiFont.setMinimumWidth(CONFIG.pxInt(162))
177
- self.guiFont.setText(CONFIG.guiFont)
178
- self.guiFontButton = NIconToolButton(self, iSz, "more")
184
+ self.guiFont.setMinimumWidth(fontWidth)
185
+ self.guiFont.setText(describeFont(self._guiFont))
186
+ self.guiFont.setCursorPosition(0)
187
+ self.guiFontButton = NIconToolButton(self, iSz, "font")
179
188
  self.guiFontButton.clicked.connect(self._selectGuiFont)
180
189
  self.mainForm.addRow(
181
- self.tr("Application font family"), self.guiFont,
190
+ self.tr("Application font"), self.guiFont,
182
191
  self.tr("Requires restart to take effect."), stretch=(3, 2),
183
192
  button=self.guiFontButton
184
193
  )
185
194
 
186
- # Application Font Size
187
- self.guiFontSize = NSpinBox(self)
188
- self.guiFontSize.setMinimum(8)
189
- self.guiFontSize.setMaximum(60)
190
- self.guiFontSize.setSingleStep(1)
191
- self.guiFontSize.setValue(CONFIG.guiFontSize)
192
- self.mainForm.addRow(
193
- self.tr("Application font size"), self.guiFontSize,
194
- self.tr("Requires restart to take effect."), unit=self.tr("pt")
195
- )
196
-
197
195
  # Vertical Scrollbars
198
196
  self.hideVScroll = NSwitch(self)
199
197
  self.hideVScroll.setChecked(CONFIG.hideVScroll)
@@ -210,6 +208,14 @@ class GuiPreferences(QDialog):
210
208
  self.tr("Scrolling available with mouse wheel and keys only.")
211
209
  )
212
210
 
211
+ # Native Font Dialog
212
+ self.nativeFont = NSwitch(self)
213
+ self.nativeFont.setChecked(CONFIG.nativeFont)
214
+ self.mainForm.addRow(
215
+ self.tr("Use the system's font selection dialog"), self.nativeFont,
216
+ self.tr("Turn off to use the Qt font dialog, which may have more options.")
217
+ )
218
+
213
219
  # Document Style
214
220
  # ==============
215
221
 
@@ -233,27 +239,17 @@ class GuiPreferences(QDialog):
233
239
  # Document Font Family
234
240
  self.textFont = QLineEdit(self)
235
241
  self.textFont.setReadOnly(True)
236
- self.textFont.setMinimumWidth(CONFIG.pxInt(162))
237
- self.textFont.setText(CONFIG.textFont)
238
- self.textFontButton = NIconToolButton(self, iSz, "more")
242
+ self.textFont.setMinimumWidth(fontWidth)
243
+ self.textFont.setText(describeFont(CONFIG.textFont))
244
+ self.textFont.setCursorPosition(0)
245
+ self.textFontButton = NIconToolButton(self, iSz, "font")
239
246
  self.textFontButton.clicked.connect(self._selectTextFont)
240
247
  self.mainForm.addRow(
241
- self.tr("Document font family"), self.textFont,
248
+ self.tr("Document font"), self.textFont,
242
249
  self.tr("Applies to both document editor and viewer."), stretch=(3, 2),
243
250
  button=self.textFontButton
244
251
  )
245
252
 
246
- # Document Font Size
247
- self.textSize = NSpinBox(self)
248
- self.textSize.setMinimum(8)
249
- self.textSize.setMaximum(60)
250
- self.textSize.setSingleStep(1)
251
- self.textSize.setValue(CONFIG.textSize)
252
- self.mainForm.addRow(
253
- self.tr("Document font size"), self.textSize,
254
- self.tr("Applies to both document editor and viewer."), unit=self.tr("pt")
255
- )
256
-
257
253
  # Emphasise Labels
258
254
  self.emphLabels = NSwitch(self)
259
255
  self.emphLabels.setChecked(CONFIG.emphLabels)
@@ -538,26 +534,59 @@ class GuiPreferences(QDialog):
538
534
  self.sidebar.addButton(title, section)
539
535
  self.mainForm.addGroupLabel(title, section)
540
536
 
541
- self.highlightQuotes = NSwitch(self)
542
- self.highlightQuotes.setChecked(CONFIG.highlightQuotes)
543
- self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes)
537
+ self.dialogStyle = NComboBox(self)
538
+ self.dialogStyle.addItem(self.tr("None"), 0)
539
+ self.dialogStyle.addItem(self.tr("Single Quotes"), 1)
540
+ self.dialogStyle.addItem(self.tr("Double Quotes"), 2)
541
+ self.dialogStyle.addItem(self.tr("Both"), 3)
542
+ self.dialogStyle.setCurrentData(CONFIG.dialogStyle, 2)
544
543
  self.mainForm.addRow(
545
- self.tr("Highlight text wrapped in quotes"), self.highlightQuotes,
546
- self.tr("Applies to the document editor only.")
544
+ self.tr("Highlight dialogue"), self.dialogStyle,
545
+ self.tr("Applies to the selected quote styles.")
546
+ )
547
+
548
+ self.allowOpenDial = NSwitch(self)
549
+ self.allowOpenDial.setChecked(CONFIG.allowOpenDial)
550
+ self.mainForm.addRow(
551
+ self.tr("Allow open-ended dialogue"), self.allowOpenDial,
552
+ self.tr("Highlight dialogue line with no closing quote.")
547
553
  )
548
554
 
549
- self.allowOpenSQuote = NSwitch(self)
550
- self.allowOpenSQuote.setChecked(CONFIG.allowOpenSQuote)
555
+ self.narratorBreak = QLineEdit(self)
556
+ self.narratorBreak.setMaxLength(1)
557
+ self.narratorBreak.setFixedWidth(boxFixed)
558
+ self.narratorBreak.setAlignment(QtAlignCenter)
559
+ self.narratorBreak.setText(CONFIG.narratorBreak)
551
560
  self.mainForm.addRow(
552
- self.tr("Allow open-ended single quotes"), self.allowOpenSQuote,
553
- self.tr("Highlight single-quoted line with no closing quote.")
561
+ self.tr("Dialogue narrator break symbol"), self.narratorBreak,
562
+ self.tr("Symbol to indicate injected narrator break.")
554
563
  )
555
564
 
556
- self.allowOpenDQuote = NSwitch(self)
557
- self.allowOpenDQuote.setChecked(CONFIG.allowOpenDQuote)
565
+ self.dialogLine = QLineEdit(self)
566
+ self.dialogLine.setMaxLength(1)
567
+ self.dialogLine.setFixedWidth(boxFixed)
568
+ self.dialogLine.setAlignment(QtAlignCenter)
569
+ self.dialogLine.setText(CONFIG.dialogLine)
570
+ self.mainForm.addRow(
571
+ self.tr("Dialogue line symbol"), self.dialogLine,
572
+ self.tr("Lines starting with this symbol are dialogue.")
573
+ )
574
+
575
+ self.altDialogOpen = QLineEdit(self)
576
+ self.altDialogOpen.setMaxLength(4)
577
+ self.altDialogOpen.setFixedWidth(boxFixed)
578
+ self.altDialogOpen.setAlignment(QtAlignCenter)
579
+ self.altDialogOpen.setText(CONFIG.altDialogOpen)
580
+
581
+ self.altDialogClose = QLineEdit(self)
582
+ self.altDialogClose.setMaxLength(4)
583
+ self.altDialogClose.setFixedWidth(boxFixed)
584
+ self.altDialogClose.setAlignment(QtAlignCenter)
585
+ self.altDialogClose.setText(CONFIG.altDialogClose)
586
+
558
587
  self.mainForm.addRow(
559
- self.tr("Allow open-ended double quotes"), self.allowOpenDQuote,
560
- self.tr("Highlight double-quoted line with no closing quote.")
588
+ self.tr("Alternative dialogue symbols"), [self.altDialogOpen, self.altDialogClose],
589
+ self.tr("Custom highlighting of dialogue text.")
561
590
  )
562
591
 
563
592
  self.highlightEmph = NSwitch(self)
@@ -666,65 +695,62 @@ class GuiPreferences(QDialog):
666
695
  self.sidebar.addButton(title, section)
667
696
  self.mainForm.addGroupLabel(title, section)
668
697
 
669
- self.quoteSym = {}
670
- qWidth = CONFIG.pxInt(40)
671
-
672
698
  # Single Quote Style
673
- self.quoteSym["SO"] = QLineEdit(self)
674
- self.quoteSym["SO"].setMaxLength(1)
675
- self.quoteSym["SO"].setReadOnly(True)
676
- self.quoteSym["SO"].setFixedWidth(qWidth)
677
- self.quoteSym["SO"].setAlignment(QtAlignCenter)
678
- self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen)
679
- self.btnSingleStyleO = NIconToolButton(self, iSz, "more")
680
- self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
681
- self.mainForm.addRow(
682
- self.tr("Single quote open style"), self.quoteSym["SO"],
699
+ self.fmtSQuoteOpen = QLineEdit(self)
700
+ self.fmtSQuoteOpen.setMaxLength(1)
701
+ self.fmtSQuoteOpen.setReadOnly(True)
702
+ self.fmtSQuoteOpen.setFixedWidth(boxFixed)
703
+ self.fmtSQuoteOpen.setAlignment(QtAlignCenter)
704
+ self.fmtSQuoteOpen.setText(CONFIG.fmtSQuoteOpen)
705
+ self.btnSQuoteOpen = NIconToolButton(self, iSz, "quote")
706
+ self.btnSQuoteOpen.clicked.connect(self._changeSingleQuoteOpen)
707
+ self.mainForm.addRow(
708
+ self.tr("Single quote open style"), self.fmtSQuoteOpen,
683
709
  self.tr("The symbol to use for a leading single quote."),
684
- button=self.btnSingleStyleO
710
+ button=self.btnSQuoteOpen
685
711
  )
686
712
 
687
- self.quoteSym["SC"] = QLineEdit(self)
688
- self.quoteSym["SC"].setMaxLength(1)
689
- self.quoteSym["SC"].setReadOnly(True)
690
- self.quoteSym["SC"].setFixedWidth(qWidth)
691
- self.quoteSym["SC"].setAlignment(QtAlignCenter)
692
- self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose)
693
- self.btnSingleStyleC = NIconToolButton(self, iSz, "more")
694
- self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
713
+ self.fmtSQuoteClose = QLineEdit(self)
714
+ self.fmtSQuoteClose.setMaxLength(1)
715
+ self.fmtSQuoteClose.setReadOnly(True)
716
+ self.fmtSQuoteClose.setFixedWidth(boxFixed)
717
+ self.fmtSQuoteClose.setAlignment(QtAlignCenter)
718
+ self.fmtSQuoteClose.setText(CONFIG.fmtSQuoteClose)
719
+ self.btnSQuoteClose = NIconToolButton(self, iSz, "quote")
720
+ self.btnSQuoteClose.clicked.connect(self._changeSingleQuoteClose)
695
721
  self.mainForm.addRow(
696
- self.tr("Single quote close style"), self.quoteSym["SC"],
722
+ self.tr("Single quote close style"), self.fmtSQuoteClose,
697
723
  self.tr("The symbol to use for a trailing single quote."),
698
- button=self.btnSingleStyleC
724
+ button=self.btnSQuoteClose
699
725
  )
700
726
 
701
727
  # Double Quote Style
702
- self.quoteSym["DO"] = QLineEdit(self)
703
- self.quoteSym["DO"].setMaxLength(1)
704
- self.quoteSym["DO"].setReadOnly(True)
705
- self.quoteSym["DO"].setFixedWidth(qWidth)
706
- self.quoteSym["DO"].setAlignment(QtAlignCenter)
707
- self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen)
708
- self.btnDoubleStyleO = NIconToolButton(self, iSz, "more")
709
- self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
710
- self.mainForm.addRow(
711
- self.tr("Double quote open style"), self.quoteSym["DO"],
728
+ self.fmtDQuoteOpen = QLineEdit(self)
729
+ self.fmtDQuoteOpen.setMaxLength(1)
730
+ self.fmtDQuoteOpen.setReadOnly(True)
731
+ self.fmtDQuoteOpen.setFixedWidth(boxFixed)
732
+ self.fmtDQuoteOpen.setAlignment(QtAlignCenter)
733
+ self.fmtDQuoteOpen.setText(CONFIG.fmtDQuoteOpen)
734
+ self.btnDQuoteOpen = NIconToolButton(self, iSz, "quote")
735
+ self.btnDQuoteOpen.clicked.connect(self._changeDoubleQuoteOpen)
736
+ self.mainForm.addRow(
737
+ self.tr("Double quote open style"), self.fmtDQuoteOpen,
712
738
  self.tr("The symbol to use for a leading double quote."),
713
- button=self.btnDoubleStyleO
739
+ button=self.btnDQuoteOpen
714
740
  )
715
741
 
716
- self.quoteSym["DC"] = QLineEdit(self)
717
- self.quoteSym["DC"].setMaxLength(1)
718
- self.quoteSym["DC"].setReadOnly(True)
719
- self.quoteSym["DC"].setFixedWidth(qWidth)
720
- self.quoteSym["DC"].setAlignment(QtAlignCenter)
721
- self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose)
722
- self.btnDoubleStyleC = NIconToolButton(self, iSz, "more")
723
- self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
742
+ self.fmtDQuoteClose = QLineEdit(self)
743
+ self.fmtDQuoteClose.setMaxLength(1)
744
+ self.fmtDQuoteClose.setReadOnly(True)
745
+ self.fmtDQuoteClose.setFixedWidth(boxFixed)
746
+ self.fmtDQuoteClose.setAlignment(QtAlignCenter)
747
+ self.fmtDQuoteClose.setText(CONFIG.fmtDQuoteClose)
748
+ self.btnDQuoteClose = NIconToolButton(self, iSz, "quote")
749
+ self.btnDQuoteClose.clicked.connect(self._changeDoubleQuoteClose)
724
750
  self.mainForm.addRow(
725
- self.tr("Double quote close style"), self.quoteSym["DC"],
751
+ self.tr("Double quote close style"), self.fmtDQuoteClose,
726
752
  self.tr("The symbol to use for a trailing double quote."),
727
- button=self.btnDoubleStyleC
753
+ button=self.btnDQuoteClose
728
754
  )
729
755
 
730
756
  self.mainForm.finalise()
@@ -741,13 +767,14 @@ class GuiPreferences(QDialog):
741
767
  logger.debug("Close: GuiPreferences")
742
768
  self._saveWindowSize()
743
769
  event.accept()
744
- QApplication.processEvents()
745
- self.done(nwConst.DLG_FINISHED)
746
- self.deleteLater()
770
+ self.softDelete()
747
771
  return
748
772
 
749
773
  def keyPressEvent(self, event: QKeyEvent) -> None:
750
- """Overload keyPressEvent to block enter key to save."""
774
+ """Overload keyPressEvent and only accept escape. The main
775
+ purpose here is to prevent Enter/Return from closing the dialog
776
+ as it is used for the search box.
777
+ """
751
778
  if event.matches(QKeySequence.StandardKey.Cancel):
752
779
  self.close()
753
780
  event.ignore()
@@ -785,25 +812,21 @@ class GuiPreferences(QDialog):
785
812
  @pyqtSlot()
786
813
  def _selectGuiFont(self) -> None:
787
814
  """Open the QFontDialog and set a font for the font style."""
788
- current = QFont()
789
- current.setFamily(CONFIG.guiFont)
790
- current.setPointSize(CONFIG.guiFontSize)
791
- font, status = QFontDialog.getFont(current, self)
815
+ font, status = SHARED.getFont(self._guiFont, self.nativeFont.isChecked())
792
816
  if status:
793
- self.guiFont.setText(font.family())
794
- self.guiFontSize.setValue(font.pointSize())
817
+ self.guiFont.setText(describeFont(font))
818
+ self.guiFont.setCursorPosition(0)
819
+ self._guiFont = font
795
820
  return
796
821
 
797
822
  @pyqtSlot()
798
823
  def _selectTextFont(self) -> None:
799
824
  """Open the QFontDialog and set a font for the font style."""
800
- current = QFont()
801
- current.setFamily(CONFIG.textFont)
802
- current.setPointSize(CONFIG.textSize)
803
- font, status = QFontDialog.getFont(current, self)
825
+ font, status = SHARED.getFont(self._textFont, self.nativeFont.isChecked())
804
826
  if status:
805
- self.textFont.setText(font.family())
806
- self.textSize.setValue(font.pointSize())
827
+ self.textFont.setText(describeFont(font))
828
+ self.textFont.setCursorPosition(0)
829
+ self._textFont = font
807
830
  return
808
831
 
809
832
  @pyqtSlot()
@@ -823,13 +846,6 @@ class GuiPreferences(QDialog):
823
846
  self.askBeforeBackup.setEnabled(state)
824
847
  return
825
848
 
826
- @pyqtSlot(bool)
827
- def _toggleHighlightQuotes(self, state: bool) -> None:
828
- """Toggle switches controlled by the highlight quotes switch."""
829
- self.allowOpenSQuote.setEnabled(state)
830
- self.allowOpenDQuote.setEnabled(state)
831
- return
832
-
833
849
  @pyqtSlot(bool)
834
850
  def _toggleAutoReplaceMain(self, state: bool) -> None:
835
851
  """Toggle switches controlled by the auto replace switch."""
@@ -840,11 +856,36 @@ class GuiPreferences(QDialog):
840
856
  self.fmtPadThin.setEnabled(state)
841
857
  return
842
858
 
843
- def _getQuote(self, qType: str) -> None:
844
- """Dialog for single quote open."""
845
- quote, status = GuiQuoteSelect.getQuote(self, current=self.quoteSym[qType].text())
859
+ @pyqtSlot()
860
+ def _changeSingleQuoteOpen(self) -> None:
861
+ """Change single quote open style."""
862
+ quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteOpen.text())
863
+ if status:
864
+ self.fmtSQuoteOpen.setText(quote)
865
+ return
866
+
867
+ @pyqtSlot()
868
+ def _changeSingleQuoteClose(self) -> None:
869
+ """Change single quote close style."""
870
+ quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteClose.text())
846
871
  if status:
847
- self.quoteSym[qType].setText(quote)
872
+ self.fmtSQuoteClose.setText(quote)
873
+ return
874
+
875
+ @pyqtSlot()
876
+ def _changeDoubleQuoteOpen(self) -> None:
877
+ """Change double quote open style."""
878
+ quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteOpen.text())
879
+ if status:
880
+ self.fmtDQuoteOpen.setText(quote)
881
+ return
882
+
883
+ @pyqtSlot()
884
+ def _changeDoubleQuoteClose(self) -> None:
885
+ """Change double quote close style."""
886
+ quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteClose.text())
887
+ if status:
888
+ self.fmtDQuoteClose.setText(quote)
848
889
  return
849
890
 
850
891
  ##
@@ -864,22 +905,19 @@ class GuiPreferences(QDialog):
864
905
  refreshTree = False
865
906
 
866
907
  # Appearance
867
- guiLocale = self.guiLocale.currentData()
868
- guiTheme = self.guiTheme.currentData()
869
- guiFont = self.guiFont.text()
870
- guiFontSize = self.guiFontSize.value()
908
+ guiLocale = self.guiLocale.currentData()
909
+ guiTheme = self.guiTheme.currentData()
871
910
 
872
911
  updateTheme |= CONFIG.guiTheme != guiTheme
873
912
  needsRestart |= CONFIG.guiLocale != guiLocale
874
- needsRestart |= CONFIG.guiFont != guiFont
875
- needsRestart |= CONFIG.guiFontSize != guiFontSize
913
+ needsRestart |= CONFIG.guiFont != self._guiFont
876
914
 
877
915
  CONFIG.guiLocale = guiLocale
878
916
  CONFIG.guiTheme = guiTheme
879
- CONFIG.guiFont = guiFont
880
- CONFIG.guiFontSize = guiFontSize
881
917
  CONFIG.hideVScroll = self.hideVScroll.isChecked()
882
918
  CONFIG.hideHScroll = self.hideHScroll.isChecked()
919
+ CONFIG.nativeFont = self.nativeFont.isChecked()
920
+ CONFIG.setGuiFont(self._guiFont)
883
921
 
884
922
  # Document Style
885
923
  guiSyntax = self.guiSyntax.currentData()
@@ -892,7 +930,7 @@ class GuiPreferences(QDialog):
892
930
  CONFIG.emphLabels = emphLabels
893
931
  CONFIG.showFullPath = self.showFullPath.isChecked()
894
932
  CONFIG.incNotesWCount = self.incNotesWCount.isChecked()
895
- CONFIG.setTextFont(self.textFont.text(), self.textSize.value())
933
+ CONFIG.setTextFont(self._textFont)
896
934
 
897
935
  # Auto Save
898
936
  CONFIG.autoSaveDoc = self.autoSaveDoc.value()
@@ -927,19 +965,32 @@ class GuiPreferences(QDialog):
927
965
  CONFIG.scrollPastEnd = self.scrollPastEnd.isChecked()
928
966
 
929
967
  # Text Highlighting
930
- highlightQuotes = self.highlightQuotes.isChecked()
968
+ dialogueStyle = self.dialogStyle.currentData()
969
+ allowOpenDial = self.allowOpenDial.isChecked()
970
+ narratorBreak = self.narratorBreak.text()
971
+ dialogueLine = self.dialogLine.text()
972
+ altDialogOpen = self.altDialogOpen.text()
973
+ altDialogClose = self.altDialogClose.text()
931
974
  highlightEmph = self.highlightEmph.isChecked()
932
975
  showMultiSpaces = self.showMultiSpaces.isChecked()
933
976
 
934
- updateSyntax |= CONFIG.highlightQuotes != highlightQuotes
977
+ updateSyntax |= CONFIG.dialogStyle != dialogueStyle
978
+ updateSyntax |= CONFIG.allowOpenDial != allowOpenDial
979
+ updateSyntax |= CONFIG.narratorBreak != narratorBreak
980
+ updateSyntax |= CONFIG.dialogLine != dialogueLine
981
+ updateSyntax |= CONFIG.altDialogOpen != altDialogOpen
982
+ updateSyntax |= CONFIG.altDialogClose != altDialogClose
935
983
  updateSyntax |= CONFIG.highlightEmph != highlightEmph
936
984
  updateSyntax |= CONFIG.showMultiSpaces != showMultiSpaces
937
985
 
938
- CONFIG.highlightQuotes = highlightQuotes
986
+ CONFIG.dialogStyle = dialogueStyle
987
+ CONFIG.allowOpenDial = allowOpenDial
988
+ CONFIG.narratorBreak = narratorBreak
989
+ CONFIG.dialogLine = dialogueLine
990
+ CONFIG.altDialogOpen = altDialogOpen
991
+ CONFIG.altDialogClose = altDialogClose
939
992
  CONFIG.highlightEmph = highlightEmph
940
993
  CONFIG.showMultiSpaces = showMultiSpaces
941
- CONFIG.allowOpenSQuote = self.allowOpenSQuote.isChecked()
942
- CONFIG.allowOpenDQuote = self.allowOpenDQuote.isChecked()
943
994
 
944
995
  # Text Automation
945
996
  CONFIG.doReplace = self.doReplace.isChecked()
@@ -952,15 +1003,13 @@ class GuiPreferences(QDialog):
952
1003
  CONFIG.fmtPadThin = self.fmtPadThin.isChecked()
953
1004
 
954
1005
  # Quotation Style
955
- CONFIG.fmtSQuoteOpen = self.quoteSym["SO"].text()
956
- CONFIG.fmtSQuoteClose = self.quoteSym["SC"].text()
957
- CONFIG.fmtDQuoteOpen = self.quoteSym["DO"].text()
958
- CONFIG.fmtDQuoteClose = self.quoteSym["DC"].text()
1006
+ CONFIG.fmtSQuoteOpen = self.fmtSQuoteOpen.text()
1007
+ CONFIG.fmtSQuoteClose = self.fmtSQuoteClose.text()
1008
+ CONFIG.fmtDQuoteOpen = self.fmtDQuoteOpen.text()
1009
+ CONFIG.fmtDQuoteClose = self.fmtDQuoteClose.text()
959
1010
 
960
1011
  # Finalise
961
1012
  CONFIG.saveConfig()
962
1013
  self.newPreferencesReady.emit(needsRestart, refreshTree, updateTheme, updateSyntax)
963
1014
 
964
1015
  return
965
-
966
- # END Class GuiPreferences