novelWriter 2.4.4__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 (122) hide show
  1. {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/METADATA +4 -5
  2. {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/RECORD +121 -111
  3. {novelWriter-2.4.4.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/icons/typicons_dark/icons.conf +2 -0
  19. novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
  20. novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
  21. novelwriter/assets/icons/typicons_light/icons.conf +2 -0
  22. novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
  23. novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
  24. novelwriter/assets/manual.pdf +0 -0
  25. novelwriter/assets/sample.zip +0 -0
  26. novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
  27. novelwriter/assets/syntax/default_dark.conf +32 -18
  28. novelwriter/assets/syntax/default_light.conf +24 -10
  29. novelwriter/assets/syntax/dracula.conf +44 -0
  30. novelwriter/assets/syntax/grey_dark.conf +5 -4
  31. novelwriter/assets/syntax/grey_light.conf +5 -4
  32. novelwriter/assets/syntax/light_owl.conf +7 -6
  33. novelwriter/assets/syntax/night_owl.conf +7 -6
  34. novelwriter/assets/syntax/snazzy.conf +42 -0
  35. novelwriter/assets/syntax/solarized_dark.conf +4 -3
  36. novelwriter/assets/syntax/solarized_light.conf +4 -3
  37. novelwriter/assets/syntax/tango.conf +27 -11
  38. novelwriter/assets/syntax/tomorrow.conf +6 -5
  39. novelwriter/assets/syntax/tomorrow_night.conf +7 -6
  40. novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
  41. novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
  42. novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
  43. novelwriter/assets/text/credits_en.htm +52 -41
  44. novelwriter/assets/themes/cyberpunk_night.conf +3 -0
  45. novelwriter/assets/themes/default_dark.conf +2 -0
  46. novelwriter/assets/themes/default_light.conf +2 -0
  47. novelwriter/assets/themes/dracula.conf +48 -0
  48. novelwriter/assets/themes/solarized_dark.conf +2 -0
  49. novelwriter/assets/themes/solarized_light.conf +2 -0
  50. novelwriter/common.py +33 -12
  51. novelwriter/config.py +184 -98
  52. novelwriter/constants.py +47 -35
  53. novelwriter/core/buildsettings.py +68 -69
  54. novelwriter/core/coretools.py +5 -23
  55. novelwriter/core/docbuild.py +52 -40
  56. novelwriter/core/document.py +3 -5
  57. novelwriter/core/index.py +115 -45
  58. novelwriter/core/item.py +8 -19
  59. novelwriter/core/options.py +2 -4
  60. novelwriter/core/project.py +37 -61
  61. novelwriter/core/projectdata.py +1 -3
  62. novelwriter/core/projectxml.py +12 -15
  63. novelwriter/core/sessions.py +3 -5
  64. novelwriter/core/spellcheck.py +4 -9
  65. novelwriter/core/status.py +211 -164
  66. novelwriter/core/storage.py +0 -8
  67. novelwriter/core/tohtml.py +139 -105
  68. novelwriter/core/tokenizer.py +278 -122
  69. novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
  70. novelwriter/core/toodt.py +257 -166
  71. novelwriter/core/toqdoc.py +419 -0
  72. novelwriter/core/tree.py +5 -7
  73. novelwriter/dialogs/about.py +11 -18
  74. novelwriter/dialogs/docmerge.py +17 -19
  75. novelwriter/dialogs/docsplit.py +17 -19
  76. novelwriter/dialogs/editlabel.py +6 -10
  77. novelwriter/dialogs/preferences.py +200 -164
  78. novelwriter/dialogs/projectsettings.py +225 -189
  79. novelwriter/dialogs/quotes.py +12 -9
  80. novelwriter/dialogs/wordlist.py +9 -15
  81. novelwriter/enum.py +35 -30
  82. novelwriter/error.py +8 -15
  83. novelwriter/extensions/configlayout.py +55 -21
  84. novelwriter/extensions/eventfilters.py +1 -5
  85. novelwriter/extensions/modified.py +58 -14
  86. novelwriter/extensions/novelselector.py +1 -3
  87. novelwriter/extensions/pagedsidebar.py +9 -12
  88. novelwriter/extensions/{circularprogress.py → progressbars.py} +30 -8
  89. novelwriter/extensions/statusled.py +40 -26
  90. novelwriter/extensions/switch.py +4 -6
  91. novelwriter/extensions/switchbox.py +7 -6
  92. novelwriter/extensions/versioninfo.py +3 -9
  93. novelwriter/gui/doceditor.py +120 -139
  94. novelwriter/gui/dochighlight.py +231 -186
  95. novelwriter/gui/docviewer.py +69 -108
  96. novelwriter/gui/docviewerpanel.py +3 -10
  97. novelwriter/gui/editordocument.py +1 -3
  98. novelwriter/gui/itemdetails.py +7 -11
  99. novelwriter/gui/mainmenu.py +22 -18
  100. novelwriter/gui/noveltree.py +11 -24
  101. novelwriter/gui/outline.py +15 -26
  102. novelwriter/gui/projtree.py +35 -60
  103. novelwriter/gui/search.py +10 -3
  104. novelwriter/gui/sidebar.py +2 -6
  105. novelwriter/gui/statusbar.py +29 -37
  106. novelwriter/gui/theme.py +26 -48
  107. novelwriter/guimain.py +162 -160
  108. novelwriter/shared.py +36 -32
  109. novelwriter/text/patterns.py +113 -0
  110. novelwriter/tools/dictionaries.py +10 -20
  111. novelwriter/tools/lipsum.py +10 -16
  112. novelwriter/tools/manusbuild.py +9 -11
  113. novelwriter/tools/manuscript.py +71 -145
  114. novelwriter/tools/manussettings.py +71 -75
  115. novelwriter/tools/noveldetails.py +16 -21
  116. novelwriter/tools/welcome.py +21 -26
  117. novelwriter/tools/writingstats.py +9 -12
  118. novelwriter/types.py +49 -4
  119. novelwriter/extensions/simpleprogress.py +0 -55
  120. {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/LICENSE.md +0 -0
  121. {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/entry_points.txt +0 -0
  122. {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/top_level.txt +0 -0
@@ -23,37 +23,34 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- import json
27
26
  import logging
28
27
 
29
- from datetime import datetime
30
28
  from time import time
31
29
  from typing import TYPE_CHECKING
32
30
 
33
31
  from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
34
- from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QPalette, QResizeEvent
32
+ from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent, QTextDocument
35
33
  from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
36
34
  from PyQt5.QtWidgets import (
37
35
  QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
38
- QLabel, QListWidget, QListWidgetItem, QPushButton, QSizePolicy, QSplitter,
36
+ QLabel, QListWidget, QListWidgetItem, QPushButton, QSplitter,
39
37
  QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem,
40
38
  QVBoxLayout, QWidget
41
39
  )
42
40
 
43
41
  from novelwriter import CONFIG, SHARED
44
- from novelwriter.common import checkInt, fuzzyTime
42
+ from novelwriter.common import fuzzyTime
45
43
  from novelwriter.core.buildsettings import BuildCollection, BuildSettings
46
44
  from novelwriter.core.docbuild import NWBuildDocument
47
- from novelwriter.core.tohtml import ToHtml
48
45
  from novelwriter.core.tokenizer import HeadingFormatter
49
- from novelwriter.error import logException
50
- from novelwriter.extensions.circularprogress import NProgressCircle
51
- from novelwriter.extensions.modified import NDialog, NIconToggleButton, NIconToolButton
46
+ from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
47
+ from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
48
+ from novelwriter.extensions.progressbars import NProgressCircle
52
49
  from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON
53
50
  from novelwriter.tools.manusbuild import GuiManuscriptBuild
54
51
  from novelwriter.tools.manussettings import GuiBuildSettings
55
52
  from novelwriter.types import (
56
- QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignRight, QtAlignTop,
53
+ QtAlignCenter, QtAlignRight, QtAlignTop, QtSizeExpanding, QtSizeIgnored,
57
54
  QtUserRole
58
55
  )
59
56
 
@@ -63,7 +60,7 @@ if TYPE_CHECKING: # pragma: no cover
63
60
  logger = logging.getLogger(__name__)
64
61
 
65
62
 
66
- class GuiManuscript(NDialog):
63
+ class GuiManuscript(NToolDialog):
67
64
  """GUI Tools: Manuscript Tool
68
65
 
69
66
  The dialog displays all the users build definitions, a preview panel
@@ -73,15 +70,11 @@ class GuiManuscript(NDialog):
73
70
 
74
71
  D_KEY = QtUserRole
75
72
 
76
- def __init__(self, mainGui: GuiMain) -> None:
77
- super().__init__(parent=mainGui)
73
+ def __init__(self, parent: GuiMain) -> None:
74
+ super().__init__(parent=parent)
78
75
 
79
76
  logger.debug("Create: GuiManuscript")
80
77
  self.setObjectName("GuiManuscript")
81
- if CONFIG.osDarwin:
82
- self.setWindowFlag(Qt.WindowType.Tool)
83
-
84
- self.mainGui = mainGui
85
78
 
86
79
  self._builds = BuildCollection(SHARED.project)
87
80
  self._buildMap: dict[str, QListWidgetItem] = {}
@@ -253,20 +246,7 @@ class GuiManuscript(NDialog):
253
246
  self._updateBuildsList()
254
247
  if selected in self._buildMap:
255
248
  self.buildList.setCurrentItem(self._buildMap[selected])
256
-
257
- logger.debug("Loading build cache")
258
- cache = CONFIG.dataPath("cache") / f"build_{SHARED.project.data.uuid}.json"
259
- if cache.is_file():
260
- try:
261
- with open(cache, mode="r", encoding="utf-8") as fObj:
262
- data = json.load(fObj)
263
- build = self._builds.getBuild(data.get("uuid", ""))
264
- if isinstance(build, BuildSettings):
265
- self._updatePreview(data, build)
266
- except Exception:
267
- logger.error("Failed to load build cache")
268
- logException()
269
- return
249
+ QTimer.singleShot(200, self._generatePreview)
270
250
 
271
251
  return
272
252
 
@@ -280,7 +260,7 @@ class GuiManuscript(NDialog):
280
260
  dialog open.
281
261
  """
282
262
  self._saveSettings()
283
- for obj in self.mainGui.children():
263
+ for obj in SHARED.mainGui.children():
284
264
  # Make sure we don't have any settings windows open
285
265
  if isinstance(obj, GuiBuildSettings) and obj.isVisible():
286
266
  obj.close()
@@ -342,40 +322,47 @@ class GuiManuscript(NDialog):
342
322
  if not (build := self._getSelectedBuild()):
343
323
  return
344
324
 
325
+ start = time()
326
+
345
327
  # Make sure editor content is saved before we start
346
- SHARED.ensureEditorSaved(None)
328
+ SHARED.saveEditor()
347
329
 
348
330
  docBuild = NWBuildDocument(SHARED.project, build)
349
- docBuild.setPreviewMode(True)
350
331
  docBuild.queueAll()
351
332
 
333
+ theme = TextDocumentTheme()
334
+ theme.text = QColor(0, 0, 0)
335
+ theme.highlight = QColor(255, 255, 166)
336
+ theme.head = QColor(66, 113, 174)
337
+ theme.comment = QColor(100, 100, 100)
338
+ theme.note = QColor(129, 55, 9)
339
+ theme.code = QColor(66, 113, 174)
340
+ theme.modifier = QColor(129, 55, 9)
341
+ theme.keyword = QColor(245, 135, 31)
342
+ theme.tag = QColor(66, 113, 174)
343
+ theme.optional = QColor(66, 113, 174)
344
+ theme.dialog = QColor(66, 113, 174)
345
+ theme.altdialog = QColor(129, 55, 9)
346
+
352
347
  self.docPreview.beginNewBuild(len(docBuild))
353
- for step, _ in docBuild.iterBuildHTML(None):
348
+ for step, _ in docBuild.iterBuildPreview(theme):
354
349
  self.docPreview.buildStep(step + 1)
355
350
  QApplication.processEvents()
356
351
 
357
352
  buildObj = docBuild.lastBuild
358
- assert isinstance(buildObj, ToHtml)
359
- result = {
360
- "uuid": build.buildID,
361
- "time": int(time()),
362
- "stats": buildObj.textStats,
363
- "outline": buildObj.textOutline,
364
- "styles": buildObj.getStyleSheet(),
365
- "html": buildObj.fullHTML,
366
- }
367
-
368
- self._updatePreview(result, build)
369
-
370
- logger.debug("Saving build cache")
371
- cache = CONFIG.dataPath("cache") / f"build_{SHARED.project.data.uuid}.json"
372
- try:
373
- with open(cache, mode="w+", encoding="utf-8") as outFile:
374
- outFile.write(json.dumps(result, indent=2))
375
- except Exception:
376
- logger.error("Failed to save build cache")
377
- logException()
378
- return
353
+ assert isinstance(buildObj, ToQTextDocument)
354
+
355
+ font = QFont()
356
+ font.fromString(build.getStr("format.textFont"))
357
+
358
+ self.docPreview.setTextFont(font)
359
+ self.docPreview.setContent(buildObj.document)
360
+ self.docPreview.setBuildName(build.name)
361
+
362
+ self.docStats.updateStats(buildObj.textStats)
363
+ self.buildOutline.updateOutline(buildObj.textOutline)
364
+
365
+ logger.debug("Build completed in %.3f ms", 1000*(time()-start))
379
366
 
380
367
  return
381
368
 
@@ -383,8 +370,8 @@ class GuiManuscript(NDialog):
383
370
  def _buildManuscript(self) -> None:
384
371
  """Open the build dialog and build the manuscript."""
385
372
  if build := self._getSelectedBuild():
386
- dlgBuild = GuiManuscriptBuild(self, build)
387
- dlgBuild.exec()
373
+ dialog = GuiManuscriptBuild(self, build)
374
+ dialog.exec()
388
375
 
389
376
  # After the build is done, save build settings changes
390
377
  if build.changed:
@@ -404,21 +391,6 @@ class GuiManuscript(NDialog):
404
391
  # Internal Functions
405
392
  ##
406
393
 
407
- def _updatePreview(self, data: dict, build: BuildSettings) -> None:
408
- """Update the preview widget and set relevant values."""
409
- self.docPreview.setContent(data)
410
- self.docPreview.setBuildName(build.name)
411
- self.docPreview.setTextFont(
412
- build.getStr("format.textFont"),
413
- build.getInt("format.textSize")
414
- )
415
- self.docPreview.setJustify(
416
- build.getBool("format.justifyText")
417
- )
418
- self.docStats.updateStats(data.get("stats", {}))
419
- self.buildOutline.updateOutline(data.get("outline", {}))
420
- return
421
-
422
394
  def _getSelectedBuild(self) -> BuildSettings | None:
423
395
  """Get the currently selected build. If none are selected,
424
396
  automatically select the first one.
@@ -473,17 +445,13 @@ class GuiManuscript(NDialog):
473
445
  def _openSettingsDialog(self, build: BuildSettings) -> None:
474
446
  """Open the build settings dialog."""
475
447
  if dialog := self._findSettingsDialog(build.buildID):
476
- dialog.show()
477
- dialog.raise_()
448
+ dialog.activateDialog()
478
449
  return
479
450
 
480
- dlgSettings = GuiBuildSettings(self.mainGui, build)
481
- dlgSettings.setModal(False)
482
- dlgSettings.show()
483
- dlgSettings.raise_()
484
- QApplication.processEvents()
485
- dlgSettings.loadContent()
486
- dlgSettings.newSettingsReady.connect(self._processNewSettings)
451
+ dialog = GuiBuildSettings(SHARED.mainGui, build)
452
+ dialog.activateDialog()
453
+ dialog.loadContent()
454
+ dialog.newSettingsReady.connect(self._processNewSettings)
487
455
 
488
456
  return
489
457
 
@@ -518,8 +486,6 @@ class GuiManuscript(NDialog):
518
486
  return obj
519
487
  return None
520
488
 
521
- # END Class GuiManuscript
522
-
523
489
 
524
490
  class _DetailsWidget(QWidget):
525
491
 
@@ -661,8 +627,6 @@ class _DetailsWidget(QWidget):
661
627
 
662
628
  return
663
629
 
664
- # END Class _DetailsWidget
665
-
666
630
 
667
631
  class _OutlineWidget(QWidget):
668
632
 
@@ -742,8 +706,6 @@ class _OutlineWidget(QWidget):
742
706
  self.outlineEntryClicked.emit(str(item.data(0, self.D_LINE)))
743
707
  return
744
708
 
745
- # END Class _OutlineWidget
746
-
747
709
 
748
710
  class _PreviewWidget(QTextBrowser):
749
711
 
@@ -801,7 +763,7 @@ class _PreviewWidget(QTextBrowser):
801
763
  self._updateDocMargins()
802
764
  self._updateBuildAge()
803
765
 
804
- self.setTextFont(CONFIG.textFont, CONFIG.textSize)
766
+ self.setTextFont(CONFIG.textFont)
805
767
 
806
768
  # Age Timer
807
769
  self.ageTimer = QTimer(self)
@@ -821,28 +783,14 @@ class _PreviewWidget(QTextBrowser):
821
783
  self._updateBuildAge()
822
784
  return
823
785
 
824
- def setJustify(self, state: bool) -> None:
825
- """Enable/disable the justify text option."""
826
- pOptions = self.document().defaultTextOption()
827
- if state:
828
- pOptions.setAlignment(QtAlignJustify)
829
- else:
830
- pOptions.setAlignment(QtAlignAbsolute)
831
- self.document().setDefaultTextOption(pOptions)
832
- return
833
-
834
- def setTextFont(self, family: str, size: int) -> None:
786
+ def setTextFont(self, font: QFont) -> None:
835
787
  """Set the text font properties and then reset for sub-widgets.
836
788
  This needs special attention since there appears to be a bug in
837
789
  Qt 5.15.3. See issues #1862 and #1875.
838
790
  """
839
- if family and size > 4:
840
- font = self.font()
841
- font.setFamily(family)
842
- font.setPointSize(size)
843
- self.setFont(font)
844
- self.buildProgress.setFont(SHARED.theme.guiFont)
845
- self.ageLabel.setFont(SHARED.theme.guiFontSmall)
791
+ self.setFont(font)
792
+ self.buildProgress.setFont(SHARED.theme.guiFont)
793
+ self.ageLabel.setFont(SHARED.theme.guiFontSmall)
846
794
  return
847
795
 
848
796
  ##
@@ -866,31 +814,19 @@ class _PreviewWidget(QTextBrowser):
866
814
  QApplication.processEvents()
867
815
  return
868
816
 
869
- def setContent(self, data: dict) -> None:
817
+ def setContent(self, document: QTextDocument) -> None:
870
818
  """Set the content of the preview widget."""
871
819
  QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
872
820
 
873
821
  self.buildProgress.setCentreText(self.tr("Processing ..."))
874
822
  QApplication.processEvents()
875
823
 
876
- styles = "\n".join(data.get("styles", []))
877
- self.document().setDefaultStyleSheet(styles)
878
-
879
- html = "".join(data.get("html", []))
880
- html = html.replace("\t", "!!tab!!")
881
- self.setHtml(html)
882
- QApplication.processEvents()
883
- while self.find("!!tab!!"):
884
- cursor = self.textCursor()
885
- cursor.insertText("\t")
824
+ document.setDocumentMargin(CONFIG.getTextMargin())
825
+ self.setDocument(document)
886
826
 
887
- self._docTime = checkInt(data.get("time"), 0)
827
+ self._docTime = int(time())
888
828
  self._updateBuildAge()
889
829
 
890
- # Since we change the content while it may still be rendering, we mark
891
- # the document as dirty again to make sure it's re-rendered properly.
892
- self.document().markContentsDirty(0, self.document().characterCount())
893
-
894
830
  self.buildProgress.setCentreText(self.tr("Done"))
895
831
  QApplication.restoreOverrideCursor()
896
832
  QApplication.processEvents()
@@ -935,17 +871,14 @@ class _PreviewWidget(QTextBrowser):
935
871
  @pyqtSlot()
936
872
  def _updateBuildAge(self) -> None:
937
873
  """Update the build time and the fuzzy age."""
938
- if self._docTime > 0:
939
- strBuildTime = "%s (%s)" % (
940
- CONFIG.localDateTime(datetime.fromtimestamp(self._docTime)),
941
- fuzzyTime(int(time()) - self._docTime)
942
- )
874
+ if self._buildName and self._docTime > 0:
875
+ self.ageLabel.setText("<b>{0}</b><br>{1}: {2}".format(
876
+ self._buildName,
877
+ self.tr("Built"),
878
+ fuzzyTime(int(time()) - self._docTime),
879
+ ))
943
880
  else:
944
- strBuildTime = self.tr("Unknown")
945
- text = "{0}: {1}".format(self.tr("Built"), strBuildTime)
946
- if self._buildName:
947
- text = "<b>{0}</b><br>{1}".format(self._buildName, text)
948
- self.ageLabel.setText(text)
881
+ self.ageLabel.setText("<b>{0}</b>".format(self.tr("No Preview")))
949
882
  return
950
883
 
951
884
  @pyqtSlot()
@@ -964,9 +897,8 @@ class _PreviewWidget(QTextBrowser):
964
897
  document within the viewport.
965
898
  """
966
899
  vBar = self.verticalScrollBar()
967
- sW = vBar.width() if vBar.isVisible() else 0
968
900
  tB = self.frameWidth()
969
- vW = self.width() - 2*tB - sW
901
+ vW = self.width() - 2*tB - vBar.width()
970
902
  vH = self.height() - 2*tB
971
903
  tH = self.ageLabel.height()
972
904
  pS = self.buildProgress.width()
@@ -975,8 +907,6 @@ class _PreviewWidget(QTextBrowser):
975
907
  self.buildProgress.move((vW-pS)//2, (vH-pS)//2)
976
908
  return
977
909
 
978
- # END Class _PreviewWidget
979
-
980
910
 
981
911
  class _StatsWidget(QWidget):
982
912
 
@@ -1041,16 +971,14 @@ class _StatsWidget(QWidget):
1041
971
  @pyqtSlot(bool)
1042
972
  def _toggleView(self, state: bool) -> None:
1043
973
  """Toggle minimal or maximal view."""
1044
- ignored = QSizePolicy.Policy.Ignored
1045
- expanded = QSizePolicy.Policy.Expanding
1046
974
  if state:
1047
975
  self.mainStack.setCurrentWidget(self.maxWidget)
1048
- self.maxWidget.setSizePolicy(expanded, expanded)
1049
- self.minWidget.setSizePolicy(ignored, ignored)
976
+ self.maxWidget.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
977
+ self.minWidget.setSizePolicy(QtSizeIgnored, QtSizeIgnored)
1050
978
  else:
1051
979
  self.mainStack.setCurrentWidget(self.minWidget)
1052
- self.maxWidget.setSizePolicy(ignored, ignored)
1053
- self.minWidget.setSizePolicy(expanded, expanded)
980
+ self.maxWidget.setSizePolicy(QtSizeIgnored, QtSizeIgnored)
981
+ self.minWidget.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
1054
982
  self.maxWidget.adjustSize()
1055
983
  self.minWidget.adjustSize()
1056
984
  self.mainStack.adjustSize()
@@ -1152,5 +1080,3 @@ class _StatsWidget(QWidget):
1152
1080
  self.maxWidget.setLayout(self.maxLayout)
1153
1081
 
1154
1082
  return
1155
-
1156
- # END Class _StatsWidget