novelWriter 2.2rc1__py3-none-any.whl → 2.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/METADATA +1 -1
  2. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/RECORD +113 -111
  3. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +10 -5
  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_zh_CN.qm +0 -0
  13. novelwriter/assets/i18n/project_de_DE.json +1 -0
  14. novelwriter/assets/i18n/project_en_US.json +1 -0
  15. novelwriter/assets/i18n/project_es_419.json +11 -0
  16. novelwriter/assets/i18n/project_fr_FR.json +11 -0
  17. novelwriter/assets/i18n/project_it_IT.json +11 -0
  18. novelwriter/assets/i18n/project_ja_JP.json +2 -1
  19. novelwriter/assets/i18n/project_nb_NO.json +1 -0
  20. novelwriter/assets/i18n/project_zh_CN.json +11 -0
  21. novelwriter/assets/icons/typicons_dark/icons.conf +3 -2
  22. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
  23. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
  24. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
  25. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
  26. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
  27. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
  28. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
  29. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
  30. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
  31. novelwriter/assets/icons/typicons_light/icons.conf +3 -2
  32. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
  33. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
  34. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
  35. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
  36. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
  37. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
  38. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
  39. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
  40. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
  41. novelwriter/assets/manual.pdf +0 -0
  42. novelwriter/assets/sample.zip +0 -0
  43. novelwriter/assets/text/release_notes.htm +50 -7
  44. novelwriter/common.py +16 -29
  45. novelwriter/config.py +3 -3
  46. novelwriter/constants.py +1 -1
  47. novelwriter/core/buildsettings.py +1 -1
  48. novelwriter/core/coretools.py +2 -1
  49. novelwriter/core/docbuild.py +1 -1
  50. novelwriter/core/document.py +1 -1
  51. novelwriter/core/index.py +2 -2
  52. novelwriter/core/item.py +2 -2
  53. novelwriter/core/options.py +3 -3
  54. novelwriter/core/project.py +3 -3
  55. novelwriter/core/projectdata.py +2 -2
  56. novelwriter/core/projectxml.py +1 -1
  57. novelwriter/core/sessions.py +2 -2
  58. novelwriter/core/spellcheck.py +4 -3
  59. novelwriter/core/status.py +3 -3
  60. novelwriter/core/storage.py +1 -1
  61. novelwriter/core/tohtml.py +2 -2
  62. novelwriter/core/tokenizer.py +1 -1
  63. novelwriter/core/tomd.py +2 -2
  64. novelwriter/core/toodt.py +1 -1
  65. novelwriter/core/tree.py +2 -2
  66. novelwriter/dialogs/about.py +30 -31
  67. novelwriter/dialogs/docmerge.py +24 -15
  68. novelwriter/dialogs/docsplit.py +27 -16
  69. novelwriter/dialogs/editlabel.py +19 -7
  70. novelwriter/dialogs/preferences.py +44 -57
  71. novelwriter/dialogs/projdetails.py +29 -36
  72. novelwriter/dialogs/projload.py +32 -36
  73. novelwriter/dialogs/projsettings.py +20 -15
  74. novelwriter/dialogs/quotes.py +32 -25
  75. novelwriter/dialogs/updates.py +4 -14
  76. novelwriter/dialogs/wordlist.py +34 -21
  77. novelwriter/enum.py +5 -4
  78. novelwriter/error.py +1 -1
  79. novelwriter/extensions/circularprogress.py +1 -1
  80. novelwriter/extensions/configlayout.py +3 -15
  81. novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
  82. novelwriter/extensions/novelselector.py +1 -1
  83. novelwriter/extensions/pageddialog.py +1 -1
  84. novelwriter/extensions/pagedsidebar.py +2 -5
  85. novelwriter/extensions/simpleprogress.py +8 -9
  86. novelwriter/extensions/statusled.py +1 -1
  87. novelwriter/extensions/switch.py +4 -4
  88. novelwriter/extensions/switchbox.py +1 -6
  89. novelwriter/gui/doceditor.py +72 -64
  90. novelwriter/gui/dochighlight.py +3 -2
  91. novelwriter/gui/docviewer.py +22 -47
  92. novelwriter/gui/docviewerpanel.py +68 -23
  93. novelwriter/gui/editordocument.py +3 -3
  94. novelwriter/gui/itemdetails.py +2 -2
  95. novelwriter/gui/mainmenu.py +35 -30
  96. novelwriter/gui/noveltree.py +44 -53
  97. novelwriter/gui/outline.py +2 -1
  98. novelwriter/gui/projtree.py +5 -6
  99. novelwriter/gui/sidebar.py +6 -4
  100. novelwriter/gui/statusbar.py +47 -4
  101. novelwriter/gui/theme.py +5 -6
  102. novelwriter/guimain.py +139 -189
  103. novelwriter/shared.py +53 -29
  104. novelwriter/tools/dictionaries.py +2 -2
  105. novelwriter/tools/lipsum.py +34 -28
  106. novelwriter/tools/manusbuild.py +3 -4
  107. novelwriter/tools/manuscript.py +19 -26
  108. novelwriter/tools/manussettings.py +2 -4
  109. novelwriter/tools/projwizard.py +3 -3
  110. novelwriter/tools/writingstats.py +17 -4
  111. novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
  112. novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
  113. novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
  114. novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
  115. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/LICENSE.md +0 -0
  116. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/entry_points.txt +0 -0
  117. {novelWriter-2.2rc1.dist-info → novelWriter-2.2.1.dist-info}/top_level.txt +0 -0
@@ -3,10 +3,10 @@ novelWriter – Lorem Ipsum Tool
3
3
  ==============================
4
4
 
5
5
  File History:
6
- Created: 2022-04-02 [2.0rc1]
6
+ Created: 2022-04-02 [2.0rc1] GuiLipsum
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -26,10 +26,10 @@ from __future__ import annotations
26
26
  import random
27
27
  import logging
28
28
 
29
- from PyQt5.QtCore import Qt
29
+ from PyQt5.QtCore import Qt, pyqtSlot
30
30
  from PyQt5.QtWidgets import (
31
- QDialog, QGridLayout, QHBoxLayout, QVBoxLayout, QLabel, QDialogButtonBox,
32
- QSpinBox
31
+ QDialog, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, QSpinBox,
32
+ QVBoxLayout, QWidget
33
33
  )
34
34
 
35
35
  from novelwriter import CONFIG, SHARED
@@ -41,15 +41,15 @@ logger = logging.getLogger(__name__)
41
41
 
42
42
  class GuiLipsum(QDialog):
43
43
 
44
- def __init__(self, mainGui):
45
- super().__init__(parent=mainGui)
44
+ def __init__(self, parent: QWidget) -> None:
45
+ super().__init__(parent=parent)
46
46
 
47
47
  logger.debug("Create: GuiLipsum")
48
48
  self.setObjectName("GuiLipsum")
49
49
  if CONFIG.osDarwin:
50
50
  self.setWindowFlag(Qt.WindowType.Tool)
51
51
 
52
- self.mainGui = mainGui
52
+ self._lipsumText = ""
53
53
 
54
54
  self.setWindowTitle(self.tr("Insert Placeholder Text"))
55
55
 
@@ -92,14 +92,16 @@ class GuiLipsum(QDialog):
92
92
 
93
93
  # Buttons
94
94
  self.buttonBox = QDialogButtonBox()
95
- self.buttonBox.rejected.connect(self._doClose)
95
+ self.buttonBox.rejected.connect(self.close)
96
96
 
97
97
  self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
98
98
  self.btnClose.setAutoDefault(False)
99
99
 
100
- self.btnSave = self.buttonBox.addButton(self.tr("Insert"), QDialogButtonBox.ActionRole)
101
- self.btnSave.clicked.connect(self._doInsert)
102
- self.btnSave.setAutoDefault(False)
100
+ self.btnInsert = self.buttonBox.addButton(self.tr("Insert"), QDialogButtonBox.ActionRole)
101
+ self.btnInsert.clicked.connect(self._doInsert)
102
+ self.btnInsert.setAutoDefault(False)
103
+
104
+ self.rejected.connect(self.close)
103
105
 
104
106
  # Assemble
105
107
  self.outerBox = QVBoxLayout()
@@ -112,33 +114,37 @@ class GuiLipsum(QDialog):
112
114
 
113
115
  return
114
116
 
115
- def __del__(self): # pragma: no cover
117
+ def __del__(self) -> None: # pragma: no cover
116
118
  logger.debug("Delete: GuiLipsum")
117
119
  return
118
120
 
121
+ @property
122
+ def lipsumText(self) -> str:
123
+ """Return the generated text."""
124
+ return self._lipsumText
125
+
126
+ @classmethod
127
+ def getLipsum(cls, parent: QWidget) -> str:
128
+ """Pop the dialog and return the lipsum text."""
129
+ cls = GuiLipsum(parent)
130
+ cls.exec_()
131
+ text = cls.lipsumText
132
+ cls.deleteLater()
133
+ return text
134
+
119
135
  ##
120
- # Slots
136
+ # Private Slots
121
137
  ##
122
138
 
123
- def _doInsert(self):
124
- """Load the text and insert it in the open document.
125
- """
139
+ @pyqtSlot()
140
+ def _doInsert(self) -> None:
141
+ """Generate the text."""
126
142
  lipsumFile = CONFIG.assetPath("text") / "lipsum.txt"
127
143
  lipsumText = readTextFile(lipsumFile).splitlines()
128
-
129
144
  if self.randSwitch.isChecked():
130
145
  random.shuffle(lipsumText)
131
-
132
146
  pCount = self.paraCount.value()
133
- inText = "\n\n".join(lipsumText[0:pCount]) + "\n\n"
134
-
135
- self.mainGui.docEditor.insertText(inText)
136
-
137
- return
138
-
139
- def _doClose(self):
140
- """Close the dialog window without doing anything.
141
- """
147
+ self._lipsumText = "\n\n".join(lipsumText[0:pCount]) + "\n\n"
142
148
  self.close()
143
149
  return
144
150
 
@@ -6,7 +6,7 @@ File History:
6
6
  Created: 2023-05-24 [2.1b1] GuiManuscriptBuild
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -331,7 +331,7 @@ class GuiManuscriptBuild(QDialog):
331
331
  self._build.setLastBuildName(bName)
332
332
  self._build.setLastFormat(bFormat)
333
333
 
334
- QTimer.singleShot(1000, self._resetProgress)
334
+ QTimer.singleShot(3000, self._resetProgress)
335
335
 
336
336
  return True
337
337
 
@@ -344,8 +344,6 @@ class GuiManuscriptBuild(QDialog):
344
344
 
345
345
  def _saveSettings(self):
346
346
  """Save the user GUI settings."""
347
- logger.debug("Saving GuiManuscriptBuild settings")
348
-
349
347
  winWidth = CONFIG.rpxInt(self.width())
350
348
  winHeight = CONFIG.rpxInt(self.height())
351
349
 
@@ -353,6 +351,7 @@ class GuiManuscriptBuild(QDialog):
353
351
  fmtWidth = CONFIG.rpxInt(mainSplit[0])
354
352
  sumWidth = CONFIG.rpxInt(mainSplit[1])
355
353
 
354
+ logger.debug("Saving State: GuiManuscriptBuild")
356
355
  pOptions = SHARED.project.options
357
356
  pOptions.setValue("GuiManuscriptBuild", "winWidth", winWidth)
358
357
  pOptions.setValue("GuiManuscriptBuild", "winHeight", winHeight)
@@ -6,7 +6,7 @@ File History:
6
6
  Created: 2023-05-13 [2.1b1] GuiManuscript
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -66,7 +66,7 @@ class GuiManuscript(QDialog):
66
66
 
67
67
  D_KEY = Qt.ItemDataRole.UserRole
68
68
 
69
- def __init__(self, mainGui: GuiMain):
69
+ def __init__(self, mainGui: GuiMain) -> None:
70
70
  super().__init__(parent=mainGui)
71
71
 
72
72
  logger.debug("Create: GuiManuscript")
@@ -173,7 +173,7 @@ class GuiManuscript(QDialog):
173
173
  self.btnBuild.clicked.connect(self._buildManuscript)
174
174
 
175
175
  self.btnClose = QPushButton(self.tr("Close"))
176
- self.btnClose.clicked.connect(self._doClose)
176
+ self.btnClose.clicked.connect(self.close)
177
177
 
178
178
  self.processBox = QGridLayout()
179
179
  self.processBox.addWidget(self.btnPreview, 0, 0)
@@ -217,11 +217,11 @@ class GuiManuscript(QDialog):
217
217
 
218
218
  return
219
219
 
220
- def __del__(self): # pragma: no cover
220
+ def __del__(self) -> None: # pragma: no cover
221
221
  logger.debug("Delete: GuiManuscript")
222
222
  return
223
223
 
224
- def loadContent(self):
224
+ def loadContent(self) -> None:
225
225
  """Load dialog content from project data."""
226
226
  if len(self._builds) == 0:
227
227
  build = BuildSettings()
@@ -255,7 +255,7 @@ class GuiManuscript(QDialog):
255
255
  # Events
256
256
  ##
257
257
 
258
- def closeEvent(self, event: QCloseEvent):
258
+ def closeEvent(self, event: QCloseEvent) -> None:
259
259
  """Capture the user closing the window so we can save GUI
260
260
  settings. We also check that we don't have a build settings
261
261
  dialog open.
@@ -274,7 +274,7 @@ class GuiManuscript(QDialog):
274
274
  ##
275
275
 
276
276
  @pyqtSlot()
277
- def _createNewBuild(self):
277
+ def _createNewBuild(self) -> None:
278
278
  """Open the build settings dialog for a new build."""
279
279
  build = BuildSettings()
280
280
  build.setName(self.tr("My Manuscript"))
@@ -282,7 +282,7 @@ class GuiManuscript(QDialog):
282
282
  return
283
283
 
284
284
  @pyqtSlot()
285
- def _editSelectedBuild(self):
285
+ def _editSelectedBuild(self) -> None:
286
286
  """Edit the currently selected build settings entry."""
287
287
  build = self._getSelectedBuild()
288
288
  if build is not None:
@@ -299,7 +299,7 @@ class GuiManuscript(QDialog):
299
299
  return
300
300
 
301
301
  @pyqtSlot()
302
- def _deleteSelectedBuild(self):
302
+ def _deleteSelectedBuild(self) -> None:
303
303
  """Delete the currently selected build settings entry."""
304
304
  build = self._getSelectedBuild()
305
305
  if build is not None:
@@ -309,7 +309,7 @@ class GuiManuscript(QDialog):
309
309
  return
310
310
 
311
311
  @pyqtSlot(BuildSettings)
312
- def _processNewSettings(self, build: BuildSettings):
312
+ def _processNewSettings(self, build: BuildSettings) -> None:
313
313
  """Process new build settings from the settings dialog."""
314
314
  self._builds.setBuild(build)
315
315
  self._updateBuildItem(build)
@@ -319,7 +319,7 @@ class GuiManuscript(QDialog):
319
319
  return
320
320
 
321
321
  @pyqtSlot()
322
- def _generatePreview(self):
322
+ def _generatePreview(self) -> None:
323
323
  """Run the document builder on the current build settings for
324
324
  the preview widget.
325
325
  """
@@ -359,7 +359,7 @@ class GuiManuscript(QDialog):
359
359
  return
360
360
 
361
361
  @pyqtSlot()
362
- def _buildManuscript(self):
362
+ def _buildManuscript(self) -> None:
363
363
  """Open the build dialog and build the manuscript."""
364
364
  build = self._getSelectedBuild()
365
365
  if isinstance(build, BuildSettings):
@@ -373,24 +373,18 @@ class GuiManuscript(QDialog):
373
373
  return
374
374
 
375
375
  @pyqtSlot()
376
- def _printDocument(self):
376
+ def _printDocument(self) -> None:
377
377
  """Open the print preview dialog."""
378
378
  thePreview = QPrintPreviewDialog(self)
379
379
  thePreview.paintRequested.connect(self.docPreview.printPreview)
380
380
  thePreview.exec_()
381
381
  return
382
382
 
383
- @pyqtSlot()
384
- def _doClose(self):
385
- """Forward the close button to the default close method."""
386
- self.close()
387
- return
388
-
389
383
  ##
390
384
  # Internal Functions
391
385
  ##
392
386
 
393
- def _updatePreview(self, data: dict, build: BuildSettings):
387
+ def _updatePreview(self, data: dict, build: BuildSettings) -> None:
394
388
  """Update the preview widget and set relevant values."""
395
389
  self.docPreview.setContent(data)
396
390
  self.docPreview.setBuildName(build.name)
@@ -415,10 +409,8 @@ class GuiManuscript(QDialog):
415
409
  return build
416
410
  return None
417
411
 
418
- def _saveSettings(self):
412
+ def _saveSettings(self) -> None:
419
413
  """Save the user GUI settings."""
420
- logger.debug("Saving GuiManuscript settings")
421
-
422
414
  buildOrder = []
423
415
  for i in range(self.buildList.count()):
424
416
  if item := self.buildList.item(i):
@@ -442,6 +434,7 @@ class GuiManuscript(QDialog):
442
434
  detailsWidth = CONFIG.rpxInt(self.buildDetails.getColumnWidth())
443
435
  detailsExpanded = self.buildDetails.getExpandedState()
444
436
 
437
+ logger.debug("Saving State: GuiManuscript")
445
438
  pOptions = SHARED.project.options
446
439
  pOptions.setValue("GuiManuscript", "winWidth", winWidth)
447
440
  pOptions.setValue("GuiManuscript", "winHeight", winHeight)
@@ -455,7 +448,7 @@ class GuiManuscript(QDialog):
455
448
 
456
449
  return
457
450
 
458
- def _openSettingsDialog(self, build: BuildSettings):
451
+ def _openSettingsDialog(self, build: BuildSettings) -> None:
459
452
  """Open the build settings dialog."""
460
453
  for obj in self.mainGui.children():
461
454
  # Don't open a second dialog if one exists
@@ -476,7 +469,7 @@ class GuiManuscript(QDialog):
476
469
 
477
470
  return
478
471
 
479
- def _updateBuildsList(self):
472
+ def _updateBuildsList(self) -> None:
480
473
  """Update the list of available builds."""
481
474
  self.buildList.clear()
482
475
  for key, name in self._builds.builds():
@@ -488,7 +481,7 @@ class GuiManuscript(QDialog):
488
481
  self._buildMap[key] = bItem
489
482
  return
490
483
 
491
- def _updateBuildItem(self, build: BuildSettings):
484
+ def _updateBuildItem(self, build: BuildSettings) -> None:
492
485
  """Update the entry of a specific build item."""
493
486
  bItem = self._buildMap.get(build.buildID, None)
494
487
  if isinstance(bItem, QListWidgetItem):
@@ -6,7 +6,7 @@ File History:
6
6
  Created: 2023-02-13 [2.1b1] GuiBuildSettings
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -253,13 +253,11 @@ class GuiBuildSettings(QDialog):
253
253
 
254
254
  def _saveSettings(self) -> None:
255
255
  """Save the various user settings."""
256
- logger.debug("Saving GuiBuildSettings settings")
257
-
258
256
  winWidth = CONFIG.rpxInt(self.width())
259
257
  winHeight = CONFIG.rpxInt(self.height())
260
-
261
258
  treeWidth, filterWidth = self.optTabSelect.mainSplitSizes()
262
259
 
260
+ logger.debug("Saving State: GuiBuildSettings")
263
261
  pOptions = SHARED.project.options
264
262
  pOptions.setValue("GuiBuildSettings", "winWidth", winWidth)
265
263
  pOptions.setValue("GuiBuildSettings", "winHeight", winHeight)
@@ -3,10 +3,10 @@ novelWriter – GUI New Project Wizard
3
3
  ====================================
4
4
 
5
5
  File History:
6
- Created: 2020-07-11 [0.10.1]
6
+ Created: 2020-07-11 [0.10.1] GuiProjectWizard
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ class GuiProjectWizard(QWizard):
80
80
 
81
81
  return
82
82
 
83
- def __del__(self): # pragma: no cover
83
+ def __del__(self) -> None: # pragma: no cover
84
84
  logger.debug("Delete: GuiProjectWizard")
85
85
  return
86
86
 
@@ -3,10 +3,10 @@ novelWriter – GUI Writing Statistics
3
3
  ====================================
4
4
 
5
5
  File History:
6
- Created: 2019-10-20 [0.3]
6
+ Created: 2019-10-20 [0.3.0] GuiWritingStats
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
9
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
10
 
11
11
  This program is free software: you can redistribute it and/or modify
12
12
  it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@ import logging
29
29
  from datetime import datetime
30
30
  from typing import TYPE_CHECKING
31
31
 
32
- from PyQt5.QtGui import QPixmap, QCursor
32
+ from PyQt5.QtGui import QCloseEvent, QPixmap, QCursor
33
33
  from PyQt5.QtCore import Qt, pyqtSlot
34
34
  from PyQt5.QtWidgets import (
35
35
  qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
@@ -307,9 +307,20 @@ class GuiWritingStats(QDialog):
307
307
  return
308
308
 
309
309
  ##
310
- # Slots
310
+ # Events
311
311
  ##
312
312
 
313
+ def closeEvent(self, event: QCloseEvent) -> None:
314
+ """Capture the user closing the window."""
315
+ event.accept()
316
+ self.deleteLater()
317
+ return
318
+
319
+ ##
320
+ # Private Slots
321
+ ##
322
+
323
+ @pyqtSlot()
313
324
  def _doClose(self) -> None:
314
325
  """Save the state of the window, clear cache, end close."""
315
326
  self.logData = []
@@ -330,6 +341,7 @@ class GuiWritingStats(QDialog):
330
341
  showIdleTime = self.showIdleTime.isChecked()
331
342
  histMax = self.histMax.value()
332
343
 
344
+ logger.debug("Saving State: GuiWritingStats")
333
345
  pOptions = SHARED.project.options
334
346
  pOptions.setValue("GuiWritingStats", "winWidth", winWidth)
335
347
  pOptions.setValue("GuiWritingStats", "winHeight", winHeight)
@@ -347,6 +359,7 @@ class GuiWritingStats(QDialog):
347
359
  pOptions.setValue("GuiWritingStats", "showIdleTime", showIdleTime)
348
360
  pOptions.setValue("GuiWritingStats", "histMax", histMax)
349
361
  pOptions.saveSettings()
362
+
350
363
  self.close()
351
364
 
352
365
  return
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
3
- <g fill="#aeaeae" stroke-width="1.1">
4
- <path d="m0.79397 2.8846-0.29357-0.21175 0.28393-0.5005-0.51975-0.23582 0.11068-0.3465 0.55825 0.1155 0.062562-0.56787h0.37057l0.062562 0.57268 0.55343-0.12032 0.1155 0.3465-0.51975 0.23582 0.28393 0.5005-0.29356 0.21175-0.385-0.42832z"/>
5
- <path d="m2.8219 3.15-0.09999 0.37496h0.86866l-0.09374-0.37496q-0.08749-0.30622-0.16873-0.64993-0.081241-0.34372-0.16248-0.66243h-0.024997q-0.074992 0.32496-0.15623 0.66868-0.074992 0.33747-0.16248 0.64369zm-1.4749 2.0623 1.2749-4.0746h1.1062l1.2749 4.0746h-0.97489l-0.24997-0.96865h-1.2437l-0.24997 0.96865z"/>
6
- <path d="m4.7812 2.8846-0.29357-0.21175 0.28394-0.5005-0.51975-0.23582 0.11069-0.3465 0.55825 0.1155 0.062562-0.56787h0.37056l0.062562 0.57268 0.55343-0.12032 0.1155 0.3465-0.51975 0.23582 0.28393 0.5005-0.29356 0.21175-0.385-0.42832z"/>
7
- </g>
8
- </svg>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
3
- <g fill="#aeaeae" stroke-width="1.3799">
4
- <path d="m0.52917 5.2683v-4.1866h1.0272v0.37972h-0.49167v3.4272h0.49167v0.37972z"/>
5
- <path d="m2.9 2.9219-0.077889 0.29209h0.67667l-0.073022-0.29209q-0.068154-0.23854-0.13144-0.50628-0.063285-0.26775-0.12657-0.51601h-0.019472q-0.058417 0.25314-0.1217 0.52088-0.058417 0.26288-0.12657 0.50141zm-1.1489 1.6065 0.9931-3.174h0.86166l0.9931 3.174h-0.75942l-0.19472-0.75455h-0.96876l-0.19472 0.75455z"/>
6
- <path d="m4.7937 5.2683v-0.37972h0.49654v-3.4272h-0.49654v-0.37972h1.0272v4.1866z"/>
7
- </g>
8
- </svg>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
3
- <g fill-opacity=".78039" stroke-width="1.1">
4
- <path d="m0.79397 2.8846-0.29357-0.21175 0.28393-0.5005-0.51975-0.23582 0.11068-0.3465 0.55825 0.1155 0.062562-0.56787h0.37057l0.062562 0.57268 0.55343-0.12032 0.1155 0.3465-0.51975 0.23582 0.28393 0.5005-0.29356 0.21175-0.385-0.42832z"/>
5
- <path d="m2.8219 3.15-0.09999 0.37496h0.86866l-0.09374-0.37496q-0.08749-0.30622-0.16873-0.64993-0.081241-0.34372-0.16248-0.66243h-0.024997q-0.074992 0.32496-0.15623 0.66868-0.074992 0.33747-0.16248 0.64369zm-1.4749 2.0623 1.2749-4.0746h1.1062l1.2749 4.0746h-0.97489l-0.24997-0.96865h-1.2437l-0.24997 0.96865z"/>
6
- <path d="m4.7812 2.8846-0.29357-0.21175 0.28394-0.5005-0.51975-0.23582 0.11069-0.3465 0.55825 0.1155 0.062562-0.56787h0.37056l0.062562 0.57268 0.55343-0.12032 0.1155 0.3465-0.51975 0.23582 0.28393 0.5005-0.29356 0.21175-0.385-0.42832z"/>
7
- </g>
8
- </svg>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
3
- <g fill-opacity=".78039" stroke-width="1.3799">
4
- <path d="m0.52917 5.2683v-4.1866h1.0272v0.37972h-0.49167v3.4272h0.49167v0.37972z"/>
5
- <path d="m2.9 2.9219-0.077889 0.29209h0.67667l-0.073022-0.29209q-0.068154-0.23854-0.13144-0.50628-0.063285-0.26775-0.12657-0.51601h-0.019472q-0.058417 0.25314-0.1217 0.52088-0.058417 0.26288-0.12657 0.50141zm-1.1489 1.6065 0.9931-3.174h0.86166l0.9931 3.174h-0.75942l-0.19472-0.75455h-0.96876l-0.19472 0.75455z"/>
6
- <path d="m4.7937 5.2683v-0.37972h0.49654v-3.4272h-0.49654v-0.37972h1.0272v4.1866z"/>
7
- </g>
8
- </svg>