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/gui/noveltree.py
CHANGED
@@ -31,20 +31,23 @@ from enum import Enum
|
|
31
31
|
from time import time
|
32
32
|
from typing import TYPE_CHECKING
|
33
33
|
|
34
|
+
from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSlot, pyqtSignal
|
34
35
|
from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
|
35
|
-
from PyQt5.QtCore import QModelIndex, QPoint, Qt, QSize, pyqtSlot, pyqtSignal
|
36
36
|
from PyQt5.QtWidgets import (
|
37
37
|
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
|
38
|
-
QInputDialog, QMenu, QSizePolicy,
|
39
|
-
|
38
|
+
QInputDialog, QMenu, QSizePolicy, QToolTip, QTreeWidget, QTreeWidgetItem,
|
39
|
+
QVBoxLayout, QWidget
|
40
40
|
)
|
41
41
|
|
42
42
|
from novelwriter import CONFIG, SHARED
|
43
|
-
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
|
44
43
|
from novelwriter.common import minmax
|
45
44
|
from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst
|
46
45
|
from novelwriter.core.index import IndexHeading
|
46
|
+
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
|
47
|
+
from novelwriter.extensions.modified import NIconToolButton
|
47
48
|
from novelwriter.extensions.novelselector import NovelSelector
|
49
|
+
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
50
|
+
from novelwriter.types import QtAlignRight, QtDecoration, QtMouseLeft, QtMouseMiddle, QtUserRole
|
48
51
|
|
49
52
|
if TYPE_CHECKING: # pragma: no cover
|
50
53
|
from novelwriter.guimain import GuiMain
|
@@ -198,7 +201,7 @@ class GuiNovelToolBar(QWidget):
|
|
198
201
|
self.novelView = novelView
|
199
202
|
self.mainGui = novelView.mainGui
|
200
203
|
|
201
|
-
|
204
|
+
iSz = SHARED.theme.baseIconSize
|
202
205
|
mPx = CONFIG.pxInt(2)
|
203
206
|
|
204
207
|
self.setContentsMargins(0, 0, 0, 0)
|
@@ -215,15 +218,13 @@ class GuiNovelToolBar(QWidget):
|
|
215
218
|
self.novelValue.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
216
219
|
self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot)
|
217
220
|
|
218
|
-
self.tbNovel =
|
221
|
+
self.tbNovel = NIconToolButton(self, iSz)
|
219
222
|
self.tbNovel.setToolTip(self.tr("Novel Root"))
|
220
|
-
self.tbNovel.setIconSize(QSize(iPx, iPx))
|
221
223
|
self.tbNovel.clicked.connect(self.novelValue.showPopup)
|
222
224
|
|
223
225
|
# Refresh Button
|
224
|
-
self.tbRefresh =
|
226
|
+
self.tbRefresh = NIconToolButton(self, iSz)
|
225
227
|
self.tbRefresh.setToolTip(self.tr("Refresh"))
|
226
|
-
self.tbRefresh.setIconSize(QSize(iPx, iPx))
|
227
228
|
self.tbRefresh.clicked.connect(self._refreshNovelTree)
|
228
229
|
|
229
230
|
# More Options Menu
|
@@ -241,11 +242,9 @@ class GuiNovelToolBar(QWidget):
|
|
241
242
|
self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size"))
|
242
243
|
self.aLastColSize.triggered.connect(self._selectLastColumnSize)
|
243
244
|
|
244
|
-
self.tbMore =
|
245
|
+
self.tbMore = NIconToolButton(self, iSz)
|
245
246
|
self.tbMore.setToolTip(self.tr("More Options"))
|
246
|
-
self.tbMore.setIconSize(QSize(iPx, iPx))
|
247
247
|
self.tbMore.setMenu(self.mMore)
|
248
|
-
self.tbMore.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
249
248
|
|
250
249
|
# Assemble
|
251
250
|
self.outerBox = QHBoxLayout()
|
@@ -271,25 +270,19 @@ class GuiNovelToolBar(QWidget):
|
|
271
270
|
def updateTheme(self) -> None:
|
272
271
|
"""Update theme elements."""
|
273
272
|
# Icons
|
274
|
-
self.tbNovel.
|
275
|
-
self.tbRefresh.
|
276
|
-
self.tbMore.
|
273
|
+
self.tbNovel.setThemeIcon("cls_novel")
|
274
|
+
self.tbRefresh.setThemeIcon("refresh")
|
275
|
+
self.tbMore.setThemeIcon("menu")
|
277
276
|
|
278
277
|
qPalette = self.palette()
|
279
278
|
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
280
279
|
self.setPalette(qPalette)
|
281
280
|
|
282
281
|
# StyleSheets
|
283
|
-
|
284
|
-
buttonStyle = (
|
285
|
-
"QToolButton {{padding: {0}px; border: none; background: transparent;}} "
|
286
|
-
"QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}"
|
287
|
-
).format(CONFIG.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue())
|
288
|
-
buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}"
|
289
|
-
|
282
|
+
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
290
283
|
self.tbNovel.setStyleSheet(buttonStyle)
|
291
284
|
self.tbRefresh.setStyleSheet(buttonStyle)
|
292
|
-
self.tbMore.setStyleSheet(
|
285
|
+
self.tbMore.setStyleSheet(buttonStyle)
|
293
286
|
|
294
287
|
self.novelValue.setStyleSheet(
|
295
288
|
"QComboBox {border-style: none; padding-left: 0;} "
|
@@ -351,7 +344,7 @@ class GuiNovelToolBar(QWidget):
|
|
351
344
|
# Internal Functions
|
352
345
|
##
|
353
346
|
|
354
|
-
def _addLastColAction(self, colType, actionLabel) -> None:
|
347
|
+
def _addLastColAction(self, colType: NovelTreeColumn, actionLabel: str) -> None:
|
355
348
|
"""Add a column selection entry to the last column menu."""
|
356
349
|
aLast = self.mLastCol.addAction(actionLabel)
|
357
350
|
aLast.setCheckable(True)
|
@@ -371,10 +364,10 @@ class GuiNovelTree(QTreeWidget):
|
|
371
364
|
C_EXTRA = 2
|
372
365
|
C_MORE = 3
|
373
366
|
|
374
|
-
D_HANDLE =
|
375
|
-
D_TITLE =
|
376
|
-
D_KEY =
|
377
|
-
D_EXTRA =
|
367
|
+
D_HANDLE = QtUserRole
|
368
|
+
D_TITLE = QtUserRole + 1
|
369
|
+
D_KEY = QtUserRole + 2
|
370
|
+
D_EXTRA = QtUserRole + 3
|
378
371
|
|
379
372
|
def __init__(self, novelView: GuiNovelView) -> None:
|
380
373
|
super().__init__(parent=novelView)
|
@@ -399,10 +392,11 @@ class GuiNovelTree(QTreeWidget):
|
|
399
392
|
# Build GUI
|
400
393
|
# =========
|
401
394
|
|
402
|
-
iPx = SHARED.theme.
|
395
|
+
iPx = SHARED.theme.baseIconHeight
|
396
|
+
iSz = SHARED.theme.baseIconSize
|
403
397
|
cMg = CONFIG.pxInt(6)
|
404
398
|
|
405
|
-
self.setIconSize(
|
399
|
+
self.setIconSize(iSz)
|
406
400
|
self.setFrameStyle(QFrame.Shape.NoFrame)
|
407
401
|
self.setUniformRowHeights(True)
|
408
402
|
self.setAllColumnsShowFocus(True)
|
@@ -463,7 +457,7 @@ class GuiNovelTree(QTreeWidget):
|
|
463
457
|
|
464
458
|
def updateTheme(self) -> None:
|
465
459
|
"""Update theme elements."""
|
466
|
-
iPx = SHARED.theme.
|
460
|
+
iPx = SHARED.theme.baseIconHeight
|
467
461
|
self._pMore = SHARED.theme.loadDecoration("deco_doc_more", h=iPx)
|
468
462
|
return
|
469
463
|
|
@@ -589,12 +583,12 @@ class GuiNovelTree(QTreeWidget):
|
|
589
583
|
"""
|
590
584
|
super().mousePressEvent(event)
|
591
585
|
|
592
|
-
if event.button() ==
|
586
|
+
if event.button() == QtMouseLeft:
|
593
587
|
selItem = self.indexAt(event.pos())
|
594
588
|
if not selItem.isValid():
|
595
589
|
self.clearSelection()
|
596
590
|
|
597
|
-
elif event.button() ==
|
591
|
+
elif event.button() == QtMouseMiddle:
|
598
592
|
selItem = self.itemAt(event.pos())
|
599
593
|
if not isinstance(selItem, QTreeWidgetItem):
|
600
594
|
return
|
@@ -684,7 +678,7 @@ class GuiNovelTree(QTreeWidget):
|
|
684
678
|
newItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
|
685
679
|
newItem.setData(self.C_DATA, self.D_TITLE, sTitle)
|
686
680
|
newItem.setData(self.C_DATA, self.D_KEY, tKey)
|
687
|
-
newItem.setTextAlignment(self.C_WORDS,
|
681
|
+
newItem.setTextAlignment(self.C_WORDS, QtAlignRight)
|
688
682
|
|
689
683
|
self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle)
|
690
684
|
self._treeMap[tKey] = newItem
|
@@ -703,11 +697,11 @@ class GuiNovelTree(QTreeWidget):
|
|
703
697
|
iLevel = nwHeaders.H_LEVEL.get(idxItem.level, 0)
|
704
698
|
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
705
699
|
|
706
|
-
trItem.setData(self.C_TITLE,
|
700
|
+
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
707
701
|
trItem.setText(self.C_TITLE, idxItem.title)
|
708
702
|
trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
|
709
703
|
trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
|
710
|
-
trItem.setData(self.C_MORE,
|
704
|
+
trItem.setData(self.C_MORE, QtDecoration, self._pMore)
|
711
705
|
|
712
706
|
# Custom column
|
713
707
|
mW = int(self._lastColSize * self.viewport().width())
|
@@ -750,7 +744,7 @@ class GuiNovelTree(QTreeWidget):
|
|
750
744
|
logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
|
751
745
|
|
752
746
|
pIndex = SHARED.project.index
|
753
|
-
novIdx = pIndex.
|
747
|
+
novIdx = pIndex.getItemHeading(tHandle, sTitle)
|
754
748
|
refTags = pIndex.getReferences(tHandle, sTitle)
|
755
749
|
if not novIdx:
|
756
750
|
return
|
novelwriter/gui/outline.py
CHANGED
@@ -33,7 +33,7 @@ import logging
|
|
33
33
|
from time import time
|
34
34
|
from enum import Enum
|
35
35
|
|
36
|
-
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot,
|
36
|
+
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QT_TRANSLATE_NOOP
|
37
37
|
from PyQt5.QtWidgets import (
|
38
38
|
QAbstractItemView, QAction, QFileDialog, QFrame, QGridLayout, QGroupBox,
|
39
39
|
QHBoxLayout, QLabel, QMenu, QScrollArea, QSizePolicy, QSplitter, QToolBar,
|
@@ -47,7 +47,11 @@ from novelwriter.enum import (
|
|
47
47
|
from novelwriter.error import logException
|
48
48
|
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
|
49
49
|
from novelwriter.constants import nwHeaders, trConst, nwKeyWords, nwLabels
|
50
|
+
from novelwriter.extensions.configlayout import NColourLabel
|
50
51
|
from novelwriter.extensions.novelselector import NovelSelector
|
52
|
+
from novelwriter.types import (
|
53
|
+
QtAlignLeftTop, QtAlignRight, QtAlignRightTop, QtDecoration, QtUserRole
|
54
|
+
)
|
51
55
|
|
52
56
|
|
53
57
|
logger = logging.getLogger(__name__)
|
@@ -67,7 +71,7 @@ class GuiOutlineView(QWidget):
|
|
67
71
|
self.outlineBar = GuiOutlineToolBar(self)
|
68
72
|
self.outlineBar.setEnabled(False)
|
69
73
|
|
70
|
-
self.splitOutline = QSplitter(Qt.Vertical)
|
74
|
+
self.splitOutline = QSplitter(Qt.Orientation.Vertical, self)
|
71
75
|
self.splitOutline.addWidget(self.outlineTree)
|
72
76
|
self.splitOutline.addWidget(self.outlineData)
|
73
77
|
self.splitOutline.setOpaqueResize(False)
|
@@ -187,7 +191,7 @@ class GuiOutlineView(QWidget):
|
|
187
191
|
return
|
188
192
|
|
189
193
|
@pyqtSlot(str)
|
190
|
-
def _rootItemChanged(self, tHandle) -> None:
|
194
|
+
def _rootItemChanged(self, tHandle: str) -> None:
|
191
195
|
"""Handle root novel changed or needs to be refreshed."""
|
192
196
|
self.outlineTree.refreshTree(rootHandle=(tHandle or None), overRide=True)
|
193
197
|
return
|
@@ -206,19 +210,18 @@ class GuiOutlineToolBar(QToolBar):
|
|
206
210
|
|
207
211
|
logger.debug("Create: GuiOutlineToolBar")
|
208
212
|
|
209
|
-
iPx = CONFIG.pxInt(22)
|
210
|
-
mPx = CONFIG.pxInt(12)
|
211
|
-
|
212
213
|
self.setMovable(False)
|
213
|
-
self.setIconSize(
|
214
|
+
self.setIconSize(1.4*SHARED.theme.baseIconSize)
|
214
215
|
self.setContentsMargins(0, 0, 0, 0)
|
215
216
|
|
216
217
|
stretch = QWidget(self)
|
217
218
|
stretch.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
218
219
|
|
219
220
|
# Novel Selector
|
220
|
-
self.novelLabel =
|
221
|
-
|
221
|
+
self.novelLabel = NColourLabel(
|
222
|
+
self.tr("Outline of"), parent=self, scale=NColourLabel.HEADER_SCALE, bold=True
|
223
|
+
)
|
224
|
+
self.novelLabel.setContentsMargins(0, 0, CONFIG.pxInt(12), 0)
|
222
225
|
|
223
226
|
self.novelValue = NovelSelector(self)
|
224
227
|
self.novelValue.setIncludeAll(True)
|
@@ -353,8 +356,8 @@ class GuiOutlineTree(QTreeWidget):
|
|
353
356
|
nwOutline.SYNOP: False,
|
354
357
|
}
|
355
358
|
|
356
|
-
D_HANDLE =
|
357
|
-
D_TITLE =
|
359
|
+
D_HANDLE = QtUserRole
|
360
|
+
D_TITLE = QtUserRole + 1
|
358
361
|
|
359
362
|
hiddenStateChanged = pyqtSignal()
|
360
363
|
activeItemChanged = pyqtSignal(str, str)
|
@@ -375,8 +378,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
375
378
|
self.itemDoubleClicked.connect(self._treeDoubleClick)
|
376
379
|
self.itemSelectionChanged.connect(self._itemSelected)
|
377
380
|
|
378
|
-
|
379
|
-
self.setIconSize(QSize(iPx, iPx))
|
381
|
+
self.setIconSize(SHARED.theme.baseIconSize)
|
380
382
|
self.setIndentation(0)
|
381
383
|
|
382
384
|
self.treeHead = self.header()
|
@@ -426,7 +428,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
426
428
|
##
|
427
429
|
|
428
430
|
@property
|
429
|
-
def hiddenColumns(self):
|
431
|
+
def hiddenColumns(self) -> dict[nwOutline, bool]:
|
430
432
|
return self._colHidden
|
431
433
|
|
432
434
|
##
|
@@ -584,7 +586,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
584
586
|
# Internal Functions
|
585
587
|
##
|
586
588
|
|
587
|
-
def _loadHeaderState(self):
|
589
|
+
def _loadHeaderState(self) -> None:
|
588
590
|
"""Load the state of the main tree header, that is, column order
|
589
591
|
and column width.
|
590
592
|
"""
|
@@ -675,11 +677,11 @@ class GuiOutlineTree(QTreeWidget):
|
|
675
677
|
headItem = self.headerItem()
|
676
678
|
if isinstance(headItem, QTreeWidgetItem):
|
677
679
|
headItem.setTextAlignment(
|
678
|
-
self._colIdx[nwOutline.CCOUNT],
|
680
|
+
self._colIdx[nwOutline.CCOUNT], QtAlignRight)
|
679
681
|
headItem.setTextAlignment(
|
680
|
-
self._colIdx[nwOutline.WCOUNT],
|
682
|
+
self._colIdx[nwOutline.WCOUNT], QtAlignRight)
|
681
683
|
headItem.setTextAlignment(
|
682
|
-
self._colIdx[nwOutline.PCOUNT],
|
684
|
+
self._colIdx[nwOutline.PCOUNT], QtAlignRight)
|
683
685
|
|
684
686
|
novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
|
685
687
|
for _, tHandle, sTitle, novIdx in novStruct:
|
@@ -692,7 +694,7 @@ class GuiOutlineTree(QTreeWidget):
|
|
692
694
|
trItem = QTreeWidgetItem()
|
693
695
|
hDec = SHARED.theme.getHeaderDecoration(iLevel)
|
694
696
|
|
695
|
-
trItem.setData(self._colIdx[nwOutline.TITLE],
|
697
|
+
trItem.setData(self._colIdx[nwOutline.TITLE], QtDecoration, hDec)
|
696
698
|
trItem.setText(self._colIdx[nwOutline.TITLE], novIdx.title)
|
697
699
|
trItem.setData(self._colIdx[nwOutline.TITLE], self.D_HANDLE, tHandle)
|
698
700
|
trItem.setData(self._colIdx[nwOutline.TITLE], self.D_TITLE, sTitle)
|
@@ -705,9 +707,9 @@ class GuiOutlineTree(QTreeWidget):
|
|
705
707
|
trItem.setText(self._colIdx[nwOutline.CCOUNT], f"{novIdx.charCount:n}")
|
706
708
|
trItem.setText(self._colIdx[nwOutline.WCOUNT], f"{novIdx.wordCount:n}")
|
707
709
|
trItem.setText(self._colIdx[nwOutline.PCOUNT], f"{novIdx.paraCount:n}")
|
708
|
-
trItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT],
|
709
|
-
trItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT],
|
710
|
-
trItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT],
|
710
|
+
trItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT], QtAlignRight)
|
711
|
+
trItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT], QtAlignRight)
|
712
|
+
trItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT], QtAlignRight)
|
711
713
|
|
712
714
|
refs = SHARED.project.index.getReferences(tHandle, sTitle)
|
713
715
|
trItem.setText(self._colIdx[nwOutline.POV], ", ".join(refs[nwKeyWords.POV_KEY]))
|
@@ -798,13 +800,19 @@ class GuiOutlineDetails(QScrollArea):
|
|
798
800
|
hSpace = int(CONFIG.pxInt(10))
|
799
801
|
vSpace = int(CONFIG.pxInt(4))
|
800
802
|
|
803
|
+
bFont = SHARED.theme.guiFontB
|
804
|
+
|
801
805
|
# Details Area
|
802
|
-
self.titleLabel = QLabel(
|
803
|
-
self.fileLabel = QLabel(
|
804
|
-
self.itemLabel = QLabel(
|
805
|
-
self.titleValue = QLabel("")
|
806
|
-
self.fileValue = QLabel("")
|
807
|
-
self.itemValue = QLabel("")
|
806
|
+
self.titleLabel = QLabel(self.tr("Title"), self)
|
807
|
+
self.fileLabel = QLabel(self.tr("Document"), self)
|
808
|
+
self.itemLabel = QLabel(self.tr("Status"), self)
|
809
|
+
self.titleValue = QLabel("", self)
|
810
|
+
self.fileValue = QLabel("", self)
|
811
|
+
self.itemValue = QLabel("", self)
|
812
|
+
|
813
|
+
self.titleLabel.setFont(bFont)
|
814
|
+
self.fileLabel.setFont(bFont)
|
815
|
+
self.itemLabel.setFont(bFont)
|
808
816
|
|
809
817
|
self.titleValue.setMinimumWidth(minTitle)
|
810
818
|
self.titleValue.setMaximumWidth(maxTitle)
|
@@ -814,38 +822,55 @@ class GuiOutlineDetails(QScrollArea):
|
|
814
822
|
self.itemValue.setMaximumWidth(maxTitle)
|
815
823
|
|
816
824
|
# Stats Area
|
817
|
-
self.cCLabel = QLabel(
|
818
|
-
self.wCLabel = QLabel(
|
819
|
-
self.pCLabel = QLabel(
|
820
|
-
self.cCValue = QLabel("")
|
821
|
-
self.wCValue = QLabel("")
|
822
|
-
self.pCValue = QLabel("")
|
825
|
+
self.cCLabel = QLabel(self.tr("Characters"), self)
|
826
|
+
self.wCLabel = QLabel(self.tr("Words"), self)
|
827
|
+
self.pCLabel = QLabel(self.tr("Paragraphs"), self)
|
828
|
+
self.cCValue = QLabel("", self)
|
829
|
+
self.wCValue = QLabel("", self)
|
830
|
+
self.pCValue = QLabel("", self)
|
831
|
+
|
832
|
+
self.cCLabel.setFont(bFont)
|
833
|
+
self.wCLabel.setFont(bFont)
|
834
|
+
self.pCLabel.setFont(bFont)
|
823
835
|
|
824
836
|
self.cCValue.setMinimumWidth(wCount)
|
825
837
|
self.wCValue.setMinimumWidth(wCount)
|
826
838
|
self.pCValue.setMinimumWidth(wCount)
|
827
|
-
self.cCValue.setAlignment(
|
828
|
-
self.wCValue.setAlignment(
|
829
|
-
self.pCValue.setAlignment(
|
839
|
+
self.cCValue.setAlignment(QtAlignRight)
|
840
|
+
self.wCValue.setAlignment(QtAlignRight)
|
841
|
+
self.pCValue.setAlignment(QtAlignRight)
|
830
842
|
|
831
843
|
# Synopsis
|
832
|
-
self.synopLabel = QLabel(
|
833
|
-
self.
|
834
|
-
|
844
|
+
self.synopLabel = QLabel(self.tr("Synopsis"), self)
|
845
|
+
self.synopLabel.setFont(bFont)
|
846
|
+
|
847
|
+
self.synopValue = QLabel("", self)
|
835
848
|
self.synopValue.setWordWrap(True)
|
836
|
-
self.synopValue.setAlignment(
|
849
|
+
self.synopValue.setAlignment(QtAlignLeftTop)
|
850
|
+
|
851
|
+
self.synopLWrap = QHBoxLayout()
|
837
852
|
self.synopLWrap.addWidget(self.synopValue, 1)
|
838
853
|
|
839
854
|
# Tags
|
840
|
-
self.povKeyLabel = QLabel(
|
841
|
-
self.focKeyLabel = QLabel(
|
842
|
-
self.chrKeyLabel = QLabel(
|
843
|
-
self.pltKeyLabel = QLabel(
|
844
|
-
self.timKeyLabel = QLabel(
|
845
|
-
self.wldKeyLabel = QLabel(
|
846
|
-
self.objKeyLabel = QLabel(
|
847
|
-
self.entKeyLabel = QLabel(
|
848
|
-
self.cstKeyLabel = QLabel(
|
855
|
+
self.povKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]), self)
|
856
|
+
self.focKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]), self)
|
857
|
+
self.chrKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]), self)
|
858
|
+
self.pltKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]), self)
|
859
|
+
self.timKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]), self)
|
860
|
+
self.wldKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]), self)
|
861
|
+
self.objKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]), self)
|
862
|
+
self.entKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]), self)
|
863
|
+
self.cstKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]), self)
|
864
|
+
|
865
|
+
self.povKeyLabel.setFont(bFont)
|
866
|
+
self.focKeyLabel.setFont(bFont)
|
867
|
+
self.chrKeyLabel.setFont(bFont)
|
868
|
+
self.pltKeyLabel.setFont(bFont)
|
869
|
+
self.timKeyLabel.setFont(bFont)
|
870
|
+
self.wldKeyLabel.setFont(bFont)
|
871
|
+
self.objKeyLabel.setFont(bFont)
|
872
|
+
self.entKeyLabel.setFont(bFont)
|
873
|
+
self.cstKeyLabel.setFont(bFont)
|
849
874
|
|
850
875
|
self.povKeyLWrap = QHBoxLayout()
|
851
876
|
self.focKeyLWrap = QHBoxLayout()
|
@@ -857,15 +882,15 @@ class GuiOutlineDetails(QScrollArea):
|
|
857
882
|
self.entKeyLWrap = QHBoxLayout()
|
858
883
|
self.cstKeyLWrap = QHBoxLayout()
|
859
884
|
|
860
|
-
self.povKeyValue = QLabel("")
|
861
|
-
self.focKeyValue = QLabel("")
|
862
|
-
self.chrKeyValue = QLabel("")
|
863
|
-
self.pltKeyValue = QLabel("")
|
864
|
-
self.timKeyValue = QLabel("")
|
865
|
-
self.wldKeyValue = QLabel("")
|
866
|
-
self.objKeyValue = QLabel("")
|
867
|
-
self.entKeyValue = QLabel("")
|
868
|
-
self.cstKeyValue = QLabel("")
|
885
|
+
self.povKeyValue = QLabel("", self)
|
886
|
+
self.focKeyValue = QLabel("", self)
|
887
|
+
self.chrKeyValue = QLabel("", self)
|
888
|
+
self.pltKeyValue = QLabel("", self)
|
889
|
+
self.timKeyValue = QLabel("", self)
|
890
|
+
self.wldKeyValue = QLabel("", self)
|
891
|
+
self.objKeyValue = QLabel("", self)
|
892
|
+
self.entKeyValue = QLabel("", self)
|
893
|
+
self.cstKeyValue = QLabel("", self)
|
869
894
|
|
870
895
|
self.povKeyValue.setWordWrap(True)
|
871
896
|
self.focKeyValue.setWordWrap(True)
|
@@ -902,23 +927,20 @@ class GuiOutlineDetails(QScrollArea):
|
|
902
927
|
self.mainForm = QGridLayout()
|
903
928
|
self.mainGroup.setLayout(self.mainForm)
|
904
929
|
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
self.mainForm.addWidget(self.
|
909
|
-
self.mainForm.addWidget(self.
|
910
|
-
self.mainForm.addWidget(self.
|
911
|
-
self.mainForm.addWidget(self.
|
912
|
-
self.mainForm.addWidget(self.
|
913
|
-
self.mainForm.addWidget(self.
|
914
|
-
self.mainForm.addWidget(self.
|
915
|
-
self.mainForm.addWidget(self.
|
916
|
-
self.mainForm.addWidget(self.
|
917
|
-
self.mainForm.addWidget(self.
|
918
|
-
self.mainForm.
|
919
|
-
self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, topRight)
|
920
|
-
self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, topLeft)
|
921
|
-
self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, topLeft)
|
930
|
+
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop)
|
931
|
+
self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, QtAlignLeftTop)
|
932
|
+
self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, QtAlignLeftTop)
|
933
|
+
self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, QtAlignRightTop)
|
934
|
+
self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1, QtAlignLeftTop)
|
935
|
+
self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1, QtAlignLeftTop)
|
936
|
+
self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, QtAlignLeftTop)
|
937
|
+
self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, QtAlignRightTop)
|
938
|
+
self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1, QtAlignLeftTop)
|
939
|
+
self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1, QtAlignLeftTop)
|
940
|
+
self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, QtAlignLeftTop)
|
941
|
+
self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, QtAlignRightTop)
|
942
|
+
self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, QtAlignLeftTop)
|
943
|
+
self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, QtAlignLeftTop)
|
922
944
|
|
923
945
|
self.mainForm.setColumnStretch(1, 1)
|
924
946
|
self.mainForm.setRowStretch(4, 1)
|
@@ -930,24 +952,24 @@ class GuiOutlineDetails(QScrollArea):
|
|
930
952
|
self.tagsForm = QGridLayout()
|
931
953
|
self.tagsGroup.setLayout(self.tagsForm)
|
932
954
|
|
933
|
-
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1,
|
934
|
-
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1,
|
935
|
-
self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1,
|
936
|
-
self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1,
|
937
|
-
self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1,
|
938
|
-
self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1,
|
939
|
-
self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1,
|
940
|
-
self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1,
|
941
|
-
self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1,
|
942
|
-
self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1,
|
943
|
-
self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1,
|
944
|
-
self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1,
|
945
|
-
self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1,
|
946
|
-
self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1,
|
947
|
-
self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1,
|
948
|
-
self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1,
|
949
|
-
self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1,
|
950
|
-
self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1,
|
955
|
+
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, QtAlignLeftTop)
|
956
|
+
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1, QtAlignLeftTop)
|
957
|
+
self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1, QtAlignLeftTop)
|
958
|
+
self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1, QtAlignLeftTop)
|
959
|
+
self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1, QtAlignLeftTop)
|
960
|
+
self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1, QtAlignLeftTop)
|
961
|
+
self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1, QtAlignLeftTop)
|
962
|
+
self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1, QtAlignLeftTop)
|
963
|
+
self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1, QtAlignLeftTop)
|
964
|
+
self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1, QtAlignLeftTop)
|
965
|
+
self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1, QtAlignLeftTop)
|
966
|
+
self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1, QtAlignLeftTop)
|
967
|
+
self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1, QtAlignLeftTop)
|
968
|
+
self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1, QtAlignLeftTop)
|
969
|
+
self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1, QtAlignLeftTop)
|
970
|
+
self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1, QtAlignLeftTop)
|
971
|
+
self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1, QtAlignLeftTop)
|
972
|
+
self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1, QtAlignLeftTop)
|
951
973
|
|
952
974
|
self.tagsForm.setColumnStretch(1, 1)
|
953
975
|
self.tagsForm.setRowStretch(8, 1)
|
@@ -955,7 +977,7 @@ class GuiOutlineDetails(QScrollArea):
|
|
955
977
|
self.tagsForm.setVerticalSpacing(vSpace)
|
956
978
|
|
957
979
|
# Assemble
|
958
|
-
self.outerWidget = QWidget()
|
980
|
+
self.outerWidget = QWidget(self)
|
959
981
|
self.outerBox = QHBoxLayout()
|
960
982
|
self.outerBox.addWidget(self.mainGroup, 0)
|
961
983
|
self.outerBox.addWidget(self.tagsGroup, 1)
|
@@ -989,7 +1011,7 @@ class GuiOutlineDetails(QScrollArea):
|
|
989
1011
|
|
990
1012
|
def clearDetails(self) -> None:
|
991
1013
|
"""Clear all the data labels."""
|
992
|
-
self.titleLabel.setText(
|
1014
|
+
self.titleLabel.setText(self.tr("Title"))
|
993
1015
|
self.titleValue.setText("")
|
994
1016
|
self.fileValue.setText("")
|
995
1017
|
self.itemValue.setText("")
|
@@ -1020,10 +1042,10 @@ class GuiOutlineDetails(QScrollArea):
|
|
1020
1042
|
"""
|
1021
1043
|
pIndex = SHARED.project.index
|
1022
1044
|
nwItem = SHARED.project.tree[tHandle]
|
1023
|
-
novIdx = pIndex.
|
1045
|
+
novIdx = pIndex.getItemHeading(tHandle, sTitle)
|
1024
1046
|
novRefs = pIndex.getReferences(tHandle, sTitle)
|
1025
1047
|
if nwItem and novIdx:
|
1026
|
-
self.titleLabel.setText(
|
1048
|
+
self.titleLabel.setText(self.tr(self.LVL_MAP.get(novIdx.level, "H1")))
|
1027
1049
|
self.titleValue.setText(novIdx.title)
|
1028
1050
|
|
1029
1051
|
itemStatus, _ = nwItem.getImportStatus(incIcon=False)
|