novelWriter 2.2b1__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.2b1.dist-info → novelWriter-2.2.1.dist-info}/METADATA +3 -3
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/RECORD +128 -114
- {novelWriter-2.2b1.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_GB.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/novelwriter.ico +0 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +11 -3
- novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_panel.svg +4 -0
- 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_dark/typ_eye.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +11 -3
- novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_panel.svg +4 -0
- 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/icons/typicons_light/typ_eye.svg +4 -0
- novelwriter/assets/icons/x-novelwriter-project.ico +0 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/release_notes.htm +50 -7
- novelwriter/common.py +35 -27
- novelwriter/config.py +13 -28
- novelwriter/constants.py +21 -4
- novelwriter/core/buildsettings.py +2 -2
- novelwriter/core/coretools.py +8 -2
- novelwriter/core/docbuild.py +1 -1
- novelwriter/core/document.py +1 -1
- novelwriter/core/index.py +102 -36
- novelwriter/core/item.py +2 -2
- novelwriter/core/options.py +6 -3
- novelwriter/core/project.py +5 -5
- novelwriter/core/projectdata.py +3 -3
- 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 +11 -5
- novelwriter/core/tokenizer.py +28 -21
- novelwriter/core/tomd.py +6 -2
- novelwriter/core/toodt.py +12 -5
- 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 +116 -131
- 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 +17 -16
- novelwriter/dialogs/wordlist.py +34 -21
- novelwriter/enum.py +19 -8
- 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 +349 -236
- novelwriter/gui/dochighlight.py +10 -11
- novelwriter/gui/docviewer.py +158 -360
- novelwriter/gui/docviewerpanel.py +502 -0
- novelwriter/gui/editordocument.py +4 -4
- novelwriter/gui/itemdetails.py +2 -2
- novelwriter/gui/mainmenu.py +50 -36
- novelwriter/gui/noveltree.py +44 -53
- novelwriter/gui/outline.py +12 -7
- novelwriter/gui/projtree.py +465 -381
- novelwriter/gui/sidebar.py +9 -7
- novelwriter/gui/statusbar.py +48 -5
- novelwriter/gui/theme.py +26 -8
- novelwriter/guimain.py +212 -208
- novelwriter/shared.py +76 -30
- novelwriter/tools/dictionaries.py +268 -0
- novelwriter/tools/lipsum.py +34 -28
- novelwriter/tools/manusbuild.py +20 -10
- novelwriter/tools/manuscript.py +20 -27
- novelwriter/tools/manussettings.py +2 -4
- novelwriter/tools/projwizard.py +3 -3
- novelwriter/tools/writingstats.py +18 -5
- 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_dark/typ_at.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_light/typ_at.svg +0 -4
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/top_level.txt +0 -0
@@ -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)
|
@@ -3,10 +3,10 @@ novelWriter – GUI Project Settings
|
|
3
3
|
==================================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2018-09-29 [0.0.1]
|
6
|
+
Created: 2018-09-29 [0.0.1] GuiProjectSettings
|
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
|
@@ -27,11 +27,11 @@ import logging
|
|
27
27
|
|
28
28
|
from typing import TYPE_CHECKING
|
29
29
|
|
30
|
-
from PyQt5.QtGui import QIcon, QPixmap, QColor
|
31
|
-
from PyQt5.QtCore import Qt, pyqtSlot
|
30
|
+
from PyQt5.QtGui import QCloseEvent, QIcon, QPixmap, QColor
|
31
|
+
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
32
32
|
from PyQt5.QtWidgets import (
|
33
33
|
QColorDialog, QComboBox, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit,
|
34
|
-
QPushButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
34
|
+
QPushButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, qApp
|
35
35
|
)
|
36
36
|
|
37
37
|
from novelwriter import CONFIG, SHARED
|
@@ -53,6 +53,8 @@ class GuiProjectSettings(NPagedDialog):
|
|
53
53
|
TAB_IMPORT = 2
|
54
54
|
TAB_REPLACE = 3
|
55
55
|
|
56
|
+
newProjectSettingsReady = pyqtSignal()
|
57
|
+
|
56
58
|
def __init__(self, mainGui: GuiMain, focusTab: int = TAB_MAIN) -> None:
|
57
59
|
super().__init__(parent=mainGui)
|
58
60
|
|
@@ -86,7 +88,8 @@ class GuiProjectSettings(NPagedDialog):
|
|
86
88
|
|
87
89
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
88
90
|
self.buttonBox.accepted.connect(self._doSave)
|
89
|
-
self.buttonBox.rejected.connect(self.
|
91
|
+
self.buttonBox.rejected.connect(self.close)
|
92
|
+
self.rejected.connect(self.close)
|
90
93
|
self.addControls(self.buttonBox)
|
91
94
|
|
92
95
|
# Focus Tab
|
@@ -100,6 +103,13 @@ class GuiProjectSettings(NPagedDialog):
|
|
100
103
|
logger.debug("Delete: GuiProjectSettings")
|
101
104
|
return
|
102
105
|
|
106
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
107
|
+
"""Capture the close event and perform cleanup."""
|
108
|
+
self._saveGuiSettings()
|
109
|
+
event.accept()
|
110
|
+
self.deleteLater()
|
111
|
+
return
|
112
|
+
|
103
113
|
##
|
104
114
|
# Private Slots
|
105
115
|
##
|
@@ -137,18 +147,12 @@ class GuiProjectSettings(NPagedDialog):
|
|
137
147
|
newList = self.tabReplace.getNewList()
|
138
148
|
project.data.setAutoReplace(newList)
|
139
149
|
|
140
|
-
self.
|
141
|
-
|
150
|
+
self.newProjectSettingsReady.emit()
|
151
|
+
qApp.processEvents()
|
152
|
+
self.close()
|
142
153
|
|
143
154
|
return
|
144
155
|
|
145
|
-
@pyqtSlot()
|
146
|
-
def _doClose(self) -> None:
|
147
|
-
"""Save settings and close the dialog."""
|
148
|
-
self._saveGuiSettings()
|
149
|
-
self.reject()
|
150
|
-
return
|
151
|
-
|
152
156
|
##
|
153
157
|
# Internal Functions
|
154
158
|
##
|
@@ -173,6 +177,7 @@ class GuiProjectSettings(NPagedDialog):
|
|
173
177
|
statusColW = CONFIG.rpxInt(self.tabStatus.listBox.columnWidth(0))
|
174
178
|
importColW = CONFIG.rpxInt(self.tabImport.listBox.columnWidth(0))
|
175
179
|
|
180
|
+
logger.debug("Saving State: GuiProjectSettings")
|
176
181
|
pOptions = SHARED.project.options
|
177
182
|
pOptions.setValue("GuiProjectSettings", "winWidth", winWidth)
|
178
183
|
pOptions.setValue("GuiProjectSettings", "winHeight", winHeight)
|
novelwriter/dialogs/quotes.py
CHANGED
@@ -3,10 +3,10 @@ novelWriter – GUI Quotes Dialog
|
|
3
3
|
===============================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2020-06-18 [0.9]
|
6
|
+
Created: 2020-06-18 [0.9.0] GuiQuoteSelect
|
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 QFontMetrics
|
29
|
-
from PyQt5.QtCore import Qt,
|
28
|
+
from PyQt5.QtGui import QCloseEvent, QFontMetrics
|
29
|
+
from PyQt5.QtCore import QSize, Qt, pyqtSlot
|
30
30
|
from PyQt5.QtWidgets import (
|
31
|
-
|
32
|
-
|
31
|
+
QDialog, QDialogButtonBox, QFrame, QHBoxLayout, QLabel, QListWidget,
|
32
|
+
QListWidgetItem, QVBoxLayout, QWidget
|
33
33
|
)
|
34
34
|
|
35
35
|
from novelwriter import CONFIG
|
@@ -44,9 +44,12 @@ class GuiQuoteSelect(QDialog):
|
|
44
44
|
|
45
45
|
D_KEY = Qt.ItemDataRole.UserRole
|
46
46
|
|
47
|
-
def __init__(self, parent
|
47
|
+
def __init__(self, parent: QWidget, currentQuote: str = '"') -> None:
|
48
48
|
super().__init__(parent=parent)
|
49
49
|
|
50
|
+
logger.debug("Create: GuiQuoteSelect")
|
51
|
+
self.setObjectName("GuiQuoteSelect")
|
52
|
+
|
50
53
|
self.outerBox = QVBoxLayout()
|
51
54
|
self.innerBox = QHBoxLayout()
|
52
55
|
self.labelBox = QVBoxLayout()
|
@@ -87,8 +90,8 @@ class GuiQuoteSelect(QDialog):
|
|
87
90
|
|
88
91
|
# Buttons
|
89
92
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
90
|
-
self.buttonBox.accepted.connect(self.
|
91
|
-
self.buttonBox.rejected.connect(self.
|
93
|
+
self.buttonBox.accepted.connect(self.accept)
|
94
|
+
self.buttonBox.rejected.connect(self.reject)
|
92
95
|
|
93
96
|
# Assemble
|
94
97
|
self.labelBox.addWidget(self.previewLabel, 0, Qt.AlignTop)
|
@@ -102,15 +105,31 @@ class GuiQuoteSelect(QDialog):
|
|
102
105
|
|
103
106
|
self.setLayout(self.outerBox)
|
104
107
|
|
108
|
+
logger.debug("Ready: GuiQuoteSelect")
|
109
|
+
|
110
|
+
return
|
111
|
+
|
112
|
+
def __del__(self) -> None: # pragma: no cover
|
113
|
+
logger.debug("Delete: GuiQuoteSelect")
|
105
114
|
return
|
106
115
|
|
107
116
|
##
|
108
|
-
#
|
117
|
+
# Events
|
109
118
|
##
|
110
119
|
|
111
|
-
def
|
112
|
-
"""
|
113
|
-
|
120
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
121
|
+
"""Capture the close event and perform cleanup."""
|
122
|
+
event.accept()
|
123
|
+
self.deleteLater()
|
124
|
+
return
|
125
|
+
|
126
|
+
##
|
127
|
+
# Private Slots
|
128
|
+
##
|
129
|
+
|
130
|
+
@pyqtSlot()
|
131
|
+
def _selectedSymbol(self) -> None:
|
132
|
+
"""Update the preview label and the selected quote style."""
|
114
133
|
selItems = self.listBox.selectedItems()
|
115
134
|
if selItems:
|
116
135
|
theSymbol = selItems[0].data(self.D_KEY)
|
@@ -118,16 +137,4 @@ class GuiQuoteSelect(QDialog):
|
|
118
137
|
self.selectedQuote = theSymbol
|
119
138
|
return
|
120
139
|
|
121
|
-
def _doAccept(self):
|
122
|
-
"""Ok button clicked.
|
123
|
-
"""
|
124
|
-
self.accept()
|
125
|
-
return
|
126
|
-
|
127
|
-
def _doReject(self):
|
128
|
-
"""Cancel button clicked.
|
129
|
-
"""
|
130
|
-
self.reject()
|
131
|
-
return
|
132
|
-
|
133
140
|
# END Class GuiQuoteSelect
|
novelwriter/dialogs/updates.py
CHANGED
@@ -3,10 +3,10 @@ novelWriter – GUI Updates
|
|
3
3
|
=========================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2021-08-21 [1.5b1]
|
6
|
+
Created: 2021-08-21 [1.5b1] GuiUpdates
|
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,10 +29,10 @@ import logging
|
|
29
29
|
from datetime import datetime
|
30
30
|
from urllib.request import Request, urlopen
|
31
31
|
|
32
|
-
from PyQt5.QtGui import QCursor
|
32
|
+
from PyQt5.QtGui import QCloseEvent, QCursor
|
33
33
|
from PyQt5.QtCore import Qt
|
34
34
|
from PyQt5.QtWidgets import (
|
35
|
-
qApp, QDialog, QHBoxLayout, QVBoxLayout, QDialogButtonBox, QLabel
|
35
|
+
QWidget, qApp, QDialog, QHBoxLayout, QVBoxLayout, QDialogButtonBox, QLabel
|
36
36
|
)
|
37
37
|
|
38
38
|
from novelwriter import CONFIG, SHARED, __version__, __date__
|
@@ -44,8 +44,8 @@ logger = logging.getLogger(__name__)
|
|
44
44
|
|
45
45
|
class GuiUpdates(QDialog):
|
46
46
|
|
47
|
-
def __init__(self,
|
48
|
-
super().__init__(parent=
|
47
|
+
def __init__(self, parent: QWidget) -> None:
|
48
|
+
super().__init__(parent=parent)
|
49
49
|
|
50
50
|
logger.debug("Create: GuiUpdates")
|
51
51
|
self.setObjectName("GuiUpdates")
|
@@ -94,8 +94,8 @@ class GuiUpdates(QDialog):
|
|
94
94
|
self.latestLabel.setFont(hFont)
|
95
95
|
|
96
96
|
# Buttons
|
97
|
-
self.buttonBox = QDialogButtonBox(QDialogButtonBox.
|
98
|
-
self.buttonBox.
|
97
|
+
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
98
|
+
self.buttonBox.rejected.connect(self.close)
|
99
99
|
|
100
100
|
# Assemble
|
101
101
|
self.innerBox = QHBoxLayout()
|
@@ -114,17 +114,16 @@ class GuiUpdates(QDialog):
|
|
114
114
|
|
115
115
|
return
|
116
116
|
|
117
|
-
def __del__(self): # pragma: no cover
|
117
|
+
def __del__(self) -> None: # pragma: no cover
|
118
118
|
logger.debug("Delete: GuiUpdates")
|
119
119
|
return
|
120
120
|
|
121
|
-
def checkLatest(self):
|
122
|
-
"""Check for latest release.
|
123
|
-
"""
|
121
|
+
def checkLatest(self) -> None:
|
122
|
+
"""Check for latest release."""
|
124
123
|
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
125
124
|
|
126
125
|
urlReq = Request("https://api.github.com/repos/vkbo/novelwriter/releases/latest")
|
127
|
-
urlReq.add_header("User-Agent",
|
126
|
+
urlReq.add_header("User-Agent", nwConst.USER_AGENT)
|
128
127
|
urlReq.add_header("Accept", "application/vnd.github.v3+json")
|
129
128
|
|
130
129
|
rawData = {}
|
@@ -161,11 +160,13 @@ class GuiUpdates(QDialog):
|
|
161
160
|
return
|
162
161
|
|
163
162
|
##
|
164
|
-
#
|
163
|
+
# Events
|
165
164
|
##
|
166
165
|
|
167
|
-
def
|
168
|
-
|
166
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
167
|
+
"""Capture the user closing the window."""
|
168
|
+
event.accept()
|
169
|
+
self.deleteLater()
|
169
170
|
return
|
170
171
|
|
171
172
|
# END Class GuiUpdates
|