novelWriter 2.2rc1__py3-none-any.whl → 2.2.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.2rc1.dist-info → novelWriter-2.2.1.dist-info}/METADATA +1 -1
- {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/RECORD +113 -111
- {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +10 -5
- 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_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_de_DE.json +1 -0
- novelwriter/assets/i18n/project_en_US.json +1 -0
- novelwriter/assets/i18n/project_es_419.json +11 -0
- novelwriter/assets/i18n/project_fr_FR.json +11 -0
- novelwriter/assets/i18n/project_it_IT.json +11 -0
- novelwriter/assets/i18n/project_ja_JP.json +2 -1
- novelwriter/assets/i18n/project_nb_NO.json +1 -0
- novelwriter/assets/i18n/project_zh_CN.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +3 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
- novelwriter/assets/icons/typicons_light/icons.conf +3 -2
- novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/release_notes.htm +50 -7
- novelwriter/common.py +16 -29
- novelwriter/config.py +3 -3
- novelwriter/constants.py +1 -1
- novelwriter/core/buildsettings.py +1 -1
- novelwriter/core/coretools.py +2 -1
- novelwriter/core/docbuild.py +1 -1
- novelwriter/core/document.py +1 -1
- novelwriter/core/index.py +2 -2
- novelwriter/core/item.py +2 -2
- novelwriter/core/options.py +3 -3
- novelwriter/core/project.py +3 -3
- novelwriter/core/projectdata.py +2 -2
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/sessions.py +2 -2
- novelwriter/core/spellcheck.py +4 -3
- novelwriter/core/status.py +3 -3
- novelwriter/core/storage.py +1 -1
- novelwriter/core/tohtml.py +2 -2
- novelwriter/core/tokenizer.py +1 -1
- novelwriter/core/tomd.py +2 -2
- novelwriter/core/toodt.py +1 -1
- novelwriter/core/tree.py +2 -2
- novelwriter/dialogs/about.py +30 -31
- novelwriter/dialogs/docmerge.py +24 -15
- novelwriter/dialogs/docsplit.py +27 -16
- novelwriter/dialogs/editlabel.py +19 -7
- novelwriter/dialogs/preferences.py +44 -57
- novelwriter/dialogs/projdetails.py +29 -36
- novelwriter/dialogs/projload.py +32 -36
- novelwriter/dialogs/projsettings.py +20 -15
- novelwriter/dialogs/quotes.py +32 -25
- novelwriter/dialogs/updates.py +4 -14
- novelwriter/dialogs/wordlist.py +34 -21
- novelwriter/enum.py +5 -4
- novelwriter/error.py +1 -1
- novelwriter/extensions/circularprogress.py +1 -1
- novelwriter/extensions/configlayout.py +3 -15
- novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
- novelwriter/extensions/novelselector.py +1 -1
- novelwriter/extensions/pageddialog.py +1 -1
- novelwriter/extensions/pagedsidebar.py +2 -5
- novelwriter/extensions/simpleprogress.py +8 -9
- novelwriter/extensions/statusled.py +1 -1
- novelwriter/extensions/switch.py +4 -4
- novelwriter/extensions/switchbox.py +1 -6
- novelwriter/gui/doceditor.py +72 -64
- novelwriter/gui/dochighlight.py +3 -2
- novelwriter/gui/docviewer.py +22 -47
- novelwriter/gui/docviewerpanel.py +68 -23
- novelwriter/gui/editordocument.py +3 -3
- novelwriter/gui/itemdetails.py +2 -2
- novelwriter/gui/mainmenu.py +35 -30
- novelwriter/gui/noveltree.py +44 -53
- novelwriter/gui/outline.py +2 -1
- novelwriter/gui/projtree.py +5 -6
- novelwriter/gui/sidebar.py +6 -4
- novelwriter/gui/statusbar.py +47 -4
- novelwriter/gui/theme.py +5 -6
- novelwriter/guimain.py +139 -189
- novelwriter/shared.py +53 -29
- novelwriter/tools/dictionaries.py +2 -2
- novelwriter/tools/lipsum.py +34 -28
- novelwriter/tools/manusbuild.py +3 -4
- novelwriter/tools/manuscript.py +19 -26
- novelwriter/tools/manussettings.py +2 -4
- novelwriter/tools/projwizard.py +3 -3
- novelwriter/tools/writingstats.py +17 -4
- novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
- {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/top_level.txt +0 -0
@@ -3,10 +3,10 @@ novelWriter – GUI Preferences
|
|
3
3
|
=============================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2019-06-10 [0.1.5]
|
6
|
+
Created: 2019-06-10 [0.1.5] GuiPreferences
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright 2018–
|
9
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -25,11 +25,11 @@ from __future__ import annotations
|
|
25
25
|
|
26
26
|
import logging
|
27
27
|
|
28
|
-
from PyQt5.QtGui import QFont
|
29
|
-
from PyQt5.QtCore import Qt, pyqtSlot
|
28
|
+
from PyQt5.QtGui import QCloseEvent, QFont
|
29
|
+
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
30
30
|
from PyQt5.QtWidgets import (
|
31
31
|
QDialog, QWidget, QComboBox, QSpinBox, QPushButton, QDialogButtonBox,
|
32
|
-
QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox
|
32
|
+
QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox, qApp
|
33
33
|
)
|
34
34
|
|
35
35
|
from novelwriter import CONFIG, SHARED
|
@@ -43,6 +43,8 @@ logger = logging.getLogger(__name__)
|
|
43
43
|
|
44
44
|
class GuiPreferences(NPagedDialog):
|
45
45
|
|
46
|
+
newPreferencesReady = pyqtSignal(bool, bool, bool, bool)
|
47
|
+
|
46
48
|
def __init__(self, parent: QWidget) -> None:
|
47
49
|
super().__init__(parent=parent)
|
48
50
|
|
@@ -66,9 +68,10 @@ class GuiPreferences(NPagedDialog):
|
|
66
68
|
self.addTab(self.tabAuto, self.tr("Automation"))
|
67
69
|
self.addTab(self.tabQuote, self.tr("Quotes"))
|
68
70
|
|
69
|
-
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
71
|
+
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
|
70
72
|
self.buttonBox.accepted.connect(self._doSave)
|
71
|
-
self.buttonBox.rejected.connect(self.
|
73
|
+
self.buttonBox.rejected.connect(self.close)
|
74
|
+
self.rejected.connect(self.close)
|
72
75
|
self.addControls(self.buttonBox)
|
73
76
|
|
74
77
|
self.resize(*CONFIG.preferencesWinSize)
|
@@ -83,29 +86,21 @@ class GuiPreferences(NPagedDialog):
|
|
83
86
|
|
84
87
|
return
|
85
88
|
|
86
|
-
def __del__(self): # pragma: no cover
|
89
|
+
def __del__(self) -> None: # pragma: no cover
|
87
90
|
logger.debug("Delete: GuiPreferences")
|
88
91
|
return
|
89
92
|
|
90
93
|
##
|
91
|
-
#
|
94
|
+
# Events
|
92
95
|
##
|
93
96
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
return
|
101
|
-
|
102
|
-
@property
|
103
|
-
def needsRestart(self) -> bool:
|
104
|
-
return self._needsRestart
|
105
|
-
|
106
|
-
@property
|
107
|
-
def refreshTree(self) -> bool:
|
108
|
-
return self._refreshTree
|
97
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
98
|
+
"""Capture the close event and perform cleanup."""
|
99
|
+
logger.debug("Close: GuiPreferences")
|
100
|
+
self._saveWindowSize()
|
101
|
+
event.accept()
|
102
|
+
self.deleteLater()
|
103
|
+
return
|
109
104
|
|
110
105
|
##
|
111
106
|
# Private Slots
|
@@ -113,11 +108,7 @@ class GuiPreferences(NPagedDialog):
|
|
113
108
|
|
114
109
|
@pyqtSlot()
|
115
110
|
def _doSave(self) -> None:
|
116
|
-
"""Trigger
|
117
|
-
status of the saves.
|
118
|
-
"""
|
119
|
-
logger.debug("Saving new preferences")
|
120
|
-
|
111
|
+
"""Trigger save functions in the tabs and emit ready signal."""
|
121
112
|
self.tabGeneral.saveValues()
|
122
113
|
self.tabProjects.saveValues()
|
123
114
|
self.tabDocs.saveValues()
|
@@ -126,17 +117,13 @@ class GuiPreferences(NPagedDialog):
|
|
126
117
|
self.tabAuto.saveValues()
|
127
118
|
self.tabQuote.saveValues()
|
128
119
|
|
129
|
-
self._saveWindowSize()
|
130
120
|
CONFIG.saveConfig()
|
131
|
-
self.
|
132
|
-
|
133
|
-
|
121
|
+
self.newPreferencesReady.emit(
|
122
|
+
self._needsRestart, self._refreshTree, self._updateTheme, self._updateSyntax
|
123
|
+
)
|
124
|
+
qApp.processEvents()
|
125
|
+
self.close()
|
134
126
|
|
135
|
-
@pyqtSlot()
|
136
|
-
def _doClose(self) -> None:
|
137
|
-
"""Close the preferences without saving the changes."""
|
138
|
-
self._saveWindowSize()
|
139
|
-
self.reject()
|
140
127
|
return
|
141
128
|
|
142
129
|
##
|
@@ -169,7 +156,7 @@ class GuiPreferencesGeneral(QWidget):
|
|
169
156
|
minWidth = CONFIG.pxInt(200)
|
170
157
|
|
171
158
|
# Select Locale
|
172
|
-
self.guiLocale = QComboBox()
|
159
|
+
self.guiLocale = QComboBox(self)
|
173
160
|
self.guiLocale.setMinimumWidth(minWidth)
|
174
161
|
theLangs = CONFIG.listLanguages(CONFIG.LANG_NW)
|
175
162
|
for lang, langName in theLangs:
|
@@ -187,7 +174,7 @@ class GuiPreferencesGeneral(QWidget):
|
|
187
174
|
)
|
188
175
|
|
189
176
|
# Select Theme
|
190
|
-
self.guiTheme = QComboBox()
|
177
|
+
self.guiTheme = QComboBox(self)
|
191
178
|
self.guiTheme.setMinimumWidth(minWidth)
|
192
179
|
self.theThemes = SHARED.theme.listThemes()
|
193
180
|
for themeDir, themeName in self.theThemes:
|
@@ -203,7 +190,7 @@ class GuiPreferencesGeneral(QWidget):
|
|
203
190
|
)
|
204
191
|
|
205
192
|
# Editor Theme
|
206
|
-
self.guiSyntax = QComboBox()
|
193
|
+
self.guiSyntax = QComboBox(self)
|
207
194
|
self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200))
|
208
195
|
self.theSyntaxes = SHARED.theme.listSyntax()
|
209
196
|
for syntaxFile, syntaxName in self.theSyntaxes:
|
@@ -219,11 +206,11 @@ class GuiPreferencesGeneral(QWidget):
|
|
219
206
|
)
|
220
207
|
|
221
208
|
# Font Family
|
222
|
-
self.guiFont = QLineEdit()
|
209
|
+
self.guiFont = QLineEdit(self)
|
223
210
|
self.guiFont.setReadOnly(True)
|
224
211
|
self.guiFont.setFixedWidth(CONFIG.pxInt(162))
|
225
212
|
self.guiFont.setText(CONFIG.guiFont)
|
226
|
-
self.fontButton = QPushButton("...")
|
213
|
+
self.fontButton = QPushButton("...", self)
|
227
214
|
self.fontButton.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("...")))
|
228
215
|
self.fontButton.clicked.connect(self._selectFont)
|
229
216
|
self.mainForm.addRow(
|
@@ -378,7 +365,7 @@ class GuiPreferencesProjects(QWidget):
|
|
378
365
|
|
379
366
|
# Backup Path
|
380
367
|
self.backupPath = CONFIG.backupPath()
|
381
|
-
self.backupGetPath = QPushButton(self.tr("Browse"))
|
368
|
+
self.backupGetPath = QPushButton(self.tr("Browse"), self)
|
382
369
|
self.backupGetPath.clicked.connect(self._backupFolder)
|
383
370
|
self.backupPathRow = self.mainForm.addRow(
|
384
371
|
self.tr("Backup storage location"),
|
@@ -421,7 +408,7 @@ class GuiPreferencesProjects(QWidget):
|
|
421
408
|
)
|
422
409
|
|
423
410
|
# Inactive time for idle
|
424
|
-
self.userIdleTime = QDoubleSpinBox()
|
411
|
+
self.userIdleTime = QDoubleSpinBox(self)
|
425
412
|
self.userIdleTime.setMinimum(0.5)
|
426
413
|
self.userIdleTime.setMaximum(600.0)
|
427
414
|
self.userIdleTime.setSingleStep(0.5)
|
@@ -496,11 +483,11 @@ class GuiPreferencesDocuments(QWidget):
|
|
496
483
|
self.mainForm.addGroupLabel(self.tr("Text Style"))
|
497
484
|
|
498
485
|
# Font Family
|
499
|
-
self.textFont = QLineEdit()
|
486
|
+
self.textFont = QLineEdit(self)
|
500
487
|
self.textFont.setReadOnly(True)
|
501
488
|
self.textFont.setFixedWidth(CONFIG.pxInt(162))
|
502
489
|
self.textFont.setText(CONFIG.textFont)
|
503
|
-
self.fontButton = QPushButton("...")
|
490
|
+
self.fontButton = QPushButton("...", self)
|
504
491
|
self.fontButton.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("...")))
|
505
492
|
self.fontButton.clicked.connect(self._selectFont)
|
506
493
|
self.mainForm.addRow(
|
@@ -960,7 +947,7 @@ class GuiPreferencesAutomation(QWidget):
|
|
960
947
|
self.mainForm.addGroupLabel(self.tr("Automatic Padding"))
|
961
948
|
|
962
949
|
# Pad Before
|
963
|
-
self.fmtPadBefore = QLineEdit()
|
950
|
+
self.fmtPadBefore = QLineEdit(self)
|
964
951
|
self.fmtPadBefore.setMaxLength(32)
|
965
952
|
self.fmtPadBefore.setText(CONFIG.fmtPadBefore)
|
966
953
|
self.mainForm.addRow(
|
@@ -970,7 +957,7 @@ class GuiPreferencesAutomation(QWidget):
|
|
970
957
|
)
|
971
958
|
|
972
959
|
# Pad After
|
973
|
-
self.fmtPadAfter = QLineEdit()
|
960
|
+
self.fmtPadAfter = QLineEdit(self)
|
974
961
|
self.fmtPadAfter.setMaxLength(32)
|
975
962
|
self.fmtPadAfter.setText(CONFIG.fmtPadAfter)
|
976
963
|
self.mainForm.addRow(
|
@@ -1046,13 +1033,13 @@ class GuiPreferencesQuotes(QWidget):
|
|
1046
1033
|
self.quoteSym = {}
|
1047
1034
|
|
1048
1035
|
# Single Quote Style
|
1049
|
-
self.quoteSym["SO"] = QLineEdit()
|
1036
|
+
self.quoteSym["SO"] = QLineEdit(self)
|
1050
1037
|
self.quoteSym["SO"].setMaxLength(1)
|
1051
1038
|
self.quoteSym["SO"].setReadOnly(True)
|
1052
1039
|
self.quoteSym["SO"].setFixedWidth(qWidth)
|
1053
1040
|
self.quoteSym["SO"].setAlignment(Qt.AlignCenter)
|
1054
1041
|
self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen)
|
1055
|
-
self.btnSingleStyleO = QPushButton("...")
|
1042
|
+
self.btnSingleStyleO = QPushButton("...", self)
|
1056
1043
|
self.btnSingleStyleO.setMaximumWidth(bWidth)
|
1057
1044
|
self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO"))
|
1058
1045
|
self.mainForm.addRow(
|
@@ -1062,13 +1049,13 @@ class GuiPreferencesQuotes(QWidget):
|
|
1062
1049
|
button=self.btnSingleStyleO
|
1063
1050
|
)
|
1064
1051
|
|
1065
|
-
self.quoteSym["SC"] = QLineEdit()
|
1052
|
+
self.quoteSym["SC"] = QLineEdit(self)
|
1066
1053
|
self.quoteSym["SC"].setMaxLength(1)
|
1067
1054
|
self.quoteSym["SC"].setReadOnly(True)
|
1068
1055
|
self.quoteSym["SC"].setFixedWidth(qWidth)
|
1069
1056
|
self.quoteSym["SC"].setAlignment(Qt.AlignCenter)
|
1070
1057
|
self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose)
|
1071
|
-
self.btnSingleStyleC = QPushButton("...")
|
1058
|
+
self.btnSingleStyleC = QPushButton("...", self)
|
1072
1059
|
self.btnSingleStyleC.setMaximumWidth(bWidth)
|
1073
1060
|
self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC"))
|
1074
1061
|
self.mainForm.addRow(
|
@@ -1079,13 +1066,13 @@ class GuiPreferencesQuotes(QWidget):
|
|
1079
1066
|
)
|
1080
1067
|
|
1081
1068
|
# Double Quote Style
|
1082
|
-
self.quoteSym["DO"] = QLineEdit()
|
1069
|
+
self.quoteSym["DO"] = QLineEdit(self)
|
1083
1070
|
self.quoteSym["DO"].setMaxLength(1)
|
1084
1071
|
self.quoteSym["DO"].setReadOnly(True)
|
1085
1072
|
self.quoteSym["DO"].setFixedWidth(qWidth)
|
1086
1073
|
self.quoteSym["DO"].setAlignment(Qt.AlignCenter)
|
1087
1074
|
self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen)
|
1088
|
-
self.btnDoubleStyleO = QPushButton("...")
|
1075
|
+
self.btnDoubleStyleO = QPushButton("...", self)
|
1089
1076
|
self.btnDoubleStyleO.setMaximumWidth(bWidth)
|
1090
1077
|
self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO"))
|
1091
1078
|
self.mainForm.addRow(
|
@@ -1095,13 +1082,13 @@ class GuiPreferencesQuotes(QWidget):
|
|
1095
1082
|
button=self.btnDoubleStyleO
|
1096
1083
|
)
|
1097
1084
|
|
1098
|
-
self.quoteSym["DC"] = QLineEdit()
|
1085
|
+
self.quoteSym["DC"] = QLineEdit(self)
|
1099
1086
|
self.quoteSym["DC"].setMaxLength(1)
|
1100
1087
|
self.quoteSym["DC"].setReadOnly(True)
|
1101
1088
|
self.quoteSym["DC"].setFixedWidth(qWidth)
|
1102
1089
|
self.quoteSym["DC"].setAlignment(Qt.AlignCenter)
|
1103
1090
|
self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose)
|
1104
|
-
self.btnDoubleStyleC = QPushButton("...")
|
1091
|
+
self.btnDoubleStyleC = QPushButton("...", self)
|
1105
1092
|
self.btnDoubleStyleC.setMaximumWidth(bWidth)
|
1106
1093
|
self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC"))
|
1107
1094
|
self.mainForm.addRow(
|
@@ -3,10 +3,10 @@ novelWriter – GUI Project Details
|
|
3
3
|
=================================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2021-01-03 [1.1rc1]
|
6
|
+
Created: 2021-01-03 [1.1rc1] GuiProjectDetails
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright 2018–
|
9
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -26,8 +26,8 @@ from __future__ import annotations
|
|
26
26
|
import math
|
27
27
|
import logging
|
28
28
|
|
29
|
+
from PyQt5.QtGui import QCloseEvent, QFont
|
29
30
|
from PyQt5.QtCore import Qt, QSize, pyqtSlot
|
30
|
-
from PyQt5.QtGui import QFont
|
31
31
|
from PyQt5.QtWidgets import (
|
32
32
|
QAbstractItemView, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel,
|
33
33
|
QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
@@ -45,7 +45,7 @@ logger = logging.getLogger(__name__)
|
|
45
45
|
|
46
46
|
class GuiProjectDetails(NPagedDialog):
|
47
47
|
|
48
|
-
def __init__(self, parent):
|
48
|
+
def __init__(self, parent: QWidget) -> None:
|
49
49
|
super().__init__(parent=parent)
|
50
50
|
|
51
51
|
logger.debug("Create: GuiProjectDetails")
|
@@ -71,43 +71,41 @@ class GuiProjectDetails(NPagedDialog):
|
|
71
71
|
self.addTab(self.tabContents, self.tr("Contents"))
|
72
72
|
|
73
73
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
74
|
-
self.buttonBox.
|
75
|
-
self.
|
74
|
+
self.buttonBox.rejected.connect(self.close)
|
75
|
+
self.rejected.connect(self.close)
|
76
76
|
self.addControls(self.buttonBox)
|
77
77
|
|
78
78
|
logger.debug("Ready: GuiProjectDetails")
|
79
79
|
|
80
80
|
return
|
81
81
|
|
82
|
-
def __del__(self): # pragma: no cover
|
82
|
+
def __del__(self) -> None: # pragma: no cover
|
83
83
|
logger.debug("Delete: GuiProjectDetails")
|
84
84
|
return
|
85
85
|
|
86
|
-
def updateValues(self):
|
87
|
-
"""Set all the values of the pages.
|
88
|
-
"""
|
86
|
+
def updateValues(self) -> None:
|
87
|
+
"""Set all the values of the pages."""
|
89
88
|
self.tabMain.updateValues()
|
90
89
|
self.tabContents.updateValues()
|
91
90
|
return
|
92
91
|
|
93
92
|
##
|
94
|
-
#
|
93
|
+
# Events
|
95
94
|
##
|
96
95
|
|
97
|
-
def
|
98
|
-
"""
|
99
|
-
"""
|
96
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
97
|
+
"""Capture the close event and perform cleanup."""
|
100
98
|
self._saveGuiSettings()
|
101
|
-
|
99
|
+
event.accept()
|
100
|
+
self.deleteLater()
|
102
101
|
return
|
103
102
|
|
104
103
|
##
|
105
104
|
# Internal Functions
|
106
105
|
##
|
107
106
|
|
108
|
-
def _saveGuiSettings(self):
|
109
|
-
"""Save GUI settings.
|
110
|
-
"""
|
107
|
+
def _saveGuiSettings(self) -> None:
|
108
|
+
"""Save GUI settings."""
|
111
109
|
winWidth = CONFIG.rpxInt(self.width())
|
112
110
|
winHeight = CONFIG.rpxInt(self.height())
|
113
111
|
|
@@ -122,6 +120,7 @@ class GuiProjectDetails(NPagedDialog):
|
|
122
120
|
countFrom = self.tabContents.poValue.value()
|
123
121
|
clearDouble = self.tabContents.dblValue.isChecked()
|
124
122
|
|
123
|
+
logger.debug("Saving State: GuiProjectDetails")
|
125
124
|
pOptions = SHARED.project.options
|
126
125
|
pOptions.setValue("GuiProjectDetails", "winWidth", winWidth)
|
127
126
|
pOptions.setValue("GuiProjectDetails", "winHeight", winHeight)
|
@@ -141,7 +140,7 @@ class GuiProjectDetails(NPagedDialog):
|
|
141
140
|
|
142
141
|
class GuiProjectDetailsMain(QWidget):
|
143
142
|
|
144
|
-
def __init__(self, parent):
|
143
|
+
def __init__(self, parent: QWidget) -> None:
|
145
144
|
super().__init__(parent=parent)
|
146
145
|
|
147
146
|
fPx = SHARED.theme.fontPixelSize
|
@@ -270,7 +269,7 @@ class GuiProjectDetailsContents(QWidget):
|
|
270
269
|
C_PAGE = 3
|
271
270
|
C_PROG = 4
|
272
271
|
|
273
|
-
def __init__(self, parent):
|
272
|
+
def __init__(self, parent: QWidget) -> None:
|
274
273
|
super().__init__(parent=parent)
|
275
274
|
|
276
275
|
# Internal
|
@@ -406,9 +405,8 @@ class GuiProjectDetailsContents(QWidget):
|
|
406
405
|
|
407
406
|
return
|
408
407
|
|
409
|
-
def getColumnSizes(self):
|
410
|
-
"""Return the column widths for the tree columns.
|
411
|
-
"""
|
408
|
+
def getColumnSizes(self) -> list[int]:
|
409
|
+
"""Return the column widths for the tree columns."""
|
412
410
|
retVals = [
|
413
411
|
self.tocTree.columnWidth(0),
|
414
412
|
self.tocTree.columnWidth(1),
|
@@ -418,24 +416,21 @@ class GuiProjectDetailsContents(QWidget):
|
|
418
416
|
]
|
419
417
|
return retVals
|
420
418
|
|
421
|
-
def updateValues(self):
|
422
|
-
"""Populate the tree.
|
423
|
-
"""
|
419
|
+
def updateValues(self) -> None:
|
420
|
+
"""Populate the tree."""
|
424
421
|
self._currentRoot = None
|
425
422
|
self.novelValue.updateList()
|
426
423
|
self.novelValue.setHandle(self.novelValue.firstHandle)
|
427
424
|
self._prepareData(self.novelValue.firstHandle)
|
428
425
|
self._populateTree()
|
429
|
-
|
430
426
|
return
|
431
427
|
|
432
428
|
##
|
433
429
|
# Internal Functions
|
434
430
|
##
|
435
431
|
|
436
|
-
def _prepareData(self, rootHandle):
|
437
|
-
"""Extract the information from the project index.
|
438
|
-
"""
|
432
|
+
def _prepareData(self, rootHandle: str | None) -> None:
|
433
|
+
"""Extract the information from the project index."""
|
439
434
|
logger.debug("Populating ToC from handle '%s'", rootHandle)
|
440
435
|
self._theToC = SHARED.project.index.getTableOfContents(rootHandle, 2)
|
441
436
|
self._theToC.append(("", 0, self.tr("END"), 0))
|
@@ -446,9 +441,8 @@ class GuiProjectDetailsContents(QWidget):
|
|
446
441
|
##
|
447
442
|
|
448
443
|
@pyqtSlot(str)
|
449
|
-
def _novelValueChanged(self, tHandle):
|
450
|
-
"""Refresh the tree with another root item.
|
451
|
-
"""
|
444
|
+
def _novelValueChanged(self, tHandle: str) -> None:
|
445
|
+
"""Refresh the tree with another root item."""
|
452
446
|
if tHandle != self._currentRoot:
|
453
447
|
self._prepareData(tHandle)
|
454
448
|
self._populateTree()
|
@@ -456,9 +450,8 @@ class GuiProjectDetailsContents(QWidget):
|
|
456
450
|
return
|
457
451
|
|
458
452
|
@pyqtSlot()
|
459
|
-
def _populateTree(self):
|
460
|
-
"""Set the content of the chapter/page tree.
|
461
|
-
"""
|
453
|
+
def _populateTree(self) -> None:
|
454
|
+
"""Set the content of the chapter/page tree."""
|
462
455
|
dblPages = self.dblValue.isChecked()
|
463
456
|
wpPage = self.wpValue.value()
|
464
457
|
fstPage = self.poValue.value() - 1
|
novelwriter/dialogs/projload.py
CHANGED
@@ -3,10 +3,10 @@ novelWriter – GUI Open Project
|
|
3
3
|
==============================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2020-02-26 [0.4.5]
|
6
|
+
Created: 2020-02-26 [0.4.5] GuiProjectLoad
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright 2018–
|
9
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -29,8 +29,8 @@ from typing import TYPE_CHECKING
|
|
29
29
|
from pathlib import Path
|
30
30
|
from datetime import datetime
|
31
31
|
|
32
|
-
from PyQt5.QtGui import QKeySequence
|
33
|
-
from PyQt5.QtCore import Qt, QSize
|
32
|
+
from PyQt5.QtGui import QCloseEvent, QKeySequence
|
33
|
+
from PyQt5.QtCore import Qt, QSize, pyqtSlot
|
34
34
|
from PyQt5.QtWidgets import (
|
35
35
|
QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QTreeWidget,
|
36
36
|
QAbstractItemView, QTreeWidgetItem, QDialogButtonBox, QLabel, QShortcut,
|
@@ -112,8 +112,7 @@ class GuiProjectLoad(QDialog):
|
|
112
112
|
self.selPath = QLineEdit("")
|
113
113
|
self.selPath.setReadOnly(True)
|
114
114
|
|
115
|
-
self.browseButton = QPushButton("
|
116
|
-
self.browseButton.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("...")))
|
115
|
+
self.browseButton = QPushButton(SHARED.theme.getIcon("browse"), "", self)
|
117
116
|
self.browseButton.clicked.connect(self._doBrowse)
|
118
117
|
|
119
118
|
self.projectForm.addWidget(self.lblRecent, 0, 0, 1, 3)
|
@@ -154,17 +153,17 @@ class GuiProjectLoad(QDialog):
|
|
154
153
|
|
155
154
|
return
|
156
155
|
|
157
|
-
def __del__(self): # pragma: no cover
|
156
|
+
def __del__(self) -> None: # pragma: no cover
|
158
157
|
logger.debug("Delete: GuiProjectLoad")
|
159
158
|
return
|
160
159
|
|
161
160
|
##
|
162
|
-
#
|
161
|
+
# Private Slots
|
163
162
|
##
|
164
163
|
|
165
|
-
|
166
|
-
|
167
|
-
"""
|
164
|
+
@pyqtSlot()
|
165
|
+
def _doOpenRecent(self) -> None:
|
166
|
+
"""Close the dialog window with a recent project selected."""
|
168
167
|
self._saveSettings()
|
169
168
|
|
170
169
|
self.openPath = None
|
@@ -178,17 +177,17 @@ class GuiProjectLoad(QDialog):
|
|
178
177
|
|
179
178
|
return
|
180
179
|
|
181
|
-
|
182
|
-
|
183
|
-
"""
|
180
|
+
@pyqtSlot()
|
181
|
+
def _doSelectRecent(self) -> None:
|
182
|
+
"""Update path when a recent item has been selected."""
|
184
183
|
selList = self.listBox.selectedItems()
|
185
184
|
if selList:
|
186
185
|
self.selPath.setText(selList[0].data(self.C_NAME, self.D_PATH))
|
187
186
|
return
|
188
187
|
|
189
|
-
|
190
|
-
|
191
|
-
"""
|
188
|
+
@pyqtSlot()
|
189
|
+
def _doBrowse(self) -> None:
|
190
|
+
"""Browse for a folder path."""
|
192
191
|
extFilter = [
|
193
192
|
self.tr("novelWriter Project File ({0})").format(nwFiles.PROJ_FILE),
|
194
193
|
self.tr("All files ({0})").format("*"),
|
@@ -205,26 +204,26 @@ class GuiProjectLoad(QDialog):
|
|
205
204
|
|
206
205
|
return
|
207
206
|
|
208
|
-
|
209
|
-
|
210
|
-
"""
|
207
|
+
@pyqtSlot()
|
208
|
+
def _doCancel(self) -> None:
|
209
|
+
"""Close the dialog window without doing anything."""
|
211
210
|
self.openPath = None
|
212
211
|
self.openState = self.NONE_STATE
|
213
212
|
self.close()
|
214
213
|
return
|
215
214
|
|
216
|
-
|
217
|
-
|
218
|
-
"""
|
215
|
+
@pyqtSlot()
|
216
|
+
def _doNewProject(self) -> None:
|
217
|
+
"""Create a new project."""
|
219
218
|
self._saveSettings()
|
220
219
|
self.openPath = None
|
221
220
|
self.openState = self.NEW_STATE
|
222
221
|
self.accept()
|
223
222
|
return
|
224
223
|
|
225
|
-
|
226
|
-
|
227
|
-
"""
|
224
|
+
@pyqtSlot()
|
225
|
+
def _doDeleteRecent(self) -> None:
|
226
|
+
"""Remove an entry from the recent projects list."""
|
228
227
|
selList = self.listBox.selectedItems()
|
229
228
|
if selList:
|
230
229
|
projName = selList[0].text(self.C_NAME)
|
@@ -244,20 +243,18 @@ class GuiProjectLoad(QDialog):
|
|
244
243
|
# Events
|
245
244
|
##
|
246
245
|
|
247
|
-
def closeEvent(self,
|
248
|
-
"""Capture the user closing the dialog
|
249
|
-
"""
|
246
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
247
|
+
"""Capture the user closing the dialog and save settings."""
|
250
248
|
self._saveSettings()
|
251
|
-
|
249
|
+
event.accept()
|
252
250
|
return
|
253
251
|
|
254
252
|
##
|
255
253
|
# Internal Functions
|
256
254
|
##
|
257
255
|
|
258
|
-
def _saveSettings(self):
|
259
|
-
"""Save the changes made to the dialog.
|
260
|
-
"""
|
256
|
+
def _saveSettings(self) -> None:
|
257
|
+
"""Save the changes made to the dialog."""
|
261
258
|
colWidths = [0, 0, 0]
|
262
259
|
colWidths[self.C_NAME] = self.listBox.columnWidth(self.C_NAME)
|
263
260
|
colWidths[self.C_COUNT] = self.listBox.columnWidth(self.C_COUNT)
|
@@ -265,9 +262,8 @@ class GuiProjectLoad(QDialog):
|
|
265
262
|
CONFIG.setProjLoadColWidths(colWidths)
|
266
263
|
return
|
267
264
|
|
268
|
-
def _populateList(self):
|
269
|
-
"""Populate the list box with recent project data.
|
270
|
-
"""
|
265
|
+
def _populateList(self) -> None:
|
266
|
+
"""Populate the list box with recent project data."""
|
271
267
|
self.listBox.clear()
|
272
268
|
dataList = CONFIG.recentProjects.listEntries()
|
273
269
|
sortList = sorted(dataList, key=lambda x: x[3], reverse=True)
|