novelWriter 2.3.1__py3-none-any.whl → 2.4__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.3.1.dist-info → novelWriter-2.4.dist-info}/METADATA +5 -6
- {novelWriter-2.3.1.dist-info → novelWriter-2.4.dist-info}/RECORD +114 -107
- novelwriter/__init__.py +17 -10
- 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_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/icons/none.svg +4 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +7 -0
- novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +1 -1
- novelwriter/assets/icons/typicons_dark/typ_refresh.svg +1 -1
- novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_times.svg +1 -1
- novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +7 -0
- novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +1 -1
- novelwriter/assets/icons/typicons_light/typ_refresh.svg +1 -1
- novelwriter/assets/icons/typicons_light/typ_search-grey.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_times.svg +1 -1
- novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +4 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/default_dark.conf +1 -0
- novelwriter/assets/syntax/default_light.conf +1 -0
- novelwriter/assets/syntax/grey_dark.conf +1 -0
- novelwriter/assets/syntax/grey_light.conf +1 -0
- novelwriter/assets/syntax/light_owl.conf +1 -0
- novelwriter/assets/syntax/night_owl.conf +1 -0
- novelwriter/assets/syntax/solarized_dark.conf +1 -0
- novelwriter/assets/syntax/solarized_light.conf +1 -0
- novelwriter/assets/syntax/tomorrow.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
- novelwriter/assets/text/credits_en.htm +25 -23
- novelwriter/common.py +12 -4
- novelwriter/config.py +47 -16
- novelwriter/constants.py +5 -6
- novelwriter/core/buildsettings.py +64 -44
- novelwriter/core/coretools.py +97 -13
- novelwriter/core/docbuild.py +74 -7
- novelwriter/core/document.py +24 -3
- novelwriter/core/index.py +31 -112
- novelwriter/core/project.py +10 -15
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/sessions.py +2 -2
- novelwriter/core/spellcheck.py +3 -3
- novelwriter/core/status.py +6 -5
- novelwriter/core/storage.py +8 -2
- novelwriter/core/tohtml.py +22 -25
- novelwriter/core/tokenizer.py +417 -233
- novelwriter/core/tomd.py +17 -8
- novelwriter/core/toodt.py +386 -351
- novelwriter/core/tree.py +8 -8
- novelwriter/dialogs/about.py +9 -11
- novelwriter/dialogs/docmerge.py +17 -14
- novelwriter/dialogs/docsplit.py +20 -19
- novelwriter/dialogs/editlabel.py +5 -4
- novelwriter/dialogs/preferences.py +32 -40
- novelwriter/dialogs/projectsettings.py +31 -28
- novelwriter/dialogs/quotes.py +10 -9
- novelwriter/dialogs/wordlist.py +17 -14
- novelwriter/enum.py +17 -14
- novelwriter/error.py +14 -12
- novelwriter/extensions/circularprogress.py +12 -8
- novelwriter/extensions/configlayout.py +1 -3
- novelwriter/extensions/modified.py +51 -2
- novelwriter/extensions/pagedsidebar.py +16 -14
- novelwriter/extensions/simpleprogress.py +3 -1
- novelwriter/extensions/statusled.py +3 -1
- novelwriter/extensions/switch.py +10 -9
- novelwriter/extensions/switchbox.py +14 -13
- novelwriter/extensions/versioninfo.py +1 -1
- novelwriter/gui/doceditor.py +433 -496
- novelwriter/gui/dochighlight.py +54 -33
- novelwriter/gui/docviewer.py +162 -175
- novelwriter/gui/docviewerpanel.py +20 -37
- novelwriter/gui/editordocument.py +15 -4
- novelwriter/gui/itemdetails.py +51 -54
- novelwriter/gui/mainmenu.py +37 -16
- novelwriter/gui/noveltree.py +31 -37
- novelwriter/gui/outline.py +120 -98
- novelwriter/gui/projtree.py +61 -67
- novelwriter/gui/search.py +362 -0
- novelwriter/gui/sidebar.py +36 -45
- novelwriter/gui/statusbar.py +14 -14
- novelwriter/gui/theme.py +107 -32
- novelwriter/guimain.py +209 -202
- novelwriter/shared.py +31 -6
- novelwriter/text/counting.py +138 -0
- novelwriter/tools/dictionaries.py +15 -14
- novelwriter/tools/lipsum.py +20 -17
- novelwriter/tools/manusbuild.py +43 -35
- novelwriter/tools/manuscript.py +381 -104
- novelwriter/tools/manussettings.py +262 -125
- novelwriter/tools/noveldetails.py +20 -18
- novelwriter/tools/welcome.py +52 -49
- novelwriter/tools/writingstats.py +61 -55
- novelwriter/types.py +90 -0
- novelwriter/core/__init__.py +0 -3
- novelwriter/dialogs/__init__.py +0 -3
- novelwriter/extensions/__init__.py +0 -3
- novelwriter/gui/__init__.py +0 -3
- novelwriter/tools/__init__.py +0 -3
- {novelWriter-2.3.1.dist-info → novelWriter-2.4.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.3.1.dist-info → novelWriter-2.4.dist-info}/WHEEL +0 -0
- {novelWriter-2.3.1.dist-info → novelWriter-2.4.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.3.1.dist-info → novelWriter-2.4.dist-info}/top_level.txt +0 -0
novelwriter/guimain.py
CHANGED
@@ -30,41 +30,39 @@ from time import time
|
|
30
30
|
from pathlib import Path
|
31
31
|
from datetime import datetime
|
32
32
|
|
33
|
-
from PyQt5.QtGui import QCloseEvent, QCursor, QIcon
|
34
33
|
from PyQt5.QtCore import Qt, QTimer, pyqtSlot
|
34
|
+
from PyQt5.QtGui import QCloseEvent, QCursor, QIcon
|
35
35
|
from PyQt5.QtWidgets import (
|
36
|
-
QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, QSplitter,
|
37
|
-
QStackedWidget, QVBoxLayout, QWidget
|
36
|
+
QApplication, QFileDialog, QHBoxLayout, QMainWindow, QMessageBox, QShortcut, QSplitter,
|
37
|
+
QStackedWidget, QVBoxLayout, QWidget
|
38
38
|
)
|
39
39
|
|
40
40
|
from novelwriter import CONFIG, SHARED, __hexversion__, __version__
|
41
|
+
from novelwriter.common import formatFileFilter, formatVersion, hexToInt
|
41
42
|
from novelwriter.constants import nwConst
|
42
|
-
from novelwriter.
|
43
|
-
from novelwriter.
|
44
|
-
from novelwriter.
|
45
|
-
from novelwriter.
|
46
|
-
from novelwriter.
|
43
|
+
from novelwriter.dialogs.about import GuiAbout
|
44
|
+
from novelwriter.dialogs.preferences import GuiPreferences
|
45
|
+
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
46
|
+
from novelwriter.dialogs.wordlist import GuiWordList
|
47
|
+
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwWidget, nwView
|
47
48
|
from novelwriter.gui.doceditor import GuiDocEditor
|
48
49
|
from novelwriter.gui.docviewer import GuiDocViewer
|
50
|
+
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
|
51
|
+
from novelwriter.gui.itemdetails import GuiItemDetails
|
52
|
+
from novelwriter.gui.mainmenu import GuiMainMenu
|
49
53
|
from novelwriter.gui.noveltree import GuiNovelView
|
54
|
+
from novelwriter.gui.outline import GuiOutlineView
|
55
|
+
from novelwriter.gui.projtree import GuiProjectView
|
56
|
+
from novelwriter.gui.search import GuiProjectSearch
|
57
|
+
from novelwriter.gui.sidebar import GuiSideBar
|
50
58
|
from novelwriter.gui.statusbar import GuiMainStatus
|
51
|
-
from novelwriter.gui.
|
52
|
-
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
|
53
|
-
from novelwriter.dialogs.about import GuiAbout
|
54
|
-
from novelwriter.dialogs.wordlist import GuiWordList
|
55
|
-
from novelwriter.dialogs.preferences import GuiPreferences
|
56
|
-
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
57
|
-
from novelwriter.tools.welcome import GuiWelcome
|
58
|
-
from novelwriter.tools.manuscript import GuiManuscript
|
59
|
+
from novelwriter.gui.theme import GuiTheme
|
59
60
|
from novelwriter.tools.dictionaries import GuiDictionaries
|
61
|
+
from novelwriter.tools.manuscript import GuiManuscript
|
60
62
|
from novelwriter.tools.noveldetails import GuiNovelDetails
|
63
|
+
from novelwriter.tools.welcome import GuiWelcome
|
61
64
|
from novelwriter.tools.writingstats import GuiWritingStats
|
62
65
|
|
63
|
-
from novelwriter.enum import (
|
64
|
-
nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwWidget, nwView
|
65
|
-
)
|
66
|
-
from novelwriter.common import formatFileFilter, formatVersion, hexToInt
|
67
|
-
|
68
66
|
logger = logging.getLogger(__name__)
|
69
67
|
|
70
68
|
|
@@ -104,9 +102,6 @@ class GuiMain(QMainWindow):
|
|
104
102
|
# Initialise UserData Instance
|
105
103
|
SHARED.initSharedData(self, GuiTheme())
|
106
104
|
|
107
|
-
# Core Settings
|
108
|
-
self.isFocusMode = False
|
109
|
-
|
110
105
|
# Prepare Main Window
|
111
106
|
self.resize(*CONFIG.mainWinSize)
|
112
107
|
self._updateWindowTitle()
|
@@ -114,7 +109,7 @@ class GuiMain(QMainWindow):
|
|
114
109
|
nwIcon = CONFIG.assetPath("icons") / "novelwriter.svg"
|
115
110
|
self.nwIcon = QIcon(str(nwIcon)) if nwIcon.is_file() else QIcon()
|
116
111
|
self.setWindowIcon(self.nwIcon)
|
117
|
-
|
112
|
+
QApplication.setWindowIcon(self.nwIcon)
|
118
113
|
|
119
114
|
# Build the GUI
|
120
115
|
# =============
|
@@ -126,6 +121,7 @@ class GuiMain(QMainWindow):
|
|
126
121
|
# Main GUI Elements
|
127
122
|
self.mainStatus = GuiMainStatus(self)
|
128
123
|
self.projView = GuiProjectView(self)
|
124
|
+
self.projSearch = GuiProjectSearch(self)
|
129
125
|
self.novelView = GuiNovelView(self)
|
130
126
|
self.docEditor = GuiDocEditor(self)
|
131
127
|
self.docViewer = GuiDocViewer(self)
|
@@ -139,6 +135,7 @@ class GuiMain(QMainWindow):
|
|
139
135
|
self.projStack = QStackedWidget(self)
|
140
136
|
self.projStack.addWidget(self.projView)
|
141
137
|
self.projStack.addWidget(self.novelView)
|
138
|
+
self.projStack.addWidget(self.projSearch)
|
142
139
|
self.projStack.currentChanged.connect(self._projStackChanged)
|
143
140
|
|
144
141
|
# Project Tree View
|
@@ -151,28 +148,36 @@ class GuiMain(QMainWindow):
|
|
151
148
|
self.treePane.setLayout(self.treeBox)
|
152
149
|
|
153
150
|
# Splitter : Document Viewer / Document Meta
|
154
|
-
self.splitView = QSplitter(Qt.Vertical, self)
|
151
|
+
self.splitView = QSplitter(Qt.Orientation.Vertical, self)
|
155
152
|
self.splitView.addWidget(self.docViewer)
|
156
153
|
self.splitView.addWidget(self.docViewerPanel)
|
157
154
|
self.splitView.setHandleWidth(hWd)
|
158
155
|
self.splitView.setOpaqueResize(False)
|
159
156
|
self.splitView.setSizes(CONFIG.viewPanePos)
|
157
|
+
self.splitView.setCollapsible(0, False)
|
158
|
+
self.splitView.setCollapsible(1, False)
|
160
159
|
|
161
160
|
# Splitter : Document Editor / Document Viewer
|
162
|
-
self.splitDocs = QSplitter(Qt.Horizontal, self)
|
161
|
+
self.splitDocs = QSplitter(Qt.Orientation.Horizontal, self)
|
163
162
|
self.splitDocs.addWidget(self.docEditor)
|
164
163
|
self.splitDocs.addWidget(self.splitView)
|
165
164
|
self.splitDocs.setOpaqueResize(False)
|
166
165
|
self.splitDocs.setHandleWidth(hWd)
|
166
|
+
self.splitDocs.setCollapsible(0, False)
|
167
|
+
self.splitDocs.setCollapsible(1, False)
|
167
168
|
|
168
169
|
# Splitter : Project Tree / Document Area
|
169
|
-
self.splitMain = QSplitter(Qt.Horizontal)
|
170
|
+
self.splitMain = QSplitter(Qt.Orientation.Horizontal)
|
170
171
|
self.splitMain.setContentsMargins(0, 0, 0, 0)
|
171
172
|
self.splitMain.addWidget(self.treePane)
|
172
173
|
self.splitMain.addWidget(self.splitDocs)
|
173
174
|
self.splitMain.setOpaqueResize(False)
|
174
175
|
self.splitMain.setHandleWidth(hWd)
|
175
176
|
self.splitMain.setSizes(CONFIG.mainPanePos)
|
177
|
+
self.splitMain.setCollapsible(0, False)
|
178
|
+
self.splitMain.setCollapsible(0, False)
|
179
|
+
self.splitMain.setStretchFactor(1, 0)
|
180
|
+
self.splitMain.setStretchFactor(1, 1)
|
176
181
|
|
177
182
|
# Main Stack : Editor / Outline
|
178
183
|
self.mainStack = QStackedWidget(self)
|
@@ -180,31 +185,6 @@ class GuiMain(QMainWindow):
|
|
180
185
|
self.mainStack.addWidget(self.outlineView)
|
181
186
|
self.mainStack.currentChanged.connect(self._mainStackChanged)
|
182
187
|
|
183
|
-
# Indices of Splitter Widgets
|
184
|
-
self.idxTree = self.splitMain.indexOf(self.treePane)
|
185
|
-
self.idxMain = self.splitMain.indexOf(self.splitDocs)
|
186
|
-
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
187
|
-
self.idxViewer = self.splitDocs.indexOf(self.splitView)
|
188
|
-
self.idxViewDoc = self.splitView.indexOf(self.docViewer)
|
189
|
-
self.idxViewDocPanel = self.splitView.indexOf(self.docViewerPanel)
|
190
|
-
|
191
|
-
# Indices of Stack Widgets
|
192
|
-
self.idxEditorView = self.mainStack.indexOf(self.splitMain)
|
193
|
-
self.idxOutlineView = self.mainStack.indexOf(self.outlineView)
|
194
|
-
self.idxProjView = self.projStack.indexOf(self.projView)
|
195
|
-
self.idxNovelView = self.projStack.indexOf(self.novelView)
|
196
|
-
|
197
|
-
# Splitter Behaviour
|
198
|
-
self.splitMain.setCollapsible(self.idxTree, False)
|
199
|
-
self.splitMain.setCollapsible(self.idxMain, False)
|
200
|
-
self.splitDocs.setCollapsible(self.idxEditor, False)
|
201
|
-
self.splitDocs.setCollapsible(self.idxViewer, False)
|
202
|
-
self.splitView.setCollapsible(self.idxViewDoc, False)
|
203
|
-
self.splitView.setCollapsible(self.idxViewDocPanel, False)
|
204
|
-
|
205
|
-
self.splitMain.setStretchFactor(self.idxTree, 0)
|
206
|
-
self.splitMain.setStretchFactor(self.idxMain, 1)
|
207
|
-
|
208
188
|
# Editor / Viewer Default State
|
209
189
|
self.splitView.setVisible(False)
|
210
190
|
self.docEditor.closeSearch()
|
@@ -225,7 +205,7 @@ class GuiMain(QMainWindow):
|
|
225
205
|
self.setMenuBar(self.mainMenu)
|
226
206
|
self.setCentralWidget(self.mainWidget)
|
227
207
|
self.setStatusBar(self.mainStatus)
|
228
|
-
self.setContextMenuPolicy(Qt.NoContextMenu) # Issue #1147
|
208
|
+
self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) # Issue #1147
|
229
209
|
|
230
210
|
# Connect Signals
|
231
211
|
# ===============
|
@@ -233,20 +213,23 @@ class GuiMain(QMainWindow):
|
|
233
213
|
SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus)
|
234
214
|
SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage)
|
235
215
|
SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage)
|
216
|
+
SHARED.focusModeChanged.connect(self._focusModeChanged)
|
236
217
|
SHARED.indexChangedTags.connect(self.docViewerPanel.updateChangedTags)
|
237
218
|
SHARED.indexScannedText.connect(self.docViewerPanel.projectItemChanged)
|
238
219
|
SHARED.indexScannedText.connect(self.projView.updateItemValues)
|
239
220
|
SHARED.indexScannedText.connect(self.itemDetails.updateViewBox)
|
240
221
|
SHARED.indexCleared.connect(self.docViewerPanel.indexWasCleared)
|
241
222
|
SHARED.indexAvailable.connect(self.docViewerPanel.indexHasAppeared)
|
223
|
+
SHARED.mainClockTick.connect(self._timeTick)
|
242
224
|
|
243
225
|
self.mainMenu.requestDocAction.connect(self._passDocumentAction)
|
244
226
|
self.mainMenu.requestDocInsert.connect(self._passDocumentInsert)
|
245
227
|
self.mainMenu.requestDocInsertText.connect(self._passDocumentInsert)
|
246
228
|
self.mainMenu.requestDocKeyWordInsert.connect(self.docEditor.insertKeyWord)
|
247
229
|
self.mainMenu.requestFocusChange.connect(self.switchFocus)
|
230
|
+
self.mainMenu.requestViewChange.connect(self._changeView)
|
248
231
|
|
249
|
-
self.sideBar.
|
232
|
+
self.sideBar.requestViewChange.connect(self._changeView)
|
250
233
|
|
251
234
|
self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
|
252
235
|
self.projView.openDocumentRequest.connect(self._openDocument)
|
@@ -263,6 +246,9 @@ class GuiMain(QMainWindow):
|
|
263
246
|
self.novelView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
|
264
247
|
self.novelView.openDocumentRequest.connect(self._openDocument)
|
265
248
|
|
249
|
+
self.projSearch.openDocumentSelectRequest.connect(self._openDocumentSelection)
|
250
|
+
self.projSearch.selectedItemChanged.connect(self.itemDetails.updateViewBox)
|
251
|
+
|
266
252
|
self.docEditor.editedStatusChanged.connect(self.mainStatus.updateDocumentStatus)
|
267
253
|
self.docEditor.docCountsChanged.connect(self.itemDetails.updateCounts)
|
268
254
|
self.docEditor.docCountsChanged.connect(self.projView.updateCounts)
|
@@ -275,9 +261,13 @@ class GuiMain(QMainWindow):
|
|
275
261
|
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
|
276
262
|
self.docEditor.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
277
263
|
self.docEditor.requestProjectItemRenamed.connect(self.projView.renameTreeItem)
|
264
|
+
self.docEditor.requestNewNoteCreation.connect(self.projView.createNewNote)
|
265
|
+
self.docEditor.docTextChanged.connect(self.projSearch.textChanged)
|
278
266
|
|
279
267
|
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
|
280
268
|
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
269
|
+
self.docViewer.closeDocumentRequest.connect(self.closeDocViewer)
|
270
|
+
self.docViewer.reloadDocumentRequest.connect(self._reloadViewer)
|
281
271
|
self.docViewer.togglePanelVisibility.connect(self._toggleViewerPanelVisibility)
|
282
272
|
self.docViewer.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
283
273
|
|
@@ -298,12 +288,6 @@ class GuiMain(QMainWindow):
|
|
298
288
|
self.asDocTimer = QTimer(self)
|
299
289
|
self.asDocTimer.timeout.connect(self._autoSaveDocument)
|
300
290
|
|
301
|
-
# Main Clock
|
302
|
-
self.mainTimer = QTimer(self)
|
303
|
-
self.mainTimer.setInterval(1000)
|
304
|
-
self.mainTimer.timeout.connect(self._timeTick)
|
305
|
-
self.mainTimer.start()
|
306
|
-
|
307
291
|
# Shortcuts and Actions
|
308
292
|
self._connectMenuActions()
|
309
293
|
|
@@ -344,7 +328,7 @@ class GuiMain(QMainWindow):
|
|
344
328
|
def postLaunchTasks(self, cmdOpen: str | None) -> None:
|
345
329
|
"""Process tasks after the main window has been created."""
|
346
330
|
if cmdOpen:
|
347
|
-
|
331
|
+
QApplication.processEvents()
|
348
332
|
logger.info("Command line path: %s", cmdOpen)
|
349
333
|
self.openProject(cmdOpen)
|
350
334
|
|
@@ -401,12 +385,13 @@ class GuiMain(QMainWindow):
|
|
401
385
|
if saveOK:
|
402
386
|
self.closeDocument()
|
403
387
|
self.docViewer.clearNavHistory()
|
404
|
-
self.
|
388
|
+
self.closeViewerPanel(byUser=False)
|
405
389
|
|
406
390
|
self.docViewerPanel.closeProjectTasks()
|
407
391
|
self.outlineView.closeProjectTasks()
|
408
392
|
self.novelView.closeProjectTasks()
|
409
393
|
self.projView.closeProjectTasks()
|
394
|
+
self.projSearch.closeProjectTasks()
|
410
395
|
self.itemDetails.clearDetails()
|
411
396
|
self.mainStatus.clearStatus()
|
412
397
|
|
@@ -457,7 +442,7 @@ class GuiMain(QMainWindow):
|
|
457
442
|
"'{0}' ({1} {2}), last active on {3}."
|
458
443
|
).format(
|
459
444
|
lockStatus[0], lockStatus[1], lockStatus[2],
|
460
|
-
datetime.fromtimestamp(int(lockStatus[3]))
|
445
|
+
CONFIG.localDateTime(datetime.fromtimestamp(int(lockStatus[3])))
|
461
446
|
)
|
462
447
|
except Exception:
|
463
448
|
lockDetails = ""
|
@@ -489,12 +474,12 @@ class GuiMain(QMainWindow):
|
|
489
474
|
break
|
490
475
|
|
491
476
|
if lastEdited is not None:
|
492
|
-
|
477
|
+
QApplication.processEvents()
|
493
478
|
self.openDocument(lastEdited, doScroll=True)
|
494
479
|
|
495
480
|
lastViewed = SHARED.project.data.getLastHandle("viewer")
|
496
481
|
if lastViewed is not None:
|
497
|
-
|
482
|
+
QApplication.processEvents()
|
498
483
|
self.viewDocument(lastViewed)
|
499
484
|
|
500
485
|
# Check if we need to rebuild the index
|
@@ -503,7 +488,7 @@ class GuiMain(QMainWindow):
|
|
503
488
|
self.rebuildIndex()
|
504
489
|
|
505
490
|
# Make sure the changed status is set to false on things opened
|
506
|
-
|
491
|
+
QApplication.processEvents()
|
507
492
|
self.docEditor.setDocumentChanged(False)
|
508
493
|
SHARED.project.setProjectChanged(False)
|
509
494
|
|
@@ -523,24 +508,19 @@ class GuiMain(QMainWindow):
|
|
523
508
|
# Document Actions
|
524
509
|
##
|
525
510
|
|
526
|
-
def closeDocument(self, beforeOpen: bool = False) ->
|
511
|
+
def closeDocument(self, beforeOpen: bool = False) -> None:
|
527
512
|
"""Close the document and clear the editor and title field."""
|
528
|
-
if
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
self.docEditor.clearEditor()
|
540
|
-
if not beforeOpen:
|
541
|
-
self.novelView.setActiveHandle(None)
|
542
|
-
|
543
|
-
return True
|
513
|
+
if SHARED.hasProject:
|
514
|
+
# Disable focus mode if it is active
|
515
|
+
if SHARED.focusMode:
|
516
|
+
SHARED.setFocusMode(False)
|
517
|
+
self.docEditor.saveCursorPosition()
|
518
|
+
if self.docEditor.docChanged:
|
519
|
+
self.saveDocument()
|
520
|
+
self.docEditor.clearEditor()
|
521
|
+
if not beforeOpen:
|
522
|
+
self.novelView.setActiveHandle(None)
|
523
|
+
return
|
544
524
|
|
545
525
|
def openDocument(self, tHandle: str | None, tLine: int | None = None,
|
546
526
|
changeFocus: bool = True, doScroll: bool = False) -> bool:
|
@@ -604,13 +584,12 @@ class GuiMain(QMainWindow):
|
|
604
584
|
|
605
585
|
return False
|
606
586
|
|
607
|
-
|
587
|
+
@pyqtSlot()
|
588
|
+
def saveDocument(self) -> None:
|
608
589
|
"""Save the current documents."""
|
609
|
-
if
|
610
|
-
|
611
|
-
|
612
|
-
self.docEditor.saveText()
|
613
|
-
return True
|
590
|
+
if SHARED.hasProject:
|
591
|
+
self.docEditor.saveText()
|
592
|
+
return
|
614
593
|
|
615
594
|
def viewDocument(self, tHandle: str | None = None, sTitle: str | None = None) -> bool:
|
616
595
|
"""Load a document for viewing in the view panel."""
|
@@ -640,7 +619,8 @@ class GuiMain(QMainWindow):
|
|
640
619
|
self._changeView(nwView.EDITOR)
|
641
620
|
|
642
621
|
logger.debug("Viewing document with handle '%s'", tHandle)
|
643
|
-
|
622
|
+
updateHistory = tHandle != self.docViewer.docHandle
|
623
|
+
if self.docViewer.loadText(tHandle, updateHistory=updateHistory):
|
644
624
|
if not self.splitView.isVisible():
|
645
625
|
cursorVisible = self.docEditor.cursorIsVisible()
|
646
626
|
bPos = self.splitMain.sizes()
|
@@ -657,7 +637,7 @@ class GuiMain(QMainWindow):
|
|
657
637
|
self.docEditor.ensureCursorVisibleNoCentre()
|
658
638
|
|
659
639
|
if sTitle:
|
660
|
-
self.docViewer.navigateTo(f"#{sTitle}")
|
640
|
+
self.docViewer.navigateTo(f"#{tHandle}:{sTitle}")
|
661
641
|
|
662
642
|
return True
|
663
643
|
|
@@ -713,80 +693,71 @@ class GuiMain(QMainWindow):
|
|
713
693
|
# Tree Item Actions
|
714
694
|
##
|
715
695
|
|
716
|
-
|
696
|
+
@pyqtSlot()
|
697
|
+
def openSelectedItem(self) -> None:
|
717
698
|
"""Open the selected item from the tree that is currently
|
718
699
|
active. It is not checked that the item is actually a document.
|
719
700
|
That should be handled by the openDocument function.
|
720
701
|
"""
|
721
|
-
if
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
else:
|
735
|
-
logger.warning("No item selected")
|
736
|
-
return False
|
737
|
-
|
738
|
-
if tHandle is not None and sTitle is not None:
|
739
|
-
hItem = SHARED.project.index.getItemHeader(tHandle, sTitle)
|
740
|
-
if hItem is not None:
|
741
|
-
tLine = hItem.line
|
702
|
+
if SHARED.hasProject:
|
703
|
+
tHandle = None
|
704
|
+
sTitle = None
|
705
|
+
tLine = None
|
706
|
+
if self.projView.treeHasFocus():
|
707
|
+
tHandle = self.projView.getSelectedHandle()
|
708
|
+
elif self.novelView.treeHasFocus():
|
709
|
+
tHandle, sTitle = self.novelView.getSelectedHandle()
|
710
|
+
elif self.outlineView.treeHasFocus():
|
711
|
+
tHandle, sTitle = self.outlineView.getSelectedHandle()
|
712
|
+
else:
|
713
|
+
logger.warning("No item selected")
|
714
|
+
return
|
742
715
|
|
743
|
-
|
744
|
-
|
716
|
+
if tHandle and sTitle:
|
717
|
+
if hItem := SHARED.project.index.getItemHeading(tHandle, sTitle):
|
718
|
+
tLine = hItem.line
|
719
|
+
if tHandle:
|
720
|
+
self.openDocument(tHandle, tLine=tLine, changeFocus=False, doScroll=False)
|
745
721
|
|
746
|
-
return
|
722
|
+
return
|
747
723
|
|
748
|
-
def editItemLabel(self, tHandle: str | None = None) ->
|
724
|
+
def editItemLabel(self, tHandle: str | None = None) -> None:
|
749
725
|
"""Open the edit item dialog."""
|
750
|
-
if
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
self.projView.renameTreeItem(tHandle)
|
756
|
-
return True
|
726
|
+
if SHARED.hasProject:
|
727
|
+
if tHandle is None and (self.docEditor.anyFocus() or SHARED.focusMode):
|
728
|
+
tHandle = self.docEditor.docHandle
|
729
|
+
self.projView.renameTreeItem(tHandle)
|
730
|
+
return
|
757
731
|
|
758
732
|
def rebuildTrees(self) -> None:
|
759
733
|
"""Rebuild the project tree."""
|
760
734
|
self.projView.populateTree()
|
761
735
|
return
|
762
736
|
|
763
|
-
def rebuildIndex(self, beQuiet: bool = False) ->
|
737
|
+
def rebuildIndex(self, beQuiet: bool = False) -> None:
|
764
738
|
"""Rebuild the entire index."""
|
765
|
-
if
|
766
|
-
logger.
|
767
|
-
|
768
|
-
|
769
|
-
logger.info("Rebuilding index ...")
|
770
|
-
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
771
|
-
tStart = time()
|
739
|
+
if SHARED.hasProject:
|
740
|
+
logger.info("Rebuilding index ...")
|
741
|
+
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
742
|
+
tStart = time()
|
772
743
|
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
744
|
+
self.projView.saveProjectTasks()
|
745
|
+
SHARED.project.index.rebuildIndex()
|
746
|
+
self.projView.populateTree()
|
747
|
+
self.novelView.refreshTree()
|
777
748
|
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
749
|
+
tEnd = time()
|
750
|
+
self.mainStatus.setStatusMessage(
|
751
|
+
self.tr("Indexing completed in {0} ms").format(f"{(tEnd - tStart)*1000.0:.1f}")
|
752
|
+
)
|
753
|
+
self.docEditor.updateTagHighLighting()
|
754
|
+
self._updateStatusWordCount()
|
755
|
+
QApplication.restoreOverrideCursor()
|
785
756
|
|
786
|
-
|
787
|
-
|
757
|
+
if not beQuiet:
|
758
|
+
SHARED.info(self.tr("The project index has been successfully rebuilt."))
|
788
759
|
|
789
|
-
return
|
760
|
+
return
|
790
761
|
|
791
762
|
##
|
792
763
|
# Main Dialogs
|
@@ -797,7 +768,7 @@ class GuiMain(QMainWindow):
|
|
797
768
|
"""Open the welcome dialog."""
|
798
769
|
dialog = GuiWelcome(self)
|
799
770
|
dialog.openProjectRequest.connect(self._openProjectFromWelcome)
|
800
|
-
dialog.
|
771
|
+
dialog.exec()
|
801
772
|
return
|
802
773
|
|
803
774
|
@pyqtSlot()
|
@@ -805,7 +776,7 @@ class GuiMain(QMainWindow):
|
|
805
776
|
"""Open the preferences dialog."""
|
806
777
|
dialog = GuiPreferences(self)
|
807
778
|
dialog.newPreferencesReady.connect(self._processConfigChanges)
|
808
|
-
dialog.
|
779
|
+
dialog.exec()
|
809
780
|
return
|
810
781
|
|
811
782
|
@pyqtSlot()
|
@@ -815,7 +786,7 @@ class GuiMain(QMainWindow):
|
|
815
786
|
if SHARED.hasProject:
|
816
787
|
dialog = GuiProjectSettings(self, gotoPage=focusTab)
|
817
788
|
dialog.newProjectSettingsReady.connect(self._processProjectSettingsChanges)
|
818
|
-
dialog.
|
789
|
+
dialog.exec()
|
819
790
|
return
|
820
791
|
|
821
792
|
@pyqtSlot()
|
@@ -826,7 +797,7 @@ class GuiMain(QMainWindow):
|
|
826
797
|
dialog.setModal(True)
|
827
798
|
dialog.show()
|
828
799
|
dialog.raise_()
|
829
|
-
|
800
|
+
QApplication.processEvents()
|
830
801
|
dialog.updateValues()
|
831
802
|
return
|
832
803
|
|
@@ -839,7 +810,7 @@ class GuiMain(QMainWindow):
|
|
839
810
|
dialog.setModal(False)
|
840
811
|
dialog.show()
|
841
812
|
dialog.raise_()
|
842
|
-
|
813
|
+
QApplication.processEvents()
|
843
814
|
dialog.loadContent()
|
844
815
|
return
|
845
816
|
|
@@ -849,7 +820,7 @@ class GuiMain(QMainWindow):
|
|
849
820
|
if SHARED.hasProject:
|
850
821
|
dialog = GuiWordList(self)
|
851
822
|
dialog.newWordListReady.connect(self._processWordListChanges)
|
852
|
-
dialog.
|
823
|
+
dialog.exec()
|
853
824
|
return
|
854
825
|
|
855
826
|
@pyqtSlot()
|
@@ -861,7 +832,7 @@ class GuiMain(QMainWindow):
|
|
861
832
|
dialog.setModal(False)
|
862
833
|
dialog.show()
|
863
834
|
dialog.raise_()
|
864
|
-
|
835
|
+
QApplication.processEvents()
|
865
836
|
dialog.populateGUI()
|
866
837
|
return
|
867
838
|
|
@@ -872,7 +843,7 @@ class GuiMain(QMainWindow):
|
|
872
843
|
dialog.setModal(True)
|
873
844
|
dialog.show()
|
874
845
|
dialog.raise_()
|
875
|
-
|
846
|
+
QApplication.processEvents()
|
876
847
|
dialog.populateGUI()
|
877
848
|
return
|
878
849
|
|
@@ -890,21 +861,20 @@ class GuiMain(QMainWindow):
|
|
890
861
|
dialog.setModal(True)
|
891
862
|
dialog.show()
|
892
863
|
dialog.raise_()
|
893
|
-
|
864
|
+
QApplication.processEvents()
|
894
865
|
if not dialog.initDialog():
|
895
866
|
dialog.close()
|
896
867
|
SHARED.error(self.tr("Could not initialise the dialog."))
|
897
868
|
return
|
898
869
|
|
899
|
-
def reportConfErr(self) ->
|
870
|
+
def reportConfErr(self) -> None:
|
900
871
|
"""Checks if the Config module has any errors to report, and let
|
901
872
|
the user know if this is the case. The Config module caches
|
902
873
|
errors since it is initialised before the GUI itself.
|
903
874
|
"""
|
904
875
|
if CONFIG.hasError:
|
905
876
|
SHARED.error(CONFIG.errorText())
|
906
|
-
|
907
|
-
return False
|
877
|
+
return
|
908
878
|
|
909
879
|
##
|
910
880
|
# Main Window Actions
|
@@ -922,14 +892,15 @@ class GuiMain(QMainWindow):
|
|
922
892
|
|
923
893
|
logger.info("Exiting novelWriter")
|
924
894
|
|
925
|
-
if not
|
895
|
+
if not SHARED.focusMode:
|
926
896
|
CONFIG.setMainPanePos(self.splitMain.sizes())
|
927
897
|
CONFIG.setOutlinePanePos(self.outlineView.splitSizes())
|
928
898
|
if self.docViewerPanel.isVisible():
|
929
899
|
CONFIG.setViewPanePos(self.splitView.sizes())
|
930
900
|
|
931
901
|
CONFIG.showViewerPanel = self.docViewerPanel.isVisible()
|
932
|
-
|
902
|
+
wFull = Qt.WindowState.WindowFullScreen
|
903
|
+
if self.windowState() & wFull != wFull:
|
933
904
|
# Ignore window size if in full screen mode
|
934
905
|
CONFIG.setMainWinSize(self.width(), self.height())
|
935
906
|
|
@@ -939,11 +910,11 @@ class GuiMain(QMainWindow):
|
|
939
910
|
CONFIG.saveConfig()
|
940
911
|
self.reportConfErr()
|
941
912
|
|
942
|
-
|
913
|
+
QApplication.quit()
|
943
914
|
|
944
915
|
return True
|
945
916
|
|
946
|
-
def
|
917
|
+
def closeViewerPanel(self, byUser: bool = True) -> bool:
|
947
918
|
"""Close the document view panel."""
|
948
919
|
self.docViewer.clearViewer()
|
949
920
|
if byUser:
|
@@ -966,14 +937,14 @@ class GuiMain(QMainWindow):
|
|
966
937
|
|
967
938
|
def toggleFullScreenMode(self) -> None:
|
968
939
|
"""Toggle full screen mode"""
|
969
|
-
self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
|
940
|
+
self.setWindowState(self.windowState() ^ Qt.WindowState.WindowFullScreen)
|
970
941
|
return
|
971
942
|
|
972
943
|
##
|
973
944
|
# Events
|
974
945
|
##
|
975
946
|
|
976
|
-
def closeEvent(self, event: QCloseEvent):
|
947
|
+
def closeEvent(self, event: QCloseEvent) -> None:
|
977
948
|
"""Capture the closing event of the GUI and call the close
|
978
949
|
function to handle all the close process steps.
|
979
950
|
"""
|
@@ -991,32 +962,40 @@ class GuiMain(QMainWindow):
|
|
991
962
|
SHARED.project.data.setLastHandle(None, "editor")
|
992
963
|
return
|
993
964
|
|
965
|
+
@pyqtSlot()
|
966
|
+
def closeDocViewer(self) -> None:
|
967
|
+
"""Close the document viewer."""
|
968
|
+
self.closeViewerPanel()
|
969
|
+
SHARED.project.data.setLastHandle(None, "viewer")
|
970
|
+
return
|
971
|
+
|
994
972
|
@pyqtSlot()
|
995
973
|
def toggleFocusMode(self) -> None:
|
996
|
-
"""
|
974
|
+
"""Toggle focus mode."""
|
975
|
+
if self.docEditor.docHandle:
|
976
|
+
SHARED.setFocusMode(not SHARED.focusMode)
|
977
|
+
return
|
978
|
+
|
979
|
+
@pyqtSlot(bool)
|
980
|
+
def _focusModeChanged(self, focusMode: bool) -> None:
|
981
|
+
"""Handle change of focus mode. The Main GUI Focus Mode hides tree,
|
997
982
|
view, statusbar and menu.
|
998
983
|
"""
|
999
|
-
if
|
1000
|
-
logger.error("No document open, so not activating Focus Mode")
|
1001
|
-
return
|
1002
|
-
|
1003
|
-
self.isFocusMode = not self.isFocusMode
|
1004
|
-
if self.isFocusMode:
|
984
|
+
if focusMode:
|
1005
985
|
logger.debug("Activating Focus Mode")
|
1006
986
|
self.switchFocus(nwWidget.EDITOR)
|
1007
987
|
else:
|
1008
988
|
logger.debug("Deactivating Focus Mode")
|
1009
989
|
|
1010
990
|
cursorVisible = self.docEditor.cursorIsVisible()
|
1011
|
-
isVisible = not
|
991
|
+
isVisible = not focusMode
|
1012
992
|
self.treePane.setVisible(isVisible)
|
1013
993
|
self.mainStatus.setVisible(isVisible)
|
1014
994
|
self.mainMenu.setVisible(isVisible)
|
1015
995
|
self.sideBar.setVisible(isVisible)
|
1016
996
|
|
1017
|
-
hideDocFooter =
|
997
|
+
hideDocFooter = focusMode and CONFIG.hideFocusFooter
|
1018
998
|
self.docEditor.docFooter.setVisible(not hideDocFooter)
|
1019
|
-
self.docEditor.docHeader.updateFocusMode()
|
1020
999
|
|
1021
1000
|
if self.splitView.isVisible():
|
1022
1001
|
self.splitView.setVisible(False)
|
@@ -1025,7 +1004,6 @@ class GuiMain(QMainWindow):
|
|
1025
1004
|
|
1026
1005
|
if cursorVisible:
|
1027
1006
|
self.docEditor.ensureCursorVisibleNoCentre()
|
1028
|
-
|
1029
1007
|
return
|
1030
1008
|
|
1031
1009
|
@pyqtSlot(nwWidget)
|
@@ -1038,12 +1016,15 @@ class GuiMain(QMainWindow):
|
|
1038
1016
|
self.novelView.setTreeFocus()
|
1039
1017
|
else:
|
1040
1018
|
self.projView.setTreeFocus()
|
1041
|
-
|
1019
|
+
elif self.projStack.currentWidget() is self.novelView:
|
1042
1020
|
if self.novelView.treeHasFocus():
|
1043
1021
|
self._changeView(nwView.PROJECT)
|
1044
1022
|
self.projView.setTreeFocus()
|
1045
1023
|
else:
|
1046
1024
|
self.novelView.setTreeFocus()
|
1025
|
+
else:
|
1026
|
+
self._changeView(nwView.PROJECT)
|
1027
|
+
self.projView.setTreeFocus()
|
1047
1028
|
elif paneNo == nwWidget.EDITOR:
|
1048
1029
|
self._changeView(nwView.EDITOR)
|
1049
1030
|
self.docEditor.setFocus()
|
@@ -1076,7 +1057,7 @@ class GuiMain(QMainWindow):
|
|
1076
1057
|
|
1077
1058
|
if theme:
|
1078
1059
|
# We are doing this manually instead of connecting to
|
1079
|
-
#
|
1060
|
+
# paletteChanged since the processing order matters
|
1080
1061
|
SHARED.theme.loadTheme()
|
1081
1062
|
self.docEditor.updateTheme()
|
1082
1063
|
self.docViewer.updateTheme()
|
@@ -1084,6 +1065,7 @@ class GuiMain(QMainWindow):
|
|
1084
1065
|
self.sideBar.updateTheme()
|
1085
1066
|
self.projView.updateTheme()
|
1086
1067
|
self.novelView.updateTheme()
|
1068
|
+
self.projSearch.updateTheme()
|
1087
1069
|
self.outlineView.updateTheme()
|
1088
1070
|
self.itemDetails.updateTheme()
|
1089
1071
|
self.mainStatus.updateTheme()
|
@@ -1134,7 +1116,7 @@ class GuiMain(QMainWindow):
|
|
1134
1116
|
@pyqtSlot(Path)
|
1135
1117
|
def _openProjectFromWelcome(self, path: Path) -> None:
|
1136
1118
|
"""Handle an open project request from the welcome dialog."""
|
1137
|
-
|
1119
|
+
QApplication.processEvents()
|
1138
1120
|
self.openProject(path)
|
1139
1121
|
if not SHARED.hasProject:
|
1140
1122
|
self.showWelcomeDialog()
|
@@ -1146,7 +1128,7 @@ class GuiMain(QMainWindow):
|
|
1146
1128
|
if tHandle is not None:
|
1147
1129
|
if mode == nwDocMode.EDIT:
|
1148
1130
|
tLine = None
|
1149
|
-
hItem = SHARED.project.index.
|
1131
|
+
hItem = SHARED.project.index.getItemHeading(tHandle, sTitle)
|
1150
1132
|
if hItem is not None:
|
1151
1133
|
tLine = hItem.line
|
1152
1134
|
self.openDocument(tHandle, tLine=tLine, changeFocus=setFocus)
|
@@ -1154,6 +1136,24 @@ class GuiMain(QMainWindow):
|
|
1154
1136
|
self.viewDocument(tHandle=tHandle, sTitle=sTitle)
|
1155
1137
|
return
|
1156
1138
|
|
1139
|
+
@pyqtSlot(str, int, int, bool)
|
1140
|
+
def _openDocumentSelection(
|
1141
|
+
self, tHandle: str, selStart: int, selLength: int, changeFocus: bool
|
1142
|
+
) -> None:
|
1143
|
+
"""Open a document and select a section of the text."""
|
1144
|
+
if self.openDocument(tHandle, changeFocus=changeFocus):
|
1145
|
+
self.docEditor.setCursorSelection(selStart, selLength)
|
1146
|
+
return
|
1147
|
+
|
1148
|
+
@pyqtSlot()
|
1149
|
+
def _reloadViewer(self) -> None:
|
1150
|
+
"""Reload the document in the viewer."""
|
1151
|
+
if self.docEditor.docChanged and self.docEditor.docHandle == self.docViewer.docHandle:
|
1152
|
+
# If the two panels have the same document, save any changes in the editor
|
1153
|
+
self.saveDocument()
|
1154
|
+
self.docViewer.reloadText()
|
1155
|
+
return
|
1156
|
+
|
1157
1157
|
@pyqtSlot(nwView)
|
1158
1158
|
def _changeView(self, view: nwView) -> None:
|
1159
1159
|
"""Handle the requested change of view from the GuiViewBar."""
|
@@ -1166,6 +1166,12 @@ class GuiMain(QMainWindow):
|
|
1166
1166
|
elif view == nwView.NOVEL:
|
1167
1167
|
self.mainStack.setCurrentWidget(self.splitMain)
|
1168
1168
|
self.projStack.setCurrentWidget(self.novelView)
|
1169
|
+
elif view == nwView.SEARCH:
|
1170
|
+
self.mainStack.setCurrentWidget(self.splitMain)
|
1171
|
+
self.projStack.setCurrentWidget(self.projSearch)
|
1172
|
+
self.projSearch.beginSearch(
|
1173
|
+
self.docEditor.getSelectedText() if self.docEditor.anyFocus() else ""
|
1174
|
+
)
|
1169
1175
|
elif view == nwView.OUTLINE:
|
1170
1176
|
self.mainStack.setCurrentWidget(self.outlineView)
|
1171
1177
|
return
|
@@ -1195,7 +1201,7 @@ class GuiMain(QMainWindow):
|
|
1195
1201
|
return
|
1196
1202
|
|
1197
1203
|
@pyqtSlot()
|
1198
|
-
def _toggleViewerPanelVisibility(self):
|
1204
|
+
def _toggleViewerPanelVisibility(self) -> None:
|
1199
1205
|
"""Toggle the visibility of the document viewer panel."""
|
1200
1206
|
CONFIG.showViewerPanel = not CONFIG.showViewerPanel
|
1201
1207
|
self.docViewerPanel.setVisible(CONFIG.showViewerPanel)
|
@@ -1204,16 +1210,15 @@ class GuiMain(QMainWindow):
|
|
1204
1210
|
@pyqtSlot()
|
1205
1211
|
def _timeTick(self) -> None:
|
1206
1212
|
"""Process time tick of the main timer."""
|
1207
|
-
if
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
self.mainStatus.memInfo()
|
1213
|
+
if SHARED.hasProject:
|
1214
|
+
currTime = time()
|
1215
|
+
editIdle = currTime - self.docEditor.lastActive > CONFIG.userIdleTime
|
1216
|
+
userIdle = QApplication.applicationState() != Qt.ApplicationState.ApplicationActive
|
1217
|
+
self.mainStatus.setUserIdle(editIdle or userIdle)
|
1218
|
+
SHARED.updateIdleTime(currTime, editIdle or userIdle)
|
1219
|
+
self.mainStatus.updateTime(idleTime=SHARED.projectIdleTime)
|
1220
|
+
if CONFIG.memInfo and int(currTime) % 5 == 0: # pragma: no cover
|
1221
|
+
self.mainStatus.memInfo()
|
1217
1222
|
return
|
1218
1223
|
|
1219
1224
|
@pyqtSlot()
|
@@ -1255,25 +1260,26 @@ class GuiMain(QMainWindow):
|
|
1255
1260
|
|
1256
1261
|
@pyqtSlot()
|
1257
1262
|
def _keyPressReturn(self) -> None:
|
1258
|
-
"""
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1263
|
+
"""Process a return or enter keypress in the main window."""
|
1264
|
+
if self.projStack.currentWidget() == self.projSearch:
|
1265
|
+
self.projSearch.processReturn()
|
1266
|
+
else:
|
1267
|
+
self.openSelectedItem()
|
1262
1268
|
return
|
1263
1269
|
|
1264
1270
|
@pyqtSlot()
|
1265
1271
|
def _keyPressEscape(self) -> None:
|
1266
|
-
"""Process escape keypress in the main window."""
|
1267
|
-
if self.docEditor.
|
1272
|
+
"""Process an escape keypress in the main window."""
|
1273
|
+
if self.docEditor.searchVisible():
|
1268
1274
|
self.docEditor.closeSearch()
|
1269
|
-
elif
|
1270
|
-
|
1275
|
+
elif SHARED.focusMode:
|
1276
|
+
SHARED.setFocusMode(False)
|
1271
1277
|
return
|
1272
1278
|
|
1273
1279
|
@pyqtSlot(int)
|
1274
1280
|
def _mainStackChanged(self, index: int) -> None:
|
1275
1281
|
"""Process main window tab change."""
|
1276
|
-
if index == self.
|
1282
|
+
if self.mainStack.widget(index) == self.outlineView:
|
1277
1283
|
if SHARED.hasProject:
|
1278
1284
|
self.outlineView.refreshTree()
|
1279
1285
|
return
|
@@ -1282,9 +1288,10 @@ class GuiMain(QMainWindow):
|
|
1282
1288
|
def _projStackChanged(self, index: int) -> None:
|
1283
1289
|
"""Process project view tab change."""
|
1284
1290
|
sHandle = None
|
1285
|
-
|
1291
|
+
widget = self.projStack.widget(index)
|
1292
|
+
if widget == self.projView:
|
1286
1293
|
sHandle = self.projView.getSelectedHandle()
|
1287
|
-
elif
|
1294
|
+
elif widget == self.novelView:
|
1288
1295
|
sHandle, _ = self.novelView.getSelectedHandle()
|
1289
1296
|
self.itemDetails.updateViewBox(sHandle)
|
1290
1297
|
return
|