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.
Files changed (89) hide show
  1. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/METADATA +5 -6
  2. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/RECORD +79 -83
  3. novelwriter/__init__.py +15 -8
  4. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  5. novelwriter/assets/i18n/nw_en_US.qm +0 -0
  6. novelwriter/assets/i18n/nw_es_419.qm +0 -0
  7. novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
  8. novelwriter/assets/i18n/nw_it_IT.qm +0 -0
  9. novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
  10. novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
  11. novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
  12. novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
  13. novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
  14. novelwriter/assets/icons/none.svg +4 -0
  15. novelwriter/assets/icons/typicons_dark/icons.conf +2 -2
  16. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +4 -0
  17. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +4 -0
  18. novelwriter/assets/icons/typicons_light/icons.conf +2 -2
  19. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +4 -0
  20. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +4 -0
  21. novelwriter/assets/manual.pdf +0 -0
  22. novelwriter/assets/sample.zip +0 -0
  23. novelwriter/common.py +11 -3
  24. novelwriter/config.py +12 -4
  25. novelwriter/core/buildsettings.py +7 -7
  26. novelwriter/core/coretools.py +21 -22
  27. novelwriter/core/docbuild.py +2 -2
  28. novelwriter/core/projectxml.py +1 -1
  29. novelwriter/core/spellcheck.py +3 -3
  30. novelwriter/core/status.py +3 -2
  31. novelwriter/core/tokenizer.py +3 -3
  32. novelwriter/core/toodt.py +333 -356
  33. novelwriter/dialogs/about.py +9 -11
  34. novelwriter/dialogs/docmerge.py +17 -14
  35. novelwriter/dialogs/docsplit.py +14 -12
  36. novelwriter/dialogs/editlabel.py +5 -4
  37. novelwriter/dialogs/preferences.py +29 -34
  38. novelwriter/dialogs/projectsettings.py +31 -28
  39. novelwriter/dialogs/quotes.py +10 -9
  40. novelwriter/dialogs/wordlist.py +17 -14
  41. novelwriter/error.py +14 -12
  42. novelwriter/extensions/circularprogress.py +12 -8
  43. novelwriter/extensions/configlayout.py +1 -3
  44. novelwriter/extensions/modified.py +33 -2
  45. novelwriter/extensions/pagedsidebar.py +16 -14
  46. novelwriter/extensions/simpleprogress.py +3 -1
  47. novelwriter/extensions/statusled.py +3 -1
  48. novelwriter/extensions/switch.py +10 -9
  49. novelwriter/extensions/switchbox.py +14 -13
  50. novelwriter/gui/doceditor.py +205 -246
  51. novelwriter/gui/dochighlight.py +26 -9
  52. novelwriter/gui/docviewer.py +55 -59
  53. novelwriter/gui/docviewerpanel.py +16 -13
  54. novelwriter/gui/editordocument.py +4 -4
  55. novelwriter/gui/itemdetails.py +45 -48
  56. novelwriter/gui/mainmenu.py +2 -2
  57. novelwriter/gui/noveltree.py +23 -21
  58. novelwriter/gui/outline.py +93 -94
  59. novelwriter/gui/projtree.py +32 -30
  60. novelwriter/gui/search.py +75 -29
  61. novelwriter/gui/sidebar.py +24 -28
  62. novelwriter/gui/statusbar.py +14 -14
  63. novelwriter/gui/theme.py +61 -39
  64. novelwriter/guimain.py +37 -33
  65. novelwriter/shared.py +21 -9
  66. novelwriter/text/counting.py +1 -0
  67. novelwriter/tools/dictionaries.py +15 -14
  68. novelwriter/tools/lipsum.py +20 -17
  69. novelwriter/tools/manusbuild.py +44 -35
  70. novelwriter/tools/manuscript.py +112 -112
  71. novelwriter/tools/manussettings.py +91 -98
  72. novelwriter/tools/noveldetails.py +20 -18
  73. novelwriter/tools/welcome.py +51 -48
  74. novelwriter/tools/writingstats.py +61 -55
  75. novelwriter/types.py +90 -0
  76. novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +0 -4
  77. novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +0 -4
  78. novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +0 -4
  79. novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +0 -4
  80. novelwriter/core/__init__.py +0 -3
  81. novelwriter/dialogs/__init__.py +0 -3
  82. novelwriter/extensions/__init__.py +0 -3
  83. novelwriter/gui/__init__.py +0 -3
  84. novelwriter/text/__init__.py +0 -3
  85. novelwriter/tools/__init__.py +0 -3
  86. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/LICENSE.md +0 -0
  87. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/WHEEL +0 -0
  88. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/entry_points.txt +0 -0
  89. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/top_level.txt +0 -0
@@ -39,17 +39,16 @@ from time import time
39
39
  from typing import TYPE_CHECKING
40
40
 
41
41
  from PyQt5.QtCore import (
42
- pyqtSignal, pyqtSlot, QObject, QPoint, QRegExp, QRegularExpression,
43
- QRunnable, QSize, Qt, QTimer
42
+ QObject, QPoint, QRegExp, QRegularExpression, QRunnable, Qt, QTimer,
43
+ pyqtSignal, pyqtSlot
44
44
  )
45
45
  from PyQt5.QtGui import (
46
46
  QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette,
47
47
  QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
48
48
  )
49
49
  from PyQt5.QtWidgets import (
50
- QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
51
- QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout,
52
- QWidget, qApp
50
+ QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
51
+ QMenu, QPlainTextEdit, QShortcut, QToolBar, QVBoxLayout, QWidget
53
52
  )
54
53
 
55
54
  from novelwriter import CONFIG, SHARED
@@ -58,12 +57,17 @@ from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
58
57
  from novelwriter.core.document import NWDocument
59
58
  from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
60
59
  from novelwriter.extensions.eventfilters import WheelEventFilter
61
- from novelwriter.extensions.modified import NIconToolButton
60
+ from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
62
61
  from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
63
62
  from novelwriter.gui.editordocument import GuiTextDocument
64
63
  from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
65
64
  from novelwriter.text.counting import standardCounter
66
65
  from novelwriter.tools.lipsum import GuiLipsum
66
+ from novelwriter.types import (
67
+ QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop,
68
+ QtAlignRight, QtKeepAnchor, QtModCtrl, QtModeNone, QtModShift, QtMouseLeft,
69
+ QtMoveAnchor, QtMoveLeft, QtMoveRight
70
+ )
67
71
 
68
72
  if TYPE_CHECKING: # pragma: no cover
69
73
  from novelwriter.guimain import GuiMain
@@ -92,6 +96,7 @@ class GuiDocEditor(QPlainTextEdit):
92
96
  # Custom Signals
93
97
  statusMessage = pyqtSignal(str)
94
98
  docCountsChanged = pyqtSignal(str, int, int, int)
99
+ docTextChanged = pyqtSignal(str, float)
95
100
  editedStatusChanged = pyqtSignal(bool)
96
101
  loadDocumentTagRequest = pyqtSignal(str, Enum)
97
102
  novelStructureChanged = pyqtSignal()
@@ -178,12 +183,12 @@ class GuiDocEditor(QPlainTextEdit):
178
183
  self.keyContext.activated.connect(self._openContextFromCursor)
179
184
 
180
185
  self.followTag1 = QShortcut(self)
181
- self.followTag1.setKey(Qt.Key.Key_Return | Qt.KeyboardModifier.ControlModifier)
186
+ self.followTag1.setKey(Qt.Key.Key_Return | QtModCtrl)
182
187
  self.followTag1.setContext(Qt.ShortcutContext.WidgetShortcut)
183
188
  self.followTag1.activated.connect(self._processTag)
184
189
 
185
190
  self.followTag2 = QShortcut(self)
186
- self.followTag2.setKey(Qt.Key.Key_Enter | Qt.KeyboardModifier.ControlModifier)
191
+ self.followTag2.setKey(Qt.Key.Key_Enter | QtModCtrl)
187
192
  self.followTag2.setContext(Qt.ShortcutContext.WidgetShortcut)
188
193
  self.followTag2.activated.connect(self._processTag)
189
194
 
@@ -209,6 +214,10 @@ class GuiDocEditor(QPlainTextEdit):
209
214
  self.wheelEventFilter = WheelEventFilter(self)
210
215
  self.installEventFilter(self.wheelEventFilter)
211
216
 
217
+ # Function Mapping
218
+ self.closeSearch = self.docSearch.closeSearch
219
+ self.searchVisible = self.docSearch.isVisible
220
+
212
221
  # Finalise
213
222
  self.updateSyntaxColours()
214
223
  self.initEditor()
@@ -325,7 +334,7 @@ class GuiDocEditor(QPlainTextEdit):
325
334
  font = QFont()
326
335
  font.setFamily(CONFIG.textFont)
327
336
  font.setPointSize(CONFIG.textSize)
328
- self.setFont(font)
337
+ self._qDocument.setDefaultFont(font)
329
338
 
330
339
  # Set default text margins
331
340
  # Due to cursor visibility, a part of the margin must be
@@ -338,7 +347,7 @@ class GuiDocEditor(QPlainTextEdit):
338
347
  options = QTextOption()
339
348
 
340
349
  if CONFIG.doJustify:
341
- options.setAlignment(Qt.AlignmentFlag.AlignJustify)
350
+ options.setAlignment(QtAlignJustify)
342
351
  if CONFIG.showTabsNSpaces:
343
352
  options.setFlags(options.flags() | QTextOption.Flag.ShowTabsAndSpaces)
344
353
  if CONFIG.showLineEndings:
@@ -372,7 +381,7 @@ class GuiDocEditor(QPlainTextEdit):
372
381
 
373
382
  return
374
383
 
375
- def loadText(self, tHandle: str, tLine=None) -> bool:
384
+ def loadText(self, tHandle: str, tLine: int | None = None) -> bool:
376
385
  """Load text from a document into the editor. If we have an I/O
377
386
  error, we must handle this and clear the editor so that we don't
378
387
  risk overwriting the file if it exists. This can for instance
@@ -390,13 +399,13 @@ class GuiDocEditor(QPlainTextEdit):
390
399
  self.clearEditor()
391
400
  return False
392
401
 
393
- qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
402
+ QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
394
403
  self._docHandle = tHandle
395
404
 
396
405
  self._allowAutoReplace(False)
397
406
  self._qDocument.setTextContent(docText, tHandle)
398
407
  self._allowAutoReplace(True)
399
- qApp.processEvents()
408
+ QApplication.processEvents()
400
409
 
401
410
  self._lastEdit = time()
402
411
  self._lastActive = time()
@@ -420,12 +429,12 @@ class GuiDocEditor(QPlainTextEdit):
420
429
  self.setPlainText("")
421
430
  self.setCursorPosition(0)
422
431
 
423
- qApp.processEvents()
432
+ QApplication.processEvents()
424
433
  self.setDocumentChanged(False)
425
434
  self._qDocument.clearUndoRedoStacks()
426
435
  self.docToolBar.setVisible(CONFIG.showEditToolBar)
427
436
 
428
- qApp.restoreOverrideCursor()
437
+ QApplication.restoreOverrideCursor()
429
438
 
430
439
  # Update the status bar
431
440
  if self._nwItem is not None:
@@ -442,11 +451,11 @@ class GuiDocEditor(QPlainTextEdit):
442
451
  """Replace the text of the current document with the provided
443
452
  text. This also clears undo history.
444
453
  """
445
- qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
454
+ QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
446
455
  self.setPlainText(text)
447
456
  self.updateDocMargins()
448
457
  self.setDocumentChanged(True)
449
- qApp.restoreOverrideCursor()
458
+ QApplication.restoreOverrideCursor()
450
459
  return
451
460
 
452
461
  def saveText(self) -> bool:
@@ -488,6 +497,7 @@ class GuiDocEditor(QPlainTextEdit):
488
497
  return False
489
498
 
490
499
  self.setDocumentChanged(False)
500
+ self.docTextChanged.emit(self._docHandle, self._lastEdit)
491
501
 
492
502
  oldHeader = self._nwItem.mainHeading
493
503
  oldCount = SHARED.project.index.getHandleHeaderCount(tHandle)
@@ -533,7 +543,7 @@ class GuiDocEditor(QPlainTextEdit):
533
543
  while self.cursorRect().bottom() > vH and count < 100000:
534
544
  vBar.setValue(vBar.value() + 1)
535
545
  count += 1
536
- qApp.processEvents()
546
+ QApplication.processEvents()
537
547
  return
538
548
 
539
549
  def updateDocMargins(self) -> None:
@@ -593,6 +603,15 @@ class GuiDocEditor(QPlainTextEdit):
593
603
  text = text.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators
594
604
  return text
595
605
 
606
+ def getSelectedText(self) -> str:
607
+ """Get currently selected text."""
608
+ if (cursor := self.textCursor()).hasSelection():
609
+ text = cursor.selectedText()
610
+ text = text.replace(nwUnicode.U_LSEP, "\n") # Line separators
611
+ text = text.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators
612
+ return text
613
+ return ""
614
+
596
615
  def getCursorPosition(self) -> int:
597
616
  """Find the cursor position in the document. If the editor has a
598
617
  selection, return the position of the end of the selection.
@@ -639,12 +658,13 @@ class GuiDocEditor(QPlainTextEdit):
639
658
  logger.debug("Cursor moved to line %d", line)
640
659
  return
641
660
 
642
- def setCursorSelection(self, selStart: int, selLength: int) -> None:
661
+ def setCursorSelection(self, start: int, length: int) -> None:
643
662
  """Make a text selection."""
644
- cursor = self.textCursor()
645
- cursor.setPosition(selStart, QTextCursor.MoveMode.MoveAnchor)
646
- cursor.setPosition(selStart + selLength, QTextCursor.MoveMode.KeepAnchor)
647
- self.setTextCursor(cursor)
663
+ if start >= 0 and length > 0:
664
+ cursor = self.textCursor()
665
+ cursor.setPosition(start, QtMoveAnchor)
666
+ cursor.setPosition(start + length, QtKeepAnchor)
667
+ self.setTextCursor(cursor)
648
668
  return
649
669
 
650
670
  ##
@@ -686,9 +706,9 @@ class GuiDocEditor(QPlainTextEdit):
686
706
  """
687
707
  logger.debug("Running spell checker")
688
708
  start = time()
689
- qApp.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
709
+ QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
690
710
  self._qDocument.syntaxHighlighter.rehighlight()
691
- qApp.restoreOverrideCursor()
711
+ QApplication.restoreOverrideCursor()
692
712
  logger.debug("Document highlighted in %.3f ms", 1000*(time() - start))
693
713
  self.statusMessage.emit(self.tr("Spell check complete"))
694
714
  return
@@ -801,7 +821,7 @@ class GuiDocEditor(QPlainTextEdit):
801
821
 
802
822
  def anyFocus(self) -> bool:
803
823
  """Check if any widget or child widget has focus."""
804
- return self.hasFocus() or self.isAncestorOf(qApp.focusWidget())
824
+ return self.hasFocus() or self.isAncestorOf(QApplication.focusWidget())
805
825
 
806
826
  def revealLocation(self) -> None:
807
827
  """Tell the user where on the file system the file in the editor
@@ -910,11 +930,6 @@ class GuiDocEditor(QPlainTextEdit):
910
930
 
911
931
  return True
912
932
 
913
- def closeSearch(self) -> bool:
914
- """Close the search box."""
915
- self.docSearch.closeSearch()
916
- return self.docSearch.isVisible()
917
-
918
933
  ##
919
934
  # Document Events and Maintenance
920
935
  ##
@@ -949,7 +964,7 @@ class GuiDocEditor(QPlainTextEdit):
949
964
  super().keyPressEvent(event)
950
965
  nPos = self.cursorRect().topLeft().y()
951
966
  kMod = event.modifiers()
952
- okMod = kMod in (Qt.KeyboardModifier.NoModifier, Qt.KeyboardModifier.ShiftModifier)
967
+ okMod = kMod in (QtModeNone, QtModShift)
953
968
  okKey = event.key() not in self.MOVE_KEYS
954
969
  if nPos != cPos and okMod and okKey:
955
970
  mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height()
@@ -970,7 +985,7 @@ class GuiDocEditor(QPlainTextEdit):
970
985
  if self.hasFocus():
971
986
  return False
972
987
  elif self.docSearch.isVisible():
973
- return self.docSearch.cycleFocus(next)
988
+ return self.docSearch.cycleFocus()
974
989
  return True
975
990
 
976
991
  def mouseReleaseEvent(self, event: QMouseEvent) -> None:
@@ -978,7 +993,7 @@ class GuiDocEditor(QPlainTextEdit):
978
993
  pressed, check if we're clicking on a tag, and trigger the
979
994
  follow tag function.
980
995
  """
981
- if qApp.keyboardModifiers() == Qt.KeyboardModifier.ControlModifier:
996
+ if QApplication.keyboardModifiers() == QtModCtrl:
982
997
  self._processTag(self.cursorForPosition(event.pos()))
983
998
  super().mouseReleaseEvent(event)
984
999
  return
@@ -1021,8 +1036,8 @@ class GuiDocEditor(QPlainTextEdit):
1021
1036
  @pyqtSlot()
1022
1037
  def toggleSearch(self) -> None:
1023
1038
  """Toggle the visibility of the search box."""
1024
- if self.docSearch.isVisible():
1025
- self.docSearch.closeSearch()
1039
+ if self.searchVisible():
1040
+ self.closeSearch()
1026
1041
  else:
1027
1042
  self.beginSearch()
1028
1043
  return
@@ -1066,7 +1081,7 @@ class GuiDocEditor(QPlainTextEdit):
1066
1081
  return
1067
1082
 
1068
1083
  @pyqtSlot()
1069
- def _cursorMoved(self):
1084
+ def _cursorMoved(self) -> None:
1070
1085
  """Triggered when the cursor moved in the editor."""
1071
1086
  self.docFooter.updateLineCount(self.textCursor())
1072
1087
  return
@@ -1078,8 +1093,8 @@ class GuiDocEditor(QPlainTextEdit):
1078
1093
  block = cursor.block()
1079
1094
  if block.isValid():
1080
1095
  pos += block.position()
1081
- cursor.setPosition(pos, QTextCursor.MoveMode.MoveAnchor)
1082
- cursor.setPosition(pos + length, QTextCursor.MoveMode.KeepAnchor)
1096
+ cursor.setPosition(pos, QtMoveAnchor)
1097
+ cursor.setPosition(pos + length, QtKeepAnchor)
1083
1098
  cursor.insertText(text)
1084
1099
  self._completer.hide()
1085
1100
  return
@@ -1139,9 +1154,7 @@ class GuiDocEditor(QPlainTextEdit):
1139
1154
  block = pCursor.block()
1140
1155
  sCursor = self.textCursor()
1141
1156
  sCursor.setPosition(block.position() + cPos)
1142
- sCursor.movePosition(
1143
- QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, cLen
1144
- )
1157
+ sCursor.movePosition(QtMoveRight, QtKeepAnchor, cLen)
1145
1158
  if suggest:
1146
1159
  ctxMenu.addSeparator()
1147
1160
  ctxMenu.addAction(self.tr("Spelling Suggestion(s)"))
@@ -1158,7 +1171,7 @@ class GuiDocEditor(QPlainTextEdit):
1158
1171
  action.triggered.connect(lambda: self._addWord(word, block))
1159
1172
 
1160
1173
  # Execute the context menu
1161
- ctxMenu.exec_(self.viewport().mapToGlobal(pos))
1174
+ ctxMenu.exec(self.viewport().mapToGlobal(pos))
1162
1175
  ctxMenu.deleteLater()
1163
1176
 
1164
1177
  return
@@ -1193,18 +1206,19 @@ class GuiDocEditor(QPlainTextEdit):
1193
1206
  if self._docHandle is None:
1194
1207
  return
1195
1208
 
1196
- if self.wCounterDoc.isRunning():
1197
- logger.debug("Word counter is busy")
1198
- return
1199
-
1200
1209
  if time() - self._lastEdit < 25.0:
1201
- logger.debug("Running word counter")
1202
- SHARED.runInThreadPool(self.wCounterDoc)
1210
+ logger.debug("Running document tasks")
1211
+ if not self.wCounterDoc.isRunning():
1212
+ SHARED.runInThreadPool(self.wCounterDoc)
1213
+
1203
1214
  self.docHeader.setOutline({
1204
1215
  block.blockNumber(): block.text()
1205
1216
  for block in self._qDocument.iterBlockByType(BLOCK_TITLE, maxCount=30)
1206
1217
  })
1207
1218
 
1219
+ if self._docChanged:
1220
+ self.docTextChanged.emit(self._docHandle, self._lastEdit)
1221
+
1208
1222
  return
1209
1223
 
1210
1224
  @pyqtSlot(int, int, int)
@@ -1276,11 +1290,7 @@ class GuiDocEditor(QPlainTextEdit):
1276
1290
 
1277
1291
  def beginSearch(self) -> None:
1278
1292
  """Set the selected text as the search text."""
1279
- cursor = self.textCursor()
1280
- if cursor.hasSelection():
1281
- self.docSearch.setSearchText(cursor.selectedText())
1282
- else:
1283
- self.docSearch.setSearchText(None)
1293
+ self.docSearch.setSearchText(self.getSelectedText() or None)
1284
1294
  resS, _ = self.findAllOccurences()
1285
1295
  self.docSearch.setResultCount(None, len(resS))
1286
1296
  return
@@ -1309,9 +1319,9 @@ class GuiDocEditor(QPlainTextEdit):
1309
1319
  if len(resS) == 0 and self._docHandle:
1310
1320
  self.docSearch.setResultCount(0, 0)
1311
1321
  self._lastFind = None
1312
- if self.docSearch.doNextFile and not goBack:
1322
+ if CONFIG.searchNextFile and not goBack:
1313
1323
  self.mainGui.openNextDocument(
1314
- self._docHandle, wrapAround=self.docSearch.doLoop
1324
+ self._docHandle, wrapAround=CONFIG.searchLoop
1315
1325
  )
1316
1326
  self.beginSearch()
1317
1327
  self.setFocus()
@@ -1320,7 +1330,7 @@ class GuiDocEditor(QPlainTextEdit):
1320
1330
  cursor = self.textCursor()
1321
1331
  resIdx = bisect.bisect_left(resS, cursor.position())
1322
1332
 
1323
- doLoop = self.docSearch.doLoop
1333
+ doLoop = CONFIG.searchLoop
1324
1334
  maxIdx = len(resS) - 1
1325
1335
 
1326
1336
  if goBack:
@@ -1330,9 +1340,9 @@ class GuiDocEditor(QPlainTextEdit):
1330
1340
  resIdx = maxIdx if doLoop else 0
1331
1341
 
1332
1342
  if resIdx > maxIdx and self._docHandle:
1333
- if self.docSearch.doNextFile and not goBack:
1343
+ if CONFIG.searchNextFile and not goBack:
1334
1344
  self.mainGui.openNextDocument(
1335
- self._docHandle, wrapAround=self.docSearch.doLoop
1345
+ self._docHandle, wrapAround=CONFIG.searchLoop
1336
1346
  )
1337
1347
  self.beginSearch()
1338
1348
  self.setFocus()
@@ -1340,8 +1350,8 @@ class GuiDocEditor(QPlainTextEdit):
1340
1350
  else:
1341
1351
  resIdx = 0 if doLoop else maxIdx
1342
1352
 
1343
- cursor.setPosition(resS[resIdx], QTextCursor.MoveMode.MoveAnchor)
1344
- cursor.setPosition(resE[resIdx], QTextCursor.MoveMode.KeepAnchor)
1353
+ cursor.setPosition(resS[resIdx], QtMoveAnchor)
1354
+ cursor.setPosition(resE[resIdx], QtKeepAnchor)
1345
1355
  self.setTextCursor(cursor)
1346
1356
 
1347
1357
  self.docSearch.setResultCount(resIdx + 1, len(resS))
@@ -1365,9 +1375,9 @@ class GuiDocEditor(QPlainTextEdit):
1365
1375
  origB = cursor.position()
1366
1376
 
1367
1377
  findOpt = QTextDocument.FindFlag(0)
1368
- if self.docSearch.isCaseSense:
1378
+ if CONFIG.searchCase:
1369
1379
  findOpt |= QTextDocument.FindFlag.FindCaseSensitively
1370
- if self.docSearch.isWholeWord:
1380
+ if CONFIG.searchWord:
1371
1381
  findOpt |= QTextDocument.FindFlag.FindWholeWords
1372
1382
 
1373
1383
  searchFor = self.docSearch.getSearchObject()
@@ -1387,8 +1397,8 @@ class GuiDocEditor(QPlainTextEdit):
1387
1397
  break
1388
1398
 
1389
1399
  if hasSelection:
1390
- cursor.setPosition(origA, QTextCursor.MoveMode.MoveAnchor)
1391
- cursor.setPosition(origB, QTextCursor.MoveMode.KeepAnchor)
1400
+ cursor.setPosition(origA, QtMoveAnchor)
1401
+ cursor.setPosition(origB, QtKeepAnchor)
1392
1402
  else:
1393
1403
  cursor.setPosition(origA)
1394
1404
 
@@ -1436,7 +1446,7 @@ class GuiDocEditor(QPlainTextEdit):
1436
1446
  searchFor = self.docSearch.searchText
1437
1447
  replWith = self.docSearch.replaceText
1438
1448
 
1439
- if self.docSearch.doMatchCap:
1449
+ if CONFIG.searchMatchCap:
1440
1450
  replWith = transferCase(cursor.selectedText(), replWith)
1441
1451
 
1442
1452
  # Make sure the selected text was selected by an actual find
@@ -1461,7 +1471,7 @@ class GuiDocEditor(QPlainTextEdit):
1461
1471
  # Internal Functions : Text Manipulation
1462
1472
  ##
1463
1473
 
1464
- def _toggleFormat(self, fLen: int, fChar: str) -> bool:
1474
+ def _toggleFormat(self, fLen: int, fChar: str) -> None:
1465
1475
  """Toggle the formatting of a specific type for a piece of text.
1466
1476
  If more than one block is selected, the formatting is applied to
1467
1477
  the first block.
@@ -1479,20 +1489,20 @@ class GuiDocEditor(QPlainTextEdit):
1479
1489
 
1480
1490
  posS = cursor.selectionStart()
1481
1491
  posE = cursor.selectionEnd()
1482
- if self._qDocument.characterAt(posO - 1) == fChar:
1492
+ if posS == posE and self._qDocument.characterAt(posO - 1) == fChar:
1483
1493
  logger.warning("Format repetition, cancelling action")
1484
1494
  cursor.clearSelection()
1485
1495
  cursor.setPosition(posO)
1486
1496
  self.setTextCursor(cursor)
1487
- return False
1497
+ return
1488
1498
 
1489
1499
  blockS = self._qDocument.findBlock(posS)
1490
1500
  blockE = self._qDocument.findBlock(posE)
1491
1501
  if blockS != blockE:
1492
1502
  posE = blockS.position() + blockS.length() - 1
1493
1503
  cursor.clearSelection()
1494
- cursor.setPosition(posS, QTextCursor.MoveMode.MoveAnchor)
1495
- cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
1504
+ cursor.setPosition(posS, QtMoveAnchor)
1505
+ cursor.setPosition(posE, QtKeepAnchor)
1496
1506
  self.setTextCursor(cursor)
1497
1507
 
1498
1508
  numB = 0
@@ -1510,7 +1520,6 @@ class GuiDocEditor(QPlainTextEdit):
1510
1520
  break
1511
1521
 
1512
1522
  if fLen == min(numA, numB):
1513
- cursor.clearSelection()
1514
1523
  cursor.beginEditBlock()
1515
1524
  cursor.setPosition(posS)
1516
1525
  for i in range(fLen):
@@ -1519,17 +1528,19 @@ class GuiDocEditor(QPlainTextEdit):
1519
1528
  for i in range(fLen):
1520
1529
  cursor.deletePreviousChar()
1521
1530
  cursor.endEditBlock()
1522
- cursor.clearSelection()
1523
- cursor.setPosition(posO - fLen)
1524
- self.setTextCursor(cursor)
1531
+
1532
+ if select != _SelectAction.KEEP_SELECTION:
1533
+ cursor.clearSelection()
1534
+ cursor.setPosition(posO - fLen)
1535
+ self.setTextCursor(cursor)
1525
1536
 
1526
1537
  else:
1527
1538
  self._wrapSelection(fChar*fLen, pos=posO, select=select)
1528
1539
 
1529
- return True
1540
+ return
1530
1541
 
1531
1542
  def _wrapSelection(self, before: str, after: str | None = None, pos: int | None = None,
1532
- select: _SelectAction = _SelectAction.NO_DECISION) -> bool:
1543
+ select: _SelectAction = _SelectAction.NO_DECISION) -> None:
1533
1544
  """Wrap the selected text in whatever is in tBefore and tAfter.
1534
1545
  If there is no selection, the autoSelect setting decides the
1535
1546
  action. AutoSelect will select the word under the cursor before
@@ -1569,21 +1580,21 @@ class GuiDocEditor(QPlainTextEdit):
1569
1580
  if select == _SelectAction.MOVE_AFTER:
1570
1581
  cursor.setPosition(posE + len(before + after))
1571
1582
  elif select == _SelectAction.KEEP_SELECTION:
1572
- cursor.setPosition(posE + len(before), QTextCursor.MoveMode.MoveAnchor)
1573
- cursor.setPosition(posS + len(before), QTextCursor.MoveMode.KeepAnchor)
1583
+ cursor.setPosition(posS + len(before), QtMoveAnchor)
1584
+ cursor.setPosition(posE + len(before), QtKeepAnchor)
1574
1585
  elif select == _SelectAction.KEEP_POSITION:
1575
1586
  cursor.setPosition(posO + len(before))
1576
1587
 
1577
1588
  self.setTextCursor(cursor)
1578
1589
 
1579
- return True
1590
+ return
1580
1591
 
1581
- def _replaceQuotes(self, sQuote: str, oQuote: str, cQuote: str) -> bool:
1592
+ def _replaceQuotes(self, sQuote: str, oQuote: str, cQuote: str) -> None:
1582
1593
  """Replace all straight quotes in the selected text."""
1583
1594
  cursor = self.textCursor()
1584
1595
  if not cursor.hasSelection():
1585
1596
  SHARED.error(self.tr("Please select some text before calling replace quotes."))
1586
- return False
1597
+ return
1587
1598
 
1588
1599
  posS = cursor.selectionStart()
1589
1600
  posE = cursor.selectionEnd()
@@ -1592,9 +1603,7 @@ class GuiDocEditor(QPlainTextEdit):
1592
1603
  self._allowAutoReplace(False)
1593
1604
  for posC in range(posS, posE+1):
1594
1605
  cursor.setPosition(posC)
1595
- cursor.movePosition(
1596
- QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 2
1597
- )
1606
+ cursor.movePosition(QtMoveLeft, QtKeepAnchor, 2)
1598
1607
  selText = cursor.selectedText()
1599
1608
 
1600
1609
  nS = len(selText)
@@ -1614,22 +1623,18 @@ class GuiDocEditor(QPlainTextEdit):
1614
1623
  cursor.setPosition(posC)
1615
1624
  if pC in closeCheck:
1616
1625
  cursor.beginEditBlock()
1617
- cursor.movePosition(
1618
- QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
1619
- )
1626
+ cursor.movePosition(QtMoveLeft, QtKeepAnchor, 1)
1620
1627
  cursor.insertText(oQuote)
1621
1628
  cursor.endEditBlock()
1622
1629
  else:
1623
1630
  cursor.beginEditBlock()
1624
- cursor.movePosition(
1625
- QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, 1
1626
- )
1631
+ cursor.movePosition(QtMoveLeft, QtKeepAnchor, 1)
1627
1632
  cursor.insertText(cQuote)
1628
1633
  cursor.endEditBlock()
1629
1634
 
1630
1635
  self._allowAutoReplace(True)
1631
1636
 
1632
- return True
1637
+ return
1633
1638
 
1634
1639
  def _processBlockFormat(
1635
1640
  self, action: nwDocAction, text: str, toggle: bool = True
@@ -1839,9 +1844,7 @@ class GuiDocEditor(QPlainTextEdit):
1839
1844
  cursor.beginEditBlock()
1840
1845
  cursor.clearSelection()
1841
1846
  cursor.setPosition(rS)
1842
- cursor.movePosition(
1843
- QTextCursor.MoveOperation.Right, QTextCursor.MoveMode.KeepAnchor, rE-rS
1844
- )
1847
+ cursor.movePosition(QtMoveRight, QtKeepAnchor, rE-rS)
1845
1848
  cursor.insertText(cleanText.rstrip() + "\n")
1846
1849
  cursor.endEditBlock()
1847
1850
 
@@ -1902,7 +1905,7 @@ class GuiDocEditor(QPlainTextEdit):
1902
1905
  ).format(tag)):
1903
1906
  itemClass = nwKeyWords.KEY_CLASS.get(tBits[0], nwItemClass.NO_CLASS)
1904
1907
  self.requestNewNoteCreation.emit(tag, itemClass)
1905
- qApp.processEvents()
1908
+ QApplication.processEvents()
1906
1909
  self._qDocument.syntaxHighlighter.rehighlightBlock(block)
1907
1910
 
1908
1911
  return nwTrinary.POSITIVE if exist else nwTrinary.NEGATIVE
@@ -2007,9 +2010,7 @@ class GuiDocEditor(QPlainTextEdit):
2007
2010
  tInsert = tInsert + self._typPadChar
2008
2011
 
2009
2012
  if nDelete > 0:
2010
- cursor.movePosition(
2011
- QTextCursor.MoveOperation.Left, QTextCursor.MoveMode.KeepAnchor, nDelete
2012
- )
2013
+ cursor.movePosition(QtMoveLeft, QtKeepAnchor, nDelete)
2013
2014
  cursor.insertText(tInsert)
2014
2015
 
2015
2016
  return
@@ -2065,8 +2066,8 @@ class GuiDocEditor(QPlainTextEdit):
2065
2066
  return cursor
2066
2067
 
2067
2068
  cursor.clearSelection()
2068
- cursor.setPosition(sPos, QTextCursor.MoveMode.MoveAnchor)
2069
- cursor.setPosition(ePos, QTextCursor.MoveMode.KeepAnchor)
2069
+ cursor.setPosition(sPos, QtMoveAnchor)
2070
+ cursor.setPosition(ePos, QtKeepAnchor)
2070
2071
 
2071
2072
  self.setTextCursor(cursor)
2072
2073
 
@@ -2090,8 +2091,8 @@ class GuiDocEditor(QPlainTextEdit):
2090
2091
  posE = cursor.selectionEnd()
2091
2092
  selTxt = cursor.selectedText()
2092
2093
  if selTxt.startswith(nwUnicode.U_PSEP):
2093
- cursor.setPosition(posS+1, QTextCursor.MoveMode.MoveAnchor)
2094
- cursor.setPosition(posE, QTextCursor.MoveMode.KeepAnchor)
2094
+ cursor.setPosition(posS+1, QtMoveAnchor)
2095
+ cursor.setPosition(posE, QtKeepAnchor)
2095
2096
 
2096
2097
  self.setTextCursor(cursor)
2097
2098
 
@@ -2186,7 +2187,7 @@ class MetaCompleter(QMenu):
2186
2187
  # Internal Functions
2187
2188
  ##
2188
2189
 
2189
- def _emitComplete(self, pos: int, length: int, value: str):
2190
+ def _emitComplete(self, pos: int, length: int, value: str) -> None:
2190
2191
  """Emit the signal to indicate a selection has been made."""
2191
2192
  self.complete.emit(pos, length, value)
2192
2193
  return
@@ -2222,7 +2223,7 @@ class BackgroundWordCounter(QRunnable):
2222
2223
  """
2223
2224
  self._isRunning = True
2224
2225
  if self._forSelection:
2225
- text = self._docEditor.textCursor().selectedText()
2226
+ text = self._docEditor.getSelectedText()
2226
2227
  else:
2227
2228
  text = self._docEditor.getText()
2228
2229
 
@@ -2258,79 +2259,68 @@ class GuiDocToolBar(QWidget):
2258
2259
 
2259
2260
  logger.debug("Create: GuiDocToolBar")
2260
2261
 
2262
+ iSz = SHARED.theme.baseIconSize
2261
2263
  cM = CONFIG.pxInt(4)
2262
- tPx = int(0.8*SHARED.theme.fontPixelSize)
2263
- iconSize = QSize(tPx, tPx)
2264
2264
  self.setContentsMargins(0, 0, 0, 0)
2265
2265
 
2266
2266
  # General Buttons
2267
2267
  # ===============
2268
2268
 
2269
- self.tbBoldMD = QToolButton(self)
2270
- self.tbBoldMD.setIconSize(iconSize)
2269
+ self.tbBoldMD = NIconToolButton(self, iSz)
2271
2270
  self.tbBoldMD.setToolTip(self.tr("Markdown Bold"))
2272
2271
  self.tbBoldMD.clicked.connect(
2273
2272
  lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
2274
2273
  )
2275
2274
 
2276
- self.tbItalicMD = QToolButton(self)
2277
- self.tbItalicMD.setIconSize(iconSize)
2275
+ self.tbItalicMD = NIconToolButton(self, iSz)
2278
2276
  self.tbItalicMD.setToolTip(self.tr("Markdown Italic"))
2279
2277
  self.tbItalicMD.clicked.connect(
2280
2278
  lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
2281
2279
  )
2282
2280
 
2283
- self.tbStrikeMD = QToolButton(self)
2284
- self.tbStrikeMD.setIconSize(iconSize)
2281
+ self.tbStrikeMD = NIconToolButton(self, iSz)
2285
2282
  self.tbStrikeMD.setToolTip(self.tr("Markdown Strikethrough"))
2286
2283
  self.tbStrikeMD.clicked.connect(
2287
2284
  lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
2288
2285
  )
2289
2286
 
2290
- self.tbBold = QToolButton(self)
2291
- self.tbBold.setIconSize(iconSize)
2287
+ self.tbBold = NIconToolButton(self, iSz)
2292
2288
  self.tbBold.setToolTip(self.tr("Shortcode Bold"))
2293
2289
  self.tbBold.clicked.connect(
2294
2290
  lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
2295
2291
  )
2296
2292
 
2297
- self.tbItalic = QToolButton(self)
2298
- self.tbItalic.setIconSize(iconSize)
2293
+ self.tbItalic = NIconToolButton(self, iSz)
2299
2294
  self.tbItalic.setToolTip(self.tr("Shortcode Italic"))
2300
2295
  self.tbItalic.clicked.connect(
2301
2296
  lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
2302
2297
  )
2303
2298
 
2304
- self.tbStrike = QToolButton(self)
2305
- self.tbStrike.setIconSize(iconSize)
2299
+ self.tbStrike = NIconToolButton(self, iSz)
2306
2300
  self.tbStrike.setToolTip(self.tr("Shortcode Strikethrough"))
2307
2301
  self.tbStrike.clicked.connect(
2308
2302
  lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE)
2309
2303
  )
2310
2304
 
2311
- self.tbUnderline = QToolButton(self)
2312
- self.tbUnderline.setIconSize(iconSize)
2305
+ self.tbUnderline = NIconToolButton(self, iSz)
2313
2306
  self.tbUnderline.setToolTip(self.tr("Shortcode Underline"))
2314
2307
  self.tbUnderline.clicked.connect(
2315
2308
  lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
2316
2309
  )
2317
2310
 
2318
- self.tbMark = QToolButton(self)
2319
- self.tbMark.setIconSize(iconSize)
2311
+ self.tbMark = NIconToolButton(self, iSz)
2320
2312
  self.tbMark.setToolTip(self.tr("Shortcode Highlight"))
2321
2313
  self.tbMark.clicked.connect(
2322
2314
  lambda: self.requestDocAction.emit(nwDocAction.SC_MARK)
2323
2315
  )
2324
2316
 
2325
- self.tbSuperscript = QToolButton(self)
2326
- self.tbSuperscript.setIconSize(iconSize)
2317
+ self.tbSuperscript = NIconToolButton(self, iSz)
2327
2318
  self.tbSuperscript.setToolTip(self.tr("Shortcode Superscript"))
2328
2319
  self.tbSuperscript.clicked.connect(
2329
2320
  lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
2330
2321
  )
2331
2322
 
2332
- self.tbSubscript = QToolButton(self)
2333
- self.tbSubscript.setIconSize(iconSize)
2323
+ self.tbSubscript = NIconToolButton(self, iSz)
2334
2324
  self.tbSubscript.setToolTip(self.tr("Shortcode Subscript"))
2335
2325
  self.tbSubscript.clicked.connect(
2336
2326
  lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
@@ -2372,16 +2362,16 @@ class GuiDocToolBar(QWidget):
2372
2362
  palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText)
2373
2363
  self.setPalette(palette)
2374
2364
 
2375
- self.tbBoldMD.setIcon(SHARED.theme.getIcon("fmt_bold-md"))
2376
- self.tbItalicMD.setIcon(SHARED.theme.getIcon("fmt_italic-md"))
2377
- self.tbStrikeMD.setIcon(SHARED.theme.getIcon("fmt_strike-md"))
2378
- self.tbBold.setIcon(SHARED.theme.getIcon("fmt_bold"))
2379
- self.tbItalic.setIcon(SHARED.theme.getIcon("fmt_italic"))
2380
- self.tbStrike.setIcon(SHARED.theme.getIcon("fmt_strike"))
2381
- self.tbUnderline.setIcon(SHARED.theme.getIcon("fmt_underline"))
2382
- self.tbMark.setIcon(SHARED.theme.getIcon("fmt_mark"))
2383
- self.tbSuperscript.setIcon(SHARED.theme.getIcon("fmt_superscript"))
2384
- self.tbSubscript.setIcon(SHARED.theme.getIcon("fmt_subscript"))
2365
+ self.tbBoldMD.setThemeIcon("fmt_bold-md")
2366
+ self.tbItalicMD.setThemeIcon("fmt_italic-md")
2367
+ self.tbStrikeMD.setThemeIcon("fmt_strike-md")
2368
+ self.tbBold.setThemeIcon("fmt_bold")
2369
+ self.tbItalic.setThemeIcon("fmt_italic")
2370
+ self.tbStrike.setThemeIcon("fmt_strike")
2371
+ self.tbUnderline.setThemeIcon("fmt_underline")
2372
+ self.tbMark.setThemeIcon("fmt_mark")
2373
+ self.tbSuperscript.setThemeIcon("fmt_superscript")
2374
+ self.tbSubscript.setThemeIcon("fmt_subscript")
2385
2375
 
2386
2376
  return
2387
2377
 
@@ -2402,16 +2392,9 @@ class GuiDocEditSearch(QFrame):
2402
2392
 
2403
2393
  self.docEditor = docEditor
2404
2394
 
2405
- self.repVisible = False
2406
- self.isCaseSense = CONFIG.searchCase
2407
- self.isWholeWord = CONFIG.searchWord
2408
- self.isRegEx = CONFIG.searchRegEx
2409
- self.doLoop = CONFIG.searchLoop
2410
- self.doNextFile = CONFIG.searchNextFile
2411
- self.doMatchCap = CONFIG.searchMatchCap
2412
-
2395
+ iSz = SHARED.theme.baseIconSize
2413
2396
  mPx = CONFIG.pxInt(6)
2414
- tPx = int(0.8*SHARED.theme.fontPixelSize)
2397
+
2415
2398
  self.boxFont = SHARED.theme.guiFont
2416
2399
  self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
2417
2400
 
@@ -2427,54 +2410,54 @@ class GuiDocEditSearch(QFrame):
2427
2410
 
2428
2411
  self.searchBox = QLineEdit(self)
2429
2412
  self.searchBox.setFont(self.boxFont)
2430
- self.searchBox.setPlaceholderText(self.tr("Search"))
2413
+ self.searchBox.setPlaceholderText(self.tr("Search for"))
2431
2414
  self.searchBox.returnPressed.connect(self._doSearch)
2432
2415
 
2433
2416
  self.replaceBox = QLineEdit(self)
2434
2417
  self.replaceBox.setFont(self.boxFont)
2435
- self.replaceBox.setPlaceholderText(self.tr("Replace"))
2418
+ self.replaceBox.setPlaceholderText(self.tr("Replace with"))
2436
2419
  self.replaceBox.returnPressed.connect(self._doReplace)
2437
2420
 
2438
2421
  self.searchOpt = QToolBar(self)
2439
2422
  self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
2440
- self.searchOpt.setIconSize(QSize(tPx, tPx))
2423
+ self.searchOpt.setIconSize(iSz)
2441
2424
  self.searchOpt.setContentsMargins(0, 0, 0, 0)
2442
2425
 
2443
- self.searchLabel = QLabel(self.tr("Search"))
2426
+ self.searchLabel = QLabel(self.tr("Search"), self)
2444
2427
  self.searchLabel.setFont(self.boxFont)
2445
2428
  self.searchLabel.setIndent(CONFIG.pxInt(6))
2446
2429
 
2447
- self.resultLabel = QLabel("?/?")
2430
+ self.resultLabel = QLabel("?/?", self)
2448
2431
  self.resultLabel.setFont(self.boxFont)
2449
2432
  self.resultLabel.setMinimumWidth(SHARED.theme.getTextWidth("?/?", self.boxFont))
2450
2433
 
2451
2434
  self.toggleCase = QAction(self.tr("Case Sensitive"), self)
2452
2435
  self.toggleCase.setCheckable(True)
2453
- self.toggleCase.setChecked(self.isCaseSense)
2436
+ self.toggleCase.setChecked(CONFIG.searchCase)
2454
2437
  self.toggleCase.toggled.connect(self._doToggleCase)
2455
2438
  self.searchOpt.addAction(self.toggleCase)
2456
2439
 
2457
2440
  self.toggleWord = QAction(self.tr("Whole Words Only"), self)
2458
2441
  self.toggleWord.setCheckable(True)
2459
- self.toggleWord.setChecked(self.isWholeWord)
2442
+ self.toggleWord.setChecked(CONFIG.searchWord)
2460
2443
  self.toggleWord.toggled.connect(self._doToggleWord)
2461
2444
  self.searchOpt.addAction(self.toggleWord)
2462
2445
 
2463
2446
  self.toggleRegEx = QAction(self.tr("RegEx Mode"), self)
2464
2447
  self.toggleRegEx.setCheckable(True)
2465
- self.toggleRegEx.setChecked(self.isRegEx)
2448
+ self.toggleRegEx.setChecked(CONFIG.searchRegEx)
2466
2449
  self.toggleRegEx.toggled.connect(self._doToggleRegEx)
2467
2450
  self.searchOpt.addAction(self.toggleRegEx)
2468
2451
 
2469
2452
  self.toggleLoop = QAction(self.tr("Loop Search"), self)
2470
2453
  self.toggleLoop.setCheckable(True)
2471
- self.toggleLoop.setChecked(self.doLoop)
2454
+ self.toggleLoop.setChecked(CONFIG.searchLoop)
2472
2455
  self.toggleLoop.toggled.connect(self._doToggleLoop)
2473
2456
  self.searchOpt.addAction(self.toggleLoop)
2474
2457
 
2475
2458
  self.toggleProject = QAction(self.tr("Search Next File"), self)
2476
2459
  self.toggleProject.setCheckable(True)
2477
- self.toggleProject.setChecked(self.doNextFile)
2460
+ self.toggleProject.setChecked(CONFIG.searchNextFile)
2478
2461
  self.toggleProject.toggled.connect(self._doToggleProject)
2479
2462
  self.searchOpt.addAction(self.toggleProject)
2480
2463
 
@@ -2482,38 +2465,32 @@ class GuiDocEditSearch(QFrame):
2482
2465
 
2483
2466
  self.toggleMatchCap = QAction(self.tr("Preserve Case"), self)
2484
2467
  self.toggleMatchCap.setCheckable(True)
2485
- self.toggleMatchCap.setChecked(self.doMatchCap)
2468
+ self.toggleMatchCap.setChecked(CONFIG.searchMatchCap)
2486
2469
  self.toggleMatchCap.toggled.connect(self._doToggleMatchCap)
2487
2470
  self.searchOpt.addAction(self.toggleMatchCap)
2488
2471
 
2489
2472
  self.searchOpt.addSeparator()
2490
2473
 
2491
2474
  self.cancelSearch = QAction(self.tr("Close Search"), self)
2492
- self.cancelSearch.triggered.connect(self._doClose)
2475
+ self.cancelSearch.triggered.connect(self.closeSearch)
2493
2476
  self.searchOpt.addAction(self.cancelSearch)
2494
2477
 
2495
2478
  # Buttons
2496
2479
  # =======
2497
2480
 
2498
- bPx = self.searchBox.sizeHint().height()
2499
-
2500
- self.showReplace = QToolButton(self)
2501
- self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
2502
- self.showReplace.setCheckable(True)
2481
+ self.showReplace = NIconToggleButton(self, iSz, "unfold")
2503
2482
  self.showReplace.toggled.connect(self._doToggleReplace)
2504
2483
 
2505
- self.searchButton = QPushButton("")
2506
- self.searchButton.setFixedSize(QSize(bPx, bPx))
2484
+ self.searchButton = NIconToolButton(self, iSz)
2507
2485
  self.searchButton.setToolTip(self.tr("Find in current document"))
2508
2486
  self.searchButton.clicked.connect(self._doSearch)
2509
2487
 
2510
- self.replaceButton = QPushButton("")
2511
- self.replaceButton.setFixedSize(QSize(bPx, bPx))
2488
+ self.replaceButton = NIconToolButton(self, iSz)
2512
2489
  self.replaceButton.setToolTip(self.tr("Find and replace in current document"))
2513
2490
  self.replaceButton.clicked.connect(self._doReplace)
2514
2491
 
2515
- self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignmentFlag.AlignLeft)
2516
- self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, Qt.AlignmentFlag.AlignRight)
2492
+ self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, QtAlignLeft)
2493
+ self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, QtAlignRight)
2517
2494
  self.mainBox.addWidget(self.showReplace, 1, 0, 1, 1)
2518
2495
  self.mainBox.addWidget(self.searchBox, 1, 1, 1, 2)
2519
2496
  self.mainBox.addWidget(self.searchButton, 1, 3, 1, 1)
@@ -2566,20 +2543,20 @@ class GuiDocEditSearch(QFrame):
2566
2543
  expression object.
2567
2544
  """
2568
2545
  text = self.searchBox.text()
2569
- if self.isRegEx:
2546
+ if CONFIG.searchRegEx:
2570
2547
  # Using the Unicode-capable QRegularExpression class was
2571
2548
  # only added in Qt 5.13. Otherwise, 5.3 and up supports
2572
2549
  # only the QRegExp class.
2573
2550
  if CONFIG.verQtValue >= 0x050d00:
2574
2551
  rxOpt = QRegularExpression.PatternOption.UseUnicodePropertiesOption
2575
- if not self.isCaseSense:
2552
+ if not CONFIG.searchCase:
2576
2553
  rxOpt |= QRegularExpression.PatternOption.CaseInsensitiveOption
2577
2554
  regEx = QRegularExpression(text, rxOpt)
2578
2555
  self._alertSearchValid(regEx.isValid())
2579
2556
  return regEx
2580
2557
  else: # pragma: no cover
2581
2558
  # >= 50300 to < 51300
2582
- if self.isCaseSense:
2559
+ if CONFIG.searchCase:
2583
2560
  rxOpt = Qt.CaseSensitivity.CaseSensitive
2584
2561
  else:
2585
2562
  rxOpt = Qt.CaseSensitivity.CaseInsensitive
@@ -2603,7 +2580,7 @@ class GuiDocEditSearch(QFrame):
2603
2580
  self.searchBox.setText(text)
2604
2581
  self.searchBox.setFocus()
2605
2582
  self.searchBox.selectAll()
2606
- if self.isRegEx:
2583
+ if CONFIG.searchRegEx:
2607
2584
  self._alertSearchValid(True)
2608
2585
  return
2609
2586
 
@@ -2633,7 +2610,7 @@ class GuiDocEditSearch(QFrame):
2633
2610
 
2634
2611
  def updateTheme(self) -> None:
2635
2612
  """Update theme elements."""
2636
- qPalette = qApp.palette()
2613
+ qPalette = QApplication.palette()
2637
2614
  self.setPalette(qPalette)
2638
2615
  self.searchBox.setPalette(qPalette)
2639
2616
  self.replaceBox.setPalette(qPalette)
@@ -2646,8 +2623,8 @@ class GuiDocEditSearch(QFrame):
2646
2623
  self.toggleProject.setIcon(SHARED.theme.getIcon("search_project"))
2647
2624
  self.toggleMatchCap.setIcon(SHARED.theme.getIcon("search_preserve"))
2648
2625
  self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel"))
2649
- self.searchButton.setIcon(SHARED.theme.getIcon("search"))
2650
- self.replaceButton.setIcon(SHARED.theme.getIcon("search_replace"))
2626
+ self.searchButton.setThemeIcon("search")
2627
+ self.replaceButton.setThemeIcon("search_replace")
2651
2628
 
2652
2629
  # Set stylesheets
2653
2630
  self.searchOpt.setStyleSheet("QToolBar {padding: 0;}")
@@ -2673,55 +2650,43 @@ class GuiDocEditSearch(QFrame):
2673
2650
 
2674
2651
  return
2675
2652
 
2676
- def closeSearch(self) -> None:
2677
- """Close the search box."""
2678
- CONFIG.searchCase = self.isCaseSense
2679
- CONFIG.searchWord = self.isWholeWord
2680
- CONFIG.searchRegEx = self.isRegEx
2681
- CONFIG.searchLoop = self.doLoop
2682
- CONFIG.searchNextFile = self.doNextFile
2683
- CONFIG.searchMatchCap = self.doMatchCap
2684
-
2685
- self.showReplace.setChecked(False)
2686
- self.setVisible(False)
2687
- self.docEditor.updateDocMargins()
2688
- self.docEditor.setFocus()
2689
-
2690
- return
2691
-
2692
- def cycleFocus(self, next: bool) -> bool:
2653
+ def cycleFocus(self) -> bool:
2693
2654
  """The tab key just alternates focus between the two input
2694
2655
  boxes, if the replace box is visible.
2695
2656
  """
2696
- if self.replaceBox.isVisible():
2697
- if self.searchBox.hasFocus():
2698
- self.replaceBox.setFocus()
2699
- return True
2700
- elif self.replaceBox.hasFocus():
2701
- self.searchBox.setFocus()
2702
- return True
2657
+ if self.searchBox.hasFocus():
2658
+ self.replaceBox.setFocus()
2659
+ return True
2660
+ elif self.replaceBox.hasFocus():
2661
+ self.searchBox.setFocus()
2662
+ return True
2703
2663
  return False
2704
2664
 
2705
2665
  def anyFocus(self) -> bool:
2706
2666
  """Return True if any of the input boxes have focus."""
2707
- return self.searchBox.hasFocus() | self.replaceBox.hasFocus()
2667
+ return self.searchBox.hasFocus() or self.replaceBox.hasFocus()
2708
2668
 
2709
2669
  ##
2710
- # Private Slots
2670
+ # Public Slots
2711
2671
  ##
2712
2672
 
2713
2673
  @pyqtSlot()
2714
- def _doClose(self) -> None:
2715
- """Hide the search/replace bar."""
2716
- self.closeSearch()
2674
+ def closeSearch(self) -> None:
2675
+ """Close the search box."""
2676
+ self.showReplace.setChecked(False)
2677
+ self.setVisible(False)
2678
+ self.docEditor.updateDocMargins()
2679
+ self.docEditor.setFocus()
2717
2680
  return
2718
2681
 
2682
+ ##
2683
+ # Private Slots
2684
+ ##
2685
+
2719
2686
  @pyqtSlot()
2720
2687
  def _doSearch(self) -> None:
2721
2688
  """Call the search action function for the document editor."""
2722
- self.docEditor.findNext(goBack=(
2723
- qApp.keyboardModifiers() == Qt.KeyboardModifier.ShiftModifier)
2724
- )
2689
+ self.docEditor.findNext(goBack=(QApplication.keyboardModifiers() == QtModShift))
2725
2690
  return
2726
2691
 
2727
2692
  @pyqtSlot()
@@ -2733,13 +2698,8 @@ class GuiDocEditSearch(QFrame):
2733
2698
  @pyqtSlot(bool)
2734
2699
  def _doToggleReplace(self, state: bool) -> None:
2735
2700
  """Toggle the show/hide of the replace box."""
2736
- if state:
2737
- self.showReplace.setArrowType(Qt.ArrowType.DownArrow)
2738
- else:
2739
- self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
2740
2701
  self.replaceBox.setVisible(state)
2741
2702
  self.replaceButton.setVisible(state)
2742
- self.repVisible = state
2743
2703
  self.adjustSize()
2744
2704
  self.docEditor.updateDocMargins()
2745
2705
  return
@@ -2747,37 +2707,37 @@ class GuiDocEditSearch(QFrame):
2747
2707
  @pyqtSlot(bool)
2748
2708
  def _doToggleCase(self, state: bool) -> None:
2749
2709
  """Enable/disable case sensitive mode."""
2750
- self.isCaseSense = state
2710
+ CONFIG.searchCase = state
2751
2711
  return
2752
2712
 
2753
2713
  @pyqtSlot(bool)
2754
2714
  def _doToggleWord(self, state: bool) -> None:
2755
2715
  """Enable/disable whole word search mode."""
2756
- self.isWholeWord = state
2716
+ CONFIG.searchWord = state
2757
2717
  return
2758
2718
 
2759
2719
  @pyqtSlot(bool)
2760
2720
  def _doToggleRegEx(self, state: bool) -> None:
2761
2721
  """Enable/disable regular expression search mode."""
2762
- self.isRegEx = state
2722
+ CONFIG.searchRegEx = state
2763
2723
  return
2764
2724
 
2765
2725
  @pyqtSlot(bool)
2766
2726
  def _doToggleLoop(self, state: bool) -> None:
2767
2727
  """Enable/disable looping the search."""
2768
- self.doLoop = state
2728
+ CONFIG.searchLoop = state
2769
2729
  return
2770
2730
 
2771
2731
  @pyqtSlot(bool)
2772
2732
  def _doToggleProject(self, state: bool) -> None:
2773
2733
  """Enable/disable continuing search in next project file."""
2774
- self.doNextFile = state
2734
+ CONFIG.searchNextFile = state
2775
2735
  return
2776
2736
 
2777
2737
  @pyqtSlot(bool)
2778
2738
  def _doToggleMatchCap(self, state: bool) -> None:
2779
2739
  """Enable/disable preserving capitalisation when replacing."""
2780
- self.doMatchCap = state
2740
+ CONFIG.searchMatchCap = state
2781
2741
  return
2782
2742
 
2783
2743
  ##
@@ -2816,7 +2776,8 @@ class GuiDocEditHeader(QWidget):
2816
2776
  self._docHandle = None
2817
2777
  self._docOutline: dict[int, str] = {}
2818
2778
 
2819
- iPx = SHARED.theme.baseIconSize
2779
+ iPx = SHARED.theme.baseIconHeight
2780
+ iSz = SHARED.theme.baseIconSize
2820
2781
  mPx = CONFIG.pxInt(4)
2821
2782
 
2822
2783
  # Main Widget Settings
@@ -2828,7 +2789,7 @@ class GuiDocEditHeader(QWidget):
2828
2789
  self.itemTitle.setMargin(0)
2829
2790
  self.itemTitle.setContentsMargins(0, 0, 0, 0)
2830
2791
  self.itemTitle.setAutoFillBackground(True)
2831
- self.itemTitle.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)
2792
+ self.itemTitle.setAlignment(QtAlignCenterTop)
2832
2793
  self.itemTitle.setFixedHeight(iPx)
2833
2794
 
2834
2795
  lblFont = self.itemTitle.font()
@@ -2839,27 +2800,27 @@ class GuiDocEditHeader(QWidget):
2839
2800
  self.outlineMenu = QMenu(self)
2840
2801
 
2841
2802
  # Buttons
2842
- self.tbButton = NIconToolButton(self, iPx)
2803
+ self.tbButton = NIconToolButton(self, iSz)
2843
2804
  self.tbButton.setVisible(False)
2844
2805
  self.tbButton.setToolTip(self.tr("Toggle Tool Bar"))
2845
2806
  self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit())
2846
2807
 
2847
- self.outlineButton = NIconToolButton(self, iPx)
2808
+ self.outlineButton = NIconToolButton(self, iSz)
2848
2809
  self.outlineButton.setVisible(False)
2849
2810
  self.outlineButton.setToolTip(self.tr("Outline"))
2850
2811
  self.outlineButton.setMenu(self.outlineMenu)
2851
2812
 
2852
- self.searchButton = NIconToolButton(self, iPx)
2813
+ self.searchButton = NIconToolButton(self, iSz)
2853
2814
  self.searchButton.setVisible(False)
2854
2815
  self.searchButton.setToolTip(self.tr("Search"))
2855
2816
  self.searchButton.clicked.connect(self.docEditor.toggleSearch)
2856
2817
 
2857
- self.minmaxButton = NIconToolButton(self, iPx)
2818
+ self.minmaxButton = NIconToolButton(self, iSz)
2858
2819
  self.minmaxButton.setVisible(False)
2859
2820
  self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode"))
2860
2821
  self.minmaxButton.clicked.connect(lambda: self.docEditor.toggleFocusModeRequest.emit())
2861
2822
 
2862
- self.closeButton = NIconToolButton(self, iPx)
2823
+ self.closeButton = NIconToolButton(self, iSz)
2863
2824
  self.closeButton.setVisible(False)
2864
2825
  self.closeButton.setToolTip(self.tr("Close"))
2865
2826
  self.closeButton.clicked.connect(self._closeDocument)
@@ -2928,11 +2889,11 @@ class GuiDocEditHeader(QWidget):
2928
2889
 
2929
2890
  def updateTheme(self) -> None:
2930
2891
  """Update theme elements."""
2931
- self.tbButton.setIcon(SHARED.theme.getIcon("menu"))
2932
- self.outlineButton.setIcon(SHARED.theme.getIcon("list"))
2933
- self.searchButton.setIcon(SHARED.theme.getIcon("search"))
2934
- self.minmaxButton.setIcon(SHARED.theme.getIcon("maximise"))
2935
- self.closeButton.setIcon(SHARED.theme.getIcon("close"))
2892
+ self.tbButton.setThemeIcon("menu")
2893
+ self.outlineButton.setThemeIcon("list")
2894
+ self.searchButton.setThemeIcon("search")
2895
+ self.minmaxButton.setThemeIcon("maximise")
2896
+ self.closeButton.setThemeIcon("close")
2936
2897
 
2937
2898
  buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
2938
2899
  self.tbButton.setStyleSheet(buttonStyle)
@@ -3000,18 +2961,18 @@ class GuiDocEditHeader(QWidget):
3000
2961
  @pyqtSlot(bool)
3001
2962
  def _focusModeChanged(self, focusMode: bool) -> None:
3002
2963
  """Update minimise/maximise icon of the Focus Mode button."""
3003
- self.minmaxButton.setIcon(SHARED.theme.getIcon("minimise" if focusMode else "maximise"))
2964
+ self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise")
3004
2965
  return
3005
2966
 
3006
2967
  ##
3007
2968
  # Events
3008
2969
  ##
3009
2970
 
3010
- def mousePressEvent(self, event: QMouseEvent):
2971
+ def mousePressEvent(self, event: QMouseEvent) -> None:
3011
2972
  """Capture a click on the title and ensure that the item is
3012
2973
  selected in the project tree.
3013
2974
  """
3014
- if event.button() == Qt.MouseButton.LeftButton:
2975
+ if event.button() == QtMouseLeft:
3015
2976
  self.docEditor.requestProjectItemSelected.emit(self._docHandle or "", True)
3016
2977
  return
3017
2978
 
@@ -3033,7 +2994,7 @@ class GuiDocEditFooter(QWidget):
3033
2994
  self._tItem = None
3034
2995
  self._docHandle = None
3035
2996
 
3036
- iPx = round(0.9*SHARED.theme.baseIconSize)
2997
+ iPx = round(0.9*SHARED.theme.baseIconHeight)
3037
2998
  fPx = int(0.9*SHARED.theme.fontPixelSize)
3038
2999
  mPx = CONFIG.pxInt(8)
3039
3000
  bSp = CONFIG.pxInt(4)
@@ -3051,28 +3012,26 @@ class GuiDocEditFooter(QWidget):
3051
3012
  self.setContentsMargins(0, 0, 0, 0)
3052
3013
  self.setAutoFillBackground(True)
3053
3014
 
3054
- alLeftTop = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
3055
-
3056
3015
  # Status
3057
3016
  self.statusIcon = QLabel("", self)
3058
3017
  self.statusIcon.setContentsMargins(0, 0, 0, 0)
3059
3018
  self.statusIcon.setFixedHeight(iPx)
3060
- self.statusIcon.setAlignment(alLeftTop)
3019
+ self.statusIcon.setAlignment(QtAlignLeftTop)
3061
3020
 
3062
- self.statusText = QLabel(self.tr("Status"))
3021
+ self.statusText = QLabel(self.tr("Status"), self)
3063
3022
  self.statusText.setIndent(0)
3064
3023
  self.statusText.setMargin(0)
3065
3024
  self.statusText.setContentsMargins(0, 0, 0, 0)
3066
3025
  self.statusText.setAutoFillBackground(True)
3067
3026
  self.statusText.setFixedHeight(fPx)
3068
- self.statusText.setAlignment(alLeftTop)
3027
+ self.statusText.setAlignment(QtAlignLeftTop)
3069
3028
  self.statusText.setFont(lblFont)
3070
3029
 
3071
3030
  # Lines
3072
3031
  self.linesIcon = QLabel("", self)
3073
3032
  self.linesIcon.setContentsMargins(0, 0, 0, 0)
3074
3033
  self.linesIcon.setFixedHeight(iPx)
3075
- self.linesIcon.setAlignment(alLeftTop)
3034
+ self.linesIcon.setAlignment(QtAlignLeftTop)
3076
3035
 
3077
3036
  self.linesText = QLabel("", self)
3078
3037
  self.linesText.setIndent(0)
@@ -3080,14 +3039,14 @@ class GuiDocEditFooter(QWidget):
3080
3039
  self.linesText.setContentsMargins(0, 0, 0, 0)
3081
3040
  self.linesText.setAutoFillBackground(True)
3082
3041
  self.linesText.setFixedHeight(fPx)
3083
- self.linesText.setAlignment(alLeftTop)
3042
+ self.linesText.setAlignment(QtAlignLeftTop)
3084
3043
  self.linesText.setFont(lblFont)
3085
3044
 
3086
3045
  # Words
3087
3046
  self.wordsIcon = QLabel("", self)
3088
3047
  self.wordsIcon.setContentsMargins(0, 0, 0, 0)
3089
3048
  self.wordsIcon.setFixedHeight(iPx)
3090
- self.wordsIcon.setAlignment(alLeftTop)
3049
+ self.wordsIcon.setAlignment(QtAlignLeftTop)
3091
3050
 
3092
3051
  self.wordsText = QLabel("", self)
3093
3052
  self.wordsText.setIndent(0)
@@ -3095,7 +3054,7 @@ class GuiDocEditFooter(QWidget):
3095
3054
  self.wordsText.setContentsMargins(0, 0, 0, 0)
3096
3055
  self.wordsText.setAutoFillBackground(True)
3097
3056
  self.wordsText.setFixedHeight(fPx)
3098
- self.wordsText.setAlignment(alLeftTop)
3057
+ self.wordsText.setAlignment(QtAlignLeftTop)
3099
3058
  self.wordsText.setFont(lblFont)
3100
3059
 
3101
3060
  # Assemble Layout
@@ -3134,7 +3093,7 @@ class GuiDocEditFooter(QWidget):
3134
3093
 
3135
3094
  def updateTheme(self) -> None:
3136
3095
  """Update theme elements."""
3137
- iPx = round(0.9*SHARED.theme.baseIconSize)
3096
+ iPx = round(0.9*SHARED.theme.baseIconHeight)
3138
3097
  self.linesIcon.setPixmap(SHARED.theme.getPixmap("status_lines", (iPx, iPx)))
3139
3098
  self.wordsIcon.setPixmap(SHARED.theme.getPixmap("status_stats", (iPx, iPx)))
3140
3099
  self.matchColours()
@@ -3176,7 +3135,7 @@ class GuiDocEditFooter(QWidget):
3176
3135
  sIcon = QPixmap()
3177
3136
  sText = ""
3178
3137
  else:
3179
- iPx = round(0.9*SHARED.theme.baseIconSize)
3138
+ iPx = round(0.9*SHARED.theme.baseIconHeight)
3180
3139
  status, icon = self._tItem.getImportStatus(incIcon=True)
3181
3140
  sIcon = icon.pixmap(iPx, iPx)
3182
3141
  sText = f"{status} / {self._tItem.describeMe()}"