novelWriter 2.4b1__py3-none-any.whl → 2.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/METADATA +5 -6
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/RECORD +79 -83
- novelwriter/__init__.py +15 -8
- 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 +2 -2
- 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 +2 -2
- 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/common.py +11 -3
- novelwriter/config.py +12 -4
- novelwriter/core/buildsettings.py +7 -7
- novelwriter/core/coretools.py +21 -22
- novelwriter/core/docbuild.py +2 -2
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/spellcheck.py +3 -3
- novelwriter/core/status.py +3 -2
- novelwriter/core/tokenizer.py +3 -3
- novelwriter/core/toodt.py +333 -356
- novelwriter/dialogs/about.py +9 -11
- novelwriter/dialogs/docmerge.py +17 -14
- novelwriter/dialogs/docsplit.py +14 -12
- novelwriter/dialogs/editlabel.py +5 -4
- novelwriter/dialogs/preferences.py +29 -34
- novelwriter/dialogs/projectsettings.py +31 -28
- novelwriter/dialogs/quotes.py +10 -9
- novelwriter/dialogs/wordlist.py +17 -14
- novelwriter/error.py +14 -12
- novelwriter/extensions/circularprogress.py +12 -8
- novelwriter/extensions/configlayout.py +1 -3
- novelwriter/extensions/modified.py +33 -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/gui/doceditor.py +205 -246
- novelwriter/gui/dochighlight.py +26 -9
- novelwriter/gui/docviewer.py +55 -59
- novelwriter/gui/docviewerpanel.py +16 -13
- novelwriter/gui/editordocument.py +4 -4
- novelwriter/gui/itemdetails.py +45 -48
- novelwriter/gui/mainmenu.py +2 -2
- novelwriter/gui/noveltree.py +23 -21
- novelwriter/gui/outline.py +93 -94
- novelwriter/gui/projtree.py +32 -30
- novelwriter/gui/search.py +75 -29
- novelwriter/gui/sidebar.py +24 -28
- novelwriter/gui/statusbar.py +14 -14
- novelwriter/gui/theme.py +61 -39
- novelwriter/guimain.py +37 -33
- novelwriter/shared.py +21 -9
- novelwriter/text/counting.py +1 -0
- novelwriter/tools/dictionaries.py +15 -14
- novelwriter/tools/lipsum.py +20 -17
- novelwriter/tools/manusbuild.py +44 -35
- novelwriter/tools/manuscript.py +112 -112
- novelwriter/tools/manussettings.py +91 -98
- novelwriter/tools/noveldetails.py +20 -18
- novelwriter/tools/welcome.py +51 -48
- novelwriter/tools/writingstats.py +61 -55
- novelwriter/types.py +90 -0
- novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +0 -4
- 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/text/__init__.py +0 -3
- novelwriter/tools/__init__.py +0 -3
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/WHEEL +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/top_level.txt +0 -0
novelwriter/gui/dochighlight.py
CHANGED
@@ -44,6 +44,10 @@ logger = logging.getLogger(__name__)
|
|
44
44
|
|
45
45
|
SPELLRX = QRegularExpression(r"\b[^\s\-\+\/–—\[\]:]+\b")
|
46
46
|
SPELLRX.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
47
|
+
SPELLSC = QRegularExpression(nwRegEx.FMT_SC)
|
48
|
+
SPELLSC.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
49
|
+
SPELLSV = QRegularExpression(nwRegEx.FMT_SV)
|
50
|
+
SPELLSV.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
47
51
|
|
48
52
|
BLOCK_NONE = 0
|
49
53
|
BLOCK_TEXT = 1
|
@@ -53,7 +57,8 @@ BLOCK_TITLE = 4
|
|
53
57
|
|
54
58
|
class GuiDocHighlighter(QSyntaxHighlighter):
|
55
59
|
|
56
|
-
__slots__ = ("
|
60
|
+
__slots__ = ("_tHandle", "_isInactive", "_spellCheck", "_spellErr",
|
61
|
+
"_hRules", "_hStyles", "_rxRules")
|
57
62
|
|
58
63
|
def __init__(self, document: QTextDocument) -> None:
|
59
64
|
super().__init__(document)
|
@@ -67,6 +72,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
67
72
|
|
68
73
|
self._hRules: list[tuple[str, dict]] = []
|
69
74
|
self._hStyles: dict[str, QTextCharFormat] = {}
|
75
|
+
self._rxRules: list[tuple[QRegularExpression, dict[str, QTextCharFormat]]] = []
|
70
76
|
|
71
77
|
self.initHighlighter()
|
72
78
|
|
@@ -116,7 +122,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
116
122
|
# Cache Spell Error Format
|
117
123
|
self._spellErr = QTextCharFormat()
|
118
124
|
self._spellErr.setUnderlineColor(SHARED.theme.colSpell)
|
119
|
-
self._spellErr.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
125
|
+
self._spellErr.setUnderlineStyle(QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
|
120
126
|
|
121
127
|
# Multiple or Trailing Spaces
|
122
128
|
if CONFIG.showMultiSpaces:
|
@@ -218,11 +224,11 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
218
224
|
))
|
219
225
|
|
220
226
|
# Build a QRegExp for each highlight pattern
|
221
|
-
self.
|
227
|
+
self._rxRules = []
|
222
228
|
for regEx, regRules in self._hRules:
|
223
229
|
hReg = QRegularExpression(regEx)
|
224
230
|
hReg.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
225
|
-
self.
|
231
|
+
self._rxRules.append((hReg, regRules))
|
226
232
|
|
227
233
|
return
|
228
234
|
|
@@ -327,7 +333,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
327
333
|
self.setFormat(0, 3, self._hStyles["head2h"])
|
328
334
|
self.setFormat(3, len(text), self._hStyles["header2"])
|
329
335
|
|
330
|
-
elif text.startswith("###! "): #
|
336
|
+
elif text.startswith("###! "): # Alternative Scene
|
331
337
|
self.setFormat(0, 4, self._hStyles["head3h"])
|
332
338
|
self.setFormat(4, len(text), self._hStyles["header3"])
|
333
339
|
|
@@ -358,7 +364,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
358
364
|
|
359
365
|
# Regular Text
|
360
366
|
self.setCurrentBlockState(BLOCK_TEXT)
|
361
|
-
for rX, xFmt in self.
|
367
|
+
for rX, xFmt in self._rxRules:
|
362
368
|
rxItt = rX.globalMatch(text, 0)
|
363
369
|
while rxItt.hasNext():
|
364
370
|
rxMatch = rxItt.next()
|
@@ -402,16 +408,16 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|
402
408
|
if style is not None:
|
403
409
|
styles = style.split(",")
|
404
410
|
if "bold" in styles:
|
405
|
-
charFormat.setFontWeight(QFont.Bold)
|
411
|
+
charFormat.setFontWeight(QFont.Weight.Bold)
|
406
412
|
if "italic" in styles:
|
407
413
|
charFormat.setFontItalic(True)
|
408
414
|
if "strike" in styles:
|
409
415
|
charFormat.setFontStrikeOut(True)
|
410
416
|
if "errline" in styles:
|
411
417
|
charFormat.setUnderlineColor(SHARED.theme.colError)
|
412
|
-
charFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
418
|
+
charFormat.setUnderlineStyle(QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
|
413
419
|
if "background" in styles and color is not None:
|
414
|
-
charFormat.setBackground(QBrush(color, Qt.SolidPattern))
|
420
|
+
charFormat.setBackground(QBrush(color, Qt.BrushStyle.SolidPattern))
|
415
421
|
|
416
422
|
if size is not None:
|
417
423
|
charFormat.setFontPointSize(int(round(size*CONFIG.textSize)))
|
@@ -439,6 +445,17 @@ class TextBlockData(QTextBlockUserData):
|
|
439
445
|
"""Run the spell checker and cache the result, and return the
|
440
446
|
list of spell check errors.
|
441
447
|
"""
|
448
|
+
if "[" in text:
|
449
|
+
# Strip shortcodes
|
450
|
+
for rX in [SPELLSC, SPELLSV]:
|
451
|
+
rxItt = rX.globalMatch(text, 0)
|
452
|
+
while rxItt.hasNext():
|
453
|
+
rxMatch = rxItt.next()
|
454
|
+
xPos = rxMatch.capturedStart(0)
|
455
|
+
xLen = rxMatch.capturedLength(0)
|
456
|
+
xEnd = rxMatch.capturedEnd(0)
|
457
|
+
text = text[:xPos] + " "*xLen + text[xEnd:]
|
458
|
+
|
442
459
|
self._spellErrors = []
|
443
460
|
rxSpell = SPELLRX.globalMatch(text.replace("_", " "), 0)
|
444
461
|
while rxSpell.hasNext():
|
novelwriter/gui/docviewer.py
CHANGED
@@ -30,24 +30,28 @@ import logging
|
|
30
30
|
|
31
31
|
from enum import Enum
|
32
32
|
|
33
|
-
from PyQt5.QtCore import
|
33
|
+
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
|
34
34
|
from PyQt5.QtGui import (
|
35
35
|
QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor,
|
36
36
|
QTextOption
|
37
37
|
)
|
38
38
|
from PyQt5.QtWidgets import (
|
39
|
-
QAction, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
|
40
|
-
|
39
|
+
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
|
40
|
+
QToolButton, QWidget
|
41
41
|
)
|
42
42
|
|
43
43
|
from novelwriter import CONFIG, SHARED
|
44
|
+
from novelwriter.common import cssCol
|
44
45
|
from novelwriter.constants import nwHeaders, nwUnicode
|
45
46
|
from novelwriter.core.tohtml import ToHtml
|
46
|
-
from novelwriter.enum import
|
47
|
+
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
|
47
48
|
from novelwriter.error import logException
|
48
49
|
from novelwriter.extensions.eventfilters import WheelEventFilter
|
49
50
|
from novelwriter.extensions.modified import NIconToolButton
|
50
51
|
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
52
|
+
from novelwriter.types import (
|
53
|
+
QtAlignCenterTop, QtAlignJustify, QtKeepAnchor, QtMouseLeft, QtMoveAnchor
|
54
|
+
)
|
51
55
|
|
52
56
|
logger = logging.getLogger(__name__)
|
53
57
|
|
@@ -142,7 +146,7 @@ class GuiDocViewer(QTextBrowser):
|
|
142
146
|
font = QFont()
|
143
147
|
font.setFamily(CONFIG.textFont)
|
144
148
|
font.setPointSize(CONFIG.textSize)
|
145
|
-
self.
|
149
|
+
self.document().setDefaultFont(font)
|
146
150
|
|
147
151
|
# Set the widget colours to match syntax theme
|
148
152
|
mainPalette = self.palette()
|
@@ -163,7 +167,7 @@ class GuiDocViewer(QTextBrowser):
|
|
163
167
|
self.document().setDocumentMargin(0)
|
164
168
|
options = QTextOption()
|
165
169
|
if CONFIG.doJustify:
|
166
|
-
options.setAlignment(
|
170
|
+
options.setAlignment(QtAlignJustify)
|
167
171
|
self.document().setDefaultTextOption(options)
|
168
172
|
|
169
173
|
# Scroll bars
|
@@ -193,7 +197,7 @@ class GuiDocViewer(QTextBrowser):
|
|
193
197
|
return False
|
194
198
|
|
195
199
|
logger.debug("Generating preview for item '%s'", tHandle)
|
196
|
-
|
200
|
+
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
197
201
|
|
198
202
|
sPos = self.verticalScrollBar().value()
|
199
203
|
aDoc = ToHtml(SHARED.project)
|
@@ -215,7 +219,7 @@ class GuiDocViewer(QTextBrowser):
|
|
215
219
|
logger.error("Failed to generate preview for document with handle '%s'", tHandle)
|
216
220
|
logException()
|
217
221
|
self.setText(self.tr("An error occurred while generating the preview."))
|
218
|
-
|
222
|
+
QApplication.restoreOverrideCursor()
|
219
223
|
return False
|
220
224
|
|
221
225
|
# Refresh the tab stops
|
@@ -248,7 +252,7 @@ class GuiDocViewer(QTextBrowser):
|
|
248
252
|
# Since we change the content while it may still be rendering, we mark
|
249
253
|
# the document dirty again to make sure it's re-rendered properly.
|
250
254
|
self.redrawText()
|
251
|
-
|
255
|
+
QApplication.restoreOverrideCursor()
|
252
256
|
self.documentLoaded.emit(tHandle)
|
253
257
|
|
254
258
|
return True
|
@@ -408,7 +412,7 @@ class GuiDocViewer(QTextBrowser):
|
|
408
412
|
ctxMenu.addAction(mnuSelPara)
|
409
413
|
|
410
414
|
# Open the context menu
|
411
|
-
ctxMenu.
|
415
|
+
ctxMenu.exec(self.viewport().mapToGlobal(point))
|
412
416
|
ctxMenu.deleteLater()
|
413
417
|
|
414
418
|
return
|
@@ -450,8 +454,8 @@ class GuiDocViewer(QTextBrowser):
|
|
450
454
|
posE = cursor.selectionEnd()
|
451
455
|
selTxt = cursor.selectedText()
|
452
456
|
if selTxt.startswith(nwUnicode.U_PSEP):
|
453
|
-
cursor.setPosition(posS+1,
|
454
|
-
cursor.setPosition(posE,
|
457
|
+
cursor.setPosition(posS+1, QtMoveAnchor)
|
458
|
+
cursor.setPosition(posE, QtKeepAnchor)
|
455
459
|
|
456
460
|
self.setTextCursor(cursor)
|
457
461
|
|
@@ -467,35 +471,25 @@ class GuiDocViewer(QTextBrowser):
|
|
467
471
|
"""Generate an appropriate style sheet for the document viewer,
|
468
472
|
based on the current syntax highlighter theme.
|
469
473
|
"""
|
470
|
-
colText = SHARED.theme.colText
|
471
|
-
colHead = SHARED.theme.colHead
|
472
|
-
colVals = SHARED.theme.colVal
|
473
|
-
colMark = SHARED.theme.colMark
|
474
|
-
colKeys = SHARED.theme.colKey
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
"body {{color:
|
480
|
-
"h1, h2, h3, h4 {{color:
|
481
|
-
"a {{color:
|
482
|
-
"mark {{background-color:
|
483
|
-
".tags {{color:
|
484
|
-
".optional {{color:
|
485
|
-
".comment {{color:
|
486
|
-
".synopsis {{color:
|
487
|
-
".title {
|
488
|
-
).format(
|
489
|
-
rT=colText.red(), gT=colText.green(), bT=colText.blue(),
|
490
|
-
rH=colHead.red(), gH=colHead.green(), bH=colHead.blue(),
|
491
|
-
rA=colVals.red(), gA=colVals.green(), bA=colVals.blue(),
|
492
|
-
rE=colMark.red(), gE=colMark.green(), bE=colMark.blue(), aE=colMark.alpha(),
|
493
|
-
rK=colKeys.red(), gK=colKeys.green(), bK=colKeys.blue(),
|
494
|
-
rC=colHide.red(), gC=colHide.green(), bC=colHide.blue(),
|
495
|
-
rM=colMods.red(), gM=colMods.green(), bM=colMods.blue(),
|
496
|
-
rO=colOpts.red(), gO=colOpts.green(), bO=colOpts.blue(),
|
474
|
+
colText = cssCol(SHARED.theme.colText)
|
475
|
+
colHead = cssCol(SHARED.theme.colHead)
|
476
|
+
colVals = cssCol(SHARED.theme.colVal)
|
477
|
+
colMark = cssCol(SHARED.theme.colMark)
|
478
|
+
colKeys = cssCol(SHARED.theme.colKey)
|
479
|
+
colOpts = cssCol(SHARED.theme.colOpt)
|
480
|
+
colHide = cssCol(SHARED.theme.colHidden)
|
481
|
+
colMods = cssCol(SHARED.theme.colMod)
|
482
|
+
self.document().setDefaultStyleSheet(
|
483
|
+
f"body {{color: {colText};}}\n"
|
484
|
+
f"h1, h2, h3, h4 {{color: {colHead};}}\n"
|
485
|
+
f"a {{color: {colVals};}}\n"
|
486
|
+
f"mark {{background-color: {colMark};}}\n"
|
487
|
+
f".tags {{color: {colKeys};}}\n"
|
488
|
+
f".optional {{color: {colOpts};}}\n"
|
489
|
+
f".comment {{color: {colHide};}}\n"
|
490
|
+
f".synopsis {{color: {colMods};}}\n"
|
491
|
+
".title {text-align: center;}\n"
|
497
492
|
)
|
498
|
-
self.document().setDefaultStyleSheet(styleSheet)
|
499
493
|
|
500
494
|
return
|
501
495
|
|
@@ -635,20 +629,21 @@ class GuiDocViewHeader(QWidget):
|
|
635
629
|
self._docHandle = None
|
636
630
|
self._docOutline: dict[str, tuple[str, int]] = {}
|
637
631
|
|
638
|
-
iPx = SHARED.theme.
|
632
|
+
iPx = SHARED.theme.baseIconHeight
|
633
|
+
iSz = SHARED.theme.baseIconSize
|
639
634
|
mPx = CONFIG.pxInt(4)
|
640
635
|
|
641
636
|
# Main Widget Settings
|
642
637
|
self.setAutoFillBackground(True)
|
643
638
|
|
644
639
|
# Title Label
|
645
|
-
self.itemTitle = QLabel()
|
640
|
+
self.itemTitle = QLabel(self)
|
646
641
|
self.itemTitle.setText("")
|
647
642
|
self.itemTitle.setIndent(0)
|
648
643
|
self.itemTitle.setMargin(0)
|
649
644
|
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
650
645
|
self.itemTitle.setAutoFillBackground(True)
|
651
|
-
self.itemTitle.setAlignment(
|
646
|
+
self.itemTitle.setAlignment(QtAlignCenterTop)
|
652
647
|
self.itemTitle.setFixedHeight(iPx)
|
653
648
|
|
654
649
|
lblFont = self.itemTitle.font()
|
@@ -659,27 +654,27 @@ class GuiDocViewHeader(QWidget):
|
|
659
654
|
self.outlineMenu = QMenu(self)
|
660
655
|
|
661
656
|
# Buttons
|
662
|
-
self.outlineButton = NIconToolButton(self,
|
657
|
+
self.outlineButton = NIconToolButton(self, iSz)
|
663
658
|
self.outlineButton.setVisible(False)
|
664
659
|
self.outlineButton.setToolTip(self.tr("Outline"))
|
665
660
|
self.outlineButton.setMenu(self.outlineMenu)
|
666
661
|
|
667
|
-
self.backButton = NIconToolButton(self,
|
662
|
+
self.backButton = NIconToolButton(self, iSz)
|
668
663
|
self.backButton.setVisible(False)
|
669
664
|
self.backButton.setToolTip(self.tr("Go Backward"))
|
670
665
|
self.backButton.clicked.connect(self.docViewer.navBackward)
|
671
666
|
|
672
|
-
self.forwardButton = NIconToolButton(self,
|
667
|
+
self.forwardButton = NIconToolButton(self, iSz)
|
673
668
|
self.forwardButton.setVisible(False)
|
674
669
|
self.forwardButton.setToolTip(self.tr("Go Forward"))
|
675
670
|
self.forwardButton.clicked.connect(self.docViewer.navForward)
|
676
671
|
|
677
|
-
self.refreshButton = NIconToolButton(self,
|
672
|
+
self.refreshButton = NIconToolButton(self, iSz)
|
678
673
|
self.refreshButton.setVisible(False)
|
679
674
|
self.refreshButton.setToolTip(self.tr("Reload"))
|
680
675
|
self.refreshButton.clicked.connect(self._refreshDocument)
|
681
676
|
|
682
|
-
self.closeButton = NIconToolButton(self,
|
677
|
+
self.closeButton = NIconToolButton(self, iSz)
|
683
678
|
self.closeButton.setVisible(False)
|
684
679
|
self.closeButton.setToolTip(self.tr("Close"))
|
685
680
|
self.closeButton.clicked.connect(self._closeDocument)
|
@@ -752,11 +747,11 @@ class GuiDocViewHeader(QWidget):
|
|
752
747
|
|
753
748
|
def updateTheme(self) -> None:
|
754
749
|
"""Update theme elements."""
|
755
|
-
self.outlineButton.
|
756
|
-
self.backButton.
|
757
|
-
self.forwardButton.
|
758
|
-
self.refreshButton.
|
759
|
-
self.closeButton.
|
750
|
+
self.outlineButton.setThemeIcon("list")
|
751
|
+
self.backButton.setThemeIcon("backward")
|
752
|
+
self.forwardButton.setThemeIcon("forward")
|
753
|
+
self.refreshButton.setThemeIcon("refresh")
|
754
|
+
self.closeButton.setThemeIcon("close")
|
760
755
|
|
761
756
|
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
762
757
|
self.outlineButton.setStyleSheet(buttonStyle)
|
@@ -833,7 +828,7 @@ class GuiDocViewHeader(QWidget):
|
|
833
828
|
"""Capture a click on the title and ensure that the item is
|
834
829
|
selected in the project tree.
|
835
830
|
"""
|
836
|
-
if event.button() ==
|
831
|
+
if event.button() == QtMouseLeft:
|
837
832
|
self.docViewer.requestProjectItemSelected.emit(self._docHandle, True)
|
838
833
|
return
|
839
834
|
|
@@ -857,7 +852,8 @@ class GuiDocViewFooter(QWidget):
|
|
857
852
|
# Internal Variables
|
858
853
|
self._docHandle = None
|
859
854
|
|
860
|
-
iPx = SHARED.theme.
|
855
|
+
iPx = SHARED.theme.baseIconHeight
|
856
|
+
iSz = SHARED.theme.baseIconSize
|
861
857
|
hSp = CONFIG.pxInt(4)
|
862
858
|
mPx = CONFIG.pxInt(4)
|
863
859
|
|
@@ -866,7 +862,7 @@ class GuiDocViewFooter(QWidget):
|
|
866
862
|
self.setAutoFillBackground(True)
|
867
863
|
|
868
864
|
# Show/Hide Details
|
869
|
-
self.showHide = NIconToolButton(self,
|
865
|
+
self.showHide = NIconToolButton(self, iSz)
|
870
866
|
self.showHide.clicked.connect(lambda: self.docViewer.togglePanelVisibility.emit())
|
871
867
|
self.showHide.setToolTip(self.tr("Show/Hide Viewer Panel"))
|
872
868
|
|
@@ -876,7 +872,7 @@ class GuiDocViewFooter(QWidget):
|
|
876
872
|
self.showComments.setCheckable(True)
|
877
873
|
self.showComments.setChecked(CONFIG.viewComments)
|
878
874
|
self.showComments.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
|
879
|
-
self.showComments.setIconSize(
|
875
|
+
self.showComments.setIconSize(iSz)
|
880
876
|
self.showComments.toggled.connect(self._doToggleComments)
|
881
877
|
self.showComments.setToolTip(self.tr("Show Comments"))
|
882
878
|
|
@@ -886,7 +882,7 @@ class GuiDocViewFooter(QWidget):
|
|
886
882
|
self.showSynopsis.setCheckable(True)
|
887
883
|
self.showSynopsis.setChecked(CONFIG.viewSynopsis)
|
888
884
|
self.showSynopsis.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
|
889
|
-
self.showSynopsis.setIconSize(
|
885
|
+
self.showSynopsis.setIconSize(iSz)
|
890
886
|
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
|
891
887
|
self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments"))
|
892
888
|
|
@@ -927,7 +923,7 @@ class GuiDocViewFooter(QWidget):
|
|
927
923
|
fPx = int(0.9*SHARED.theme.fontPixelSize)
|
928
924
|
bulletIcon = SHARED.theme.getToggleIcon("bullet", (fPx, fPx))
|
929
925
|
|
930
|
-
self.showHide.
|
926
|
+
self.showHide.setThemeIcon("panel")
|
931
927
|
self.showComments.setIcon(bulletIcon)
|
932
928
|
self.showSynopsis.setIcon(bulletIcon)
|
933
929
|
|
@@ -27,7 +27,7 @@ import logging
|
|
27
27
|
|
28
28
|
from enum import Enum
|
29
29
|
|
30
|
-
from PyQt5.QtCore import QModelIndex,
|
30
|
+
from PyQt5.QtCore import QModelIndex, Qt, pyqtSignal, pyqtSlot
|
31
31
|
from PyQt5.QtWidgets import (
|
32
32
|
QAbstractItemView, QFrame, QHeaderView, QMenu, QTabWidget, QToolButton,
|
33
33
|
QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
@@ -38,7 +38,9 @@ from novelwriter.common import checkInt
|
|
38
38
|
from novelwriter.constants import nwHeaders, nwLabels, nwLists, trConst
|
39
39
|
from novelwriter.core.index import IndexHeading, IndexItem
|
40
40
|
from novelwriter.enum import nwDocMode, nwItemClass
|
41
|
+
from novelwriter.extensions.modified import NIconToolButton
|
41
42
|
from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
|
43
|
+
from novelwriter.types import QtDecoration, QtUserRole
|
42
44
|
|
43
45
|
logger = logging.getLogger(__name__)
|
44
46
|
|
@@ -55,7 +57,7 @@ class GuiDocViewerPanel(QWidget):
|
|
55
57
|
|
56
58
|
self._lastHandle = None
|
57
59
|
|
58
|
-
|
60
|
+
iSz = SHARED.theme.baseIconSize
|
59
61
|
|
60
62
|
self.tabBackRefs = _ViewPanelBackRefs(self)
|
61
63
|
|
@@ -65,8 +67,7 @@ class GuiDocViewerPanel(QWidget):
|
|
65
67
|
self.aInactive.setCheckable(True)
|
66
68
|
self.aInactive.toggled.connect(self._toggleHideInactive)
|
67
69
|
|
68
|
-
self.optsButton =
|
69
|
-
self.optsButton.setIconSize(QSize(iPx, iPx))
|
70
|
+
self.optsButton = NIconToolButton(self, iSz)
|
70
71
|
self.optsButton.setMenu(self.optsMenu)
|
71
72
|
self.optsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
72
73
|
|
@@ -100,7 +101,7 @@ class GuiDocViewerPanel(QWidget):
|
|
100
101
|
|
101
102
|
def updateTheme(self, updateTabs: bool = True) -> None:
|
102
103
|
"""Update theme elements."""
|
103
|
-
self.optsButton.
|
104
|
+
self.optsButton.setThemeIcon("menu")
|
104
105
|
self.optsButton.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON))
|
105
106
|
self.mainTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
|
106
107
|
self.updateHandle(self._lastHandle)
|
@@ -232,7 +233,7 @@ class _ViewPanelBackRefs(QTreeWidget):
|
|
232
233
|
C_VIEW = 2
|
233
234
|
C_TITLE = 3
|
234
235
|
|
235
|
-
D_HANDLE =
|
236
|
+
D_HANDLE = QtUserRole
|
236
237
|
|
237
238
|
def __init__(self, parent: GuiDocViewerPanel) -> None:
|
238
239
|
super().__init__(parent=parent)
|
@@ -240,13 +241,14 @@ class _ViewPanelBackRefs(QTreeWidget):
|
|
240
241
|
self._parent = parent
|
241
242
|
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
242
243
|
|
243
|
-
iPx = SHARED.theme.
|
244
|
+
iPx = SHARED.theme.baseIconHeight
|
245
|
+
iSz = SHARED.theme.baseIconSize
|
244
246
|
cMg = CONFIG.pxInt(6)
|
245
247
|
|
246
248
|
self.setHeaderLabels([self.tr("Document"), "", "", self.tr("First Heading")])
|
247
249
|
self.setIndentation(0)
|
248
250
|
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
|
249
|
-
self.setIconSize(
|
251
|
+
self.setIconSize(iSz)
|
250
252
|
self.setFrameStyle(QFrame.Shape.NoFrame)
|
251
253
|
|
252
254
|
# Set Header Sizes
|
@@ -348,7 +350,7 @@ class _ViewPanelBackRefs(QTreeWidget):
|
|
348
350
|
trItem.setToolTip(self.C_DOC, nwItem.itemName)
|
349
351
|
trItem.setIcon(self.C_EDIT, self._editIcon)
|
350
352
|
trItem.setIcon(self.C_VIEW, self._viewIcon)
|
351
|
-
trItem.setData(self.C_TITLE,
|
353
|
+
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
352
354
|
trItem.setText(self.C_TITLE, hItem.title)
|
353
355
|
trItem.setToolTip(self.C_TITLE, hItem.title)
|
354
356
|
trItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
|
@@ -373,7 +375,7 @@ class _ViewPanelKeyWords(QTreeWidget):
|
|
373
375
|
C_TITLE = 5
|
374
376
|
C_SHORT = 6
|
375
377
|
|
376
|
-
D_TAG =
|
378
|
+
D_TAG = QtUserRole
|
377
379
|
|
378
380
|
def __init__(self, parent: GuiDocViewerPanel, itemClass: nwItemClass) -> None:
|
379
381
|
super().__init__(parent=parent)
|
@@ -382,7 +384,8 @@ class _ViewPanelKeyWords(QTreeWidget):
|
|
382
384
|
self._class = itemClass
|
383
385
|
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
384
386
|
|
385
|
-
iPx = SHARED.theme.
|
387
|
+
iPx = SHARED.theme.baseIconHeight
|
388
|
+
iSz = SHARED.theme.baseIconSize
|
386
389
|
cMg = CONFIG.pxInt(6)
|
387
390
|
|
388
391
|
self.setHeaderLabels([
|
@@ -390,7 +393,7 @@ class _ViewPanelKeyWords(QTreeWidget):
|
|
390
393
|
self.tr("Heading"), self.tr("Short Description")
|
391
394
|
])
|
392
395
|
self.setIndentation(0)
|
393
|
-
self.setIconSize(
|
396
|
+
self.setIconSize(iSz)
|
394
397
|
self.setFrameStyle(QFrame.Shape.NoFrame)
|
395
398
|
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
|
396
399
|
self.setExpandsOnDoubleClick(False)
|
@@ -466,7 +469,7 @@ class _ViewPanelKeyWords(QTreeWidget):
|
|
466
469
|
trItem.setIcon(self.C_DOC, docIcon)
|
467
470
|
trItem.setText(self.C_DOC, nwItem.itemName)
|
468
471
|
trItem.setToolTip(self.C_DOC, nwItem.itemName)
|
469
|
-
trItem.setData(self.C_TITLE,
|
472
|
+
trItem.setData(self.C_TITLE, QtDecoration, hDec)
|
470
473
|
trItem.setText(self.C_TITLE, hItem.title)
|
471
474
|
trItem.setToolTip(self.C_TITLE, hItem.title)
|
472
475
|
trItem.setText(self.C_SHORT, hItem.synopsis)
|
@@ -25,14 +25,14 @@ from __future__ import annotations
|
|
25
25
|
|
26
26
|
import logging
|
27
27
|
|
28
|
-
from time import time
|
29
28
|
from collections.abc import Iterable
|
29
|
+
from time import time
|
30
30
|
|
31
31
|
from PyQt5.QtGui import QTextBlock, QTextCursor, QTextDocument
|
32
32
|
from PyQt5.QtCore import QObject, pyqtSlot
|
33
|
-
from PyQt5.QtWidgets import
|
34
|
-
from novelwriter import SHARED
|
33
|
+
from PyQt5.QtWidgets import QApplication, QPlainTextDocumentLayout
|
35
34
|
|
35
|
+
from novelwriter import SHARED
|
36
36
|
from novelwriter.gui.dochighlight import GuiDocHighlighter, TextBlockData
|
37
37
|
|
38
38
|
logger = logging.getLogger(__name__)
|
@@ -86,7 +86,7 @@ class GuiTextDocument(QTextDocument):
|
|
86
86
|
self.setUndoRedoEnabled(True)
|
87
87
|
self.blockSignals(False)
|
88
88
|
self._syntax.rehighlight()
|
89
|
-
|
89
|
+
QApplication.processEvents()
|
90
90
|
|
91
91
|
tEnd = time()
|
92
92
|
|