novelWriter 2.4.2__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.2.dist-info → novelWriter-2.5b1.dist-info}/METADATA +4 -5
  2. {novelWriter-2.4.2.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 +132 -133
  82. novelwriter/gui/dochighlight.py +237 -183
  83. novelwriter/gui/docviewer.py +61 -97
  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 +26 -51
  95. novelwriter/guimain.py +50 -71
  96. novelwriter/shared.py +30 -15
  97. novelwriter/tools/dictionaries.py +12 -15
  98. novelwriter/tools/lipsum.py +2 -4
  99. novelwriter/tools/manusbuild.py +1 -3
  100. novelwriter/tools/manuscript.py +71 -144
  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.2.dist-info → novelWriter-2.5b1.dist-info}/LICENSE.md +0 -0
  107. {novelWriter-2.4.2.dist-info → novelWriter-2.5b1.dist-info}/WHEEL +0 -0
  108. {novelWriter-2.4.2.dist-info → novelWriter-2.5b1.dist-info}/entry_points.txt +0 -0
  109. {novelWriter-2.4.2.dist-info → novelWriter-2.5b1.dist-info}/top_level.txt +0 -0
@@ -25,14 +25,13 @@ from __future__ import annotations
25
25
 
26
26
  import logging
27
27
 
28
- from typing import TYPE_CHECKING
29
28
  from pathlib import Path
30
29
 
31
30
  from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
32
31
  from PyQt5.QtGui import QCloseEvent
33
32
  from PyQt5.QtWidgets import (
34
33
  QAbstractItemView, QApplication, QDialog, QDialogButtonBox, QFileDialog,
35
- QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout
34
+ QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout, QWidget
36
35
  )
37
36
 
38
37
  from novelwriter import CONFIG, SHARED
@@ -42,9 +41,6 @@ from novelwriter.extensions.configlayout import NColourLabel
42
41
  from novelwriter.extensions.modified import NIconToolButton
43
42
  from novelwriter.types import QtDialogClose, QtDialogSave
44
43
 
45
- if TYPE_CHECKING: # pragma: no cover
46
- from novelwriter.guimain import GuiMain
47
-
48
44
  logger = logging.getLogger(__name__)
49
45
 
50
46
 
@@ -52,8 +48,8 @@ class GuiWordList(QDialog):
52
48
 
53
49
  newWordListReady = pyqtSignal()
54
50
 
55
- def __init__(self, mainGui: GuiMain) -> None:
56
- super().__init__(parent=mainGui)
51
+ def __init__(self, parent: QWidget) -> None:
52
+ super().__init__(parent=parent)
57
53
 
58
54
  logger.debug("Create: GuiWordList")
59
55
  self.setObjectName("GuiWordList")
@@ -257,5 +253,3 @@ class GuiWordList(QDialog):
257
253
  if (item := self.listBox.item(i)) and (word := item.text().strip()):
258
254
  result.append(word)
259
255
  return result
260
-
261
- # END Class GuiWordList
novelwriter/enum.py CHANGED
@@ -32,8 +32,6 @@ class nwItemType(Enum):
32
32
  FOLDER = 2
33
33
  FILE = 3
34
34
 
35
- # END Enum nwItemType
36
-
37
35
 
38
36
  class nwItemClass(Enum):
39
37
 
@@ -50,8 +48,6 @@ class nwItemClass(Enum):
50
48
  TEMPLATE = 10
51
49
  TRASH = 11
52
50
 
53
- # END Enum nwItemClass
54
-
55
51
 
56
52
  class nwItemLayout(Enum):
57
53
 
@@ -59,16 +55,17 @@ class nwItemLayout(Enum):
59
55
  DOCUMENT = 1
60
56
  NOTE = 2
61
57
 
62
- # END Enum nwItemLayout
63
-
64
58
 
65
59
  class nwComment(Enum):
66
60
 
67
61
  PLAIN = 0
68
- SYNOPSIS = 1
69
- SHORT = 2
70
-
71
- # END Enum nwComment
62
+ IGNORE = 1
63
+ SYNOPSIS = 2
64
+ SHORT = 3
65
+ NOTE = 4
66
+ FOOTNOTE = 5
67
+ COMMENT = 6
68
+ STORY = 7
72
69
 
73
70
 
74
71
  class nwTrinary(Enum):
@@ -77,16 +74,12 @@ class nwTrinary(Enum):
77
74
  NEUTRAL = 0
78
75
  POSITIVE = 1
79
76
 
80
- # END Enum nwTrinary
81
-
82
77
 
83
78
  class nwDocMode(Enum):
84
79
 
85
80
  VIEW = 0
86
81
  EDIT = 1
87
82
 
88
- # END Enum nwDocMode
89
-
90
83
 
91
84
  class nwDocAction(Enum):
92
85
 
@@ -129,8 +122,6 @@ class nwDocAction(Enum):
129
122
  SC_SUP = 36
130
123
  SC_SUB = 37
131
124
 
132
- # END Enum nwDocAction
133
-
134
125
 
135
126
  class nwDocInsert(Enum):
136
127
 
@@ -145,8 +136,7 @@ class nwDocInsert(Enum):
145
136
  VSPACE_S = 8
146
137
  VSPACE_M = 9
147
138
  LIPSUM = 10
148
-
149
- # END Enum nwDocInsert
139
+ FOOTNOTE = 11
150
140
 
151
141
 
152
142
  class nwView(Enum):
@@ -157,8 +147,6 @@ class nwView(Enum):
157
147
  OUTLINE = 3
158
148
  SEARCH = 4
159
149
 
160
- # END Enum nwView
161
-
162
150
 
163
151
  class nwWidget(Enum):
164
152
 
@@ -167,8 +155,6 @@ class nwWidget(Enum):
167
155
  VIEWER = 3
168
156
  OUTLINE = 4
169
157
 
170
- # END Enum nwWidget
171
-
172
158
 
173
159
  class nwOutline(Enum):
174
160
 
@@ -190,8 +176,6 @@ class nwOutline(Enum):
190
176
  CUSTOM = 15
191
177
  SYNOP = 16
192
178
 
193
- # END Enum nwOutline
194
-
195
179
 
196
180
  class nwBuildFmt(Enum):
197
181
 
@@ -204,4 +188,26 @@ class nwBuildFmt(Enum):
204
188
  J_HTML = 6
205
189
  J_NWD = 7
206
190
 
207
- # END Enum nwBuildFormat
191
+
192
+ class nwStatusShape(Enum):
193
+
194
+ SQUARE = 0
195
+ TRIANGLE = 1
196
+ NABLA = 2
197
+ DIAMOND = 3
198
+ PENTAGON = 4
199
+ HEXAGON = 5
200
+ STAR = 6
201
+ PACMAN = 7
202
+ CIRCLE_Q = 8
203
+ CIRCLE_H = 9
204
+ CIRCLE_T = 10
205
+ CIRCLE = 11
206
+ BARS_1 = 12
207
+ BARS_2 = 13
208
+ BARS_3 = 14
209
+ BARS_4 = 15
210
+ BLOCK_1 = 16
211
+ BLOCK_2 = 17
212
+ BLOCK_3 = 18
213
+ BLOCK_4 = 19
novelwriter/error.py CHANGED
@@ -23,17 +23,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- import sys
27
- import random
28
26
  import logging
27
+ import random
28
+ import sys
29
29
 
30
30
  from typing import TYPE_CHECKING
31
31
 
32
32
  from PyQt5.QtCore import Qt, pyqtSlot
33
33
  from PyQt5.QtGui import QFont, QFontDatabase
34
34
  from PyQt5.QtWidgets import (
35
- QApplication, QWidget, QDialog, QGridLayout, QStyle, QPlainTextEdit,
36
- QLabel, QDialogButtonBox
35
+ QApplication, QDialog, QDialogButtonBox, QGridLayout, QLabel,
36
+ QPlainTextEdit, QStyle, QWidget
37
37
  )
38
38
 
39
39
  if TYPE_CHECKING: # pragma: no cover
@@ -42,10 +42,6 @@ if TYPE_CHECKING: # pragma: no cover
42
42
  logger = logging.getLogger(__name__)
43
43
 
44
44
 
45
- # =============================================================================================== #
46
- # Utility Functions
47
- # =============================================================================================== #
48
-
49
45
  def logException() -> None:
50
46
  """Log the content of an exception message."""
51
47
  exType, exValue, _ = sys.exc_info()
@@ -61,10 +57,6 @@ def formatException(exc: BaseException) -> str:
61
57
  return f"{type(exc).__name__}: {str(exc)}"
62
58
 
63
59
 
64
- # =============================================================================================== #
65
- # Error Handler
66
- # =============================================================================================== #
67
-
68
60
  class NWErrorMessage(QDialog):
69
61
 
70
62
  def __init__(self, parent: QWidget) -> None:
@@ -125,9 +117,11 @@ class NWErrorMessage(QDialog):
125
117
  error traceback.
126
118
  """
127
119
  from traceback import format_tb
120
+
121
+ from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, QSysInfo
122
+
128
123
  from novelwriter import __version__
129
124
  from novelwriter.constants import nwConst
130
- from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QSysInfo
131
125
 
132
126
  self.msgHead.setText(
133
127
  "<p>An unhandled error has been encountered.</p>"
@@ -175,12 +169,11 @@ class NWErrorMessage(QDialog):
175
169
  self.close()
176
170
  return
177
171
 
178
- # END Class NWErrorMessage
179
-
180
172
 
181
173
  def exceptionHandler(exType: type, exValue: BaseException, exTrace: TracebackType) -> None:
182
174
  """Function to catch unhandled global exceptions."""
183
175
  from traceback import print_tb
176
+
184
177
  from PyQt5.QtWidgets import QApplication
185
178
 
186
179
  logger.critical("%s: %s", exType.__name__, str(exValue))
@@ -26,11 +26,12 @@ from __future__ import annotations
26
26
  from math import ceil
27
27
 
28
28
  from PyQt5.QtCore import QRect
29
- from PyQt5.QtGui import QBrush, QColor, QPaintEvent, QPainter, QPen
30
- from PyQt5.QtWidgets import QProgressBar, QSizePolicy, QWidget
29
+ from PyQt5.QtGui import QBrush, QColor, QPainter, QPaintEvent, QPen
30
+ from PyQt5.QtWidgets import QProgressBar, QWidget
31
31
 
32
32
  from novelwriter.types import (
33
- QtPaintAnitAlias, QtAlignCenter, QtRoundCap, QtSolidLine, QtTransparent
33
+ QtAlignCenter, QtPaintAnitAlias, QtRoundCap, QtSizeFixed, QtSolidLine,
34
+ QtTransparent
34
35
  )
35
36
 
36
37
 
@@ -59,7 +60,7 @@ class NProgressCircle(QProgressBar):
59
60
  bar=self.palette().highlight().color(),
60
61
  text=self.palette().text().color()
61
62
  )
62
- self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
63
+ self.setSizePolicy(QtSizeFixed, QtSizeFixed)
63
64
  self.setFixedWidth(size)
64
65
  self.setFixedHeight(size)
65
66
  return
@@ -100,5 +101,3 @@ class NProgressCircle(QProgressBar):
100
101
  painter.setPen(self._tColor)
101
102
  painter.drawText(self._cRect, QtAlignCenter, self._text or f"{progress:.1f} %")
102
103
  return
103
-
104
- # END Class NProgressCircle
@@ -27,8 +27,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
27
27
  """
28
28
  from __future__ import annotations
29
29
 
30
- from PyQt5.QtGui import QColor, QFont, QPalette
31
30
  from PyQt5.QtCore import Qt
31
+ from PyQt5.QtGui import QColor, QFont, QPalette
32
32
  from PyQt5.QtWidgets import (
33
33
  QAbstractButton, QFrame, QHBoxLayout, QLabel, QLayout, QScrollArea,
34
34
  QVBoxLayout, QWidget
@@ -64,8 +64,6 @@ class NFixedPage(QFrame):
64
64
  self.setLayout(layout)
65
65
  return
66
66
 
67
- # END Class NFixedPage
68
-
69
67
 
70
68
  class NScrollablePage(QScrollArea):
71
69
  """Extension: Scrollable Page Widget
@@ -89,8 +87,6 @@ class NScrollablePage(QScrollArea):
89
87
  self._widget.setLayout(layout)
90
88
  return
91
89
 
92
- # END Class NScrollablePage
93
-
94
90
 
95
91
  class NScrollableForm(QScrollArea):
96
92
  """Extension: Scrollable Form Widget
@@ -184,16 +180,26 @@ class NScrollableForm(QScrollArea):
184
180
  self._sections[identifier] = qLabel
185
181
  return
186
182
 
187
- def addRow(self, label: str, widget: QWidget, helpText: str = "", unit: str | None = None,
188
- button: QWidget | None = None, editable: str | None = None,
183
+ def addRow(self, label: str, widget: QWidget | list[QWidget], helpText: str = "",
184
+ unit: str | None = None, button: QWidget | None = None, editable: str | None = None,
189
185
  stretch: tuple[int, int] = (1, 0)) -> None:
190
186
  """Add a label and a widget as a new row of the form."""
191
187
  row = QHBoxLayout()
192
188
  row.setSpacing(CONFIG.pxInt(12))
193
189
 
190
+ if isinstance(widget, list):
191
+ wBox = QHBoxLayout()
192
+ wBox.setContentsMargins(0, 0, 0, 0)
193
+ for item in widget:
194
+ wBox.addWidget(item)
195
+ qWidget = QWidget(self)
196
+ qWidget.setLayout(wBox)
197
+ else:
198
+ qWidget = widget
199
+
194
200
  qLabel = QLabel(label, self)
195
201
  qLabel.setIndent(self._indent)
196
- qLabel.setBuddy(widget)
202
+ qLabel.setBuddy(qWidget)
197
203
 
198
204
  if helpText:
199
205
  qHelp = NColourLabel(
@@ -212,19 +218,19 @@ class NScrollableForm(QScrollArea):
212
218
 
213
219
  if isinstance(unit, str):
214
220
  box = QHBoxLayout()
215
- box.addWidget(widget, 1)
221
+ box.addWidget(qWidget, 1)
216
222
  box.addWidget(QLabel(unit, self), 0)
217
223
  row.addLayout(box, stretch[1])
218
224
  elif isinstance(button, QAbstractButton):
219
225
  box = QHBoxLayout()
220
- box.addWidget(widget, 1)
226
+ box.addWidget(qWidget, 1)
221
227
  box.addWidget(button, 0)
222
228
  row.addLayout(box, stretch[1])
223
229
  else:
224
- row.addWidget(widget, stretch[1])
230
+ row.addWidget(qWidget, stretch[1])
225
231
 
226
232
  self._layout.addLayout(row)
227
- self._index[label.strip()] = widget
233
+ self._index[label.strip()] = qWidget
228
234
  self._first = False
229
235
 
230
236
  return
@@ -235,8 +241,6 @@ class NScrollableForm(QScrollArea):
235
241
  self._layout.addStretch(1)
236
242
  return
237
243
 
238
- # END Class NScrollableForm
239
-
240
244
 
241
245
  class NColourLabel(QLabel):
242
246
  """Extension: A Coloured Label
@@ -267,8 +271,6 @@ class NColourLabel(QLabel):
267
271
 
268
272
  return
269
273
 
270
- # END Class NColourLabel
271
-
272
274
 
273
275
  class NWrappedWidgetBox(QHBoxLayout):
274
276
  """Extension: A Text-Wrapped Widget Box
@@ -287,5 +289,3 @@ class NWrappedWidgetBox(QHBoxLayout):
287
289
  if after:
288
290
  self.addWidget(QLabel(after.lstrip()))
289
291
  return
290
-
291
- # END Class NWrappedWidgetBox
@@ -24,8 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
24
24
  """
25
25
  from __future__ import annotations
26
26
 
27
- from PyQt5.QtGui import QStatusTipEvent, QWheelEvent
28
27
  from PyQt5.QtCore import QEvent, QObject
28
+ from PyQt5.QtGui import QStatusTipEvent, QWheelEvent
29
29
  from PyQt5.QtWidgets import QWidget
30
30
 
31
31
 
@@ -63,13 +63,9 @@ class WheelEventFilter(QObject):
63
63
  self._locked = False
64
64
  return False
65
65
 
66
- # END Class WheelEventFilter
67
-
68
66
 
69
67
  class StatusTipFilter(QObject):
70
68
 
71
69
  def eventFilter(self, obj: QObject, event: QEvent) -> bool:
72
70
  """Filter out status tip events on menus."""
73
71
  return True if isinstance(event, QStatusTipEvent) else super().eventFilter(obj, event)
74
-
75
- # END Class StatusTipFilter
@@ -6,6 +6,8 @@ File History:
6
6
  Created: 2024-02-01 [2.3b1] NComboBox
7
7
  Created: 2024-02-01 [2.3b1] NSpinBox
8
8
  Created: 2024-02-01 [2.3b1] NDoubleSpinBox
9
+ Created: 2024-05-01 [2.5b1] NToolDialog
10
+ Created: 2024-05-01 [2.5b1] NNonBlockingDialog
9
11
 
10
12
  This file is a part of novelWriter
11
13
  Copyright 2018–2024, Veronica Berglyd Olsen
@@ -25,11 +27,56 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
25
27
  """
26
28
  from __future__ import annotations
27
29
 
30
+ from enum import Enum
31
+ from typing import TYPE_CHECKING
32
+
28
33
  from PyQt5.QtCore import QSize, Qt
29
34
  from PyQt5.QtGui import QWheelEvent
30
- from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget
35
+ from PyQt5.QtWidgets import (
36
+ QApplication, QComboBox, QDialog, QDoubleSpinBox, QSpinBox, QToolButton,
37
+ QWidget
38
+ )
39
+
40
+ from novelwriter import CONFIG, SHARED
41
+
42
+ if TYPE_CHECKING: # pragma: no cover
43
+ from novelwriter.guimain import GuiMain
44
+
45
+
46
+ class NToolDialog(QDialog):
47
+
48
+ def __init__(self, parent: GuiMain) -> None:
49
+ super().__init__(parent=parent)
50
+ self.setModal(False)
51
+ if CONFIG.osDarwin:
52
+ self.setWindowFlag(Qt.WindowType.Tool)
53
+ return
54
+
55
+ def activateDialog(self) -> None:
56
+ """Helper function to activate dialog on various systems."""
57
+ self.show()
58
+ if CONFIG.osWindows:
59
+ self.activateWindow()
60
+ self.raise_()
61
+ QApplication.processEvents()
62
+ return
63
+
31
64
 
32
- from novelwriter import SHARED
65
+ class NNonBlockingDialog(QDialog):
66
+
67
+ def __init__(self, parent: QWidget | None = None) -> None:
68
+ super().__init__(parent=parent)
69
+ self.setModal(True)
70
+ return
71
+
72
+ def activateDialog(self) -> None:
73
+ """Helper function to activate dialog on various systems."""
74
+ self.show()
75
+ if CONFIG.osWindows:
76
+ self.activateWindow()
77
+ self.raise_()
78
+ QApplication.processEvents()
79
+ return
33
80
 
34
81
 
35
82
  class NComboBox(QComboBox):
@@ -46,14 +93,12 @@ class NComboBox(QComboBox):
46
93
  event.ignore()
47
94
  return
48
95
 
49
- def setCurrentData(self, data: str, default: str) -> None:
96
+ def setCurrentData(self, data: str | int | Enum, default: str | int | Enum) -> None:
50
97
  """Set the current index from data, with a fallback."""
51
98
  idx = self.findData(data)
52
99
  self.setCurrentIndex(self.findData(default) if idx < 0 else idx)
53
100
  return
54
101
 
55
- # END Class NComboBox
56
-
57
102
 
58
103
  class NSpinBox(QSpinBox):
59
104
 
@@ -69,8 +114,6 @@ class NSpinBox(QSpinBox):
69
114
  event.ignore()
70
115
  return
71
116
 
72
- # END Class NSpinBox
73
-
74
117
 
75
118
  class NDoubleSpinBox(QDoubleSpinBox):
76
119
 
@@ -86,8 +129,6 @@ class NDoubleSpinBox(QDoubleSpinBox):
86
129
  event.ignore()
87
130
  return
88
131
 
89
- # END Class NDoubleSpinBox
90
-
91
132
 
92
133
  class NIconToolButton(QToolButton):
93
134
 
@@ -105,8 +146,6 @@ class NIconToolButton(QToolButton):
105
146
  self.setIcon(SHARED.theme.getIcon(iconKey))
106
147
  return
107
148
 
108
- # END Class NIconToolButton
109
-
110
149
 
111
150
  class NIconToggleButton(QToolButton):
112
151
 
@@ -126,5 +165,3 @@ class NIconToggleButton(QToolButton):
126
165
  iconSize = self.iconSize()
127
166
  self.setIcon(SHARED.theme.getToggleIcon(iconKey, (iconSize.width(), iconSize.height())))
128
167
  return
129
-
130
- # END Class NUnfoldButton
@@ -29,8 +29,8 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot
29
29
  from PyQt5.QtWidgets import QComboBox, QWidget
30
30
 
31
31
  from novelwriter import SHARED
32
- from novelwriter.enum import nwItemClass
33
32
  from novelwriter.constants import nwLabels
33
+ from novelwriter.enum import nwItemClass
34
34
 
35
35
  logger = logging.getLogger(__name__)
36
36
 
@@ -126,5 +126,3 @@ class NovelSelector(QComboBox):
126
126
  if not self._blockSignal:
127
127
  self.novelSelectionChanged.emit(self.currentData())
128
128
  return
129
-
130
- # END Class NovelSelector
@@ -25,14 +25,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
25
25
  """
26
26
  from __future__ import annotations
27
27
 
28
- from PyQt5.QtGui import QColor, QPaintEvent, QPainter, QPolygon
29
28
  from PyQt5.QtCore import QPoint, QRectF, QSize, Qt, pyqtSignal, pyqtSlot
29
+ from PyQt5.QtGui import QColor, QPainter, QPaintEvent, QPolygon
30
30
  from PyQt5.QtWidgets import (
31
- QAbstractButton, QAction, QButtonGroup, QLabel, QSizePolicy, QStyle,
31
+ QAbstractButton, QAction, QButtonGroup, QLabel, QStyle,
32
32
  QStyleOptionToolButton, QToolBar, QToolButton, QWidget
33
33
  )
34
34
 
35
- from novelwriter.types import QtPaintAnitAlias, QtAlignLeft, QtMouseOver, QtNoBrush, QtNoPen
35
+ from novelwriter.types import (
36
+ QtAlignLeft, QtMouseOver, QtNoBrush, QtNoPen, QtPaintAnitAlias,
37
+ QtSizeExpanding, QtSizeFixed
38
+ )
36
39
 
37
40
 
38
41
  class NPagedSideBar(QToolBar):
@@ -59,7 +62,7 @@ class NPagedSideBar(QToolBar):
59
62
  self.setOrientation(Qt.Orientation.Vertical)
60
63
 
61
64
  stretch = QWidget(self)
62
- stretch.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
65
+ stretch.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
63
66
  self._stretchAction = self.addWidget(stretch)
64
67
 
65
68
  return
@@ -109,8 +112,6 @@ class NPagedSideBar(QToolBar):
109
112
  self.buttonClicked.emit(buttonId)
110
113
  return
111
114
 
112
- # END Class NPagedSideBar
113
-
114
115
 
115
116
  class _NPagedToolButton(QToolButton):
116
117
 
@@ -119,7 +120,7 @@ class _NPagedToolButton(QToolButton):
119
120
  def __init__(self, parent: QWidget) -> None:
120
121
  super().__init__(parent=parent)
121
122
 
122
- self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
123
+ self.setSizePolicy(QtSizeExpanding, QtSizeFixed)
123
124
  self.setCheckable(True)
124
125
 
125
126
  fH = self.fontMetrics().height()
@@ -187,8 +188,6 @@ class _NPagedToolButton(QToolButton):
187
188
 
188
189
  return
189
190
 
190
- # END Class _NPagedToolButton
191
-
192
191
 
193
192
  class _NPagedToolLabel(QLabel):
194
193
 
@@ -197,7 +196,7 @@ class _NPagedToolLabel(QLabel):
197
196
  def __init__(self, parent: QWidget, textColor: QColor | None = None) -> None:
198
197
  super().__init__(parent=parent)
199
198
 
200
- self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
199
+ self.setSizePolicy(QtSizeExpanding, QtSizeFixed)
201
200
 
202
201
  fH = self.fontMetrics().height()
203
202
  self._bH = round(fH * 1.7)
@@ -228,5 +227,3 @@ class _NPagedToolLabel(QLabel):
228
227
  paint.drawText(QRectF(self._lM, self._tM, tW, tH), QtAlignLeft, self.text())
229
228
 
230
229
  return
231
-
232
- # END Class _NPagedToolLabel
@@ -25,7 +25,7 @@ from __future__ import annotations
25
25
 
26
26
  from math import ceil
27
27
 
28
- from PyQt5.QtGui import QPaintEvent, QPainter
28
+ from PyQt5.QtGui import QPainter, QPaintEvent
29
29
  from PyQt5.QtWidgets import QProgressBar, QWidget
30
30
 
31
31
  from novelwriter.types import QtPaintAnitAlias
@@ -51,5 +51,3 @@ class NProgressSimple(QProgressBar):
51
51
  painter.setBrush(self.palette().highlight())
52
52
  painter.drawRect(0, 0, progress, self.height())
53
53
  return
54
-
55
- # END Class NProgressSimple
@@ -27,7 +27,7 @@ import logging
27
27
 
28
28
  from typing import Literal
29
29
 
30
- from PyQt5.QtGui import QColor, QPaintEvent, QPainter
30
+ from PyQt5.QtGui import QColor, QPainter, QPaintEvent
31
31
  from PyQt5.QtWidgets import QAbstractButton, QWidget
32
32
 
33
33
  from novelwriter.types import QtPaintAnitAlias
@@ -75,5 +75,3 @@ class StatusLED(QAbstractButton):
75
75
  painter.setOpacity(1.0)
76
76
  painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
77
77
  return
78
-
79
- # END Class StatusLED
@@ -23,12 +23,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent
27
26
  from PyQt5.QtCore import QEvent, QPropertyAnimation, Qt, pyqtProperty
28
- from PyQt5.QtWidgets import QAbstractButton, QSizePolicy, QWidget
27
+ from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent
28
+ from PyQt5.QtWidgets import QAbstractButton, QWidget
29
29
 
30
30
  from novelwriter import CONFIG, SHARED
31
- from novelwriter.types import QtPaintAnitAlias, QtMouseLeft, QtNoPen
31
+ from novelwriter.types import QtMouseLeft, QtNoPen, QtPaintAnitAlias, QtSizeFixed
32
32
 
33
33
 
34
34
  class NSwitch(QAbstractButton):
@@ -46,7 +46,7 @@ class NSwitch(QAbstractButton):
46
46
  self._rR = self._xR - self._rB
47
47
 
48
48
  self.setCheckable(True)
49
- self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
49
+ self.setSizePolicy(QtSizeFixed, QtSizeFixed)
50
50
  self.setFixedWidth(self._xW)
51
51
  self.setFixedHeight(self._xH)
52
52
  self._offset = self._xR
@@ -133,5 +133,3 @@ class NSwitch(QAbstractButton):
133
133
  self.setCursor(Qt.CursorShape.PointingHandCursor)
134
134
  super().enterEvent(event)
135
135
  return
136
-
137
- # END Class NSwitch
@@ -23,12 +23,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- from PyQt5.QtGui import QIcon
27
26
  from PyQt5.QtCore import pyqtSignal
28
- from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QSizePolicy, QWidget
27
+ from PyQt5.QtGui import QIcon
28
+ from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QWidget
29
29
 
30
30
  from novelwriter.extensions.switch import NSwitch
31
- from novelwriter.types import QtAlignLeft, QtAlignRight, QtAlignRightMiddle
31
+ from novelwriter.types import (
32
+ QtAlignLeft, QtAlignRight, QtAlignRightMiddle, QtSizeMinimum,
33
+ QtSizeMinimumExpanding
34
+ )
32
35
 
33
36
 
34
37
  class NSwitchBox(QScrollArea):
@@ -59,7 +62,7 @@ class NSwitchBox(QScrollArea):
59
62
  self._content.setColumnStretch(1, 1)
60
63
 
61
64
  self._widget = QWidget(self)
62
- self._widget.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Minimum)
65
+ self._widget.setSizePolicy(QtSizeMinimumExpanding, QtSizeMinimum)
63
66
  self._widget.setLayout(self._content)
64
67
 
65
68
  self.setWidgetResizable(True)
@@ -124,5 +127,3 @@ class NSwitchBox(QScrollArea):
124
127
  self._content.setRowStretch(self._index + 1, 1)
125
128
  self._index += 1
126
129
  return
127
-
128
- # END Class NSwitchBox