novelWriter 2.4.3__py3-none-any.whl → 2.5b1__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 (109) hide show
  1. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/METADATA +4 -5
  2. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/RECORD +109 -101
  3. novelwriter/__init__.py +33 -39
  4. novelwriter/assets/i18n/project_en_GB.json +1 -0
  5. novelwriter/assets/icons/typicons_dark/icons.conf +2 -0
  6. novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
  7. novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
  8. novelwriter/assets/icons/typicons_light/icons.conf +2 -0
  9. novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
  10. novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
  11. novelwriter/assets/manual.pdf +0 -0
  12. novelwriter/assets/sample.zip +0 -0
  13. novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
  14. novelwriter/assets/syntax/default_dark.conf +32 -18
  15. novelwriter/assets/syntax/default_light.conf +24 -10
  16. novelwriter/assets/syntax/dracula.conf +44 -0
  17. novelwriter/assets/syntax/grey_dark.conf +5 -4
  18. novelwriter/assets/syntax/grey_light.conf +5 -4
  19. novelwriter/assets/syntax/light_owl.conf +7 -6
  20. novelwriter/assets/syntax/night_owl.conf +7 -6
  21. novelwriter/assets/syntax/snazzy.conf +42 -0
  22. novelwriter/assets/syntax/solarized_dark.conf +4 -3
  23. novelwriter/assets/syntax/solarized_light.conf +4 -3
  24. novelwriter/assets/syntax/tango.conf +27 -11
  25. novelwriter/assets/syntax/tomorrow.conf +6 -5
  26. novelwriter/assets/syntax/tomorrow_night.conf +7 -6
  27. novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
  28. novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
  29. novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
  30. novelwriter/assets/text/credits_en.htm +4 -1
  31. novelwriter/assets/themes/cyberpunk_night.conf +2 -0
  32. novelwriter/assets/themes/default_dark.conf +1 -0
  33. novelwriter/assets/themes/default_light.conf +1 -0
  34. novelwriter/assets/themes/dracula.conf +47 -0
  35. novelwriter/assets/themes/solarized_dark.conf +1 -0
  36. novelwriter/assets/themes/solarized_light.conf +1 -0
  37. novelwriter/common.py +31 -9
  38. novelwriter/config.py +118 -84
  39. novelwriter/constants.py +40 -26
  40. novelwriter/core/buildsettings.py +63 -66
  41. novelwriter/core/coretools.py +2 -22
  42. novelwriter/core/docbuild.py +51 -40
  43. novelwriter/core/document.py +3 -5
  44. novelwriter/core/index.py +115 -45
  45. novelwriter/core/item.py +8 -19
  46. novelwriter/core/options.py +2 -4
  47. novelwriter/core/project.py +23 -57
  48. novelwriter/core/projectdata.py +1 -3
  49. novelwriter/core/projectxml.py +12 -15
  50. novelwriter/core/sessions.py +3 -5
  51. novelwriter/core/spellcheck.py +4 -9
  52. novelwriter/core/status.py +211 -164
  53. novelwriter/core/storage.py +0 -8
  54. novelwriter/core/tohtml.py +94 -100
  55. novelwriter/core/tokenizer.py +199 -112
  56. novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
  57. novelwriter/core/toodt.py +212 -148
  58. novelwriter/core/toqdoc.py +403 -0
  59. novelwriter/core/tree.py +5 -7
  60. novelwriter/dialogs/about.py +3 -5
  61. novelwriter/dialogs/docmerge.py +1 -3
  62. novelwriter/dialogs/docsplit.py +1 -3
  63. novelwriter/dialogs/editlabel.py +0 -2
  64. novelwriter/dialogs/preferences.py +111 -88
  65. novelwriter/dialogs/projectsettings.py +216 -180
  66. novelwriter/dialogs/quotes.py +3 -4
  67. novelwriter/dialogs/wordlist.py +3 -9
  68. novelwriter/enum.py +31 -25
  69. novelwriter/error.py +8 -15
  70. novelwriter/extensions/circularprogress.py +5 -6
  71. novelwriter/extensions/configlayout.py +18 -18
  72. novelwriter/extensions/eventfilters.py +1 -5
  73. novelwriter/extensions/modified.py +50 -13
  74. novelwriter/extensions/novelselector.py +1 -3
  75. novelwriter/extensions/pagedsidebar.py +9 -12
  76. novelwriter/extensions/simpleprogress.py +1 -3
  77. novelwriter/extensions/statusled.py +1 -3
  78. novelwriter/extensions/switch.py +4 -6
  79. novelwriter/extensions/switchbox.py +7 -6
  80. novelwriter/extensions/versioninfo.py +3 -9
  81. novelwriter/gui/doceditor.py +98 -126
  82. novelwriter/gui/dochighlight.py +237 -183
  83. novelwriter/gui/docviewer.py +46 -94
  84. novelwriter/gui/docviewerpanel.py +3 -10
  85. novelwriter/gui/editordocument.py +1 -3
  86. novelwriter/gui/itemdetails.py +7 -11
  87. novelwriter/gui/mainmenu.py +11 -7
  88. novelwriter/gui/noveltree.py +11 -24
  89. novelwriter/gui/outline.py +11 -23
  90. novelwriter/gui/projtree.py +26 -43
  91. novelwriter/gui/search.py +1 -3
  92. novelwriter/gui/sidebar.py +2 -6
  93. novelwriter/gui/statusbar.py +6 -10
  94. novelwriter/gui/theme.py +23 -48
  95. novelwriter/guimain.py +50 -71
  96. novelwriter/shared.py +30 -15
  97. novelwriter/tools/dictionaries.py +8 -12
  98. novelwriter/tools/lipsum.py +2 -4
  99. novelwriter/tools/manusbuild.py +1 -3
  100. novelwriter/tools/manuscript.py +66 -145
  101. novelwriter/tools/manussettings.py +67 -73
  102. novelwriter/tools/noveldetails.py +6 -11
  103. novelwriter/tools/welcome.py +2 -16
  104. novelwriter/tools/writingstats.py +6 -9
  105. novelwriter/types.py +45 -3
  106. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/LICENSE.md +0 -0
  107. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/WHEEL +0 -0
  108. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/entry_points.txt +0 -0
  109. {novelWriter-2.4.3.dist-info → novelWriter-2.5b1.dist-info}/top_level.txt +0 -0
@@ -30,34 +30,31 @@ import logging
30
30
 
31
31
  from enum import Enum
32
32
  from time import time
33
- from typing import TYPE_CHECKING
34
33
 
35
- from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot
36
- from PyQt5.QtGui import (
37
- QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
38
- )
34
+ from PyQt5.QtCore import QPoint, Qt, QTimer, pyqtSignal, pyqtSlot
35
+ from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
39
36
  from PyQt5.QtWidgets import (
40
37
  QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
41
- QLabel, QMenu, QShortcut, QSizePolicy, QTreeWidget, QTreeWidgetItem,
42
- QVBoxLayout, QWidget
38
+ QLabel, QMenu, QShortcut, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
39
+ QWidget
43
40
  )
44
41
 
45
42
  from novelwriter import CONFIG, SHARED
46
43
  from novelwriter.common import minmax
47
- from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels
44
+ from novelwriter.constants import nwHeaders, nwLabels, nwUnicode, trConst
48
45
  from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
49
46
  from novelwriter.core.item import NWItem
50
47
  from novelwriter.dialogs.docmerge import GuiDocMerge
51
48
  from novelwriter.dialogs.docsplit import GuiDocSplit
52
49
  from novelwriter.dialogs.editlabel import GuiEditLabel
53
50
  from novelwriter.dialogs.projectsettings import GuiProjectSettings
54
- from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout
51
+ from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType
55
52
  from novelwriter.extensions.modified import NIconToolButton
56
53
  from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
57
- from novelwriter.types import QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtUserRole
58
-
59
- if TYPE_CHECKING: # pragma: no cover
60
- from novelwriter.guimain import GuiMain
54
+ from novelwriter.types import (
55
+ QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtSizeExpanding,
56
+ QtUserRole
57
+ )
61
58
 
62
59
  logger = logging.getLogger(__name__)
63
60
 
@@ -80,10 +77,8 @@ class GuiProjectView(QWidget):
80
77
  # Requests for the main GUI
81
78
  projectSettingsRequest = pyqtSignal(int)
82
79
 
83
- def __init__(self, mainGui: GuiMain) -> None:
84
- super().__init__(parent=mainGui)
85
-
86
- self.mainGui = mainGui
80
+ def __init__(self, parent: QWidget) -> None:
81
+ super().__init__(parent=parent)
87
82
 
88
83
  # Build GUI
89
84
  self.projTree = GuiProjectTree(self)
@@ -248,8 +243,6 @@ class GuiProjectView(QWidget):
248
243
  self.projTree.createNewNote(tag, itemClass)
249
244
  return
250
245
 
251
- # END Class GuiProjectView
252
-
253
246
 
254
247
  class GuiProjectToolBar(QWidget):
255
248
 
@@ -262,7 +255,6 @@ class GuiProjectToolBar(QWidget):
262
255
 
263
256
  self.projView = projView
264
257
  self.projTree = projView.projTree
265
- self.mainGui = projView.mainGui
266
258
 
267
259
  iSz = SHARED.theme.baseIconSize
268
260
  mPx = CONFIG.pxInt(2)
@@ -274,7 +266,7 @@ class GuiProjectToolBar(QWidget):
274
266
  self.viewLabel = QLabel(self.tr("Project Content"), self)
275
267
  self.viewLabel.setFont(SHARED.theme.guiFontB)
276
268
  self.viewLabel.setContentsMargins(0, 0, 0, 0)
277
- self.viewLabel.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
269
+ self.viewLabel.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
278
270
 
279
271
  # Quick Links
280
272
  self.mQuick = QMenu(self)
@@ -476,8 +468,6 @@ class GuiProjectToolBar(QWidget):
476
468
 
477
469
  return
478
470
 
479
- # END Class GuiProjectToolBar
480
-
481
471
 
482
472
  class GuiProjectTree(QTreeWidget):
483
473
 
@@ -498,7 +488,6 @@ class GuiProjectTree(QTreeWidget):
498
488
  logger.debug("Create: GuiProjectTree")
499
489
 
500
490
  self.projView = projView
501
- self.mainGui = projView.mainGui
502
491
 
503
492
  # Internal Variables
504
493
  self._treeMap: dict[str, QTreeWidgetItem] = {}
@@ -1009,8 +998,7 @@ class GuiProjectTree(QTreeWidget):
1009
998
  trItemP.takeChild(tIndex)
1010
999
 
1011
1000
  for dHandle in reversed(self.getTreeFromHandle(tHandle)):
1012
- if self.mainGui.docEditor.docHandle == dHandle:
1013
- self.mainGui.closeDocument()
1001
+ SHARED.closeDocument(dHandle)
1014
1002
  SHARED.project.removeItem(dHandle)
1015
1003
  self._treeMap.pop(dHandle, None)
1016
1004
 
@@ -1033,7 +1021,7 @@ class GuiProjectTree(QTreeWidget):
1033
1021
  if trItem is None or nwItem is None:
1034
1022
  return
1035
1023
 
1036
- itemStatus, statusIcon = nwItem.getImportStatus(incIcon=True)
1024
+ itemStatus, statusIcon = nwItem.getImportStatus()
1037
1025
  hLevel = nwItem.mainHeading
1038
1026
  itemIcon = SHARED.theme.getItemIcon(
1039
1027
  nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
@@ -1409,7 +1397,7 @@ class GuiProjectTree(QTreeWidget):
1409
1397
  if not newFile:
1410
1398
  itemList.remove(tHandle)
1411
1399
 
1412
- dlgMerge = GuiDocMerge(self.mainGui, tHandle, itemList)
1400
+ dlgMerge = GuiDocMerge(SHARED.mainGui, tHandle, itemList)
1413
1401
  dlgMerge.exec()
1414
1402
 
1415
1403
  if dlgMerge.result() == QDialog.DialogCode.Accepted:
@@ -1421,7 +1409,7 @@ class GuiProjectTree(QTreeWidget):
1421
1409
  return False
1422
1410
 
1423
1411
  # Save the open document first, in case it's part of merge
1424
- self.mainGui.saveDocument()
1412
+ SHARED.saveDocument()
1425
1413
 
1426
1414
  # Create merge object, and append docs
1427
1415
  docMerger = DocMerger(SHARED.project)
@@ -1450,7 +1438,8 @@ class GuiProjectTree(QTreeWidget):
1450
1438
  if newFile:
1451
1439
  self.revealNewTreeItem(mHandle, nHandle=tHandle, wordCount=True)
1452
1440
 
1453
- self.mainGui.openDocument(mHandle, doScroll=True)
1441
+ self.projView.openDocumentRequest.emit(mHandle, nwDocMode.EDIT, "", False)
1442
+ self.projView.setSelectedHandle(mHandle, doScroll=True)
1454
1443
 
1455
1444
  if mrgData.get("moveToTrash", False):
1456
1445
  for sHandle in reversed(mrgData.get("finalItems", [])):
@@ -1479,7 +1468,7 @@ class GuiProjectTree(QTreeWidget):
1479
1468
  logger.error("Only valid document items can be split")
1480
1469
  return False
1481
1470
 
1482
- dlgSplit = GuiDocSplit(self.mainGui, tHandle)
1471
+ dlgSplit = GuiDocSplit(SHARED.mainGui, tHandle)
1483
1472
  dlgSplit.exec()
1484
1473
 
1485
1474
  if dlgSplit.result() == QDialog.DialogCode.Accepted:
@@ -1658,8 +1647,6 @@ class GuiProjectTree(QTreeWidget):
1658
1647
 
1659
1648
  return
1660
1649
 
1661
- # END Class GuiProjectTree
1662
-
1663
1650
 
1664
1651
  class _UpdatableMenu(QMenu):
1665
1652
 
@@ -1723,8 +1710,6 @@ class _UpdatableMenu(QMenu):
1723
1710
  self.menuItemTriggered.emit(str(action.data()))
1724
1711
  return
1725
1712
 
1726
- # END Class _UpdatableMenu
1727
-
1728
1713
 
1729
1714
  class _TreeContextMenu(QMenu):
1730
1715
 
@@ -1855,11 +1840,11 @@ class _TreeContextMenu(QMenu):
1855
1840
  if self._item.isNovelLike():
1856
1841
  menu = self.addMenu(self.tr("Set Status to ..."))
1857
1842
  current = self._item.itemStatus
1858
- for n, (key, entry) in enumerate(SHARED.project.data.itemStatus.items()):
1859
- name = entry["name"]
1843
+ for n, (key, entry) in enumerate(SHARED.project.data.itemStatus.iterItems()):
1844
+ name = entry.name
1860
1845
  if not multi and current == key:
1861
1846
  name += f" ({nwUnicode.U_CHECK})"
1862
- action = menu.addAction(entry["icon"], name)
1847
+ action = menu.addAction(entry.icon, name)
1863
1848
  if multi:
1864
1849
  action.triggered.connect(lambda n, key=key: self._iterSetItemStatus(key))
1865
1850
  else:
@@ -1872,11 +1857,11 @@ class _TreeContextMenu(QMenu):
1872
1857
  else:
1873
1858
  menu = self.addMenu(self.tr("Set Importance to ..."))
1874
1859
  current = self._item.itemImport
1875
- for n, (key, entry) in enumerate(SHARED.project.data.itemImport.items()):
1876
- name = entry["name"]
1860
+ for n, (key, entry) in enumerate(SHARED.project.data.itemImport.iterItems()):
1861
+ name = entry.name
1877
1862
  if not multi and current == key:
1878
1863
  name += f" ({nwUnicode.U_CHECK})"
1879
- action = menu.addAction(entry["icon"], name)
1864
+ action = menu.addAction(entry.icon, name)
1880
1865
  if multi:
1881
1866
  action.triggered.connect(lambda n, key=key: self._iterSetItemImport(key))
1882
1867
  else:
@@ -2076,5 +2061,3 @@ class _TreeContextMenu(QMenu):
2076
2061
  else:
2077
2062
  logger.info("Folder conversion cancelled")
2078
2063
  return
2079
-
2080
- # END Class _TreeContextMenu
novelwriter/gui/search.py CHANGED
@@ -259,7 +259,7 @@ class GuiProjectSearch(QWidget):
259
259
  if not self._blocked:
260
260
  QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
261
261
  start = time()
262
- SHARED.mainGui.saveDocument()
262
+ SHARED.saveDocument()
263
263
  self._blocked = True
264
264
  self._map = {}
265
265
  self.searchResult.clear()
@@ -358,5 +358,3 @@ class GuiProjectSearch(QWidget):
358
358
  QApplication.processEvents()
359
359
 
360
360
  return
361
-
362
- # END Class GuiProjectSearch
@@ -27,8 +27,8 @@ import logging
27
27
 
28
28
  from typing import TYPE_CHECKING
29
29
 
30
- from PyQt5.QtGui import QPalette
31
30
  from PyQt5.QtCore import QEvent, QPoint, QSize, pyqtSignal
31
+ from PyQt5.QtGui import QPalette
32
32
  from PyQt5.QtWidgets import QMenu, QVBoxLayout, QWidget
33
33
 
34
34
  from novelwriter import CONFIG, SHARED
@@ -58,7 +58,7 @@ class GuiSideBar(QWidget):
58
58
  iSz = QSize(iPx, iPx)
59
59
 
60
60
  self.setContentsMargins(0, 0, 0, 0)
61
- self.installEventFilter(StatusTipFilter(mainGui))
61
+ self.installEventFilter(StatusTipFilter(self.mainGui))
62
62
 
63
63
  # Buttons
64
64
  self.tbProject = NIconToolButton(self, iSz)
@@ -150,8 +150,6 @@ class GuiSideBar(QWidget):
150
150
 
151
151
  return
152
152
 
153
- # END Class GuiSideBar
154
-
155
153
 
156
154
  class _PopRightMenu(QMenu):
157
155
 
@@ -162,5 +160,3 @@ class _PopRightMenu(QMenu):
162
160
  offset = QPoint(parent.width(), parent.height() - self.height())
163
161
  self.move(parent.mapToGlobal(offset))
164
162
  return super(_PopRightMenu, self).event(event)
165
-
166
- # END Class _PopRightMenu
@@ -27,26 +27,23 @@ import logging
27
27
 
28
28
  from datetime import datetime
29
29
  from time import time
30
- from typing import TYPE_CHECKING, Literal
30
+ from typing import Literal
31
31
 
32
- from PyQt5.QtCore import pyqtSlot, QLocale
33
- from PyQt5.QtWidgets import QApplication, QStatusBar, QLabel
32
+ from PyQt5.QtCore import QLocale, pyqtSlot
33
+ from PyQt5.QtWidgets import QApplication, QLabel, QStatusBar, QWidget
34
34
 
35
35
  from novelwriter import CONFIG, SHARED
36
36
  from novelwriter.common import formatTime
37
37
  from novelwriter.constants import nwConst
38
38
  from novelwriter.extensions.statusled import StatusLED
39
39
 
40
- if TYPE_CHECKING: # pragma: no cover
41
- from novelwriter.guimain import GuiMain
42
-
43
40
  logger = logging.getLogger(__name__)
44
41
 
45
42
 
46
43
  class GuiMainStatus(QStatusBar):
47
44
 
48
- def __init__(self, mainGui: GuiMain) -> None:
49
- super().__init__(parent=mainGui)
45
+ def __init__(self, parent: QWidget) -> None:
46
+ super().__init__(parent=parent)
50
47
 
51
48
  logger.debug("Create: GuiMainStatus")
52
49
 
@@ -238,6 +235,7 @@ class GuiMainStatus(QStatusBar):
238
235
  before starting novelWriter.
239
236
  """
240
237
  import tracemalloc
238
+
241
239
  from collections import Counter
242
240
 
243
241
  widgets = QApplication.allWidgets()
@@ -264,5 +262,3 @@ class GuiMainStatus(QStatusBar):
264
262
  f" \u2013 Peak: {mem[1]:n}"
265
263
  ), 6000)
266
264
  return
267
-
268
- # END Class GuiMainStatus
novelwriter/gui/theme.py CHANGED
@@ -46,12 +46,11 @@ STYLES_MIN_TOOLBUTTON = "minimalToolButton"
46
46
  STYLES_BIG_TOOLBUTTON = "bigToolButton"
47
47
 
48
48
 
49
- # =============================================================================================== #
50
- # Gui Theme Class
51
- # Handles the look and feel of novelWriter
52
- # =============================================================================================== #
53
-
54
49
  class GuiTheme:
50
+ """Gui Theme Class
51
+
52
+ Handles the look and feel of novelWriter.
53
+ """
55
54
 
56
55
  def __init__(self) -> None:
57
56
 
@@ -76,6 +75,7 @@ class GuiTheme:
76
75
  self.statUnsaved = QColor(0, 0, 0)
77
76
  self.statSaved = QColor(0, 0, 0)
78
77
  self.helpText = QColor(0, 0, 0)
78
+ self.errorText = QColor(255, 0, 0)
79
79
 
80
80
  # Loaded Syntax Settings
81
81
  # ======================
@@ -97,11 +97,12 @@ class GuiTheme:
97
97
  self.colHeadH = QColor(0, 0, 0)
98
98
  self.colEmph = QColor(0, 0, 0)
99
99
  self.colDialN = QColor(0, 0, 0)
100
- self.colDialD = QColor(0, 0, 0)
101
- self.colDialS = QColor(0, 0, 0)
100
+ self.colDialA = QColor(0, 0, 0)
102
101
  self.colHidden = QColor(0, 0, 0)
102
+ self.colNote = QColor(0, 0, 0)
103
103
  self.colCode = QColor(0, 0, 0)
104
104
  self.colKey = QColor(0, 0, 0)
105
+ self.colTag = QColor(0, 0, 0)
105
106
  self.colVal = QColor(0, 0, 0)
106
107
  self.colOpt = QColor(0, 0, 0)
107
108
  self.colSpell = QColor(0, 0, 0)
@@ -113,9 +114,6 @@ class GuiTheme:
113
114
  # Class Setup
114
115
  # ===========
115
116
 
116
- # Init GUI Font
117
- self._setGuiFont()
118
-
119
117
  # Load Themes
120
118
  self._guiPalette = QPalette()
121
119
  self._themeList: list[tuple[str, str]] = []
@@ -265,6 +263,7 @@ class GuiTheme:
265
263
  sec = "GUI"
266
264
  if parser.has_section(sec):
267
265
  self.helpText = self._parseColour(parser, sec, "helptext")
266
+ self.errorText = self._parseColour(parser, sec, "errortext")
268
267
  self.statNone = self._parseColour(parser, sec, "statusnone")
269
268
  self.statUnsaved = self._parseColour(parser, sec, "statusunsaved")
270
269
  self.statSaved = self._parseColour(parser, sec, "statussaved")
@@ -282,6 +281,10 @@ class GuiTheme:
282
281
  else:
283
282
  helpLCol = backLNess + 0.65*(textLNess - backLNess)
284
283
  self.helpText = QColor.fromHsl(0, 0, int(255*helpLCol))
284
+ logger.debug(
285
+ "Computed help text colour: rgb(%d, %d, %d)",
286
+ self.helpText.red(), self.helpText.green(), self.helpText.blue()
287
+ )
285
288
 
286
289
  # Icons
287
290
  defaultIcons = "typicons_light" if backLNess >= 0.5 else "typicons_dark"
@@ -339,12 +342,13 @@ class GuiTheme:
339
342
  self.colHead = self._parseColour(confParser, cnfSec, "headertext")
340
343
  self.colHeadH = self._parseColour(confParser, cnfSec, "headertag")
341
344
  self.colEmph = self._parseColour(confParser, cnfSec, "emphasis")
342
- self.colDialN = self._parseColour(confParser, cnfSec, "straightquotes")
343
- self.colDialD = self._parseColour(confParser, cnfSec, "doublequotes")
344
- self.colDialS = self._parseColour(confParser, cnfSec, "singlequotes")
345
+ self.colDialN = self._parseColour(confParser, cnfSec, "dialog")
346
+ self.colDialA = self._parseColour(confParser, cnfSec, "altdialog")
345
347
  self.colHidden = self._parseColour(confParser, cnfSec, "hidden")
348
+ self.colNote = self._parseColour(confParser, cnfSec, "note")
346
349
  self.colCode = self._parseColour(confParser, cnfSec, "shortcode")
347
350
  self.colKey = self._parseColour(confParser, cnfSec, "keyword")
351
+ self.colTag = self._parseColour(confParser, cnfSec, "tag")
348
352
  self.colVal = self._parseColour(confParser, cnfSec, "value")
349
353
  self.colOpt = self._parseColour(confParser, cnfSec, "optional")
350
354
  self.colSpell = self._parseColour(confParser, cnfSec, "spellcheckline")
@@ -401,27 +405,7 @@ class GuiTheme:
401
405
  self.statUnsaved = QColor(200, 15, 39)
402
406
  self.statSaved = QColor(2, 133, 37)
403
407
  self.helpText = QColor(0, 0, 0)
404
- return
405
-
406
- def _setGuiFont(self) -> None:
407
- """Update the GUI's font style from settings."""
408
- font = QFont()
409
- fontDB = QFontDatabase()
410
- if CONFIG.guiFont not in fontDB.families():
411
- if CONFIG.osWindows and "Arial" in fontDB.families():
412
- # On Windows we default to Arial if possible
413
- font.setFamily("Arial")
414
- font.setPointSize(10)
415
- else:
416
- font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
417
- CONFIG.guiFont = font.family()
418
- CONFIG.guiFontSize = font.pointSize()
419
- else:
420
- font.setFamily(CONFIG.guiFont)
421
- font.setPointSize(CONFIG.guiFontSize)
422
-
423
- QApplication.setFont(font)
424
-
408
+ self.errorText = QColor(255, 0, 0)
425
409
  return
426
410
 
427
411
  def _listConf(self, targetDict: dict, checkDir: Path) -> bool:
@@ -480,12 +464,6 @@ class GuiTheme:
480
464
 
481
465
  return
482
466
 
483
- # End Class GuiTheme
484
-
485
-
486
- # =============================================================================================== #
487
- # Icons Class
488
- # =============================================================================================== #
489
467
 
490
468
  class GuiIcons:
491
469
  """The icon class manages the content of the assets/icons folder,
@@ -523,9 +501,9 @@ class GuiIcons:
523
501
 
524
502
  # General Button Icons
525
503
  "add", "add_document", "backward", "bookmark", "browse", "checked", "close", "cross",
526
- "document", "down", "edit", "export", "forward", "import", "list", "maximise", "menu",
527
- "minimise", "more", "noncheckable", "open", "panel", "refresh", "remove", "revert",
528
- "search_replace", "search", "settings", "star", "unchecked", "up", "view",
504
+ "document", "down", "edit", "export", "font", "forward", "import", "list", "maximise",
505
+ "menu", "minimise", "more", "noncheckable", "open", "panel", "quote", "refresh", "remove",
506
+ "revert", "search_replace", "search", "settings", "star", "unchecked", "up", "view",
529
507
 
530
508
  # Switches
531
509
  "sticky-on", "sticky-off",
@@ -793,12 +771,9 @@ class GuiIcons:
793
771
 
794
772
  return self._noIcon
795
773
 
796
- # END Class GuiIcons
797
-
798
774
 
799
- # =============================================================================================== #
800
- # Module Functions
801
- # =============================================================================================== #
775
+ # Module Functions
776
+ # ================
802
777
 
803
778
 
804
779
  def _sortTheme(data: tuple[str, str]) -> str: