novelWriter 2.5b1__py3-none-any.whl → 2.5.1__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.
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/METADATA +1 -1
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/RECORD +77 -75
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +3 -3
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
- novelwriter/assets/i18n/nw_pl_PL.qm +0 -0
- novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_pl_PL.json +116 -0
- novelwriter/assets/i18n/project_pt_BR.json +74 -74
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/credits_en.htm +52 -44
- novelwriter/assets/themes/cyberpunk_night.conf +1 -0
- novelwriter/assets/themes/default_dark.conf +1 -0
- novelwriter/assets/themes/default_light.conf +1 -0
- novelwriter/assets/themes/dracula.conf +1 -0
- novelwriter/assets/themes/solarized_dark.conf +1 -0
- novelwriter/assets/themes/solarized_light.conf +1 -0
- novelwriter/common.py +12 -3
- novelwriter/config.py +67 -15
- novelwriter/constants.py +8 -10
- novelwriter/core/buildsettings.py +5 -3
- novelwriter/core/coretools.py +3 -1
- novelwriter/core/docbuild.py +1 -0
- novelwriter/core/project.py +15 -4
- novelwriter/core/status.py +4 -1
- novelwriter/core/storage.py +6 -1
- novelwriter/core/tohtml.py +69 -29
- novelwriter/core/tokenizer.py +83 -14
- novelwriter/core/toodt.py +48 -21
- novelwriter/core/toqdoc.py +37 -21
- novelwriter/dialogs/about.py +10 -15
- novelwriter/dialogs/docmerge.py +16 -16
- novelwriter/dialogs/docsplit.py +16 -16
- novelwriter/dialogs/editlabel.py +6 -8
- novelwriter/dialogs/preferences.py +106 -93
- novelwriter/dialogs/projectsettings.py +16 -20
- novelwriter/dialogs/quotes.py +9 -5
- novelwriter/dialogs/wordlist.py +6 -6
- novelwriter/enum.py +4 -5
- novelwriter/extensions/configlayout.py +38 -4
- novelwriter/extensions/modified.py +22 -3
- novelwriter/extensions/{circularprogress.py → progressbars.py} +26 -3
- novelwriter/extensions/statusled.py +39 -23
- novelwriter/gui/doceditor.py +22 -13
- novelwriter/gui/dochighlight.py +30 -39
- novelwriter/gui/docviewer.py +24 -15
- novelwriter/gui/docviewerpanel.py +7 -0
- novelwriter/gui/mainmenu.py +11 -11
- novelwriter/gui/outline.py +4 -3
- novelwriter/gui/projtree.py +85 -77
- novelwriter/gui/search.py +10 -1
- novelwriter/gui/statusbar.py +25 -29
- novelwriter/gui/theme.py +3 -0
- novelwriter/guimain.py +139 -124
- novelwriter/shared.py +19 -8
- novelwriter/text/patterns.py +113 -0
- novelwriter/tools/dictionaries.py +2 -8
- novelwriter/tools/lipsum.py +8 -12
- novelwriter/tools/manusbuild.py +9 -9
- novelwriter/tools/manuscript.py +10 -5
- novelwriter/tools/manussettings.py +7 -3
- novelwriter/tools/noveldetails.py +10 -10
- novelwriter/tools/welcome.py +19 -10
- novelwriter/tools/writingstats.py +3 -3
- novelwriter/types.py +5 -2
- novelwriter/extensions/simpleprogress.py +0 -53
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.5b1.dist-info → novelWriter-2.5.1.dist-info}/top_level.txt +0 -0
novelwriter/dialogs/about.py
CHANGED
@@ -33,14 +33,14 @@ from PyQt5.QtWidgets import (
|
|
33
33
|
from novelwriter import CONFIG, SHARED
|
34
34
|
from novelwriter.common import cssCol, readTextFile
|
35
35
|
from novelwriter.extensions.configlayout import NColourLabel
|
36
|
-
from novelwriter.extensions.modified import
|
36
|
+
from novelwriter.extensions.modified import NDialog
|
37
37
|
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
38
38
|
from novelwriter.types import QtAlignRightTop, QtDialogClose
|
39
39
|
|
40
40
|
logger = logging.getLogger(__name__)
|
41
41
|
|
42
42
|
|
43
|
-
class GuiAbout(
|
43
|
+
class GuiAbout(NDialog):
|
44
44
|
|
45
45
|
def __init__(self, parent: QWidget) -> None:
|
46
46
|
super().__init__(parent=parent)
|
@@ -75,7 +75,7 @@ class GuiAbout(NNonBlockingDialog):
|
|
75
75
|
|
76
76
|
# Credits
|
77
77
|
self.lblCredits = NColourLabel(
|
78
|
-
self.tr("Credits"), scale=1.6,
|
78
|
+
self.tr("Credits"), self, scale=1.6, bold=True
|
79
79
|
)
|
80
80
|
|
81
81
|
self.txtCredits = QTextBrowser(self)
|
@@ -85,7 +85,7 @@ class GuiAbout(NNonBlockingDialog):
|
|
85
85
|
|
86
86
|
# Buttons
|
87
87
|
self.btnBox = QDialogButtonBox(QtDialogClose, self)
|
88
|
-
self.btnBox.rejected.connect(self.
|
88
|
+
self.btnBox.rejected.connect(self.reject)
|
89
89
|
|
90
90
|
# Assemble
|
91
91
|
self.innerBox = QVBoxLayout()
|
@@ -106,7 +106,9 @@ class GuiAbout(NNonBlockingDialog):
|
|
106
106
|
|
107
107
|
self.setLayout(self.outerBox)
|
108
108
|
self.setSizeGripEnabled(True)
|
109
|
+
|
109
110
|
self._setStyleSheet()
|
111
|
+
self._fillCreditsPage()
|
110
112
|
|
111
113
|
logger.debug("Ready: GuiAbout")
|
112
114
|
|
@@ -116,11 +118,6 @@ class GuiAbout(NNonBlockingDialog):
|
|
116
118
|
logger.debug("Delete: GuiAbout")
|
117
119
|
return
|
118
120
|
|
119
|
-
def populateGUI(self) -> None:
|
120
|
-
"""Populate tabs with text."""
|
121
|
-
self._fillCreditsPage()
|
122
|
-
return
|
123
|
-
|
124
121
|
##
|
125
122
|
# Events
|
126
123
|
##
|
@@ -128,7 +125,7 @@ class GuiAbout(NNonBlockingDialog):
|
|
128
125
|
def closeEvent(self, event: QCloseEvent) -> None:
|
129
126
|
"""Capture the close event and perform cleanup."""
|
130
127
|
event.accept()
|
131
|
-
self.
|
128
|
+
self.softDelete()
|
132
129
|
return
|
133
130
|
|
134
131
|
##
|
@@ -137,16 +134,14 @@ class GuiAbout(NNonBlockingDialog):
|
|
137
134
|
|
138
135
|
def _fillCreditsPage(self) -> None:
|
139
136
|
"""Load the content for the Credits page."""
|
140
|
-
|
141
|
-
|
142
|
-
if docText:
|
143
|
-
self.txtCredits.setHtml(docText)
|
137
|
+
if html := readTextFile(CONFIG.assetPath("text") / "credits_en.htm"):
|
138
|
+
self.txtCredits.setHtml(html)
|
144
139
|
else:
|
145
140
|
self.txtCredits.setHtml("Error loading credits text ...")
|
146
141
|
return
|
147
142
|
|
148
143
|
def _setStyleSheet(self) -> None:
|
149
|
-
"""Set stylesheet
|
144
|
+
"""Set stylesheet text document."""
|
150
145
|
baseCol = cssCol(self.palette().window().color())
|
151
146
|
self.txtCredits.setStyleSheet(
|
152
147
|
f"QTextBrowser {{border: none; background: {baseCol};}} "
|
novelwriter/dialogs/docmerge.py
CHANGED
@@ -27,21 +27,21 @@ from __future__ import annotations
|
|
27
27
|
import logging
|
28
28
|
|
29
29
|
from PyQt5.QtCore import Qt, pyqtSlot
|
30
|
-
from PyQt5.QtGui import QCloseEvent
|
31
30
|
from PyQt5.QtWidgets import (
|
32
|
-
QAbstractItemView,
|
33
|
-
|
31
|
+
QAbstractItemView, QDialogButtonBox, QGridLayout, QLabel, QListWidget,
|
32
|
+
QListWidgetItem, QVBoxLayout, QWidget
|
34
33
|
)
|
35
34
|
|
36
35
|
from novelwriter import CONFIG, SHARED
|
37
36
|
from novelwriter.extensions.configlayout import NColourLabel
|
37
|
+
from novelwriter.extensions.modified import NDialog
|
38
38
|
from novelwriter.extensions.switch import NSwitch
|
39
|
-
from novelwriter.types import QtDialogCancel, QtDialogOk, QtDialogReset, QtUserRole
|
39
|
+
from novelwriter.types import QtAccepted, QtDialogCancel, QtDialogOk, QtDialogReset, QtUserRole
|
40
40
|
|
41
41
|
logger = logging.getLogger(__name__)
|
42
42
|
|
43
43
|
|
44
|
-
class GuiDocMerge(
|
44
|
+
class GuiDocMerge(NDialog):
|
45
45
|
|
46
46
|
D_HANDLE = QtUserRole
|
47
47
|
|
@@ -58,7 +58,7 @@ class GuiDocMerge(QDialog):
|
|
58
58
|
self.headLabel.setFont(SHARED.theme.guiFontB)
|
59
59
|
self.helpLabel = NColourLabel(
|
60
60
|
self.tr("Drag and drop items to change the order, or uncheck to exclude."),
|
61
|
-
SHARED.theme.helpText,
|
61
|
+
self, color=SHARED.theme.helpText, wrap=True
|
62
62
|
)
|
63
63
|
|
64
64
|
iPx = SHARED.theme.baseIconHeight
|
@@ -117,7 +117,7 @@ class GuiDocMerge(QDialog):
|
|
117
117
|
logger.debug("Delete: GuiDocMerge")
|
118
118
|
return
|
119
119
|
|
120
|
-
def
|
120
|
+
def data(self) -> dict:
|
121
121
|
"""Return the user's choices."""
|
122
122
|
finalItems = []
|
123
123
|
for i in range(self.listBox.count()):
|
@@ -130,15 +130,15 @@ class GuiDocMerge(QDialog):
|
|
130
130
|
|
131
131
|
return self._data
|
132
132
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
return
|
133
|
+
@classmethod
|
134
|
+
def getData(cls, parent: QWidget, handle: str, items: list[str]) -> tuple[dict, bool]:
|
135
|
+
"""Pop the dialog and return the result."""
|
136
|
+
cls = GuiDocMerge(parent, handle, items)
|
137
|
+
cls.exec()
|
138
|
+
data = cls.data()
|
139
|
+
accepted = cls.result() == QtAccepted
|
140
|
+
cls.softDelete()
|
141
|
+
return data, accepted
|
142
142
|
|
143
143
|
##
|
144
144
|
# Private Slots
|
novelwriter/dialogs/docsplit.py
CHANGED
@@ -27,21 +27,21 @@ from __future__ import annotations
|
|
27
27
|
import logging
|
28
28
|
|
29
29
|
from PyQt5.QtCore import pyqtSlot
|
30
|
-
from PyQt5.QtGui import QCloseEvent
|
31
30
|
from PyQt5.QtWidgets import (
|
32
|
-
QAbstractItemView, QComboBox,
|
33
|
-
|
31
|
+
QAbstractItemView, QComboBox, QDialogButtonBox, QGridLayout, QLabel,
|
32
|
+
QListWidget, QListWidgetItem, QVBoxLayout, QWidget
|
34
33
|
)
|
35
34
|
|
36
35
|
from novelwriter import CONFIG, SHARED
|
37
36
|
from novelwriter.extensions.configlayout import NColourLabel
|
37
|
+
from novelwriter.extensions.modified import NDialog
|
38
38
|
from novelwriter.extensions.switch import NSwitch
|
39
|
-
from novelwriter.types import QtDialogCancel, QtDialogOk, QtUserRole
|
39
|
+
from novelwriter.types import QtAccepted, QtDialogCancel, QtDialogOk, QtUserRole
|
40
40
|
|
41
41
|
logger = logging.getLogger(__name__)
|
42
42
|
|
43
43
|
|
44
|
-
class GuiDocSplit(
|
44
|
+
class GuiDocSplit(NDialog):
|
45
45
|
|
46
46
|
LINE_ROLE = QtUserRole
|
47
47
|
LEVEL_ROLE = QtUserRole + 1
|
@@ -62,7 +62,7 @@ class GuiDocSplit(QDialog):
|
|
62
62
|
self.headLabel.setFont(SHARED.theme.guiFontB)
|
63
63
|
self.helpLabel = NColourLabel(
|
64
64
|
self.tr("Select the maximum level to split into files."),
|
65
|
-
SHARED.theme.helpText,
|
65
|
+
self, color=SHARED.theme.helpText, wrap=True
|
66
66
|
)
|
67
67
|
|
68
68
|
# Values
|
@@ -145,7 +145,7 @@ class GuiDocSplit(QDialog):
|
|
145
145
|
logger.debug("Delete: GuiDocSplit")
|
146
146
|
return
|
147
147
|
|
148
|
-
def
|
148
|
+
def data(self) -> tuple[dict, list[str]]:
|
149
149
|
"""Return the user's choices. Also save the users options for
|
150
150
|
the next time the dialog is used.
|
151
151
|
"""
|
@@ -178,15 +178,15 @@ class GuiDocSplit(QDialog):
|
|
178
178
|
|
179
179
|
return self._data, self._text
|
180
180
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
return
|
181
|
+
@classmethod
|
182
|
+
def getData(cls, parent: QWidget, handle: str) -> tuple[dict, list[str], bool]:
|
183
|
+
"""Pop the dialog and return the result."""
|
184
|
+
cls = GuiDocSplit(parent, handle)
|
185
|
+
cls.exec()
|
186
|
+
data, text = cls.data()
|
187
|
+
accepted = cls.result() == QtAccepted
|
188
|
+
cls.softDelete()
|
189
|
+
return data, text, accepted
|
190
190
|
|
191
191
|
##
|
192
192
|
# Private Slots
|
novelwriter/dialogs/editlabel.py
CHANGED
@@ -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.
|
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(
|
37
|
+
class GuiEditLabel(NDialog):
|
40
38
|
|
41
39
|
def __init__(self, parent: QWidget, text: str = "") -> None:
|
42
40
|
super().__init__(parent=parent)
|
@@ -91,6 +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() ==
|
95
|
-
cls.
|
92
|
+
accepted = cls.result() == QtAccepted
|
93
|
+
cls.softDelete()
|
96
94
|
return label, accepted
|
@@ -29,27 +29,26 @@ import logging
|
|
29
29
|
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
30
30
|
from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence
|
31
31
|
from PyQt5.QtWidgets import (
|
32
|
-
|
33
|
-
|
32
|
+
QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit,
|
33
|
+
QPushButton, QVBoxLayout, QWidget
|
34
34
|
)
|
35
35
|
|
36
36
|
from novelwriter import CONFIG, SHARED
|
37
|
-
from novelwriter.common import describeFont
|
38
|
-
from novelwriter.constants import
|
37
|
+
from novelwriter.common import describeFont, uniqueCompact
|
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
|
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
|
-
from novelwriter.types import
|
45
|
-
QtAlignCenter, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept,
|
46
|
-
QtRoleApply, QtRoleReject
|
47
|
-
)
|
46
|
+
from novelwriter.types import QtAlignCenter, QtDialogCancel, QtDialogSave
|
48
47
|
|
49
48
|
logger = logging.getLogger(__name__)
|
50
49
|
|
51
50
|
|
52
|
-
class GuiPreferences(
|
51
|
+
class GuiPreferences(NDialog):
|
53
52
|
|
54
53
|
newPreferencesReady = pyqtSignal(bool, bool, bool, bool)
|
55
54
|
|
@@ -64,8 +63,8 @@ class GuiPreferences(QDialog):
|
|
64
63
|
|
65
64
|
# Title
|
66
65
|
self.titleLabel = NColourLabel(
|
67
|
-
self.tr("Preferences"), SHARED.theme.helpText,
|
68
|
-
|
66
|
+
self.tr("Preferences"), self, color=SHARED.theme.helpText,
|
67
|
+
scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
|
69
68
|
)
|
70
69
|
|
71
70
|
# Search Box
|
@@ -87,8 +86,9 @@ class GuiPreferences(QDialog):
|
|
87
86
|
self.mainForm.setHelpTextStyle(SHARED.theme.helpText)
|
88
87
|
|
89
88
|
# Buttons
|
90
|
-
self.buttonBox = QDialogButtonBox(
|
91
|
-
self.buttonBox.
|
89
|
+
self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogCancel, self)
|
90
|
+
self.buttonBox.accepted.connect(self._doSave)
|
91
|
+
self.buttonBox.rejected.connect(self.reject)
|
92
92
|
|
93
93
|
# Assemble
|
94
94
|
self.searchBox = QHBoxLayout()
|
@@ -546,7 +546,7 @@ class GuiPreferences(QDialog):
|
|
546
546
|
self.allowOpenDial = NSwitch(self)
|
547
547
|
self.allowOpenDial.setChecked(CONFIG.allowOpenDial)
|
548
548
|
self.mainForm.addRow(
|
549
|
-
self.tr("Allow open-ended
|
549
|
+
self.tr("Allow open-ended dialogue"), self.allowOpenDial,
|
550
550
|
self.tr("Highlight dialogue line with no closing quote.")
|
551
551
|
)
|
552
552
|
|
@@ -583,8 +583,8 @@ class GuiPreferences(QDialog):
|
|
583
583
|
self.altDialogClose.setText(CONFIG.altDialogClose)
|
584
584
|
|
585
585
|
self.mainForm.addRow(
|
586
|
-
self.tr("Alternative
|
587
|
-
self.tr("Custom highlighting of
|
586
|
+
self.tr("Alternative dialogue symbols"), [self.altDialogOpen, self.altDialogClose],
|
587
|
+
self.tr("Custom highlighting of dialogue text.")
|
588
588
|
)
|
589
589
|
|
590
590
|
self.highlightEmph = NSwitch(self)
|
@@ -693,64 +693,62 @@ class GuiPreferences(QDialog):
|
|
693
693
|
self.sidebar.addButton(title, section)
|
694
694
|
self.mainForm.addGroupLabel(title, section)
|
695
695
|
|
696
|
-
self.quoteSym = {}
|
697
|
-
|
698
696
|
# Single Quote Style
|
699
|
-
self.
|
700
|
-
self.
|
701
|
-
self.
|
702
|
-
self.
|
703
|
-
self.
|
704
|
-
self.
|
705
|
-
self.
|
706
|
-
self.
|
707
|
-
self.mainForm.addRow(
|
708
|
-
self.tr("Single quote open style"), self.
|
697
|
+
self.fmtSQuoteOpen = QLineEdit(self)
|
698
|
+
self.fmtSQuoteOpen.setMaxLength(1)
|
699
|
+
self.fmtSQuoteOpen.setReadOnly(True)
|
700
|
+
self.fmtSQuoteOpen.setFixedWidth(boxFixed)
|
701
|
+
self.fmtSQuoteOpen.setAlignment(QtAlignCenter)
|
702
|
+
self.fmtSQuoteOpen.setText(CONFIG.fmtSQuoteOpen)
|
703
|
+
self.btnSQuoteOpen = NIconToolButton(self, iSz, "quote")
|
704
|
+
self.btnSQuoteOpen.clicked.connect(self._changeSingleQuoteOpen)
|
705
|
+
self.mainForm.addRow(
|
706
|
+
self.tr("Single quote open style"), self.fmtSQuoteOpen,
|
709
707
|
self.tr("The symbol to use for a leading single quote."),
|
710
|
-
button=self.
|
708
|
+
button=self.btnSQuoteOpen
|
711
709
|
)
|
712
710
|
|
713
|
-
self.
|
714
|
-
self.
|
715
|
-
self.
|
716
|
-
self.
|
717
|
-
self.
|
718
|
-
self.
|
719
|
-
self.
|
720
|
-
self.
|
711
|
+
self.fmtSQuoteClose = QLineEdit(self)
|
712
|
+
self.fmtSQuoteClose.setMaxLength(1)
|
713
|
+
self.fmtSQuoteClose.setReadOnly(True)
|
714
|
+
self.fmtSQuoteClose.setFixedWidth(boxFixed)
|
715
|
+
self.fmtSQuoteClose.setAlignment(QtAlignCenter)
|
716
|
+
self.fmtSQuoteClose.setText(CONFIG.fmtSQuoteClose)
|
717
|
+
self.btnSQuoteClose = NIconToolButton(self, iSz, "quote")
|
718
|
+
self.btnSQuoteClose.clicked.connect(self._changeSingleQuoteClose)
|
721
719
|
self.mainForm.addRow(
|
722
|
-
self.tr("Single quote close style"), self.
|
720
|
+
self.tr("Single quote close style"), self.fmtSQuoteClose,
|
723
721
|
self.tr("The symbol to use for a trailing single quote."),
|
724
|
-
button=self.
|
722
|
+
button=self.btnSQuoteClose
|
725
723
|
)
|
726
724
|
|
727
725
|
# Double Quote Style
|
728
|
-
self.
|
729
|
-
self.
|
730
|
-
self.
|
731
|
-
self.
|
732
|
-
self.
|
733
|
-
self.
|
734
|
-
self.
|
735
|
-
self.
|
736
|
-
self.mainForm.addRow(
|
737
|
-
self.tr("Double quote open style"), self.
|
726
|
+
self.fmtDQuoteOpen = QLineEdit(self)
|
727
|
+
self.fmtDQuoteOpen.setMaxLength(1)
|
728
|
+
self.fmtDQuoteOpen.setReadOnly(True)
|
729
|
+
self.fmtDQuoteOpen.setFixedWidth(boxFixed)
|
730
|
+
self.fmtDQuoteOpen.setAlignment(QtAlignCenter)
|
731
|
+
self.fmtDQuoteOpen.setText(CONFIG.fmtDQuoteOpen)
|
732
|
+
self.btnDQuoteOpen = NIconToolButton(self, iSz, "quote")
|
733
|
+
self.btnDQuoteOpen.clicked.connect(self._changeDoubleQuoteOpen)
|
734
|
+
self.mainForm.addRow(
|
735
|
+
self.tr("Double quote open style"), self.fmtDQuoteOpen,
|
738
736
|
self.tr("The symbol to use for a leading double quote."),
|
739
|
-
button=self.
|
737
|
+
button=self.btnDQuoteOpen
|
740
738
|
)
|
741
739
|
|
742
|
-
self.
|
743
|
-
self.
|
744
|
-
self.
|
745
|
-
self.
|
746
|
-
self.
|
747
|
-
self.
|
748
|
-
self.
|
749
|
-
self.
|
740
|
+
self.fmtDQuoteClose = QLineEdit(self)
|
741
|
+
self.fmtDQuoteClose.setMaxLength(1)
|
742
|
+
self.fmtDQuoteClose.setReadOnly(True)
|
743
|
+
self.fmtDQuoteClose.setFixedWidth(boxFixed)
|
744
|
+
self.fmtDQuoteClose.setAlignment(QtAlignCenter)
|
745
|
+
self.fmtDQuoteClose.setText(CONFIG.fmtDQuoteClose)
|
746
|
+
self.btnDQuoteClose = NIconToolButton(self, iSz, "quote")
|
747
|
+
self.btnDQuoteClose.clicked.connect(self._changeDoubleQuoteClose)
|
750
748
|
self.mainForm.addRow(
|
751
|
-
self.tr("Double quote close style"), self.
|
749
|
+
self.tr("Double quote close style"), self.fmtDQuoteClose,
|
752
750
|
self.tr("The symbol to use for a trailing double quote."),
|
753
|
-
button=self.
|
751
|
+
button=self.btnDQuoteClose
|
754
752
|
)
|
755
753
|
|
756
754
|
self.mainForm.finalise()
|
@@ -767,13 +765,14 @@ class GuiPreferences(QDialog):
|
|
767
765
|
logger.debug("Close: GuiPreferences")
|
768
766
|
self._saveWindowSize()
|
769
767
|
event.accept()
|
770
|
-
|
771
|
-
self.done(nwConst.DLG_FINISHED)
|
772
|
-
self.deleteLater()
|
768
|
+
self.softDelete()
|
773
769
|
return
|
774
770
|
|
775
771
|
def keyPressEvent(self, event: QKeyEvent) -> None:
|
776
|
-
"""Overload keyPressEvent
|
772
|
+
"""Overload keyPressEvent and only accept escape. The main
|
773
|
+
purpose here is to prevent Enter/Return from closing the dialog
|
774
|
+
as it is used for the search box.
|
775
|
+
"""
|
777
776
|
if event.matches(QKeySequence.StandardKey.Cancel):
|
778
777
|
self.close()
|
779
778
|
event.ignore()
|
@@ -783,19 +782,6 @@ class GuiPreferences(QDialog):
|
|
783
782
|
# Private Slots
|
784
783
|
##
|
785
784
|
|
786
|
-
@pyqtSlot("QAbstractButton*")
|
787
|
-
def _dialogButtonClicked(self, button: QAbstractButton) -> None:
|
788
|
-
"""Handle button clicks from the dialog button box."""
|
789
|
-
role = self.buttonBox.buttonRole(button)
|
790
|
-
if role == QtRoleApply:
|
791
|
-
self._saveValues()
|
792
|
-
elif role == QtRoleAccept:
|
793
|
-
self._saveValues()
|
794
|
-
self.close()
|
795
|
-
elif role == QtRoleReject:
|
796
|
-
self.close()
|
797
|
-
return
|
798
|
-
|
799
785
|
@pyqtSlot(int)
|
800
786
|
def _sidebarClicked(self, section: int) -> None:
|
801
787
|
"""Process a user request to switch page."""
|
@@ -855,11 +841,36 @@ class GuiPreferences(QDialog):
|
|
855
841
|
self.fmtPadThin.setEnabled(state)
|
856
842
|
return
|
857
843
|
|
858
|
-
|
859
|
-
|
860
|
-
|
844
|
+
@pyqtSlot()
|
845
|
+
def _changeSingleQuoteOpen(self) -> None:
|
846
|
+
"""Change single quote open style."""
|
847
|
+
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteOpen.text())
|
861
848
|
if status:
|
862
|
-
self.
|
849
|
+
self.fmtSQuoteOpen.setText(quote)
|
850
|
+
return
|
851
|
+
|
852
|
+
@pyqtSlot()
|
853
|
+
def _changeSingleQuoteClose(self) -> None:
|
854
|
+
"""Change single quote close style."""
|
855
|
+
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtSQuoteClose.text())
|
856
|
+
if status:
|
857
|
+
self.fmtSQuoteClose.setText(quote)
|
858
|
+
return
|
859
|
+
|
860
|
+
@pyqtSlot()
|
861
|
+
def _changeDoubleQuoteOpen(self) -> None:
|
862
|
+
"""Change double quote open style."""
|
863
|
+
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteOpen.text())
|
864
|
+
if status:
|
865
|
+
self.fmtDQuoteOpen.setText(quote)
|
866
|
+
return
|
867
|
+
|
868
|
+
@pyqtSlot()
|
869
|
+
def _changeDoubleQuoteClose(self) -> None:
|
870
|
+
"""Change double quote close style."""
|
871
|
+
quote, status = GuiQuoteSelect.getQuote(self, current=self.fmtDQuoteClose.text())
|
872
|
+
if status:
|
873
|
+
self.fmtDQuoteClose.setText(quote)
|
863
874
|
return
|
864
875
|
|
865
876
|
##
|
@@ -871,7 +882,7 @@ class GuiPreferences(QDialog):
|
|
871
882
|
CONFIG.setPreferencesWinSize(self.width(), self.height())
|
872
883
|
return
|
873
884
|
|
874
|
-
def
|
885
|
+
def _doSave(self) -> None:
|
875
886
|
"""Save the values set in the form."""
|
876
887
|
updateTheme = False
|
877
888
|
needsRestart = False
|
@@ -879,8 +890,8 @@ class GuiPreferences(QDialog):
|
|
879
890
|
refreshTree = False
|
880
891
|
|
881
892
|
# Appearance
|
882
|
-
guiLocale
|
883
|
-
guiTheme
|
893
|
+
guiLocale = self.guiLocale.currentData()
|
894
|
+
guiTheme = self.guiTheme.currentData()
|
884
895
|
|
885
896
|
updateTheme |= CONFIG.guiTheme != guiTheme
|
886
897
|
needsRestart |= CONFIG.guiLocale != guiLocale
|
@@ -941,8 +952,8 @@ class GuiPreferences(QDialog):
|
|
941
952
|
# Text Highlighting
|
942
953
|
dialogueStyle = self.dialogStyle.currentData()
|
943
954
|
allowOpenDial = self.allowOpenDial.isChecked()
|
944
|
-
narratorBreak = self.narratorBreak.text()
|
945
|
-
dialogueLine = self.dialogLine.text()
|
955
|
+
narratorBreak = self.narratorBreak.text().strip()
|
956
|
+
dialogueLine = self.dialogLine.text().strip()
|
946
957
|
altDialogOpen = self.altDialogOpen.text()
|
947
958
|
altDialogClose = self.altDialogClose.text()
|
948
959
|
highlightEmph = self.highlightEmph.isChecked()
|
@@ -972,18 +983,20 @@ class GuiPreferences(QDialog):
|
|
972
983
|
CONFIG.doReplaceDQuote = self.doReplaceDQuote.isChecked()
|
973
984
|
CONFIG.doReplaceDash = self.doReplaceDash.isChecked()
|
974
985
|
CONFIG.doReplaceDots = self.doReplaceDots.isChecked()
|
975
|
-
CONFIG.fmtPadBefore = self.fmtPadBefore.text()
|
976
|
-
CONFIG.fmtPadAfter = self.fmtPadAfter.text()
|
986
|
+
CONFIG.fmtPadBefore = uniqueCompact(self.fmtPadBefore.text())
|
987
|
+
CONFIG.fmtPadAfter = uniqueCompact(self.fmtPadAfter.text())
|
977
988
|
CONFIG.fmtPadThin = self.fmtPadThin.isChecked()
|
978
989
|
|
979
990
|
# Quotation Style
|
980
|
-
CONFIG.fmtSQuoteOpen = self.
|
981
|
-
CONFIG.fmtSQuoteClose = self.
|
982
|
-
CONFIG.fmtDQuoteOpen = self.
|
983
|
-
CONFIG.fmtDQuoteClose = self.
|
991
|
+
CONFIG.fmtSQuoteOpen = self.fmtSQuoteOpen.text()
|
992
|
+
CONFIG.fmtSQuoteClose = self.fmtSQuoteClose.text()
|
993
|
+
CONFIG.fmtDQuoteOpen = self.fmtDQuoteOpen.text()
|
994
|
+
CONFIG.fmtDQuoteClose = self.fmtDQuoteClose.text()
|
984
995
|
|
985
996
|
# Finalise
|
986
997
|
CONFIG.saveConfig()
|
987
998
|
self.newPreferencesReady.emit(needsRestart, refreshTree, updateTheme, updateSyntax)
|
988
999
|
|
1000
|
+
self.close()
|
1001
|
+
|
989
1002
|
return
|