novelWriter 2.2b1__py3-none-any.whl → 2.2rc1__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.2rc1.dist-info}/METADATA +3 -3
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/RECORD +60 -48
- novelwriter/__init__.py +3 -3
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/icons/novelwriter.ico +0 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +8 -1
- 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/typ_eye.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +8 -1
- 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/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 +4 -4
- novelwriter/common.py +22 -1
- novelwriter/config.py +12 -27
- novelwriter/constants.py +20 -3
- novelwriter/core/buildsettings.py +1 -1
- novelwriter/core/coretools.py +6 -1
- novelwriter/core/index.py +100 -34
- novelwriter/core/options.py +3 -0
- novelwriter/core/project.py +2 -2
- novelwriter/core/projectdata.py +1 -1
- novelwriter/core/tohtml.py +9 -3
- novelwriter/core/tokenizer.py +27 -20
- novelwriter/core/tomd.py +4 -0
- novelwriter/core/toodt.py +11 -4
- novelwriter/dialogs/preferences.py +80 -82
- novelwriter/dialogs/updates.py +25 -14
- novelwriter/enum.py +14 -4
- novelwriter/gui/doceditor.py +282 -177
- novelwriter/gui/dochighlight.py +7 -9
- novelwriter/gui/docviewer.py +142 -319
- novelwriter/gui/docviewerpanel.py +457 -0
- novelwriter/gui/editordocument.py +1 -1
- novelwriter/gui/mainmenu.py +16 -7
- novelwriter/gui/outline.py +10 -6
- novelwriter/gui/projtree.py +461 -376
- novelwriter/gui/sidebar.py +3 -3
- novelwriter/gui/statusbar.py +1 -1
- novelwriter/gui/theme.py +21 -2
- novelwriter/guimain.py +86 -32
- novelwriter/shared.py +23 -1
- novelwriter/tools/dictionaries.py +268 -0
- novelwriter/tools/manusbuild.py +17 -6
- novelwriter/tools/manuscript.py +1 -1
- novelwriter/tools/writingstats.py +1 -1
- novelwriter/assets/icons/typicons_dark/typ_at.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_at.svg +0 -4
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/WHEEL +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2rc1.dist-info}/top_level.txt +0 -0
novelwriter/gui/sidebar.py
CHANGED
@@ -67,7 +67,7 @@ class GuiSideBar(QWidget):
|
|
67
67
|
self.tbNovel.clicked.connect(lambda: self.viewChangeRequested.emit(nwView.NOVEL))
|
68
68
|
|
69
69
|
self.tbOutline = QToolButton(self)
|
70
|
-
self.tbOutline.setToolTip(
|
70
|
+
self.tbOutline.setToolTip("{0} [Ctrl+Shift+T]".format(self.tr("Novel Outline View")))
|
71
71
|
self.tbOutline.setIconSize(iconSize)
|
72
72
|
self.tbOutline.clicked.connect(lambda: self.viewChangeRequested.emit(nwView.OUTLINE))
|
73
73
|
|
@@ -111,7 +111,7 @@ class GuiSideBar(QWidget):
|
|
111
111
|
self.outerBox.addWidget(self.tbDetails)
|
112
112
|
self.outerBox.addWidget(self.tbStats)
|
113
113
|
self.outerBox.addWidget(self.tbSettings)
|
114
|
-
self.outerBox.setContentsMargins(0, 0,
|
114
|
+
self.outerBox.setContentsMargins(0, 0, 0, 0)
|
115
115
|
self.outerBox.setSpacing(CONFIG.pxInt(4))
|
116
116
|
|
117
117
|
self.setLayout(self.outerBox)
|
@@ -131,7 +131,7 @@ class GuiSideBar(QWidget):
|
|
131
131
|
buttonStyle = (
|
132
132
|
"QToolButton {{padding: {0}px; border: none; background: transparent;}} "
|
133
133
|
"QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}"
|
134
|
-
).format(CONFIG.pxInt(
|
134
|
+
).format(CONFIG.pxInt(6), fadeCol.red(), fadeCol.green(), fadeCol.blue())
|
135
135
|
buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}"
|
136
136
|
|
137
137
|
self.tbProject.setIcon(SHARED.theme.getIcon("view_editor"))
|
novelwriter/gui/statusbar.py
CHANGED
@@ -97,7 +97,7 @@ class GuiMainStatus(QStatusBar):
|
|
97
97
|
self.addPermanentWidget(self.statsText)
|
98
98
|
|
99
99
|
# The Session Clock
|
100
|
-
# Set the
|
100
|
+
# Set the minimum width so the label doesn't rescale every second
|
101
101
|
self.timeIcon = QLabel()
|
102
102
|
self.timeText = QLabel("")
|
103
103
|
self.timeText.setToolTip(self.tr("Session Time"))
|
novelwriter/gui/theme.py
CHANGED
@@ -133,6 +133,7 @@ class GuiTheme:
|
|
133
133
|
self.getToggleIcon = self.iconCache.getToggleIcon
|
134
134
|
self.loadDecoration = self.iconCache.loadDecoration
|
135
135
|
self.getHeaderDecoration = self.iconCache.getHeaderDecoration
|
136
|
+
self.getHeaderDecorationNarrow = self.iconCache.getHeaderDecorationNarrow
|
136
137
|
|
137
138
|
# Extract Other Info
|
138
139
|
self.guiDPI = qApp.primaryScreen().logicalDotsPerInchX()
|
@@ -464,8 +465,8 @@ class GuiIcons:
|
|
464
465
|
|
465
466
|
# General Button Icons
|
466
467
|
"add", "backward", "bookmark", "browse", "checked", "close", "cross", "down", "edit",
|
467
|
-
"export", "forward", "maximise", "menu", "minimise", "noncheckable", "
|
468
|
-
"
|
468
|
+
"export", "forward", "maximise", "menu", "minimise", "noncheckable", "panel", "refresh",
|
469
|
+
"remove", "revert", "search_replace", "search", "settings", "unchecked", "up", "view",
|
469
470
|
|
470
471
|
# Switches
|
471
472
|
"sticky-on", "sticky-off",
|
@@ -473,6 +474,8 @@ class GuiIcons:
|
|
473
474
|
|
474
475
|
# Decorations
|
475
476
|
"deco_doc_h0", "deco_doc_h1", "deco_doc_h2", "deco_doc_h3", "deco_doc_h4", "deco_doc_more",
|
477
|
+
"deco_doc_h0_n", "deco_doc_h1_n", "deco_doc_h2_n", "deco_doc_h3_n", "deco_doc_h4_n",
|
478
|
+
"deco_doc_nt_n",
|
476
479
|
}
|
477
480
|
|
478
481
|
TOGGLE_ICON_KEYS = {
|
@@ -493,6 +496,7 @@ class GuiIcons:
|
|
493
496
|
self._qIcons: dict[str, QIcon] = {}
|
494
497
|
self._themeMap: dict[str, Path] = {}
|
495
498
|
self._headerDec: list[QPixmap] = []
|
499
|
+
self._headerDecNarrow: list[QPixmap] = []
|
496
500
|
|
497
501
|
# Icon Theme Path
|
498
502
|
self._confName = "icons.conf"
|
@@ -580,6 +584,7 @@ class GuiIcons:
|
|
580
584
|
self._qIcons[iconKey] = qIcon
|
581
585
|
|
582
586
|
self._headerDec = []
|
587
|
+
self._headerDecNarrow = []
|
583
588
|
|
584
589
|
return True
|
585
590
|
|
@@ -680,6 +685,20 @@ class GuiIcons:
|
|
680
685
|
]
|
681
686
|
return self._headerDec[minmax(hLevel, 0, 4)]
|
682
687
|
|
688
|
+
def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap:
|
689
|
+
"""Get the narrow decoration for a specific header level."""
|
690
|
+
if not self._headerDecNarrow:
|
691
|
+
iPx = self.mainTheme.baseIconSize
|
692
|
+
self._headerDecNarrow = [
|
693
|
+
self.loadDecoration("deco_doc_h0_n", h=iPx),
|
694
|
+
self.loadDecoration("deco_doc_h1_n", h=iPx),
|
695
|
+
self.loadDecoration("deco_doc_h2_n", h=iPx),
|
696
|
+
self.loadDecoration("deco_doc_h3_n", h=iPx),
|
697
|
+
self.loadDecoration("deco_doc_h4_n", h=iPx),
|
698
|
+
self.loadDecoration("deco_doc_nt_n", h=iPx),
|
699
|
+
]
|
700
|
+
return self._headerDecNarrow[minmax(hLevel, 0, 5)]
|
701
|
+
|
683
702
|
##
|
684
703
|
# Internal Functions
|
685
704
|
##
|
novelwriter/guimain.py
CHANGED
@@ -44,10 +44,11 @@ from novelwriter.gui.outline import GuiOutlineView
|
|
44
44
|
from novelwriter.gui.mainmenu import GuiMainMenu
|
45
45
|
from novelwriter.gui.projtree import GuiProjectView
|
46
46
|
from novelwriter.gui.doceditor import GuiDocEditor
|
47
|
-
from novelwriter.gui.docviewer import
|
47
|
+
from novelwriter.gui.docviewer import GuiDocViewer
|
48
48
|
from novelwriter.gui.noveltree import GuiNovelView
|
49
49
|
from novelwriter.gui.statusbar import GuiMainStatus
|
50
50
|
from novelwriter.gui.itemdetails import GuiItemDetails
|
51
|
+
from novelwriter.gui.docviewerpanel import GuiDocViewerPanel
|
51
52
|
from novelwriter.dialogs.about import GuiAbout
|
52
53
|
from novelwriter.dialogs.updates import GuiUpdates
|
53
54
|
from novelwriter.dialogs.projload import GuiProjectLoad
|
@@ -58,6 +59,7 @@ from novelwriter.dialogs.projsettings import GuiProjectSettings
|
|
58
59
|
from novelwriter.tools.lipsum import GuiLipsum
|
59
60
|
from novelwriter.tools.manuscript import GuiManuscript
|
60
61
|
from novelwriter.tools.projwizard import GuiProjectWizard
|
62
|
+
from novelwriter.tools.dictionaries import GuiDictionaries
|
61
63
|
from novelwriter.tools.writingstats import GuiWritingStats
|
62
64
|
from novelwriter.core.coretools import ProjectBuilder
|
63
65
|
|
@@ -133,16 +135,16 @@ class GuiMain(QMainWindow):
|
|
133
135
|
hWd = CONFIG.pxInt(4)
|
134
136
|
|
135
137
|
# Main GUI Elements
|
136
|
-
self.mainStatus
|
137
|
-
self.projView
|
138
|
-
self.novelView
|
139
|
-
self.docEditor
|
140
|
-
self.
|
141
|
-
self.
|
142
|
-
self.itemDetails
|
143
|
-
self.outlineView
|
144
|
-
self.mainMenu
|
145
|
-
self.sideBar
|
138
|
+
self.mainStatus = GuiMainStatus(self)
|
139
|
+
self.projView = GuiProjectView(self)
|
140
|
+
self.novelView = GuiNovelView(self)
|
141
|
+
self.docEditor = GuiDocEditor(self)
|
142
|
+
self.docViewer = GuiDocViewer(self)
|
143
|
+
self.docViewerPanel = GuiDocViewerPanel(self)
|
144
|
+
self.itemDetails = GuiItemDetails(self)
|
145
|
+
self.outlineView = GuiOutlineView(self)
|
146
|
+
self.mainMenu = GuiMainMenu(self)
|
147
|
+
self.sideBar = GuiSideBar(self)
|
146
148
|
|
147
149
|
# Project Tree Stack
|
148
150
|
self.projStack = QStackedWidget(self)
|
@@ -162,7 +164,7 @@ class GuiMain(QMainWindow):
|
|
162
164
|
# Splitter : Document Viewer / Document Meta
|
163
165
|
self.splitView = QSplitter(Qt.Vertical, self)
|
164
166
|
self.splitView.addWidget(self.docViewer)
|
165
|
-
self.splitView.addWidget(self.
|
167
|
+
self.splitView.addWidget(self.docViewerPanel)
|
166
168
|
self.splitView.setHandleWidth(hWd)
|
167
169
|
self.splitView.setOpaqueResize(False)
|
168
170
|
self.splitView.setSizes(CONFIG.viewPanePos)
|
@@ -190,12 +192,12 @@ class GuiMain(QMainWindow):
|
|
190
192
|
self.mainStack.currentChanged.connect(self._mainStackChanged)
|
191
193
|
|
192
194
|
# Indices of Splitter Widgets
|
193
|
-
self.idxTree
|
194
|
-
self.idxMain
|
195
|
-
self.idxEditor
|
196
|
-
self.idxViewer
|
197
|
-
self.idxViewDoc
|
198
|
-
self.
|
195
|
+
self.idxTree = self.splitMain.indexOf(self.treePane)
|
196
|
+
self.idxMain = self.splitMain.indexOf(self.splitDocs)
|
197
|
+
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
198
|
+
self.idxViewer = self.splitDocs.indexOf(self.splitView)
|
199
|
+
self.idxViewDoc = self.splitView.indexOf(self.docViewer)
|
200
|
+
self.idxViewDocPanel = self.splitView.indexOf(self.docViewerPanel)
|
199
201
|
|
200
202
|
# Indices of Stack Widgets
|
201
203
|
self.idxEditorView = self.mainStack.indexOf(self.splitMain)
|
@@ -209,7 +211,7 @@ class GuiMain(QMainWindow):
|
|
209
211
|
self.splitDocs.setCollapsible(self.idxEditor, False)
|
210
212
|
self.splitDocs.setCollapsible(self.idxViewer, False)
|
211
213
|
self.splitView.setCollapsible(self.idxViewDoc, False)
|
212
|
-
self.splitView.setCollapsible(self.
|
214
|
+
self.splitView.setCollapsible(self.idxViewDocPanel, False)
|
213
215
|
|
214
216
|
self.splitMain.setStretchFactor(self.idxTree, 0)
|
215
217
|
self.splitMain.setStretchFactor(self.idxMain, 1)
|
@@ -242,6 +244,12 @@ class GuiMain(QMainWindow):
|
|
242
244
|
SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus)
|
243
245
|
SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage)
|
244
246
|
SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage)
|
247
|
+
SHARED.indexChangedTags.connect(self.docViewerPanel.updateChangedTags)
|
248
|
+
SHARED.indexScannedText.connect(self.docViewerPanel.projectItemChanged)
|
249
|
+
SHARED.indexScannedText.connect(self.projView.updateItemValues)
|
250
|
+
SHARED.indexScannedText.connect(self.itemDetails.updateViewBox)
|
251
|
+
SHARED.indexCleared.connect(self.docViewerPanel.indexWasCleared)
|
252
|
+
SHARED.indexAvailable.connect(self.docViewerPanel.indexHasAppeared)
|
245
253
|
|
246
254
|
self.mainMenu.requestDocAction.connect(self._passDocumentAction)
|
247
255
|
self.mainMenu.requestDocInsert.connect(self._passDocumentInsert)
|
@@ -257,6 +265,7 @@ class GuiMain(QMainWindow):
|
|
257
265
|
self.projView.treeItemChanged.connect(self.docEditor.updateDocInfo)
|
258
266
|
self.projView.treeItemChanged.connect(self.docViewer.updateDocInfo)
|
259
267
|
self.projView.treeItemChanged.connect(self.itemDetails.updateViewBox)
|
268
|
+
self.projView.treeItemChanged.connect(self.docViewerPanel.projectItemChanged)
|
260
269
|
self.projView.rootFolderChanged.connect(self.outlineView.updateRootItem)
|
261
270
|
self.projView.rootFolderChanged.connect(self.novelView.updateRootItem)
|
262
271
|
self.projView.rootFolderChanged.connect(self.projView.updateRootItem)
|
@@ -275,8 +284,16 @@ class GuiMain(QMainWindow):
|
|
275
284
|
self.docEditor.spellCheckStateChanged.connect(self.mainMenu.setSpellCheckState)
|
276
285
|
self.docEditor.closeDocumentRequest.connect(self.closeDocEditor)
|
277
286
|
self.docEditor.toggleFocusModeRequest.connect(self.toggleFocusMode)
|
287
|
+
self.docEditor.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
288
|
+
self.docEditor.requestProjectItemRenamed.connect(self.projView.renameTreeItem)
|
278
289
|
|
290
|
+
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
|
279
291
|
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
292
|
+
self.docViewer.togglePanelVisibility.connect(self._toggleViewerPanelVisibility)
|
293
|
+
self.docViewer.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
294
|
+
|
295
|
+
self.docViewerPanel.loadDocumentTagRequest.connect(self._followTag)
|
296
|
+
self.docViewerPanel.openDocumentRequest.connect(self._openDocument)
|
280
297
|
|
281
298
|
self.outlineView.loadDocumentTagRequest.connect(self._followTag)
|
282
299
|
self.outlineView.openDocumentRequest.connect(self._openDocument)
|
@@ -327,12 +344,12 @@ class GuiMain(QMainWindow):
|
|
327
344
|
|
328
345
|
logger.debug("Ready: GUI")
|
329
346
|
|
330
|
-
if __hexversion__[-2] == "a" and
|
331
|
-
SHARED.warn(
|
347
|
+
if __hexversion__[-2] == "a" and not CONFIG.isDebug:
|
348
|
+
SHARED.warn(
|
332
349
|
"You are running an untested development version of novelWriter. "
|
333
|
-
"Please be careful when working on
|
350
|
+
"Please be careful when you are working on live projects "
|
334
351
|
"and make sure you take regular backups."
|
335
|
-
)
|
352
|
+
)
|
336
353
|
|
337
354
|
logger.info("novelWriter is ready ...")
|
338
355
|
self.mainStatus.setStatusMessage(self.tr("novelWriter is ready ..."))
|
@@ -437,6 +454,7 @@ class GuiMain(QMainWindow):
|
|
437
454
|
self.docViewer.clearNavHistory()
|
438
455
|
self.closeDocViewer(byUser=False)
|
439
456
|
|
457
|
+
self.docViewerPanel.closeProjectTasks()
|
440
458
|
self.outlineView.closeProjectTasks()
|
441
459
|
self.novelView.closeProjectTasks()
|
442
460
|
self.projView.clearProjectView()
|
@@ -510,6 +528,7 @@ class GuiMain(QMainWindow):
|
|
510
528
|
self.projView.openProjectTasks()
|
511
529
|
self.novelView.openProjectTasks()
|
512
530
|
self.outlineView.openProjectTasks()
|
531
|
+
self.docViewerPanel.openProjectTasks()
|
513
532
|
self._updateStatusWordCount()
|
514
533
|
|
515
534
|
# Restore previously open documents, if any
|
@@ -675,13 +694,19 @@ class GuiMain(QMainWindow):
|
|
675
694
|
logger.debug("Viewing document with handle '%s'", tHandle)
|
676
695
|
if self.docViewer.loadText(tHandle):
|
677
696
|
if not self.splitView.isVisible():
|
697
|
+
cursorVisible = self.docEditor.cursorIsVisible()
|
678
698
|
bPos = self.splitMain.sizes()
|
679
699
|
self.splitView.setVisible(True)
|
680
700
|
vPos = [0, 0]
|
681
701
|
vPos[0] = int(bPos[1]/2)
|
682
702
|
vPos[1] = bPos[1] - vPos[0]
|
683
703
|
self.splitDocs.setSizes(vPos)
|
684
|
-
self.
|
704
|
+
self.docViewerPanel.setVisible(CONFIG.showViewerPanel)
|
705
|
+
|
706
|
+
# Since editor width changes, we need to make sure we
|
707
|
+
# restore cursor visibility in the editor. See #1302
|
708
|
+
if cursorVisible:
|
709
|
+
self.docEditor.ensureCursorVisibleNoCentre()
|
685
710
|
|
686
711
|
if sTitle:
|
687
712
|
self.docViewer.navigateTo(f"#{sTitle}")
|
@@ -782,11 +807,9 @@ class GuiMain(QMainWindow):
|
|
782
807
|
if not SHARED.hasProject:
|
783
808
|
logger.error("No project open")
|
784
809
|
return False
|
785
|
-
|
786
810
|
if tHandle is None and (self.docEditor.anyFocus() or self.isFocusMode):
|
787
811
|
tHandle = self.docEditor.docHandle
|
788
812
|
self.projView.renameTreeItem(tHandle)
|
789
|
-
|
790
813
|
return True
|
791
814
|
|
792
815
|
def rebuildTrees(self) -> None:
|
@@ -877,6 +900,7 @@ class GuiMain(QMainWindow):
|
|
877
900
|
SHARED.theme.loadTheme()
|
878
901
|
self.docEditor.updateTheme()
|
879
902
|
self.docViewer.updateTheme()
|
903
|
+
self.docViewerPanel.updateTheme()
|
880
904
|
self.sideBar.updateTheme()
|
881
905
|
self.projView.updateTheme()
|
882
906
|
self.novelView.updateTheme()
|
@@ -1047,6 +1071,20 @@ class GuiMain(QMainWindow):
|
|
1047
1071
|
|
1048
1072
|
return
|
1049
1073
|
|
1074
|
+
@pyqtSlot()
|
1075
|
+
def showDictionariesDialog(self) -> None:
|
1076
|
+
"""Show the download dictionaries dialog."""
|
1077
|
+
dlgDicts = GuiDictionaries(self)
|
1078
|
+
dlgDicts.setModal(True)
|
1079
|
+
dlgDicts.show()
|
1080
|
+
dlgDicts.raise_()
|
1081
|
+
qApp.processEvents()
|
1082
|
+
if not dlgDicts.initDialog():
|
1083
|
+
dlgDicts.close()
|
1084
|
+
SHARED.error(self.tr("Could not initialise the dialog."))
|
1085
|
+
|
1086
|
+
return
|
1087
|
+
|
1050
1088
|
def reportConfErr(self) -> bool:
|
1051
1089
|
"""Checks if the Config module has any errors to report, and let
|
1052
1090
|
the user know if this is the case. The Config module caches
|
@@ -1076,10 +1114,10 @@ class GuiMain(QMainWindow):
|
|
1076
1114
|
if not self.isFocusMode:
|
1077
1115
|
CONFIG.setMainPanePos(self.splitMain.sizes())
|
1078
1116
|
CONFIG.setOutlinePanePos(self.outlineView.splitSizes())
|
1079
|
-
if self.
|
1117
|
+
if self.docViewerPanel.isVisible():
|
1080
1118
|
CONFIG.setViewPanePos(self.splitView.sizes())
|
1081
1119
|
|
1082
|
-
CONFIG.
|
1120
|
+
CONFIG.showViewerPanel = self.docViewerPanel.isVisible()
|
1083
1121
|
if self.windowState() & Qt.WindowFullScreen != Qt.WindowFullScreen:
|
1084
1122
|
# Ignore window size if in full screen mode
|
1085
1123
|
CONFIG.setMainWinSize(self.width(), self.height())
|
@@ -1101,11 +1139,18 @@ class GuiMain(QMainWindow):
|
|
1101
1139
|
# Only reset the last handle if the user called this
|
1102
1140
|
SHARED.project.data.setLastHandle(None, "viewer")
|
1103
1141
|
|
1142
|
+
cursorVisible = self.docEditor.cursorIsVisible()
|
1143
|
+
|
1104
1144
|
# Hide the panel
|
1105
1145
|
bPos = self.splitMain.sizes()
|
1106
1146
|
self.splitView.setVisible(False)
|
1107
1147
|
self.splitDocs.setSizes([bPos[1], 0])
|
1108
1148
|
|
1149
|
+
# Since editor width changes, we need to make sure we restore
|
1150
|
+
# cursor visibility in the editor. See #1302
|
1151
|
+
if cursorVisible:
|
1152
|
+
self.docEditor.ensureCursorVisibleNoCentre()
|
1153
|
+
|
1109
1154
|
return not self.splitView.isVisible()
|
1110
1155
|
|
1111
1156
|
def toggleFullScreenMode(self) -> None:
|
@@ -1121,10 +1166,7 @@ class GuiMain(QMainWindow):
|
|
1121
1166
|
"""Capture the closing event of the GUI and call the close
|
1122
1167
|
function to handle all the close process steps.
|
1123
1168
|
"""
|
1124
|
-
if self.closeMain()
|
1125
|
-
event.accept()
|
1126
|
-
else:
|
1127
|
-
event.ignore()
|
1169
|
+
event.accept() if self.closeMain() else event.ignore()
|
1128
1170
|
return
|
1129
1171
|
|
1130
1172
|
##
|
@@ -1154,6 +1196,7 @@ class GuiMain(QMainWindow):
|
|
1154
1196
|
else:
|
1155
1197
|
logger.debug("Deactivating Focus Mode")
|
1156
1198
|
|
1199
|
+
cursorVisible = self.docEditor.cursorIsVisible()
|
1157
1200
|
isVisible = not self.isFocusMode
|
1158
1201
|
self.treePane.setVisible(isVisible)
|
1159
1202
|
self.mainStatus.setVisible(isVisible)
|
@@ -1169,6 +1212,9 @@ class GuiMain(QMainWindow):
|
|
1169
1212
|
elif self.docViewer.docHandle is not None:
|
1170
1213
|
self.splitView.setVisible(True)
|
1171
1214
|
|
1215
|
+
if cursorVisible:
|
1216
|
+
self.docEditor.ensureCursorVisibleNoCentre()
|
1217
|
+
|
1172
1218
|
return
|
1173
1219
|
|
1174
1220
|
@pyqtSlot(nwWidget)
|
@@ -1267,6 +1313,13 @@ class GuiMain(QMainWindow):
|
|
1267
1313
|
self.docEditor.insertText(content)
|
1268
1314
|
return
|
1269
1315
|
|
1316
|
+
@pyqtSlot()
|
1317
|
+
def _toggleViewerPanelVisibility(self):
|
1318
|
+
"""Toggle the visibility of the document viewer panel."""
|
1319
|
+
CONFIG.showViewerPanel = not CONFIG.showViewerPanel
|
1320
|
+
self.docViewerPanel.setVisible(CONFIG.showViewerPanel)
|
1321
|
+
return
|
1322
|
+
|
1270
1323
|
@pyqtSlot()
|
1271
1324
|
def _timeTick(self) -> None:
|
1272
1325
|
"""Process time tick of the main timer."""
|
@@ -1408,6 +1461,7 @@ class GuiMain(QMainWindow):
|
|
1408
1461
|
self.addAction(self.mainMenu.aInsTimes)
|
1409
1462
|
self.addAction(self.mainMenu.aInsDivide)
|
1410
1463
|
self.addAction(self.mainMenu.aInsSynopsis)
|
1464
|
+
self.addAction(self.mainMenu.aInsShort)
|
1411
1465
|
|
1412
1466
|
for mAction, _ in self.mainMenu.mInsKWItems.values():
|
1413
1467
|
self.addAction(mAction)
|
novelwriter/shared.py
CHANGED
@@ -52,6 +52,10 @@ class SharedData(QObject):
|
|
52
52
|
projectStatusChanged = pyqtSignal(bool)
|
53
53
|
projectStatusMessage = pyqtSignal(str)
|
54
54
|
spellLanguageChanged = pyqtSignal(str, str)
|
55
|
+
indexScannedText = pyqtSignal(str)
|
56
|
+
indexChangedTags = pyqtSignal(list, list)
|
57
|
+
indexCleared = pyqtSignal()
|
58
|
+
indexAvailable = pyqtSignal()
|
55
59
|
|
56
60
|
def __init__(self) -> None:
|
57
61
|
super().__init__()
|
@@ -171,7 +175,7 @@ class SharedData(QObject):
|
|
171
175
|
return
|
172
176
|
|
173
177
|
def updateSpellCheckLanguage(self, reload: bool = False) -> None:
|
174
|
-
"""Update the active spell check
|
178
|
+
"""Update the active spell check language from settings."""
|
175
179
|
from novelwriter import CONFIG
|
176
180
|
language = self.project.data.spellLang or CONFIG.spellLanguage
|
177
181
|
if language != self.spelling.spellLanguage or reload:
|
@@ -210,6 +214,24 @@ class SharedData(QObject):
|
|
210
214
|
QThreadPool.globalInstance().start(runnable, priority=priority)
|
211
215
|
return
|
212
216
|
|
217
|
+
##
|
218
|
+
# Signal Proxy
|
219
|
+
##
|
220
|
+
|
221
|
+
def indexSignalProxy(self, data: dict) -> None:
|
222
|
+
"""Emit signals on behalf of the index."""
|
223
|
+
event = data.get("event")
|
224
|
+
logger.debug("Received '%s' event from the index", event)
|
225
|
+
if event == "updateTags":
|
226
|
+
self.indexChangedTags.emit(data.get("updated", []), data.get("deleted", []))
|
227
|
+
elif event == "scanText":
|
228
|
+
self.indexScannedText.emit(data.get("handle", ""))
|
229
|
+
elif event == "clearIndex":
|
230
|
+
self.indexCleared.emit()
|
231
|
+
elif event == "buildIndex":
|
232
|
+
self.indexAvailable.emit()
|
233
|
+
return
|
234
|
+
|
213
235
|
##
|
214
236
|
# Alert Boxes
|
215
237
|
##
|