novelWriter 2.4.3__py3-none-any.whl → 2.5__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 (123) hide show
  1. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/METADATA +4 -5
  2. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/RECORD +122 -112
  3. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +33 -39
  5. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  6. novelwriter/assets/i18n/nw_en_US.qm +0 -0
  7. novelwriter/assets/i18n/nw_es_419.qm +0 -0
  8. novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
  9. novelwriter/assets/i18n/nw_it_IT.qm +0 -0
  10. novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
  11. novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
  12. novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
  13. novelwriter/assets/i18n/nw_pl_PL.qm +0 -0
  14. novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
  15. novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
  16. novelwriter/assets/i18n/project_en_GB.json +1 -0
  17. novelwriter/assets/i18n/project_pl_PL.json +116 -0
  18. novelwriter/assets/i18n/project_pt_BR.json +74 -74
  19. novelwriter/assets/icons/typicons_dark/icons.conf +2 -0
  20. novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
  21. novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
  22. novelwriter/assets/icons/typicons_light/icons.conf +2 -0
  23. novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
  24. novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
  25. novelwriter/assets/manual.pdf +0 -0
  26. novelwriter/assets/sample.zip +0 -0
  27. novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
  28. novelwriter/assets/syntax/default_dark.conf +32 -18
  29. novelwriter/assets/syntax/default_light.conf +24 -10
  30. novelwriter/assets/syntax/dracula.conf +44 -0
  31. novelwriter/assets/syntax/grey_dark.conf +5 -4
  32. novelwriter/assets/syntax/grey_light.conf +5 -4
  33. novelwriter/assets/syntax/light_owl.conf +7 -6
  34. novelwriter/assets/syntax/night_owl.conf +7 -6
  35. novelwriter/assets/syntax/snazzy.conf +42 -0
  36. novelwriter/assets/syntax/solarized_dark.conf +4 -3
  37. novelwriter/assets/syntax/solarized_light.conf +4 -3
  38. novelwriter/assets/syntax/tango.conf +27 -11
  39. novelwriter/assets/syntax/tomorrow.conf +6 -5
  40. novelwriter/assets/syntax/tomorrow_night.conf +7 -6
  41. novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
  42. novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
  43. novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
  44. novelwriter/assets/text/credits_en.htm +52 -41
  45. novelwriter/assets/themes/cyberpunk_night.conf +3 -0
  46. novelwriter/assets/themes/default_dark.conf +2 -0
  47. novelwriter/assets/themes/default_light.conf +2 -0
  48. novelwriter/assets/themes/dracula.conf +48 -0
  49. novelwriter/assets/themes/solarized_dark.conf +2 -0
  50. novelwriter/assets/themes/solarized_light.conf +2 -0
  51. novelwriter/common.py +33 -12
  52. novelwriter/config.py +184 -98
  53. novelwriter/constants.py +47 -35
  54. novelwriter/core/buildsettings.py +68 -69
  55. novelwriter/core/coretools.py +5 -23
  56. novelwriter/core/docbuild.py +52 -40
  57. novelwriter/core/document.py +3 -5
  58. novelwriter/core/index.py +115 -45
  59. novelwriter/core/item.py +8 -19
  60. novelwriter/core/options.py +2 -4
  61. novelwriter/core/project.py +37 -61
  62. novelwriter/core/projectdata.py +1 -3
  63. novelwriter/core/projectxml.py +12 -15
  64. novelwriter/core/sessions.py +3 -5
  65. novelwriter/core/spellcheck.py +4 -9
  66. novelwriter/core/status.py +211 -164
  67. novelwriter/core/storage.py +0 -8
  68. novelwriter/core/tohtml.py +139 -105
  69. novelwriter/core/tokenizer.py +278 -122
  70. novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
  71. novelwriter/core/toodt.py +257 -166
  72. novelwriter/core/toqdoc.py +419 -0
  73. novelwriter/core/tree.py +5 -7
  74. novelwriter/dialogs/about.py +11 -18
  75. novelwriter/dialogs/docmerge.py +17 -19
  76. novelwriter/dialogs/docsplit.py +17 -19
  77. novelwriter/dialogs/editlabel.py +6 -10
  78. novelwriter/dialogs/preferences.py +200 -164
  79. novelwriter/dialogs/projectsettings.py +225 -189
  80. novelwriter/dialogs/quotes.py +12 -9
  81. novelwriter/dialogs/wordlist.py +9 -15
  82. novelwriter/enum.py +35 -30
  83. novelwriter/error.py +8 -15
  84. novelwriter/extensions/configlayout.py +55 -21
  85. novelwriter/extensions/eventfilters.py +1 -5
  86. novelwriter/extensions/modified.py +70 -14
  87. novelwriter/extensions/novelselector.py +1 -3
  88. novelwriter/extensions/pagedsidebar.py +9 -12
  89. novelwriter/extensions/{circularprogress.py → progressbars.py} +30 -8
  90. novelwriter/extensions/statusled.py +40 -26
  91. novelwriter/extensions/switch.py +4 -6
  92. novelwriter/extensions/switchbox.py +7 -6
  93. novelwriter/extensions/versioninfo.py +3 -9
  94. novelwriter/gui/doceditor.py +120 -139
  95. novelwriter/gui/dochighlight.py +231 -186
  96. novelwriter/gui/docviewer.py +69 -108
  97. novelwriter/gui/docviewerpanel.py +3 -10
  98. novelwriter/gui/editordocument.py +1 -3
  99. novelwriter/gui/itemdetails.py +7 -11
  100. novelwriter/gui/mainmenu.py +22 -18
  101. novelwriter/gui/noveltree.py +11 -24
  102. novelwriter/gui/outline.py +15 -26
  103. novelwriter/gui/projtree.py +39 -65
  104. novelwriter/gui/search.py +10 -3
  105. novelwriter/gui/sidebar.py +2 -6
  106. novelwriter/gui/statusbar.py +29 -37
  107. novelwriter/gui/theme.py +26 -48
  108. novelwriter/guimain.py +162 -160
  109. novelwriter/shared.py +36 -19
  110. novelwriter/text/patterns.py +113 -0
  111. novelwriter/tools/dictionaries.py +10 -20
  112. novelwriter/tools/lipsum.py +10 -16
  113. novelwriter/tools/manusbuild.py +9 -11
  114. novelwriter/tools/manuscript.py +75 -149
  115. novelwriter/tools/manussettings.py +74 -76
  116. novelwriter/tools/noveldetails.py +16 -21
  117. novelwriter/tools/welcome.py +21 -26
  118. novelwriter/tools/writingstats.py +9 -12
  119. novelwriter/types.py +49 -4
  120. novelwriter/extensions/simpleprogress.py +0 -55
  121. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/LICENSE.md +0 -0
  122. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/entry_points.txt +0 -0
  123. {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/top_level.txt +0 -0
novelwriter/shared.py CHANGED
@@ -31,7 +31,8 @@ from time import time
31
31
  from typing import TYPE_CHECKING, TypeVar
32
32
 
33
33
  from PyQt5.QtCore import QObject, QRunnable, QThreadPool, QTimer, pyqtSignal
34
- from PyQt5.QtWidgets import QFileDialog, QMessageBox, QWidget
34
+ from PyQt5.QtGui import QFont
35
+ from PyQt5.QtWidgets import QFileDialog, QFontDialog, QMessageBox, QWidget
35
36
 
36
37
  from novelwriter.common import formatFileFilter
37
38
  from novelwriter.constants import nwFiles
@@ -171,6 +172,23 @@ class SharedData(QObject):
171
172
  logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
172
173
  return
173
174
 
175
+ def closeEditor(self, tHandle: str | None = None) -> None:
176
+ """Close the document editor, optionally a specific document."""
177
+ if tHandle is None or tHandle == self.mainGui.docEditor.docHandle:
178
+ self.mainGui.closeDocument()
179
+ return
180
+
181
+ def saveEditor(self, tHandle: str | None = None) -> None:
182
+ """Save the editor content, optionally a specific document."""
183
+ docEditor = self.mainGui.docEditor
184
+ if (
185
+ self.hasProject and docEditor.docHandle
186
+ and (tHandle is None or tHandle == docEditor.docHandle)
187
+ ):
188
+ logger.debug("Saving editor document before action")
189
+ docEditor.saveText()
190
+ return
191
+
174
192
  def openProject(self, path: str | Path, clearLock: bool = False) -> bool:
175
193
  """Open a project."""
176
194
  if self.project.isValid:
@@ -198,7 +216,7 @@ class SharedData(QObject):
198
216
 
199
217
  def closeProject(self) -> None:
200
218
  """Close the current project."""
201
- self._closeDialogs()
219
+ self._closeToolDialogs()
202
220
  self.project.closeProject(self._idleTime)
203
221
  self._resetProject()
204
222
  self._resetIdleTimer()
@@ -244,8 +262,11 @@ class SharedData(QObject):
244
262
  QThreadPool.globalInstance().start(runnable, priority=priority)
245
263
  return
246
264
 
247
- def getProjectPath(self, parent: QWidget, path: str | Path | None = None,
248
- allowZip: bool = False) -> Path | None:
265
+ def getProjectPath(
266
+ self, parent: QWidget,
267
+ path: str | Path | None = None,
268
+ allowZip: bool = False
269
+ ) -> Path | None:
249
270
  """Open the file dialog and select a novelWriter project file."""
250
271
  label = (self.tr("novelWriter Project File or Zip File")
251
272
  if allowZip else self.tr("novelWriter Project File"))
@@ -256,6 +277,13 @@ class SharedData(QObject):
256
277
  )
257
278
  return Path(selected) if selected else None
258
279
 
280
+ def getFont(self, current: QFont, native: bool) -> tuple[QFont, bool]:
281
+ """Open the font dialog and select a font."""
282
+ kwargs = {}
283
+ if not native:
284
+ kwargs["options"] = QFontDialog.FontDialogOption.DontUseNativeDialog
285
+ return QFontDialog.getFont(current, self.mainGui, self.tr("Select Font"), **kwargs)
286
+
259
287
  def findTopLevelWidget(self, kind: type[NWWidget]) -> NWWidget | None:
260
288
  """Find a top level widget."""
261
289
  for widget in self.mainGui.children():
@@ -294,7 +322,6 @@ class SharedData(QObject):
294
322
  if log:
295
323
  logger.info(self._lastAlert, stacklevel=2)
296
324
  alert.exec()
297
- alert.deleteLater()
298
325
  return
299
326
 
300
327
  def warn(self, text: str, info: str = "", details: str = "", log: bool = True) -> None:
@@ -306,7 +333,6 @@ class SharedData(QObject):
306
333
  if log:
307
334
  logger.warning(self._lastAlert, stacklevel=2)
308
335
  alert.exec()
309
- alert.deleteLater()
310
336
  return
311
337
 
312
338
  def error(self, text: str, info: str = "", details: str = "", log: bool = True,
@@ -321,7 +347,6 @@ class SharedData(QObject):
321
347
  if log:
322
348
  logger.error(self._lastAlert, stacklevel=2)
323
349
  alert.exec()
324
- alert.deleteLater()
325
350
  return
326
351
 
327
352
  def question(self, text: str, info: str = "", details: str = "", warn: bool = False) -> bool:
@@ -332,7 +357,6 @@ class SharedData(QObject):
332
357
  self._lastAlert = alert.logMessage
333
358
  alert.exec()
334
359
  isYes = alert.result() == QMessageBox.StandardButton.Yes
335
- alert.deleteLater()
336
360
  return isYes
337
361
 
338
362
  ##
@@ -357,19 +381,14 @@ class SharedData(QObject):
357
381
  self._idleTime = 0.0
358
382
  return
359
383
 
360
- def _closeDialogs(self) -> None:
361
- """Close non-modal dialogs."""
362
- from novelwriter.tools.manuscript import GuiManuscript
363
- from novelwriter.tools.writingstats import GuiWritingStats
364
-
384
+ def _closeToolDialogs(self) -> None:
385
+ """Close all open tool dialogs."""
386
+ from novelwriter.extensions.modified import NToolDialog
365
387
  for widget in self.mainGui.children():
366
- if isinstance(widget, (GuiManuscript, GuiWritingStats)):
388
+ if isinstance(widget, NToolDialog):
367
389
  widget.close()
368
-
369
390
  return
370
391
 
371
- # END Class SharedData
372
-
373
392
 
374
393
  class _GuiAlert(QMessageBox):
375
394
 
@@ -430,5 +449,3 @@ class _GuiAlert(QMessageBox):
430
449
  self.setIconPixmap(self._theme.getPixmap("alert_question", (pSz, pSz)))
431
450
  self.setWindowTitle(self.tr("Question"))
432
451
  return
433
-
434
- # END Class _GuiAlert
@@ -0,0 +1,113 @@
1
+ """
2
+ novelWriter – Text Pattern Functions
3
+ ====================================
4
+
5
+ File History:
6
+ Created: 2024-06-01 [2.5ec1]
7
+
8
+ This file is a part of novelWriter
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
+
11
+ This program is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ This program is distributed in the hope that it will be useful, but
17
+ WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License
22
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+ """
24
+ from __future__ import annotations
25
+
26
+ from PyQt5.QtCore import QRegularExpression
27
+
28
+ from novelwriter import CONFIG
29
+ from novelwriter.constants import nwRegEx
30
+ from novelwriter.types import QRegExUnicode
31
+
32
+
33
+ class RegExPatterns:
34
+
35
+ @property
36
+ def markdownItalic(self) -> QRegularExpression:
37
+ """Markdown italic style."""
38
+ rxRule = QRegularExpression(nwRegEx.FMT_EI)
39
+ rxRule.setPatternOptions(QRegExUnicode)
40
+ return rxRule
41
+
42
+ @property
43
+ def markdownBold(self) -> QRegularExpression:
44
+ """Markdown bold style."""
45
+ rxRule = QRegularExpression(nwRegEx.FMT_EB)
46
+ rxRule.setPatternOptions(QRegExUnicode)
47
+ return rxRule
48
+
49
+ @property
50
+ def markdownStrike(self) -> QRegularExpression:
51
+ """Markdown strikethrough style."""
52
+ rxRule = QRegularExpression(nwRegEx.FMT_ST)
53
+ rxRule.setPatternOptions(QRegExUnicode)
54
+ return rxRule
55
+
56
+ @property
57
+ def shortcodePlain(self) -> QRegularExpression:
58
+ """Plain shortcode style."""
59
+ rxRule = QRegularExpression(nwRegEx.FMT_SC)
60
+ rxRule.setPatternOptions(QRegExUnicode)
61
+ return rxRule
62
+
63
+ @property
64
+ def shortcodeValue(self) -> QRegularExpression:
65
+ """Plain shortcode style."""
66
+ rxRule = QRegularExpression(nwRegEx.FMT_SV)
67
+ rxRule.setPatternOptions(QRegExUnicode)
68
+ return rxRule
69
+
70
+ @property
71
+ def dialogStyle(self) -> QRegularExpression:
72
+ """Dialogue detection rule based on user settings."""
73
+ symO = ""
74
+ symC = ""
75
+ if CONFIG.dialogStyle in (1, 3):
76
+ symO += CONFIG.fmtSQuoteOpen
77
+ symC += CONFIG.fmtSQuoteClose
78
+ if CONFIG.dialogStyle in (2, 3):
79
+ symO += CONFIG.fmtDQuoteOpen
80
+ symC += CONFIG.fmtDQuoteClose
81
+
82
+ rxEnd = "|$" if CONFIG.allowOpenDial else ""
83
+ rxRule = QRegularExpression(f"\\B[{symO}].*?(?:[{symC}]\\B{rxEnd})")
84
+ rxRule.setPatternOptions(QRegExUnicode)
85
+ return rxRule
86
+
87
+ @property
88
+ def dialogLine(self) -> QRegularExpression:
89
+ """Dialogue line rule based on user settings."""
90
+ sym = QRegularExpression.escape(CONFIG.dialogLine)
91
+ rxRule = QRegularExpression(f"^{sym}.*?$")
92
+ rxRule.setPatternOptions(QRegExUnicode)
93
+ return rxRule
94
+
95
+ @property
96
+ def narratorBreak(self) -> QRegularExpression:
97
+ """Dialogue narrator break rule based on user settings."""
98
+ sym = QRegularExpression.escape(CONFIG.narratorBreak)
99
+ rxRule = QRegularExpression(f"\\B{sym}\\S.*?\\S{sym}\\B")
100
+ rxRule.setPatternOptions(QRegExUnicode)
101
+ return rxRule
102
+
103
+ @property
104
+ def altDialogStyle(self) -> QRegularExpression:
105
+ """Dialogue alternative rule based on user settings."""
106
+ symO = QRegularExpression.escape(CONFIG.altDialogOpen)
107
+ symC = QRegularExpression.escape(CONFIG.altDialogClose)
108
+ rxRule = QRegularExpression(f"\\B{symO}.*?{symC}\\B")
109
+ rxRule.setPatternOptions(QRegExUnicode)
110
+ return rxRule
111
+
112
+
113
+ REGEX_PATTERNS = RegExPatterns()
@@ -31,20 +31,20 @@ from zipfile import ZipFile
31
31
  from PyQt5.QtCore import pyqtSlot
32
32
  from PyQt5.QtGui import QCloseEvent, QTextCursor
33
33
  from PyQt5.QtWidgets import (
34
- QApplication, QDialog, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout,
35
- QLabel, QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget
34
+ QApplication, QDialogButtonBox, QFileDialog, QFrame, QHBoxLayout, QLabel,
35
+ QLineEdit, QPlainTextEdit, QPushButton, QVBoxLayout, QWidget
36
36
  )
37
37
 
38
38
  from novelwriter import CONFIG, SHARED
39
- from novelwriter.common import formatFileFilter, formatInt, getFileSize, openExternalPath
39
+ from novelwriter.common import cssCol, formatFileFilter, formatInt, getFileSize, openExternalPath
40
40
  from novelwriter.error import formatException
41
- from novelwriter.extensions.modified import NIconToolButton
41
+ from novelwriter.extensions.modified import NIconToolButton, NNonBlockingDialog
42
42
  from novelwriter.types import QtDialogClose
43
43
 
44
44
  logger = logging.getLogger(__name__)
45
45
 
46
46
 
47
- class GuiDictionaries(QDialog):
47
+ class GuiDictionaries(NNonBlockingDialog):
48
48
 
49
49
  def __init__(self, parent: QWidget) -> None:
50
50
  super().__init__(parent=parent)
@@ -109,7 +109,7 @@ class GuiDictionaries(QDialog):
109
109
 
110
110
  # Buttons
111
111
  self.buttonBox = QDialogButtonBox(QtDialogClose, self)
112
- self.buttonBox.rejected.connect(self._doClose)
112
+ self.buttonBox.rejected.connect(self.reject)
113
113
 
114
114
  # Assemble
115
115
  self.innerBox = QVBoxLayout()
@@ -172,7 +172,7 @@ class GuiDictionaries(QDialog):
172
172
  def closeEvent(self, event: QCloseEvent) -> None:
173
173
  """Capture the user closing the window."""
174
174
  event.accept()
175
- self.deleteLater()
175
+ self.softDelete()
176
176
  return
177
177
 
178
178
  ##
@@ -186,7 +186,7 @@ class GuiDictionaries(QDialog):
186
186
  (self.tr("Free or Libre Office extension"), "*.sox *.oxt"), "*"
187
187
  ])
188
188
  soxFile, _ = QFileDialog.getOpenFileName(
189
- self, self.tr("Browse Files"), "", filter=ffilter
189
+ self, self.tr("Browse Files"), str(CONFIG.homePath()), filter=ffilter
190
190
  )
191
191
  if soxFile:
192
192
  path = Path(soxFile).absolute()
@@ -220,12 +220,6 @@ class GuiDictionaries(QDialog):
220
220
  SHARED.error("Path not found.")
221
221
  return
222
222
 
223
- @pyqtSlot()
224
- def _doClose(self) -> None:
225
- """Close the dialog."""
226
- self.close()
227
- return
228
-
229
223
  ##
230
224
  # Internal Functions
231
225
  ##
@@ -257,13 +251,9 @@ class GuiDictionaries(QDialog):
257
251
  cursor.movePosition(QTextCursor.MoveOperation.End)
258
252
  if cursor.position() > 0:
259
253
  cursor.insertText("\n")
260
- if err:
261
- cursor.insertHtml(f"<font color='red'>{text}</font>")
262
- else:
263
- cursor.insertText(text)
254
+ textCol = cssCol(SHARED.theme.errorText if err else self.palette().text().color())
255
+ cursor.insertHtml(f"<font style='color: {textCol}'>{text}</font>")
264
256
  cursor.movePosition(QTextCursor.MoveOperation.End)
265
257
  cursor.deleteChar()
266
258
  self.infoBox.setTextCursor(cursor)
267
259
  return
268
-
269
- # END Class GuiDictionaries
@@ -23,37 +23,35 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- import random
27
26
  import logging
27
+ import random
28
28
 
29
- from PyQt5.QtCore import Qt, pyqtSlot
29
+ from PyQt5.QtCore import pyqtSlot
30
30
  from PyQt5.QtWidgets import (
31
- QDialog, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, QSpinBox,
32
- QVBoxLayout, QWidget
31
+ QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, QSpinBox, QVBoxLayout,
32
+ QWidget
33
33
  )
34
34
 
35
35
  from novelwriter import CONFIG, SHARED
36
36
  from novelwriter.common import readTextFile
37
+ from novelwriter.extensions.modified import NDialog
37
38
  from novelwriter.extensions.switch import NSwitch
38
- from novelwriter.types import QtAlignLeft, QtAlignRight, QtRoleAction, QtDialogClose
39
+ from novelwriter.types import QtAlignLeft, QtAlignRight, QtDialogClose, QtRoleAction
39
40
 
40
41
  logger = logging.getLogger(__name__)
41
42
 
42
43
 
43
- class GuiLipsum(QDialog):
44
+ class GuiLipsum(NDialog):
44
45
 
45
46
  def __init__(self, parent: QWidget) -> None:
46
47
  super().__init__(parent=parent)
47
48
 
48
49
  logger.debug("Create: GuiLipsum")
49
50
  self.setObjectName("GuiLipsum")
50
- if CONFIG.osDarwin:
51
- self.setWindowFlag(Qt.WindowType.Tool)
51
+ self.setWindowTitle(self.tr("Insert Placeholder Text"))
52
52
 
53
53
  self._lipsumText = ""
54
54
 
55
- self.setWindowTitle(self.tr("Insert Placeholder Text"))
56
-
57
55
  vSp = CONFIG.pxInt(4)
58
56
  nPx = CONFIG.pxInt(64)
59
57
 
@@ -95,7 +93,7 @@ class GuiLipsum(QDialog):
95
93
 
96
94
  # Buttons
97
95
  self.buttonBox = QDialogButtonBox(self)
98
- self.buttonBox.rejected.connect(self.close)
96
+ self.buttonBox.rejected.connect(self.reject)
99
97
 
100
98
  self.btnClose = self.buttonBox.addButton(QtDialogClose)
101
99
  self.btnClose.setAutoDefault(False)
@@ -104,8 +102,6 @@ class GuiLipsum(QDialog):
104
102
  self.btnInsert.clicked.connect(self._doInsert)
105
103
  self.btnInsert.setAutoDefault(False)
106
104
 
107
- self.rejected.connect(self.close)
108
-
109
105
  # Assemble
110
106
  self.outerBox = QVBoxLayout()
111
107
  self.outerBox.addLayout(self.innerBox)
@@ -132,7 +128,7 @@ class GuiLipsum(QDialog):
132
128
  cls = GuiLipsum(parent)
133
129
  cls.exec()
134
130
  text = cls.lipsumText
135
- cls.deleteLater()
131
+ cls.softDelete()
136
132
  return text
137
133
 
138
134
  ##
@@ -150,5 +146,3 @@ class GuiLipsum(QDialog):
150
146
  self._lipsumText = "\n\n".join(lipsumText[0:pCount]) + "\n\n"
151
147
  self.close()
152
148
  return
153
-
154
- # END Class GuiLipsum
@@ -30,7 +30,7 @@ from pathlib import Path
30
30
  from PyQt5.QtCore import QTimer, pyqtSlot
31
31
  from PyQt5.QtGui import QCloseEvent
32
32
  from PyQt5.QtWidgets import (
33
- QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog,
33
+ QAbstractButton, QAbstractItemView, QDialogButtonBox, QFileDialog,
34
34
  QGridLayout, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem,
35
35
  QPushButton, QSplitter, QVBoxLayout, QWidget
36
36
  )
@@ -42,14 +42,14 @@ from novelwriter.core.buildsettings import BuildSettings
42
42
  from novelwriter.core.docbuild import NWBuildDocument
43
43
  from novelwriter.core.item import NWItem
44
44
  from novelwriter.enum import nwBuildFmt
45
- from novelwriter.extensions.modified import NIconToolButton
46
- from novelwriter.extensions.simpleprogress import NProgressSimple
45
+ from novelwriter.extensions.modified import NDialog, NIconToolButton
46
+ from novelwriter.extensions.progressbars import NProgressSimple
47
47
  from novelwriter.types import QtAlignCenter, QtDialogClose, QtRoleAction, QtRoleReject, QtUserRole
48
48
 
49
49
  logger = logging.getLogger(__name__)
50
50
 
51
51
 
52
- class GuiManuscriptBuild(QDialog):
52
+ class GuiManuscriptBuild(NDialog):
53
53
  """GUI Tools: Manuscript Build Dialog
54
54
 
55
55
  This is the tool for running the build itself. It can be accessed
@@ -220,7 +220,7 @@ class GuiManuscriptBuild(QDialog):
220
220
 
221
221
  self.btnBuild.setFocus()
222
222
  self._populateContentList()
223
- self.buildPath.setText(str(self._build.lastPath))
223
+ self.buildPath.setText(str(self._build.lastBuildPath))
224
224
  if self._build.lastBuildName:
225
225
  self.buildName.setText(self._build.lastBuildName)
226
226
  else:
@@ -250,7 +250,7 @@ class GuiManuscriptBuild(QDialog):
250
250
  """
251
251
  self._saveSettings()
252
252
  event.accept()
253
- self.deleteLater()
253
+ self.softDelete()
254
254
  return
255
255
 
256
256
  ##
@@ -274,7 +274,7 @@ class GuiManuscriptBuild(QDialog):
274
274
  def _doSelectPath(self) -> None:
275
275
  """Select a folder for output."""
276
276
  bPath = Path(self.buildPath.text())
277
- bPath = bPath if bPath.is_dir() else self._build.lastPath
277
+ bPath = bPath if bPath.is_dir() else self._build.lastBuildPath
278
278
  savePath = QFileDialog.getExistingDirectory(
279
279
  self, self.tr("Select Folder"), str(bPath)
280
280
  )
@@ -327,7 +327,7 @@ class GuiManuscriptBuild(QDialog):
327
327
  return False
328
328
 
329
329
  # Make sure editor content is saved before we start
330
- SHARED.mainGui.saveDocument()
330
+ SHARED.saveEditor()
331
331
 
332
332
  docBuild = NWBuildDocument(SHARED.project, self._build)
333
333
  docBuild.queueAll()
@@ -336,7 +336,7 @@ class GuiManuscriptBuild(QDialog):
336
336
  for i, _ in docBuild.iterBuild(buildPath, bFormat):
337
337
  self.buildProgress.setValue(i+1)
338
338
 
339
- self._build.setLastPath(bPath)
339
+ self._build.setLastBuildPath(bPath)
340
340
  self._build.setLastBuildName(bName)
341
341
  self._build.setLastFormat(bFormat)
342
342
 
@@ -403,5 +403,3 @@ class GuiManuscriptBuild(QDialog):
403
403
  """Open the build folder in the system's file explorer."""
404
404
  openExternalPath(Path(self.buildPath.text()))
405
405
  return
406
-
407
- # END Class GuiManuscriptBuild