novelWriter 2.2b1__py3-none-any.whl → 2.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/METADATA +3 -3
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/RECORD +128 -114
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +10 -5
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_de_DE.json +1 -0
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/i18n/project_en_US.json +1 -0
- novelwriter/assets/i18n/project_es_419.json +11 -0
- novelwriter/assets/i18n/project_fr_FR.json +11 -0
- novelwriter/assets/i18n/project_it_IT.json +11 -0
- novelwriter/assets/i18n/project_ja_JP.json +2 -1
- novelwriter/assets/i18n/project_nb_NO.json +1 -0
- novelwriter/assets/i18n/project_zh_CN.json +11 -0
- novelwriter/assets/icons/novelwriter.ico +0 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +11 -3
- novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_panel.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
- novelwriter/assets/icons/typicons_dark/typ_eye.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +11 -3
- novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_deco-note.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_panel.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
- novelwriter/assets/icons/typicons_light/typ_eye.svg +4 -0
- novelwriter/assets/icons/x-novelwriter-project.ico +0 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/text/release_notes.htm +50 -7
- novelwriter/common.py +35 -27
- novelwriter/config.py +13 -28
- novelwriter/constants.py +21 -4
- novelwriter/core/buildsettings.py +2 -2
- novelwriter/core/coretools.py +8 -2
- novelwriter/core/docbuild.py +1 -1
- novelwriter/core/document.py +1 -1
- novelwriter/core/index.py +102 -36
- novelwriter/core/item.py +2 -2
- novelwriter/core/options.py +6 -3
- novelwriter/core/project.py +5 -5
- novelwriter/core/projectdata.py +3 -3
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/sessions.py +2 -2
- novelwriter/core/spellcheck.py +4 -3
- novelwriter/core/status.py +3 -3
- novelwriter/core/storage.py +1 -1
- novelwriter/core/tohtml.py +11 -5
- novelwriter/core/tokenizer.py +28 -21
- novelwriter/core/tomd.py +6 -2
- novelwriter/core/toodt.py +12 -5
- novelwriter/core/tree.py +2 -2
- novelwriter/dialogs/about.py +30 -31
- novelwriter/dialogs/docmerge.py +24 -15
- novelwriter/dialogs/docsplit.py +27 -16
- novelwriter/dialogs/editlabel.py +19 -7
- novelwriter/dialogs/preferences.py +116 -131
- novelwriter/dialogs/projdetails.py +29 -36
- novelwriter/dialogs/projload.py +32 -36
- novelwriter/dialogs/projsettings.py +20 -15
- novelwriter/dialogs/quotes.py +32 -25
- novelwriter/dialogs/updates.py +17 -16
- novelwriter/dialogs/wordlist.py +34 -21
- novelwriter/enum.py +19 -8
- novelwriter/error.py +1 -1
- novelwriter/extensions/circularprogress.py +1 -1
- novelwriter/extensions/configlayout.py +3 -15
- novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
- novelwriter/extensions/novelselector.py +1 -1
- novelwriter/extensions/pageddialog.py +1 -1
- novelwriter/extensions/pagedsidebar.py +2 -5
- novelwriter/extensions/simpleprogress.py +8 -9
- novelwriter/extensions/statusled.py +1 -1
- novelwriter/extensions/switch.py +4 -4
- novelwriter/extensions/switchbox.py +1 -6
- novelwriter/gui/doceditor.py +349 -236
- novelwriter/gui/dochighlight.py +10 -11
- novelwriter/gui/docviewer.py +158 -360
- novelwriter/gui/docviewerpanel.py +502 -0
- novelwriter/gui/editordocument.py +4 -4
- novelwriter/gui/itemdetails.py +2 -2
- novelwriter/gui/mainmenu.py +50 -36
- novelwriter/gui/noveltree.py +44 -53
- novelwriter/gui/outline.py +12 -7
- novelwriter/gui/projtree.py +465 -381
- novelwriter/gui/sidebar.py +9 -7
- novelwriter/gui/statusbar.py +48 -5
- novelwriter/gui/theme.py +26 -8
- novelwriter/guimain.py +212 -208
- novelwriter/shared.py +76 -30
- novelwriter/tools/dictionaries.py +268 -0
- novelwriter/tools/lipsum.py +34 -28
- novelwriter/tools/manusbuild.py +20 -10
- novelwriter/tools/manuscript.py +20 -27
- novelwriter/tools/manussettings.py +2 -4
- novelwriter/tools/projwizard.py +3 -3
- novelwriter/tools/writingstats.py +18 -5
- novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_dark/typ_at.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_light/typ_at.svg +0 -4
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/top_level.txt +0 -0
novelwriter/gui/doceditor.py
CHANGED
@@ -10,9 +10,11 @@ Created: 2020-04-25 [0.4.5] GuiDocEditHeader
|
|
10
10
|
Rewritten: 2020-06-15 [0.9] GuiDocEditSearch
|
11
11
|
Created: 2020-06-27 [0.10] GuiDocEditFooter
|
12
12
|
Rewritten: 2020-10-07 [1.0b3] BackgroundWordCounter
|
13
|
+
Created: 2023-11-06 [2.2b1] MetaCompleter
|
14
|
+
Created: 2023-11-07 [2.2b1] GuiDocToolBar
|
13
15
|
|
14
16
|
This file is a part of novelWriter
|
15
|
-
Copyright 2018–
|
17
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
16
18
|
|
17
19
|
This program is free software: you can redistribute it and/or modify
|
18
20
|
it under the terms of the GNU General Public License as published by
|
@@ -46,8 +48,8 @@ from PyQt5.QtGui import (
|
|
46
48
|
)
|
47
49
|
from PyQt5.QtWidgets import (
|
48
50
|
QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
|
49
|
-
QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout,
|
50
|
-
qApp
|
51
|
+
QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout,
|
52
|
+
QWidget, qApp
|
51
53
|
)
|
52
54
|
|
53
55
|
from novelwriter import CONFIG, SHARED
|
@@ -56,10 +58,11 @@ from novelwriter.common import minmax, transferCase
|
|
56
58
|
from novelwriter.constants import nwKeyWords, nwLabels, nwShortcode, nwUnicode, trConst
|
57
59
|
from novelwriter.core.item import NWItem
|
58
60
|
from novelwriter.core.index import countWords
|
61
|
+
from novelwriter.tools.lipsum import GuiLipsum
|
59
62
|
from novelwriter.core.document import NWDocument
|
60
63
|
from novelwriter.gui.dochighlight import GuiDocHighlighter
|
61
64
|
from novelwriter.gui.editordocument import GuiTextDocument
|
62
|
-
from novelwriter.extensions.
|
65
|
+
from novelwriter.extensions.eventfilters import WheelEventFilter
|
63
66
|
|
64
67
|
if TYPE_CHECKING: # pragma: no cover
|
65
68
|
from novelwriter.guimain import GuiMain
|
@@ -67,12 +70,22 @@ if TYPE_CHECKING: # pragma: no cover
|
|
67
70
|
logger = logging.getLogger(__name__)
|
68
71
|
|
69
72
|
|
73
|
+
class _SelectAction(Enum):
|
74
|
+
|
75
|
+
NO_DECISION = 0
|
76
|
+
KEEP_SELECTION = 1
|
77
|
+
KEEP_POSITION = 2
|
78
|
+
MOVE_AFTER = 3
|
79
|
+
|
80
|
+
# END Class _SelectAction
|
81
|
+
|
82
|
+
|
70
83
|
class GuiDocEditor(QPlainTextEdit):
|
71
84
|
"""Gui Widget: Main Document Editor"""
|
72
85
|
|
73
86
|
MOVE_KEYS = (
|
74
|
-
Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down,
|
75
|
-
Qt.Key_PageUp, Qt.Key_PageDown
|
87
|
+
Qt.Key.Key_Left, Qt.Key.Key_Right, Qt.Key.Key_Up, Qt.Key.Key_Down,
|
88
|
+
Qt.Key.Key_PageUp, Qt.Key.Key_PageDown
|
76
89
|
)
|
77
90
|
|
78
91
|
# Custom Signals
|
@@ -85,6 +98,8 @@ class GuiDocEditor(QPlainTextEdit):
|
|
85
98
|
spellCheckStateChanged = pyqtSignal(bool)
|
86
99
|
closeDocumentRequest = pyqtSignal()
|
87
100
|
toggleFocusModeRequest = pyqtSignal()
|
101
|
+
requestProjectItemSelected = pyqtSignal(str, bool)
|
102
|
+
requestProjectItemRenamed = pyqtSignal(str, str)
|
88
103
|
|
89
104
|
def __init__(self, mainGui: GuiMain) -> None:
|
90
105
|
super().__init__(parent=mainGui)
|
@@ -145,29 +160,28 @@ class GuiDocEditor(QPlainTextEdit):
|
|
145
160
|
self.docToolBar.requestDocAction.connect(self.docAction)
|
146
161
|
|
147
162
|
# Context Menu
|
148
|
-
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
163
|
+
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
149
164
|
self.customContextMenuRequested.connect(self._openContextMenu)
|
150
165
|
|
151
166
|
# Editor Settings
|
152
167
|
self.setMinimumWidth(CONFIG.pxInt(300))
|
153
168
|
self.setAutoFillBackground(True)
|
154
|
-
self.setFrameStyle(QFrame.NoFrame)
|
155
|
-
self.setCenterOnScroll(True)
|
169
|
+
self.setFrameStyle(QFrame.Shape.NoFrame)
|
156
170
|
|
157
171
|
# Custom Shortcuts
|
158
172
|
self.keyContext = QShortcut(self)
|
159
173
|
self.keyContext.setKey("Ctrl+.")
|
160
|
-
self.keyContext.setContext(Qt.WidgetShortcut)
|
174
|
+
self.keyContext.setContext(Qt.ShortcutContext.WidgetShortcut)
|
161
175
|
self.keyContext.activated.connect(self._openContextFromCursor)
|
162
176
|
|
163
177
|
self.followTag1 = QShortcut(self)
|
164
|
-
self.followTag1.setKey(Qt.Key_Return | Qt.ControlModifier)
|
165
|
-
self.followTag1.setContext(Qt.WidgetShortcut)
|
178
|
+
self.followTag1.setKey(Qt.Key.Key_Return | Qt.KeyboardModifier.ControlModifier)
|
179
|
+
self.followTag1.setContext(Qt.ShortcutContext.WidgetShortcut)
|
166
180
|
self.followTag1.activated.connect(self._processTag)
|
167
181
|
|
168
182
|
self.followTag2 = QShortcut(self)
|
169
|
-
self.followTag2.setKey(Qt.Key_Enter | Qt.ControlModifier)
|
170
|
-
self.followTag2.setContext(Qt.WidgetShortcut)
|
183
|
+
self.followTag2.setKey(Qt.Key.Key_Enter | Qt.KeyboardModifier.ControlModifier)
|
184
|
+
self.followTag2.setContext(Qt.ShortcutContext.WidgetShortcut)
|
171
185
|
self.followTag2.activated.connect(self._processTag)
|
172
186
|
|
173
187
|
# Set Up Document Word Counter
|
@@ -263,14 +277,14 @@ class GuiDocEditor(QPlainTextEdit):
|
|
263
277
|
def updateSyntaxColours(self) -> None:
|
264
278
|
"""Update the syntax highlighting theme."""
|
265
279
|
mainPalette = self.palette()
|
266
|
-
mainPalette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
|
267
|
-
mainPalette.setColor(QPalette.Base, QColor(*SHARED.theme.colBack))
|
268
|
-
mainPalette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
|
280
|
+
mainPalette.setColor(QPalette.ColorRole.Window, QColor(*SHARED.theme.colBack))
|
281
|
+
mainPalette.setColor(QPalette.ColorRole.Base, QColor(*SHARED.theme.colBack))
|
282
|
+
mainPalette.setColor(QPalette.ColorRole.Text, QColor(*SHARED.theme.colText))
|
269
283
|
self.setPalette(mainPalette)
|
270
284
|
|
271
285
|
docPalette = self.viewport().palette()
|
272
|
-
docPalette.setColor(QPalette.Base, QColor(*SHARED.theme.colBack))
|
273
|
-
docPalette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
|
286
|
+
docPalette.setColor(QPalette.ColorRole.Base, QColor(*SHARED.theme.colBack))
|
287
|
+
docPalette.setColor(QPalette.ColorRole.Text, QColor(*SHARED.theme.colText))
|
274
288
|
self.viewport().setPalette(docPalette)
|
275
289
|
|
276
290
|
self.docHeader.matchColours()
|
@@ -322,24 +336,25 @@ class GuiDocEditor(QPlainTextEdit):
|
|
322
336
|
options = QTextOption()
|
323
337
|
|
324
338
|
if CONFIG.doJustify:
|
325
|
-
options.setAlignment(Qt.AlignJustify)
|
339
|
+
options.setAlignment(Qt.AlignmentFlag.AlignJustify)
|
326
340
|
if CONFIG.showTabsNSpaces:
|
327
|
-
options.setFlags(options.flags() | QTextOption.ShowTabsAndSpaces)
|
341
|
+
options.setFlags(options.flags() | QTextOption.Flag.ShowTabsAndSpaces)
|
328
342
|
if CONFIG.showLineEndings:
|
329
|
-
options.setFlags(options.flags() | QTextOption.ShowLineAndParagraphSeparators)
|
343
|
+
options.setFlags(options.flags() | QTextOption.Flag.ShowLineAndParagraphSeparators)
|
330
344
|
|
331
345
|
self._qDocument.setDefaultTextOption(options)
|
332
346
|
|
333
|
-
#
|
347
|
+
# Scrolling
|
348
|
+
self.setCenterOnScroll(CONFIG.scrollPastEnd)
|
334
349
|
if CONFIG.hideVScroll:
|
335
|
-
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
350
|
+
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
336
351
|
else:
|
337
|
-
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
352
|
+
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
338
353
|
|
339
354
|
if CONFIG.hideHScroll:
|
340
|
-
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
355
|
+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
341
356
|
else:
|
342
|
-
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
357
|
+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
343
358
|
|
344
359
|
# Refresh the tab stops
|
345
360
|
self.setTabStopDistance(CONFIG.getTabWidth())
|
@@ -358,7 +373,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
358
373
|
|
359
374
|
return
|
360
375
|
|
361
|
-
def loadText(self, tHandle, tLine=None) -> bool:
|
376
|
+
def loadText(self, tHandle: str, tLine=None) -> bool:
|
362
377
|
"""Load text from a document into the editor. If we have an I/O
|
363
378
|
error, we must handle this and clear the editor so that we don't
|
364
379
|
risk overwriting the file if it exists. This can for instance
|
@@ -376,7 +391,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
376
391
|
self.clearEditor()
|
377
392
|
return False
|
378
393
|
|
379
|
-
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
394
|
+
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
380
395
|
self._docHandle = tHandle
|
381
396
|
|
382
397
|
self._allowAutoReplace(False)
|
@@ -429,7 +444,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
429
444
|
"""Replace the text of the current document with the provided
|
430
445
|
text. This also clears undo history.
|
431
446
|
"""
|
432
|
-
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
447
|
+
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
433
448
|
self.setPlainText(text)
|
434
449
|
self.updateDocMargins()
|
435
450
|
self.setDocumentChanged(True)
|
@@ -488,10 +503,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
488
503
|
else:
|
489
504
|
self.novelStructureChanged.emit()
|
490
505
|
|
491
|
-
# ToDo: This should be a signal
|
492
506
|
if oldHeader != newHeader:
|
493
|
-
self.mainGui.projView.setTreeItemValues(tHandle)
|
494
|
-
self.mainGui.itemDetails.updateViewBox(tHandle)
|
495
507
|
self.docFooter.updateInfo()
|
496
508
|
|
497
509
|
# Update the status bar
|
@@ -499,6 +511,33 @@ class GuiDocEditor(QPlainTextEdit):
|
|
499
511
|
|
500
512
|
return True
|
501
513
|
|
514
|
+
def cursorIsVisible(self) -> bool:
|
515
|
+
"""Check if the cursor is visible in the editor."""
|
516
|
+
return (
|
517
|
+
0 < self.cursorRect().top()
|
518
|
+
and self.cursorRect().bottom() < self.viewport().height()
|
519
|
+
)
|
520
|
+
|
521
|
+
def ensureCursorVisibleNoCentre(self) -> None:
|
522
|
+
"""Ensure cursor is visible, but don't force it to centre."""
|
523
|
+
cT = self.cursorRect().top()
|
524
|
+
cB = self.cursorRect().bottom()
|
525
|
+
vH = self.viewport().height()
|
526
|
+
if cT < 0:
|
527
|
+
count = 0
|
528
|
+
vBar = self.verticalScrollBar()
|
529
|
+
while self.cursorRect().top() < 0 and count < 100000:
|
530
|
+
vBar.setValue(vBar.value() - 1)
|
531
|
+
count += 1
|
532
|
+
elif cB > vH:
|
533
|
+
count = 0
|
534
|
+
vBar = self.verticalScrollBar()
|
535
|
+
while self.cursorRect().bottom() > vH and count < 100000:
|
536
|
+
vBar.setValue(vBar.value() + 1)
|
537
|
+
count += 1
|
538
|
+
qApp.processEvents()
|
539
|
+
return
|
540
|
+
|
502
541
|
def updateDocMargins(self) -> None:
|
503
542
|
"""Automatically adjust the margins so the text is centred if
|
504
543
|
we have a text width set or we're in Focus Mode. Otherwise, just
|
@@ -640,7 +679,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
640
679
|
"""
|
641
680
|
logger.debug("Running spell checker")
|
642
681
|
start = time()
|
643
|
-
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
682
|
+
qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
|
644
683
|
self._qDocument.syntaxHighlighter.rehighlight()
|
645
684
|
qApp.restoreOverrideCursor()
|
646
685
|
logger.debug("Document highlighted in %.3f ms", 1000*(time() - start))
|
@@ -679,20 +718,20 @@ class GuiDocEditor(QPlainTextEdit):
|
|
679
718
|
self.copy()
|
680
719
|
elif action == nwDocAction.PASTE:
|
681
720
|
self.paste()
|
682
|
-
elif action == nwDocAction.
|
721
|
+
elif action == nwDocAction.MD_ITALIC:
|
683
722
|
self._toggleFormat(1, "_")
|
684
|
-
elif action == nwDocAction.
|
723
|
+
elif action == nwDocAction.MD_BOLD:
|
685
724
|
self._toggleFormat(2, "*")
|
686
|
-
elif action == nwDocAction.
|
725
|
+
elif action == nwDocAction.MD_STRIKE:
|
687
726
|
self._toggleFormat(2, "~")
|
688
727
|
elif action == nwDocAction.S_QUOTE:
|
689
728
|
self._wrapSelection(self._typSQuoteO, self._typSQuoteC)
|
690
729
|
elif action == nwDocAction.D_QUOTE:
|
691
730
|
self._wrapSelection(self._typDQuoteO, self._typDQuoteC)
|
692
731
|
elif action == nwDocAction.SEL_ALL:
|
693
|
-
self._makeSelection(QTextCursor.Document)
|
732
|
+
self._makeSelection(QTextCursor.SelectionType.Document)
|
694
733
|
elif action == nwDocAction.SEL_PARA:
|
695
|
-
self._makeSelection(QTextCursor.BlockUnderCursor)
|
734
|
+
self._makeSelection(QTextCursor.SelectionType.BlockUnderCursor)
|
696
735
|
elif action == nwDocAction.BLOCK_H1:
|
697
736
|
self._formatBlock(nwDocAction.BLOCK_H1)
|
698
737
|
elif action == nwDocAction.BLOCK_H2:
|
@@ -793,7 +832,11 @@ class GuiDocEditor(QPlainTextEdit):
|
|
793
832
|
elif insert == nwDocInsert.QUOTE_RD:
|
794
833
|
text = self._typDQuoteC
|
795
834
|
elif insert == nwDocInsert.SYNOPSIS:
|
796
|
-
text = "%
|
835
|
+
text = "%Synopsis: "
|
836
|
+
newBlock = True
|
837
|
+
goAfter = True
|
838
|
+
elif insert == nwDocInsert.SHORT:
|
839
|
+
text = "%Short: "
|
797
840
|
newBlock = True
|
798
841
|
goAfter = True
|
799
842
|
elif insert == nwDocInsert.NEW_PAGE:
|
@@ -808,18 +851,23 @@ class GuiDocEditor(QPlainTextEdit):
|
|
808
851
|
text = "[vspace:2]"
|
809
852
|
newBlock = True
|
810
853
|
goAfter = False
|
854
|
+
elif insert == nwDocInsert.LIPSUM:
|
855
|
+
text = GuiLipsum.getLipsum(self)
|
856
|
+
newBlock = True
|
857
|
+
goAfter = False
|
811
858
|
else:
|
812
859
|
return False
|
813
860
|
else:
|
814
861
|
return False
|
815
862
|
|
816
|
-
if
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
863
|
+
if text:
|
864
|
+
if newBlock:
|
865
|
+
self.insertNewBlock(text, defaultAfter=goAfter)
|
866
|
+
else:
|
867
|
+
cursor = self.textCursor()
|
868
|
+
cursor.beginEditBlock()
|
869
|
+
cursor.insertText(text)
|
870
|
+
cursor.endEditBlock()
|
823
871
|
|
824
872
|
return True
|
825
873
|
|
@@ -873,17 +921,17 @@ class GuiDocEditor(QPlainTextEdit):
|
|
873
921
|
* We also handle automatic scrolling here.
|
874
922
|
"""
|
875
923
|
self._lastActive = time()
|
876
|
-
isReturn = event.key() == Qt.Key_Return
|
877
|
-
isReturn |= event.key() == Qt.Key_Enter
|
924
|
+
isReturn = event.key() == Qt.Key.Key_Return
|
925
|
+
isReturn |= event.key() == Qt.Key.Key_Enter
|
878
926
|
if isReturn and self.docSearch.anyFocus():
|
879
927
|
return
|
880
|
-
elif event == QKeySequence.Redo:
|
928
|
+
elif event == QKeySequence.StandardKey.Redo:
|
881
929
|
self.docAction(nwDocAction.REDO)
|
882
930
|
return
|
883
|
-
elif event == QKeySequence.Undo:
|
931
|
+
elif event == QKeySequence.StandardKey.Undo:
|
884
932
|
self.docAction(nwDocAction.UNDO)
|
885
933
|
return
|
886
|
-
elif event == QKeySequence.SelectAll:
|
934
|
+
elif event == QKeySequence.StandardKey.SelectAll:
|
887
935
|
self.docAction(nwDocAction.SEL_ALL)
|
888
936
|
return
|
889
937
|
|
@@ -892,7 +940,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
892
940
|
super().keyPressEvent(event)
|
893
941
|
nPos = self.cursorRect().topLeft().y()
|
894
942
|
kMod = event.modifiers()
|
895
|
-
okMod = kMod
|
943
|
+
okMod = kMod in (Qt.KeyboardModifier.NoModifier, Qt.KeyboardModifier.ShiftModifier)
|
896
944
|
okKey = event.key() not in self.MOVE_KEYS
|
897
945
|
if nPos != cPos and okMod and okKey:
|
898
946
|
mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height()
|
@@ -923,7 +971,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
923
971
|
pressed, check if we're clicking on a tag, and trigger the
|
924
972
|
follow tag function.
|
925
973
|
"""
|
926
|
-
if qApp.keyboardModifiers() == Qt.ControlModifier:
|
974
|
+
if qApp.keyboardModifiers() == Qt.KeyboardModifier.ControlModifier:
|
927
975
|
self._processTag(self.cursorForPosition(event.pos()))
|
928
976
|
super().mouseReleaseEvent(event)
|
929
977
|
self.docFooter.updateLineCount()
|
@@ -996,7 +1044,9 @@ class GuiDocEditor(QPlainTextEdit):
|
|
996
1044
|
return
|
997
1045
|
|
998
1046
|
text = block.text()
|
999
|
-
if text.startswith("@"):
|
1047
|
+
if text.startswith("@") and added + removed == 1:
|
1048
|
+
# Only run on single keypresses, otherwise it will trigger
|
1049
|
+
# at unwanted times when other changes are made to the document
|
1000
1050
|
cursor = self.textCursor()
|
1001
1051
|
bPos = cursor.positionInBlock()
|
1002
1052
|
if bPos > 0:
|
@@ -1004,8 +1054,10 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1004
1054
|
point = self.cursorRect().bottomRight()
|
1005
1055
|
self._completer.move(self.viewport().mapToGlobal(point))
|
1006
1056
|
self._completer.setVisible(show)
|
1057
|
+
else:
|
1058
|
+
self._completer.setVisible(False)
|
1007
1059
|
|
1008
|
-
|
1060
|
+
if self._doReplace and added == 1:
|
1009
1061
|
self._docAutoReplace(text)
|
1010
1062
|
|
1011
1063
|
return
|
@@ -1025,43 +1077,50 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1025
1077
|
|
1026
1078
|
@pyqtSlot("QPoint")
|
1027
1079
|
def _openContextMenu(self, pos: QPoint) -> None:
|
1028
|
-
"""
|
1029
|
-
triggered by the Ctrl+. shortcut.
|
1030
|
-
"""
|
1080
|
+
"""Open the editor context menu at a given coordinate."""
|
1031
1081
|
uCursor = self.textCursor()
|
1032
1082
|
pCursor = self.cursorForPosition(pos)
|
1083
|
+
pBlock = pCursor.block()
|
1033
1084
|
|
1034
1085
|
ctxMenu = QMenu(self)
|
1086
|
+
ctxMenu.setObjectName("ContextMenu")
|
1087
|
+
if pBlock.userState() == GuiDocHighlighter.BLOCK_TITLE:
|
1088
|
+
action = ctxMenu.addAction(self.tr("Set as Document Name"))
|
1089
|
+
action.triggered.connect(lambda: self._emitRenameItem(pBlock))
|
1035
1090
|
|
1036
1091
|
# Follow
|
1037
1092
|
status = self._processTag(cursor=pCursor, follow=False)
|
1038
1093
|
if status == nwTrinary.POSITIVE:
|
1039
|
-
|
1040
|
-
|
1094
|
+
action = ctxMenu.addAction(self.tr("Follow Tag"))
|
1095
|
+
action.triggered.connect(lambda: self._processTag(cursor=pCursor, follow=True))
|
1041
1096
|
ctxMenu.addSeparator()
|
1042
1097
|
elif status == nwTrinary.NEGATIVE:
|
1043
|
-
|
1044
|
-
|
1098
|
+
action = ctxMenu.addAction(self.tr("Create Note for Tag"))
|
1099
|
+
action.triggered.connect(lambda: self._processTag(cursor=pCursor, create=True))
|
1045
1100
|
ctxMenu.addSeparator()
|
1046
1101
|
|
1047
1102
|
# Cut, Copy and Paste
|
1048
1103
|
if uCursor.hasSelection():
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1104
|
+
action = ctxMenu.addAction(self.tr("Cut"))
|
1105
|
+
action.triggered.connect(lambda: self.docAction(nwDocAction.CUT))
|
1106
|
+
action = ctxMenu.addAction(self.tr("Copy"))
|
1107
|
+
action.triggered.connect(lambda: self.docAction(nwDocAction.COPY))
|
1053
1108
|
|
1054
|
-
|
1055
|
-
|
1109
|
+
action = ctxMenu.addAction(self.tr("Paste"))
|
1110
|
+
action.triggered.connect(lambda: self.docAction(nwDocAction.PASTE))
|
1056
1111
|
ctxMenu.addSeparator()
|
1057
1112
|
|
1058
1113
|
# Selections
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1114
|
+
action = ctxMenu.addAction(self.tr("Select All"))
|
1115
|
+
action.triggered.connect(lambda: self.docAction(nwDocAction.SEL_ALL))
|
1116
|
+
action = ctxMenu.addAction(self.tr("Select Word"))
|
1117
|
+
action.triggered.connect(
|
1118
|
+
lambda: self._makePosSelection(QTextCursor.SelectionType.WordUnderCursor, pos)
|
1119
|
+
)
|
1120
|
+
action = ctxMenu.addAction(self.tr("Select Paragraph"))
|
1121
|
+
action.triggered.connect(lambda: self._makePosSelection(
|
1122
|
+
QTextCursor.SelectionType.BlockUnderCursor, pos)
|
1123
|
+
)
|
1065
1124
|
|
1066
1125
|
# Spell Checking
|
1067
1126
|
if SHARED.project.data.spellCheck:
|
@@ -1071,24 +1130,27 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1071
1130
|
block = pCursor.block()
|
1072
1131
|
sCursor = self.textCursor()
|
1073
1132
|
sCursor.setPosition(block.position() + cPos)
|
1074
|
-
sCursor.movePosition(
|
1133
|
+
sCursor.movePosition(
|
1134
|
+
QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, cLen
|
1135
|
+
)
|
1075
1136
|
if suggest:
|
1076
1137
|
ctxMenu.addSeparator()
|
1077
1138
|
ctxMenu.addAction(self.tr("Spelling Suggestion(s)"))
|
1078
1139
|
for option in suggest[:15]:
|
1079
|
-
|
1080
|
-
|
1140
|
+
action = ctxMenu.addAction(f"{nwUnicode.U_ENDASH} {option}")
|
1141
|
+
action.triggered.connect(
|
1081
1142
|
lambda _, option=option: self._correctWord(sCursor, option)
|
1082
1143
|
)
|
1083
1144
|
else:
|
1084
1145
|
ctxMenu.addAction("%s %s" % (nwUnicode.U_ENDASH, self.tr("No Suggestions")))
|
1085
1146
|
|
1086
1147
|
ctxMenu.addSeparator()
|
1087
|
-
|
1088
|
-
|
1148
|
+
action = ctxMenu.addAction(self.tr("Add Word to Dictionary"))
|
1149
|
+
action.triggered.connect(lambda: self._addWord(word, block))
|
1089
1150
|
|
1090
1151
|
# Execute the context menu
|
1091
1152
|
ctxMenu.exec_(self.viewport().mapToGlobal(pos))
|
1153
|
+
ctxMenu.deleteLater()
|
1092
1154
|
|
1093
1155
|
return
|
1094
1156
|
|
@@ -1276,8 +1338,8 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1276
1338
|
else:
|
1277
1339
|
resIdx = 0 if doLoop else maxIdx
|
1278
1340
|
|
1279
|
-
cursor.setPosition(resS[resIdx], QTextCursor.MoveAnchor)
|
1280
|
-
cursor.setPosition(resE[resIdx], QTextCursor.KeepAnchor)
|
1341
|
+
cursor.setPosition(resS[resIdx], QTextCursor.MoveMode.MoveAnchor)
|
1342
|
+
cursor.setPosition(resE[resIdx], QTextCursor.MoveMode.KeepAnchor)
|
1281
1343
|
self.setTextCursor(cursor)
|
1282
1344
|
|
1283
1345
|
self.docFooter.updateLineCount()
|
@@ -1303,9 +1365,9 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1303
1365
|
|
1304
1366
|
findOpt = QTextDocument.FindFlag(0)
|
1305
1367
|
if self.docSearch.isCaseSense:
|
1306
|
-
findOpt |= QTextDocument.FindCaseSensitively
|
1368
|
+
findOpt |= QTextDocument.FindFlag.FindCaseSensitively
|
1307
1369
|
if self.docSearch.isWholeWord:
|
1308
|
-
findOpt |= QTextDocument.FindWholeWords
|
1370
|
+
findOpt |= QTextDocument.FindFlag.FindWholeWords
|
1309
1371
|
|
1310
1372
|
searchFor = self.docSearch.getSearchObject()
|
1311
1373
|
cursor.setPosition(0)
|
@@ -1323,8 +1385,8 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1323
1385
|
break
|
1324
1386
|
|
1325
1387
|
if hasSelection:
|
1326
|
-
cursor.setPosition(origA, QTextCursor.MoveAnchor)
|
1327
|
-
cursor.setPosition(origB, QTextCursor.KeepAnchor)
|
1388
|
+
cursor.setPosition(origA, QTextCursor.MoveMode.MoveAnchor)
|
1389
|
+
cursor.setPosition(origB, QTextCursor.MoveMode.KeepAnchor)
|
1328
1390
|
else:
|
1329
1391
|
cursor.setPosition(origA)
|
1330
1392
|
|
@@ -1410,22 +1472,33 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1410
1472
|
If more than one block is selected, the formatting is applied to
|
1411
1473
|
the first block.
|
1412
1474
|
"""
|
1413
|
-
cursor = self.
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1475
|
+
cursor = self.textCursor()
|
1476
|
+
posO = cursor.position()
|
1477
|
+
if cursor.hasSelection():
|
1478
|
+
select = _SelectAction.KEEP_SELECTION
|
1479
|
+
else:
|
1480
|
+
cursor = self._autoSelect()
|
1481
|
+
if cursor.hasSelection() and posO == cursor.selectionEnd():
|
1482
|
+
select = _SelectAction.MOVE_AFTER
|
1483
|
+
else:
|
1484
|
+
select = _SelectAction.KEEP_POSITION
|
1417
1485
|
|
1418
1486
|
posS = cursor.selectionStart()
|
1419
1487
|
posE = cursor.selectionEnd()
|
1488
|
+
if self._qDocument.characterAt(posO - 1) == fChar:
|
1489
|
+
logger.warning("Format repetition, cancelling action")
|
1490
|
+
cursor.clearSelection()
|
1491
|
+
cursor.setPosition(posO)
|
1492
|
+
self.setTextCursor(cursor)
|
1493
|
+
return False
|
1420
1494
|
|
1421
1495
|
blockS = self._qDocument.findBlock(posS)
|
1422
1496
|
blockE = self._qDocument.findBlock(posE)
|
1423
|
-
|
1424
1497
|
if blockS != blockE:
|
1425
1498
|
posE = blockS.position() + blockS.length() - 1
|
1426
1499
|
cursor.clearSelection()
|
1427
|
-
cursor.setPosition(posS, QTextCursor.MoveAnchor)
|
1428
|
-
cursor.setPosition(posE, QTextCursor.KeepAnchor)
|
1500
|
+
cursor.setPosition(posS, QTextCursor.MoveMode.MoveAnchor)
|
1501
|
+
cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
|
1429
1502
|
self.setTextCursor(cursor)
|
1430
1503
|
|
1431
1504
|
numB = 0
|
@@ -1443,34 +1516,26 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1443
1516
|
break
|
1444
1517
|
|
1445
1518
|
if fLen == min(numA, numB):
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1519
|
+
cursor.clearSelection()
|
1520
|
+
cursor.beginEditBlock()
|
1521
|
+
cursor.setPosition(posS)
|
1522
|
+
for i in range(fLen):
|
1523
|
+
cursor.deletePreviousChar()
|
1524
|
+
cursor.setPosition(posE)
|
1525
|
+
for i in range(fLen):
|
1526
|
+
cursor.deletePreviousChar()
|
1527
|
+
cursor.endEditBlock()
|
1528
|
+
cursor.clearSelection()
|
1529
|
+
cursor.setPosition(posO - fLen)
|
1530
|
+
self.setTextCursor(cursor)
|
1457
1531
|
|
1458
|
-
|
1459
|
-
|
1460
|
-
cursor.clearSelection()
|
1461
|
-
cursor.beginEditBlock()
|
1462
|
-
cursor.setPosition(posS)
|
1463
|
-
for i in range(nChars):
|
1464
|
-
cursor.deletePreviousChar()
|
1465
|
-
cursor.setPosition(posE)
|
1466
|
-
for i in range(nChars):
|
1467
|
-
cursor.deletePreviousChar()
|
1468
|
-
cursor.endEditBlock()
|
1469
|
-
cursor.clearSelection()
|
1532
|
+
else:
|
1533
|
+
self._wrapSelection(fChar*fLen, pos=posO, select=select)
|
1470
1534
|
|
1471
1535
|
return True
|
1472
1536
|
|
1473
|
-
def _wrapSelection(self, before: str, after: str | None = None
|
1537
|
+
def _wrapSelection(self, before: str, after: str | None = None, pos: int | None = None,
|
1538
|
+
select: _SelectAction = _SelectAction.NO_DECISION) -> bool:
|
1474
1539
|
"""Wrap the selected text in whatever is in tBefore and tAfter.
|
1475
1540
|
If there is no selection, the autoSelect setting decides the
|
1476
1541
|
action. AutoSelect will select the word under the cursor before
|
@@ -1479,10 +1544,17 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1479
1544
|
if after is None:
|
1480
1545
|
after = before
|
1481
1546
|
|
1482
|
-
cursor = self.
|
1483
|
-
if
|
1484
|
-
|
1485
|
-
|
1547
|
+
cursor = self.textCursor()
|
1548
|
+
posO = pos if isinstance(pos, int) else cursor.position()
|
1549
|
+
if select == _SelectAction.NO_DECISION:
|
1550
|
+
if cursor.hasSelection():
|
1551
|
+
select = _SelectAction.KEEP_SELECTION
|
1552
|
+
else:
|
1553
|
+
cursor = self._autoSelect()
|
1554
|
+
if cursor.hasSelection() and posO == cursor.selectionEnd():
|
1555
|
+
select = _SelectAction.MOVE_AFTER
|
1556
|
+
else:
|
1557
|
+
select = _SelectAction.KEEP_POSITION
|
1486
1558
|
|
1487
1559
|
posS = cursor.selectionStart()
|
1488
1560
|
posE = cursor.selectionEnd()
|
@@ -1500,8 +1572,14 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1500
1572
|
cursor.insertText(before)
|
1501
1573
|
cursor.endEditBlock()
|
1502
1574
|
|
1503
|
-
|
1504
|
-
|
1575
|
+
if select == _SelectAction.MOVE_AFTER:
|
1576
|
+
cursor.setPosition(posE + len(before + after))
|
1577
|
+
elif select == _SelectAction.KEEP_SELECTION:
|
1578
|
+
cursor.setPosition(posE + len(before), QTextCursor.MoveMode.MoveAnchor)
|
1579
|
+
cursor.setPosition(posS + len(before), QTextCursor.MoveMode.KeepAnchor)
|
1580
|
+
elif select == _SelectAction.KEEP_POSITION:
|
1581
|
+
cursor.setPosition(posO + len(before))
|
1582
|
+
|
1505
1583
|
self.setTextCursor(cursor)
|
1506
1584
|
|
1507
1585
|
return True
|
@@ -1522,7 +1600,9 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1522
1600
|
self._allowAutoReplace(False)
|
1523
1601
|
for posC in range(posS, posE+1):
|
1524
1602
|
cursor.setPosition(posC)
|
1525
|
-
cursor.movePosition(
|
1603
|
+
cursor.movePosition(
|
1604
|
+
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 2
|
1605
|
+
)
|
1526
1606
|
selText = cursor.selectedText()
|
1527
1607
|
|
1528
1608
|
nS = len(selText)
|
@@ -1542,12 +1622,16 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1542
1622
|
cursor.setPosition(posC)
|
1543
1623
|
if pC in closeCheck:
|
1544
1624
|
cursor.beginEditBlock()
|
1545
|
-
cursor.movePosition(
|
1625
|
+
cursor.movePosition(
|
1626
|
+
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
|
1627
|
+
)
|
1546
1628
|
cursor.insertText(oQuote)
|
1547
1629
|
cursor.endEditBlock()
|
1548
1630
|
else:
|
1549
1631
|
cursor.beginEditBlock()
|
1550
|
-
cursor.movePosition(
|
1632
|
+
cursor.movePosition(
|
1633
|
+
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
|
1634
|
+
)
|
1551
1635
|
cursor.insertText(cQuote)
|
1552
1636
|
cursor.endEditBlock()
|
1553
1637
|
|
@@ -1667,7 +1751,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1667
1751
|
# Replace the block text
|
1668
1752
|
cursor.beginEditBlock()
|
1669
1753
|
posO = cursor.position()
|
1670
|
-
cursor.select(QTextCursor.BlockUnderCursor)
|
1754
|
+
cursor.select(QTextCursor.SelectionType.BlockUnderCursor)
|
1671
1755
|
posS = cursor.selectionStart()
|
1672
1756
|
cursor.removeSelectedText()
|
1673
1757
|
cursor.setPosition(posS)
|
@@ -1727,7 +1811,9 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1727
1811
|
cursor.beginEditBlock()
|
1728
1812
|
cursor.clearSelection()
|
1729
1813
|
cursor.setPosition(rS)
|
1730
|
-
cursor.movePosition(
|
1814
|
+
cursor.movePosition(
|
1815
|
+
QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, rE-rS
|
1816
|
+
)
|
1731
1817
|
cursor.insertText(cleanText.rstrip() + "\n")
|
1732
1818
|
cursor.endEditBlock()
|
1733
1819
|
|
@@ -1751,13 +1837,13 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1751
1837
|
block = cursor.block()
|
1752
1838
|
text = block.text()
|
1753
1839
|
if len(text) == 0:
|
1754
|
-
return nwTrinary.
|
1840
|
+
return nwTrinary.NEUTRAL
|
1755
1841
|
|
1756
1842
|
if text.startswith("@") and isinstance(self._nwItem, NWItem):
|
1757
1843
|
|
1758
1844
|
isGood, tBits, tPos = SHARED.project.index.scanThis(text)
|
1759
1845
|
if not isGood:
|
1760
|
-
return nwTrinary.
|
1846
|
+
return nwTrinary.NEUTRAL
|
1761
1847
|
|
1762
1848
|
tag = ""
|
1763
1849
|
exist = False
|
@@ -1774,7 +1860,7 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1774
1860
|
|
1775
1861
|
if not tag or tag.startswith("@"):
|
1776
1862
|
# The keyword cannot be looked up, so we ignore that
|
1777
|
-
return nwTrinary.
|
1863
|
+
return nwTrinary.NEUTRAL
|
1778
1864
|
|
1779
1865
|
if follow and exist:
|
1780
1866
|
logger.debug("Attempting to follow tag '%s'", tag)
|
@@ -1794,7 +1880,14 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1794
1880
|
|
1795
1881
|
return nwTrinary.POSITIVE if exist else nwTrinary.NEGATIVE
|
1796
1882
|
|
1797
|
-
return nwTrinary.
|
1883
|
+
return nwTrinary.NEUTRAL
|
1884
|
+
|
1885
|
+
def _emitRenameItem(self, block: QTextBlock) -> None:
|
1886
|
+
"""Emit a signal to request an item be renamed."""
|
1887
|
+
if self._docHandle:
|
1888
|
+
text = block.text().lstrip("#").lstrip("!").strip()
|
1889
|
+
self.requestProjectItemRenamed.emit(self._docHandle, text)
|
1890
|
+
return
|
1798
1891
|
|
1799
1892
|
def _openContextFromCursor(self) -> None:
|
1800
1893
|
"""Open the spell check context menu at the cursor."""
|
@@ -1887,7 +1980,9 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1887
1980
|
tInsert = tInsert + self._typPadChar
|
1888
1981
|
|
1889
1982
|
if nDelete > 0:
|
1890
|
-
cursor.movePosition(
|
1983
|
+
cursor.movePosition(
|
1984
|
+
QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, nDelete
|
1985
|
+
)
|
1891
1986
|
cursor.insertText(tInsert)
|
1892
1987
|
|
1893
1988
|
return
|
@@ -1908,27 +2003,43 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1908
2003
|
|
1909
2004
|
def _autoSelect(self) -> QTextCursor:
|
1910
2005
|
"""Return a cursor which may or may not have a selection based
|
1911
|
-
on user settings and document action.
|
2006
|
+
on user settings and document action. The selection will be the
|
2007
|
+
word closest to the cursor consisting of alphanumerical unicode
|
2008
|
+
characters.
|
1912
2009
|
"""
|
1913
2010
|
cursor = self.textCursor()
|
1914
2011
|
if CONFIG.autoSelect and not cursor.hasSelection():
|
1915
|
-
cursor.
|
1916
|
-
|
1917
|
-
|
2012
|
+
cPos = cursor.position()
|
2013
|
+
bPos = cursor.block().position()
|
2014
|
+
bLen = cursor.block().length()
|
2015
|
+
apos = nwUnicode.U_APOS + nwUnicode.U_RSQUO
|
2016
|
+
|
2017
|
+
# Scan backward
|
2018
|
+
sPos = cPos
|
2019
|
+
for i in range(cPos - bPos):
|
2020
|
+
sPos = cPos - i - 1
|
2021
|
+
cOne = self._qDocument.characterAt(sPos)
|
2022
|
+
cTwo = self._qDocument.characterAt(sPos - 1)
|
2023
|
+
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
|
2024
|
+
sPos += 1
|
2025
|
+
break
|
1918
2026
|
|
1919
|
-
#
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
if
|
1929
|
-
|
1930
|
-
cursor
|
1931
|
-
|
2027
|
+
# Scan forward
|
2028
|
+
ePos = cPos
|
2029
|
+
for i in range(bPos + bLen - cPos):
|
2030
|
+
ePos = cPos + i
|
2031
|
+
cOne = self._qDocument.characterAt(ePos)
|
2032
|
+
cTwo = self._qDocument.characterAt(ePos + 1)
|
2033
|
+
if not (cOne.isalnum() or cOne in apos and cTwo.isalnum()):
|
2034
|
+
break
|
2035
|
+
|
2036
|
+
if ePos - sPos <= 0:
|
2037
|
+
# No selection possible
|
2038
|
+
return cursor
|
2039
|
+
|
2040
|
+
cursor.clearSelection()
|
2041
|
+
cursor.setPosition(sPos, QTextCursor.MoveMode.MoveAnchor)
|
2042
|
+
cursor.setPosition(ePos, QTextCursor.MoveMode.KeepAnchor)
|
1932
2043
|
|
1933
2044
|
self.setTextCursor(cursor)
|
1934
2045
|
|
@@ -1940,18 +2051,18 @@ class GuiDocEditor(QPlainTextEdit):
|
|
1940
2051
|
cursor.clearSelection()
|
1941
2052
|
cursor.select(mode)
|
1942
2053
|
|
1943
|
-
if mode == QTextCursor.WordUnderCursor:
|
2054
|
+
if mode == QTextCursor.SelectionType.WordUnderCursor:
|
1944
2055
|
cursor = self._autoSelect()
|
1945
2056
|
|
1946
|
-
elif mode == QTextCursor.BlockUnderCursor:
|
2057
|
+
elif mode == QTextCursor.SelectionType.BlockUnderCursor:
|
1947
2058
|
# This selection mode also selects the preceding paragraph
|
1948
2059
|
# separator, which we want to avoid.
|
1949
2060
|
posS = cursor.selectionStart()
|
1950
2061
|
posE = cursor.selectionEnd()
|
1951
2062
|
selTxt = cursor.selectedText()
|
1952
2063
|
if selTxt.startswith(nwUnicode.U_PSEP):
|
1953
|
-
cursor.setPosition(posS+1, QTextCursor.MoveAnchor)
|
1954
|
-
cursor.setPosition(posE, QTextCursor.KeepAnchor)
|
2064
|
+
cursor.setPosition(posS+1, QTextCursor.MoveMode.MoveAnchor)
|
2065
|
+
cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
|
1955
2066
|
|
1956
2067
|
self.setTextCursor(cursor)
|
1957
2068
|
|
@@ -2011,7 +2122,7 @@ class MetaCompleter(QMenu):
|
|
2011
2122
|
length = len(lookup)
|
2012
2123
|
suffix = ""
|
2013
2124
|
options = list(filter(
|
2014
|
-
lambda x: lookup in x.lower(), SHARED.project.index.
|
2125
|
+
lambda x: lookup in x.lower(), SHARED.project.index.getClassTags(
|
2015
2126
|
nwKeyWords.KEY_CLASS.get(kw.strip(), nwItemClass.NO_CLASS)
|
2016
2127
|
)
|
2017
2128
|
))[:15]
|
@@ -2033,7 +2144,10 @@ class MetaCompleter(QMenu):
|
|
2033
2144
|
def keyPressEvent(self, event: QKeyEvent) -> None:
|
2034
2145
|
"""Capture keypresses and forward most of them to the editor."""
|
2035
2146
|
parent = self.parent()
|
2036
|
-
if event.key() in (
|
2147
|
+
if event.key() in (
|
2148
|
+
Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_Return,
|
2149
|
+
Qt.Key.Key_Enter, Qt.Key.Key_Escape
|
2150
|
+
):
|
2037
2151
|
super().keyPressEvent(event)
|
2038
2152
|
elif isinstance(parent, GuiDocEditor):
|
2039
2153
|
parent.keyPressEvent(event)
|
@@ -2123,39 +2237,65 @@ class GuiDocToolBar(QWidget):
|
|
2123
2237
|
# General Buttons
|
2124
2238
|
# ===============
|
2125
2239
|
|
2126
|
-
self.
|
2127
|
-
self.
|
2128
|
-
self.
|
2129
|
-
self.
|
2130
|
-
|
2131
|
-
|
2240
|
+
self.tbBoldMD = QToolButton(self)
|
2241
|
+
self.tbBoldMD.setIconSize(iconSize)
|
2242
|
+
self.tbBoldMD.setToolTip(self.tr("Markdown Bold"))
|
2243
|
+
self.tbBoldMD.clicked.connect(
|
2244
|
+
lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
|
2245
|
+
)
|
2246
|
+
|
2247
|
+
self.tbItalicMD = QToolButton(self)
|
2248
|
+
self.tbItalicMD.setIconSize(iconSize)
|
2249
|
+
self.tbItalicMD.setToolTip(self.tr("Markdown Italic"))
|
2250
|
+
self.tbItalicMD.clicked.connect(
|
2251
|
+
lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
|
2252
|
+
)
|
2253
|
+
|
2254
|
+
self.tbStrikeMD = QToolButton(self)
|
2255
|
+
self.tbStrikeMD.setIconSize(iconSize)
|
2256
|
+
self.tbStrikeMD.setToolTip(self.tr("Markdown Strikethrough"))
|
2257
|
+
self.tbStrikeMD.clicked.connect(
|
2258
|
+
lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
|
2259
|
+
)
|
2132
2260
|
|
2133
2261
|
self.tbBold = QToolButton(self)
|
2134
2262
|
self.tbBold.setIconSize(iconSize)
|
2135
|
-
self.tbBold.
|
2263
|
+
self.tbBold.setToolTip(self.tr("Shortcode Bold"))
|
2264
|
+
self.tbBold.clicked.connect(
|
2265
|
+
lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
|
2266
|
+
)
|
2136
2267
|
|
2137
2268
|
self.tbItalic = QToolButton(self)
|
2138
2269
|
self.tbItalic.setIconSize(iconSize)
|
2139
|
-
self.tbItalic.
|
2270
|
+
self.tbItalic.setToolTip(self.tr("Shortcode Italic"))
|
2271
|
+
self.tbItalic.clicked.connect(
|
2272
|
+
lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
|
2273
|
+
)
|
2140
2274
|
|
2141
2275
|
self.tbStrike = QToolButton(self)
|
2142
2276
|
self.tbStrike.setIconSize(iconSize)
|
2143
|
-
self.tbStrike.
|
2277
|
+
self.tbStrike.setToolTip(self.tr("Shortcode Strikethrough"))
|
2278
|
+
self.tbStrike.clicked.connect(
|
2279
|
+
lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE)
|
2280
|
+
)
|
2144
2281
|
|
2145
2282
|
self.tbUnderline = QToolButton(self)
|
2146
2283
|
self.tbUnderline.setIconSize(iconSize)
|
2284
|
+
self.tbUnderline.setToolTip(self.tr("Shortcode Underline"))
|
2147
2285
|
self.tbUnderline.clicked.connect(
|
2148
2286
|
lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
|
2149
2287
|
)
|
2150
2288
|
|
2151
2289
|
self.tbSuperscript = QToolButton(self)
|
2152
2290
|
self.tbSuperscript.setIconSize(iconSize)
|
2291
|
+
self.tbSuperscript.setToolTip(self.tr("Shortcode Superscript"))
|
2153
2292
|
self.tbSuperscript.clicked.connect(
|
2154
2293
|
lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
|
2155
2294
|
)
|
2156
2295
|
|
2157
2296
|
self.tbSubscript = QToolButton(self)
|
2158
2297
|
self.tbSubscript.setIconSize(iconSize)
|
2298
|
+
self.tbSubscript.setToolTip(self.tr("Shortcode Subscript"))
|
2159
2299
|
self.tbSubscript.clicked.connect(
|
2160
2300
|
lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
|
2161
2301
|
)
|
@@ -2164,7 +2304,10 @@ class GuiDocToolBar(QWidget):
|
|
2164
2304
|
# ========
|
2165
2305
|
|
2166
2306
|
self.outerBox = QVBoxLayout()
|
2167
|
-
self.outerBox.addWidget(self.
|
2307
|
+
self.outerBox.addWidget(self.tbBoldMD)
|
2308
|
+
self.outerBox.addWidget(self.tbItalicMD)
|
2309
|
+
self.outerBox.addWidget(self.tbStrikeMD)
|
2310
|
+
self.outerBox.addSpacing(cM)
|
2168
2311
|
self.outerBox.addWidget(self.tbBold)
|
2169
2312
|
self.outerBox.addWidget(self.tbItalic)
|
2170
2313
|
self.outerBox.addWidget(self.tbStrike)
|
@@ -2187,13 +2330,14 @@ class GuiDocToolBar(QWidget):
|
|
2187
2330
|
def updateTheme(self) -> None:
|
2188
2331
|
"""Initialise GUI elements that depend on specific settings."""
|
2189
2332
|
palette = QPalette()
|
2190
|
-
palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
|
2191
|
-
palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
|
2192
|
-
palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
|
2333
|
+
palette.setColor(QPalette.ColorRole.Window, QColor(*SHARED.theme.colBack))
|
2334
|
+
palette.setColor(QPalette.ColorRole.WindowText, QColor(*SHARED.theme.colText))
|
2335
|
+
palette.setColor(QPalette.ColorRole.Text, QColor(*SHARED.theme.colText))
|
2193
2336
|
self.setPalette(palette)
|
2194
2337
|
|
2195
|
-
|
2196
|
-
self.
|
2338
|
+
self.tbBoldMD.setIcon(SHARED.theme.getIcon("fmt_bold-md"))
|
2339
|
+
self.tbItalicMD.setIcon(SHARED.theme.getIcon("fmt_italic-md"))
|
2340
|
+
self.tbStrikeMD.setIcon(SHARED.theme.getIcon("fmt_strike-md"))
|
2197
2341
|
self.tbBold.setIcon(SHARED.theme.getIcon("fmt_bold"))
|
2198
2342
|
self.tbItalic.setIcon(SHARED.theme.getIcon("fmt_italic"))
|
2199
2343
|
self.tbStrike.setIcon(SHARED.theme.getIcon("fmt_strike"))
|
@@ -2203,40 +2347,6 @@ class GuiDocToolBar(QWidget):
|
|
2203
2347
|
|
2204
2348
|
return
|
2205
2349
|
|
2206
|
-
##
|
2207
|
-
# Private Slots
|
2208
|
-
##
|
2209
|
-
|
2210
|
-
@pyqtSlot(bool)
|
2211
|
-
def _toggleFormatMode(self, checked: bool) -> None:
|
2212
|
-
"""Toggle the formatting mode."""
|
2213
|
-
CONFIG.useShortcodes = checked
|
2214
|
-
return
|
2215
|
-
|
2216
|
-
@pyqtSlot()
|
2217
|
-
def _formatBold(self):
|
2218
|
-
"""Call the bold format action."""
|
2219
|
-
self.requestDocAction.emit(
|
2220
|
-
nwDocAction.SC_BOLD if self.tbMode.isChecked() else nwDocAction.STRONG
|
2221
|
-
)
|
2222
|
-
return
|
2223
|
-
|
2224
|
-
@pyqtSlot()
|
2225
|
-
def _formatItalic(self):
|
2226
|
-
"""Call the italic format action."""
|
2227
|
-
self.requestDocAction.emit(
|
2228
|
-
nwDocAction.SC_ITALIC if self.tbMode.isChecked() else nwDocAction.EMPH
|
2229
|
-
)
|
2230
|
-
return
|
2231
|
-
|
2232
|
-
@pyqtSlot()
|
2233
|
-
def _formatStrike(self):
|
2234
|
-
"""Call the strikethrough format action."""
|
2235
|
-
self.requestDocAction.emit(
|
2236
|
-
nwDocAction.SC_STRIKE if self.tbMode.isChecked() else nwDocAction.STRIKE
|
2237
|
-
)
|
2238
|
-
return
|
2239
|
-
|
2240
2350
|
# END Class GuiDocToolBar
|
2241
2351
|
|
2242
2352
|
|
@@ -2269,7 +2379,7 @@ class GuiDocEditSearch(QFrame):
|
|
2269
2379
|
|
2270
2380
|
self.setContentsMargins(0, 0, 0, 0)
|
2271
2381
|
self.setAutoFillBackground(True)
|
2272
|
-
self.setFrameStyle(QFrame.StyledPanel | QFrame.Plain)
|
2382
|
+
self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
|
2273
2383
|
|
2274
2384
|
self.mainBox = QGridLayout(self)
|
2275
2385
|
self.setLayout(self.mainBox)
|
@@ -2288,7 +2398,7 @@ class GuiDocEditSearch(QFrame):
|
|
2288
2398
|
self.replaceBox.returnPressed.connect(self._doReplace)
|
2289
2399
|
|
2290
2400
|
self.searchOpt = QToolBar(self)
|
2291
|
-
self.searchOpt.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
2401
|
+
self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
2292
2402
|
self.searchOpt.setIconSize(QSize(tPx, tPx))
|
2293
2403
|
self.searchOpt.setContentsMargins(0, 0, 0, 0)
|
2294
2404
|
|
@@ -2350,7 +2460,7 @@ class GuiDocEditSearch(QFrame):
|
|
2350
2460
|
bPx = self.searchBox.sizeHint().height()
|
2351
2461
|
|
2352
2462
|
self.showReplace = QToolButton(self)
|
2353
|
-
self.showReplace.setArrowType(Qt.RightArrow)
|
2463
|
+
self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
|
2354
2464
|
self.showReplace.setCheckable(True)
|
2355
2465
|
self.showReplace.toggled.connect(self._doToggleReplace)
|
2356
2466
|
|
@@ -2364,8 +2474,8 @@ class GuiDocEditSearch(QFrame):
|
|
2364
2474
|
self.replaceButton.setToolTip(self.tr("Find and replace in current document"))
|
2365
2475
|
self.replaceButton.clicked.connect(self._doReplace)
|
2366
2476
|
|
2367
|
-
self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignLeft)
|
2368
|
-
self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, Qt.AlignRight)
|
2477
|
+
self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignmentFlag.AlignLeft)
|
2478
|
+
self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, Qt.AlignmentFlag.AlignRight)
|
2369
2479
|
self.mainBox.addWidget(self.showReplace, 1, 0, 1, 1)
|
2370
2480
|
self.mainBox.addWidget(self.searchBox, 1, 1, 1, 2)
|
2371
2481
|
self.mainBox.addWidget(self.searchButton, 1, 3, 1, 1)
|
@@ -2423,18 +2533,18 @@ class GuiDocEditSearch(QFrame):
|
|
2423
2533
|
# only added in Qt 5.13. Otherwise, 5.3 and up supports
|
2424
2534
|
# only the QRegExp class.
|
2425
2535
|
if CONFIG.verQtValue >= 0x050d00:
|
2426
|
-
rxOpt = QRegularExpression.UseUnicodePropertiesOption
|
2536
|
+
rxOpt = QRegularExpression.PatternOption.UseUnicodePropertiesOption
|
2427
2537
|
if not self.isCaseSense:
|
2428
|
-
rxOpt |= QRegularExpression.CaseInsensitiveOption
|
2538
|
+
rxOpt |= QRegularExpression.PatternOption.CaseInsensitiveOption
|
2429
2539
|
regEx = QRegularExpression(text, rxOpt)
|
2430
2540
|
self._alertSearchValid(regEx.isValid())
|
2431
2541
|
return regEx
|
2432
2542
|
else: # pragma: no cover
|
2433
2543
|
# >= 50300 to < 51300
|
2434
2544
|
if self.isCaseSense:
|
2435
|
-
rxOpt = Qt.CaseSensitive
|
2545
|
+
rxOpt = Qt.CaseSensitivity.CaseSensitive
|
2436
2546
|
else:
|
2437
|
-
rxOpt = Qt.CaseInsensitive
|
2547
|
+
rxOpt = Qt.CaseSensitivity.CaseInsensitive
|
2438
2548
|
regEx = QRegExp(text, rxOpt)
|
2439
2549
|
self._alertSearchValid(regEx.isValid())
|
2440
2550
|
return regEx
|
@@ -2570,7 +2680,7 @@ class GuiDocEditSearch(QFrame):
|
|
2570
2680
|
def _doSearch(self) -> None:
|
2571
2681
|
"""Call the search action function for the document editor."""
|
2572
2682
|
modKey = qApp.keyboardModifiers()
|
2573
|
-
if modKey == Qt.ShiftModifier:
|
2683
|
+
if modKey == Qt.KeyboardModifier.ShiftModifier:
|
2574
2684
|
self.docEditor.findNext(goBack=True)
|
2575
2685
|
else:
|
2576
2686
|
self.docEditor.findNext()
|
@@ -2586,9 +2696,9 @@ class GuiDocEditSearch(QFrame):
|
|
2586
2696
|
def _doToggleReplace(self, state: bool) -> None:
|
2587
2697
|
"""Toggle the show/hide of the replace box."""
|
2588
2698
|
if state:
|
2589
|
-
self.showReplace.setArrowType(Qt.DownArrow)
|
2699
|
+
self.showReplace.setArrowType(Qt.ArrowType.DownArrow)
|
2590
2700
|
else:
|
2591
|
-
self.showReplace.setArrowType(Qt.RightArrow)
|
2701
|
+
self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
|
2592
2702
|
self.replaceBox.setVisible(state)
|
2593
2703
|
self.replaceButton.setVisible(state)
|
2594
2704
|
self.repVisible = state
|
@@ -2641,7 +2751,7 @@ class GuiDocEditSearch(QFrame):
|
|
2641
2751
|
isn't valid. Take the colour from the replace box.
|
2642
2752
|
"""
|
2643
2753
|
qPalette = self.replaceBox.palette()
|
2644
|
-
qPalette.setColor(QPalette.Base, self.rxCol[isValid])
|
2754
|
+
qPalette.setColor(QPalette.ColorRole.Base, self.rxCol[isValid])
|
2645
2755
|
self.searchBox.setPalette(qPalette)
|
2646
2756
|
return
|
2647
2757
|
|
@@ -2682,7 +2792,7 @@ class GuiDocEditHeader(QWidget):
|
|
2682
2792
|
self.itemTitle.setMargin(0)
|
2683
2793
|
self.itemTitle.setContentsMargins(0, 0, 0, 0)
|
2684
2794
|
self.itemTitle.setAutoFillBackground(True)
|
2685
|
-
self.itemTitle.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
|
2795
|
+
self.itemTitle.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)
|
2686
2796
|
self.itemTitle.setFixedHeight(fPx)
|
2687
2797
|
|
2688
2798
|
lblFont = self.itemTitle.font()
|
@@ -2694,7 +2804,7 @@ class GuiDocEditHeader(QWidget):
|
|
2694
2804
|
self.tbButton.setContentsMargins(0, 0, 0, 0)
|
2695
2805
|
self.tbButton.setIconSize(iconSize)
|
2696
2806
|
self.tbButton.setFixedSize(fPx, fPx)
|
2697
|
-
self.tbButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
2807
|
+
self.tbButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
2698
2808
|
self.tbButton.setVisible(False)
|
2699
2809
|
self.tbButton.setToolTip(self.tr("Toggle Tool Bar"))
|
2700
2810
|
self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit())
|
@@ -2703,7 +2813,7 @@ class GuiDocEditHeader(QWidget):
|
|
2703
2813
|
self.searchButton.setContentsMargins(0, 0, 0, 0)
|
2704
2814
|
self.searchButton.setIconSize(iconSize)
|
2705
2815
|
self.searchButton.setFixedSize(fPx, fPx)
|
2706
|
-
self.searchButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
2816
|
+
self.searchButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
2707
2817
|
self.searchButton.setVisible(False)
|
2708
2818
|
self.searchButton.setToolTip(self.tr("Search"))
|
2709
2819
|
self.searchButton.clicked.connect(self.docEditor.toggleSearch)
|
@@ -2712,7 +2822,7 @@ class GuiDocEditHeader(QWidget):
|
|
2712
2822
|
self.minmaxButton.setContentsMargins(0, 0, 0, 0)
|
2713
2823
|
self.minmaxButton.setIconSize(iconSize)
|
2714
2824
|
self.minmaxButton.setFixedSize(fPx, fPx)
|
2715
|
-
self.minmaxButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
2825
|
+
self.minmaxButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
2716
2826
|
self.minmaxButton.setVisible(False)
|
2717
2827
|
self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode"))
|
2718
2828
|
self.minmaxButton.clicked.connect(lambda: self.docEditor.toggleFocusModeRequest.emit())
|
@@ -2721,7 +2831,7 @@ class GuiDocEditHeader(QWidget):
|
|
2721
2831
|
self.closeButton.setContentsMargins(0, 0, 0, 0)
|
2722
2832
|
self.closeButton.setIconSize(iconSize)
|
2723
2833
|
self.closeButton.setFixedSize(fPx, fPx)
|
2724
|
-
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
2834
|
+
self.closeButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
|
2725
2835
|
self.closeButton.setVisible(False)
|
2726
2836
|
self.closeButton.setToolTip(self.tr("Close"))
|
2727
2837
|
self.closeButton.clicked.connect(self._closeDocument)
|
@@ -2779,9 +2889,9 @@ class GuiDocEditHeader(QWidget):
|
|
2779
2889
|
theme rather than the main GUI.
|
2780
2890
|
"""
|
2781
2891
|
palette = QPalette()
|
2782
|
-
palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
|
2783
|
-
palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
|
2784
|
-
palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
|
2892
|
+
palette.setColor(QPalette.ColorRole.Window, QColor(*SHARED.theme.colBack))
|
2893
|
+
palette.setColor(QPalette.ColorRole.WindowText, QColor(*SHARED.theme.colText))
|
2894
|
+
palette.setColor(QPalette.ColorRole.Text, QColor(*SHARED.theme.colText))
|
2785
2895
|
|
2786
2896
|
self.setPalette(palette)
|
2787
2897
|
self.itemTitle.setPalette(palette)
|
@@ -2857,7 +2967,8 @@ class GuiDocEditHeader(QWidget):
|
|
2857
2967
|
"""Capture a click on the title and ensure that the item is
|
2858
2968
|
selected in the project tree.
|
2859
2969
|
"""
|
2860
|
-
|
2970
|
+
if event.button() == Qt.MouseButton.LeftButton:
|
2971
|
+
self.docEditor.requestProjectItemSelected.emit(self._docHandle, True)
|
2861
2972
|
return
|
2862
2973
|
|
2863
2974
|
# END Class GuiDocEditHeader
|
@@ -2894,11 +3005,13 @@ class GuiDocEditFooter(QWidget):
|
|
2894
3005
|
self.setContentsMargins(0, 0, 0, 0)
|
2895
3006
|
self.setAutoFillBackground(True)
|
2896
3007
|
|
3008
|
+
alLeftTop = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
|
3009
|
+
|
2897
3010
|
# Status
|
2898
3011
|
self.statusIcon = QLabel("")
|
2899
3012
|
self.statusIcon.setContentsMargins(0, 0, 0, 0)
|
2900
3013
|
self.statusIcon.setFixedHeight(self.sPx)
|
2901
|
-
self.statusIcon.setAlignment(
|
3014
|
+
self.statusIcon.setAlignment(alLeftTop)
|
2902
3015
|
|
2903
3016
|
self.statusText = QLabel(self.tr("Status"))
|
2904
3017
|
self.statusText.setIndent(0)
|
@@ -2906,14 +3019,14 @@ class GuiDocEditFooter(QWidget):
|
|
2906
3019
|
self.statusText.setContentsMargins(0, 0, 0, 0)
|
2907
3020
|
self.statusText.setAutoFillBackground(True)
|
2908
3021
|
self.statusText.setFixedHeight(fPx)
|
2909
|
-
self.statusText.setAlignment(
|
3022
|
+
self.statusText.setAlignment(alLeftTop)
|
2910
3023
|
self.statusText.setFont(lblFont)
|
2911
3024
|
|
2912
3025
|
# Lines
|
2913
3026
|
self.linesIcon = QLabel("")
|
2914
3027
|
self.linesIcon.setContentsMargins(0, 0, 0, 0)
|
2915
3028
|
self.linesIcon.setFixedHeight(self.sPx)
|
2916
|
-
self.linesIcon.setAlignment(
|
3029
|
+
self.linesIcon.setAlignment(alLeftTop)
|
2917
3030
|
|
2918
3031
|
self.linesText = QLabel("")
|
2919
3032
|
self.linesText.setIndent(0)
|
@@ -2921,14 +3034,14 @@ class GuiDocEditFooter(QWidget):
|
|
2921
3034
|
self.linesText.setContentsMargins(0, 0, 0, 0)
|
2922
3035
|
self.linesText.setAutoFillBackground(True)
|
2923
3036
|
self.linesText.setFixedHeight(fPx)
|
2924
|
-
self.linesText.setAlignment(
|
3037
|
+
self.linesText.setAlignment(alLeftTop)
|
2925
3038
|
self.linesText.setFont(lblFont)
|
2926
3039
|
|
2927
3040
|
# Words
|
2928
3041
|
self.wordsIcon = QLabel("")
|
2929
3042
|
self.wordsIcon.setContentsMargins(0, 0, 0, 0)
|
2930
3043
|
self.wordsIcon.setFixedHeight(self.sPx)
|
2931
|
-
self.wordsIcon.setAlignment(
|
3044
|
+
self.wordsIcon.setAlignment(alLeftTop)
|
2932
3045
|
|
2933
3046
|
self.wordsText = QLabel("")
|
2934
3047
|
self.wordsText.setIndent(0)
|
@@ -2936,7 +3049,7 @@ class GuiDocEditFooter(QWidget):
|
|
2936
3049
|
self.wordsText.setContentsMargins(0, 0, 0, 0)
|
2937
3050
|
self.wordsText.setAutoFillBackground(True)
|
2938
3051
|
self.wordsText.setFixedHeight(fPx)
|
2939
|
-
self.wordsText.setAlignment(
|
3052
|
+
self.wordsText.setAlignment(alLeftTop)
|
2940
3053
|
self.wordsText.setFont(lblFont)
|
2941
3054
|
|
2942
3055
|
# Assemble Layout
|
@@ -2984,9 +3097,9 @@ class GuiDocEditFooter(QWidget):
|
|
2984
3097
|
theme rather than the main GUI.
|
2985
3098
|
"""
|
2986
3099
|
palette = QPalette()
|
2987
|
-
palette.setColor(QPalette.Window, QColor(*SHARED.theme.colBack))
|
2988
|
-
palette.setColor(QPalette.WindowText, QColor(*SHARED.theme.colText))
|
2989
|
-
palette.setColor(QPalette.Text, QColor(*SHARED.theme.colText))
|
3100
|
+
palette.setColor(QPalette.ColorRole.Window, QColor(*SHARED.theme.colBack))
|
3101
|
+
palette.setColor(QPalette.ColorRole.WindowText, QColor(*SHARED.theme.colText))
|
3102
|
+
palette.setColor(QPalette.ColorRole.Text, QColor(*SHARED.theme.colText))
|
2990
3103
|
|
2991
3104
|
self.setPalette(palette)
|
2992
3105
|
self.statusText.setPalette(palette)
|