novelWriter 2.4b1__py3-none-any.whl → 2.4.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 (89) hide show
  1. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/METADATA +5 -6
  2. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/RECORD +79 -83
  3. novelwriter/__init__.py +15 -8
  4. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  5. novelwriter/assets/i18n/nw_en_US.qm +0 -0
  6. novelwriter/assets/i18n/nw_es_419.qm +0 -0
  7. novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
  8. novelwriter/assets/i18n/nw_it_IT.qm +0 -0
  9. novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
  10. novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
  11. novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
  12. novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
  13. novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
  14. novelwriter/assets/icons/none.svg +4 -0
  15. novelwriter/assets/icons/typicons_dark/icons.conf +2 -2
  16. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +4 -0
  17. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +4 -0
  18. novelwriter/assets/icons/typicons_light/icons.conf +2 -2
  19. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +4 -0
  20. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +4 -0
  21. novelwriter/assets/manual.pdf +0 -0
  22. novelwriter/assets/sample.zip +0 -0
  23. novelwriter/common.py +11 -3
  24. novelwriter/config.py +12 -4
  25. novelwriter/core/buildsettings.py +7 -7
  26. novelwriter/core/coretools.py +21 -22
  27. novelwriter/core/docbuild.py +2 -2
  28. novelwriter/core/projectxml.py +1 -1
  29. novelwriter/core/spellcheck.py +3 -3
  30. novelwriter/core/status.py +3 -2
  31. novelwriter/core/tokenizer.py +3 -3
  32. novelwriter/core/toodt.py +333 -356
  33. novelwriter/dialogs/about.py +9 -11
  34. novelwriter/dialogs/docmerge.py +17 -14
  35. novelwriter/dialogs/docsplit.py +14 -12
  36. novelwriter/dialogs/editlabel.py +5 -4
  37. novelwriter/dialogs/preferences.py +29 -34
  38. novelwriter/dialogs/projectsettings.py +31 -28
  39. novelwriter/dialogs/quotes.py +10 -9
  40. novelwriter/dialogs/wordlist.py +17 -14
  41. novelwriter/error.py +14 -12
  42. novelwriter/extensions/circularprogress.py +12 -8
  43. novelwriter/extensions/configlayout.py +1 -3
  44. novelwriter/extensions/modified.py +33 -2
  45. novelwriter/extensions/pagedsidebar.py +16 -14
  46. novelwriter/extensions/simpleprogress.py +3 -1
  47. novelwriter/extensions/statusled.py +3 -1
  48. novelwriter/extensions/switch.py +10 -9
  49. novelwriter/extensions/switchbox.py +14 -13
  50. novelwriter/gui/doceditor.py +205 -246
  51. novelwriter/gui/dochighlight.py +26 -9
  52. novelwriter/gui/docviewer.py +55 -59
  53. novelwriter/gui/docviewerpanel.py +16 -13
  54. novelwriter/gui/editordocument.py +4 -4
  55. novelwriter/gui/itemdetails.py +45 -48
  56. novelwriter/gui/mainmenu.py +2 -2
  57. novelwriter/gui/noveltree.py +23 -21
  58. novelwriter/gui/outline.py +93 -94
  59. novelwriter/gui/projtree.py +32 -30
  60. novelwriter/gui/search.py +75 -29
  61. novelwriter/gui/sidebar.py +24 -28
  62. novelwriter/gui/statusbar.py +14 -14
  63. novelwriter/gui/theme.py +61 -39
  64. novelwriter/guimain.py +37 -33
  65. novelwriter/shared.py +21 -9
  66. novelwriter/text/counting.py +1 -0
  67. novelwriter/tools/dictionaries.py +15 -14
  68. novelwriter/tools/lipsum.py +20 -17
  69. novelwriter/tools/manusbuild.py +44 -35
  70. novelwriter/tools/manuscript.py +112 -112
  71. novelwriter/tools/manussettings.py +91 -98
  72. novelwriter/tools/noveldetails.py +20 -18
  73. novelwriter/tools/welcome.py +51 -48
  74. novelwriter/tools/writingstats.py +61 -55
  75. novelwriter/types.py +90 -0
  76. novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +0 -4
  77. novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +0 -4
  78. novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +0 -4
  79. novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +0 -4
  80. novelwriter/core/__init__.py +0 -3
  81. novelwriter/dialogs/__init__.py +0 -3
  82. novelwriter/extensions/__init__.py +0 -3
  83. novelwriter/gui/__init__.py +0 -3
  84. novelwriter/text/__init__.py +0 -3
  85. novelwriter/tools/__init__.py +0 -3
  86. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/LICENSE.md +0 -0
  87. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/WHEEL +0 -0
  88. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/entry_points.txt +0 -0
  89. {novelWriter-2.4b1.dist-info → novelWriter-2.4.1.dist-info}/top_level.txt +0 -0
@@ -27,25 +27,29 @@ import logging
27
27
 
28
28
  from typing import TYPE_CHECKING
29
29
 
30
+ from PyQt5.QtCore import QEvent, Qt, pyqtSignal, pyqtSlot
30
31
  from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
31
- from PyQt5.QtCore import QEvent, QSize, Qt, pyqtSignal, pyqtSlot
32
32
  from PyQt5.QtWidgets import (
33
- QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox,
34
- QFontDialog, QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel,
35
- QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSplitter, QStackedWidget,
36
- QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
33
+ QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFontDialog,
34
+ QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu,
35
+ QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, QTreeWidget,
36
+ QTreeWidgetItem, QVBoxLayout, QWidget
37
37
  )
38
38
 
39
39
  from novelwriter import CONFIG, SHARED
40
40
  from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst
41
41
  from novelwriter.core.buildsettings import BuildSettings, FilterMode
42
- from novelwriter.extensions.switch import NSwitch
43
- from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox
44
- from novelwriter.extensions.switchbox import NSwitchBox
45
42
  from novelwriter.extensions.configlayout import (
46
43
  NColourLabel, NFixedPage, NScrollableForm, NScrollablePage
47
44
  )
45
+ from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox
48
46
  from novelwriter.extensions.pagedsidebar import NPagedSideBar
47
+ from novelwriter.extensions.switch import NSwitch
48
+ from novelwriter.extensions.switchbox import NSwitchBox
49
+ from novelwriter.types import (
50
+ QtAlignLeft, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept,
51
+ QtRoleApply, QtRoleReject, QtUserRole
52
+ )
49
53
 
50
54
  if TYPE_CHECKING: # pragma: no cover
51
55
  from novelwriter.guimain import GuiMain
@@ -98,7 +102,7 @@ class GuiBuildSettings(QDialog):
98
102
  )
99
103
 
100
104
  # Settings Name
101
- self.lblBuildName = QLabel(self.tr("Name"))
105
+ self.lblBuildName = QLabel(self.tr("Name"), self)
102
106
  self.editBuildName = QLineEdit(self)
103
107
 
104
108
  # SideBar
@@ -130,11 +134,7 @@ class GuiBuildSettings(QDialog):
130
134
  self.toolStack.addWidget(self.optTabOutput)
131
135
 
132
136
  # Buttons
133
- self.buttonBox = QDialogButtonBox(
134
- QDialogButtonBox.StandardButton.Apply
135
- | QDialogButtonBox.StandardButton.Save
136
- | QDialogButtonBox.StandardButton.Close
137
- )
137
+ self.buttonBox = QDialogButtonBox(QtDialogApply | QtDialogSave | QtDialogClose, self)
138
138
  self.buttonBox.clicked.connect(self._dialogButtonClicked)
139
139
 
140
140
  # Assemble
@@ -225,12 +225,12 @@ class GuiBuildSettings(QDialog):
225
225
  def _dialogButtonClicked(self, button: QAbstractButton) -> None:
226
226
  """Handle button clicks from the dialog button box."""
227
227
  role = self.buttonBox.buttonRole(button)
228
- if role == QDialogButtonBox.ApplyRole:
228
+ if role == QtRoleApply:
229
229
  self._emitBuildData()
230
- elif role == QDialogButtonBox.AcceptRole:
230
+ elif role == QtRoleAccept:
231
231
  self._emitBuildData()
232
232
  self.close()
233
- elif role == QDialogButtonBox.RejectRole:
233
+ elif role == QtRoleReject:
234
234
  self.close()
235
235
  return
236
236
 
@@ -288,8 +288,8 @@ class _FilterTab(NFixedPage):
288
288
  C_ACTIVE = 1
289
289
  C_STATUS = 2
290
290
 
291
- D_HANDLE = Qt.ItemDataRole.UserRole
292
- D_FILE = Qt.ItemDataRole.UserRole + 1
291
+ D_HANDLE = QtUserRole
292
+ D_FILE = QtUserRole + 1
293
293
 
294
294
  F_NONE = 0
295
295
  F_FILTERED = 1
@@ -315,13 +315,13 @@ class _FilterTab(NFixedPage):
315
315
  # Project Tree
316
316
  # ============
317
317
 
318
- # Tree Settings
319
- iPx = SHARED.theme.baseIconSize
318
+ iSz = SHARED.theme.baseIconSize
319
+ iPx = SHARED.theme.baseIconHeight
320
320
  cMg = CONFIG.pxInt(6)
321
321
 
322
322
  # Tree Widget
323
323
  self.optTree = QTreeWidget(self)
324
- self.optTree.setIconSize(QSize(iPx, iPx))
324
+ self.optTree.setIconSize(iSz)
325
325
  self.optTree.setUniformRowHeights(True)
326
326
  self.optTree.setAllColumnsShowFocus(True)
327
327
  self.optTree.setHeaderHidden(True)
@@ -331,36 +331,35 @@ class _FilterTab(NFixedPage):
331
331
  treeHeader = self.optTree.header()
332
332
  treeHeader.setStretchLastSection(False)
333
333
  treeHeader.setMinimumSectionSize(iPx + cMg) # See Issue #1551
334
- treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.Stretch)
335
- treeHeader.setSectionResizeMode(self.C_ACTIVE, QHeaderView.Fixed)
336
- treeHeader.setSectionResizeMode(self.C_STATUS, QHeaderView.Fixed)
334
+ treeHeader.setSectionResizeMode(self.C_NAME, QHeaderView.ResizeMode.Stretch)
335
+ treeHeader.setSectionResizeMode(self.C_ACTIVE, QHeaderView.ResizeMode.Fixed)
336
+ treeHeader.setSectionResizeMode(self.C_STATUS, QHeaderView.ResizeMode.Fixed)
337
337
  treeHeader.resizeSection(self.C_ACTIVE, iPx + cMg)
338
338
  treeHeader.resizeSection(self.C_STATUS, iPx + cMg)
339
339
 
340
- self.optTree.setDragDropMode(QAbstractItemView.NoDragDrop)
341
- self.optTree.setSelectionMode(QAbstractItemView.ExtendedSelection)
342
- self.optTree.setSelectionBehavior(QAbstractItemView.SelectRows)
340
+ self.optTree.setDragDropMode(QAbstractItemView.DragDropMode.NoDragDrop)
341
+ self.optTree.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
342
+ self.optTree.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
343
343
 
344
344
  # Filters
345
345
  # =======
346
346
 
347
- self.includedButton = QToolButton(self)
347
+ self.includedButton = NIconToolButton(self, iSz)
348
348
  self.includedButton.setToolTip(self.tr("Always included"))
349
349
  self.includedButton.setIcon(self._statusFlags[self.F_INCLUDED])
350
350
  self.includedButton.clicked.connect(lambda: self._setSelectedMode(self.F_INCLUDED))
351
351
 
352
- self.excludedButton = QToolButton(self)
352
+ self.excludedButton = NIconToolButton(self, iSz)
353
353
  self.excludedButton.setToolTip(self.tr("Always excluded"))
354
354
  self.excludedButton.setIcon(self._statusFlags[self.F_EXCLUDED])
355
355
  self.excludedButton.clicked.connect(lambda: self._setSelectedMode(self.F_EXCLUDED))
356
356
 
357
- self.resetButton = QToolButton(self)
357
+ self.resetButton = NIconToolButton(self, iSz, "revert")
358
358
  self.resetButton.setToolTip(self.tr("Reset to default"))
359
- self.resetButton.setIcon(SHARED.theme.getIcon("revert"))
360
359
  self.resetButton.clicked.connect(lambda: self._setSelectedMode(self.F_FILTERED))
361
360
 
362
361
  self.modeBox = QHBoxLayout()
363
- self.modeBox.addWidget(QLabel(self.tr("Mark selection as")))
362
+ self.modeBox.addWidget(QLabel(self.tr("Mark selection as"), self))
364
363
  self.modeBox.addStretch(1)
365
364
  self.modeBox.addWidget(self.includedButton)
366
365
  self.modeBox.addWidget(self.excludedButton)
@@ -370,7 +369,7 @@ class _FilterTab(NFixedPage):
370
369
  # Filer Options
371
370
  self.filterOpt = NSwitchBox(self, iPx)
372
371
  self.filterOpt.switchToggled.connect(self._applyFilterSwitch)
373
- self.filterOpt.setFrameStyle(QFrame.NoFrame)
372
+ self.filterOpt.setFrameStyle(QFrame.Shape.NoFrame)
374
373
 
375
374
  # Assemble GUI
376
375
  # ============
@@ -382,10 +381,10 @@ class _FilterTab(NFixedPage):
382
381
  self.selectionBox.addLayout(self.modeBox)
383
382
  self.selectionBox.setContentsMargins(0, 0, 0, 0)
384
383
 
385
- self.selectionWidget = QWidget()
384
+ self.selectionWidget = QWidget(self)
386
385
  self.selectionWidget.setLayout(self.selectionBox)
387
386
 
388
- self.mainSplit = QSplitter()
387
+ self.mainSplit = QSplitter(self)
389
388
  self.mainSplit.addWidget(self.selectionWidget)
390
389
  self.mainSplit.addWidget(self.filterOpt)
391
390
  self.mainSplit.setCollapsible(0, False)
@@ -469,7 +468,7 @@ class _FilterTab(NFixedPage):
469
468
  trItem.setData(self.C_DATA, self.D_FILE, isFile)
470
469
  trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))
471
470
 
472
- trItem.setTextAlignment(self.C_NAME, Qt.AlignLeft)
471
+ trItem.setTextAlignment(self.C_NAME, QtAlignLeft)
473
472
 
474
473
  if pHandle is None and nwItem.isRootType():
475
474
  self.optTree.addTopLevelItem(trItem)
@@ -593,10 +592,12 @@ class _HeadingsTab(NScrollablePage):
593
592
  self._build = build
594
593
  self._editing = 0
595
594
 
596
- iPx = SHARED.theme.baseIconSize
595
+ iPx = SHARED.theme.baseIconHeight
596
+ iSz = SHARED.theme.baseIconSize
597
597
  sSp = CONFIG.pxInt(16)
598
598
  vSp = CONFIG.pxInt(12)
599
599
  bSp = CONFIG.pxInt(6)
600
+ trHide = self.tr("Hide")
600
601
 
601
602
  # Format Boxes
602
603
  # ============
@@ -607,10 +608,9 @@ class _HeadingsTab(NScrollablePage):
607
608
  self.lblTitle = QLabel(self._build.getLabel("headings.fmtTitle"), self)
608
609
  self.fmtTitle = QLineEdit("", self)
609
610
  self.fmtTitle.setReadOnly(True)
610
- self.btnTitle = QToolButton(self)
611
- self.btnTitle.setIcon(SHARED.theme.getIcon("edit"))
611
+ self.btnTitle = NIconToolButton(self, iSz, "edit")
612
612
  self.btnTitle.clicked.connect(lambda: self._editHeading(self.EDIT_TITLE))
613
- self.hdeTitle = QLabel(self.tr("Hide"), self)
613
+ self.hdeTitle = QLabel(trHide, self)
614
614
  self.hdeTitle.setIndent(bSp)
615
615
  self.swtTitle = NSwitch(self, height=iPx)
616
616
 
@@ -624,10 +624,9 @@ class _HeadingsTab(NScrollablePage):
624
624
  self.lblChapter = QLabel(self._build.getLabel("headings.fmtChapter"), self)
625
625
  self.fmtChapter = QLineEdit("", self)
626
626
  self.fmtChapter.setReadOnly(True)
627
- self.btnChapter = QToolButton(self)
628
- self.btnChapter.setIcon(SHARED.theme.getIcon("edit"))
627
+ self.btnChapter = NIconToolButton(self, iSz, "edit")
629
628
  self.btnChapter.clicked.connect(lambda: self._editHeading(self.EDIT_CHAPTER))
630
- self.hdeChapter = QLabel(self.tr("Hide"), self)
629
+ self.hdeChapter = QLabel(trHide, self)
631
630
  self.hdeChapter.setIndent(bSp)
632
631
  self.swtChapter = NSwitch(self, height=iPx)
633
632
 
@@ -641,10 +640,9 @@ class _HeadingsTab(NScrollablePage):
641
640
  self.lblUnnumbered = QLabel(self._build.getLabel("headings.fmtUnnumbered"), self)
642
641
  self.fmtUnnumbered = QLineEdit("", self)
643
642
  self.fmtUnnumbered.setReadOnly(True)
644
- self.btnUnnumbered = QToolButton(self)
645
- self.btnUnnumbered.setIcon(SHARED.theme.getIcon("edit"))
643
+ self.btnUnnumbered = NIconToolButton(self, iSz, "edit")
646
644
  self.btnUnnumbered.clicked.connect(lambda: self._editHeading(self.EDIT_UNNUM))
647
- self.hdeUnnumbered = QLabel(self.tr("Hide"), self)
645
+ self.hdeUnnumbered = QLabel(trHide, self)
648
646
  self.hdeUnnumbered.setIndent(bSp)
649
647
  self.swtUnnumbered = NSwitch(self, height=iPx)
650
648
 
@@ -658,10 +656,9 @@ class _HeadingsTab(NScrollablePage):
658
656
  self.lblScene = QLabel(self._build.getLabel("headings.fmtScene"), self)
659
657
  self.fmtScene = QLineEdit("", self)
660
658
  self.fmtScene.setReadOnly(True)
661
- self.btnScene = QToolButton(self)
662
- self.btnScene.setIcon(SHARED.theme.getIcon("edit"))
659
+ self.btnScene = NIconToolButton(self, iSz, "edit")
663
660
  self.btnScene.clicked.connect(lambda: self._editHeading(self.EDIT_SCENE))
664
- self.hdeScene = QLabel(self.tr("Hide"), self)
661
+ self.hdeScene = QLabel(trHide, self)
665
662
  self.hdeScene.setIndent(bSp)
666
663
  self.swtScene = NSwitch(self, height=iPx)
667
664
 
@@ -672,30 +669,28 @@ class _HeadingsTab(NScrollablePage):
672
669
  self.formatBox.addWidget(self.swtScene, 3, 4)
673
670
 
674
671
  # Alt Scene Heading
675
- self.lblHScene = QLabel(self._build.getLabel("headings.fmtHardScene"), self)
676
- self.fmtHScene = QLineEdit("", self)
677
- self.fmtHScene.setReadOnly(True)
678
- self.btnHScene = QToolButton(self)
679
- self.btnHScene.setIcon(SHARED.theme.getIcon("edit"))
680
- self.btnHScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE))
681
- self.hdeHScene = QLabel(self.tr("Hide"), self)
682
- self.hdeHScene.setIndent(bSp)
683
- self.swtHScene = NSwitch(self, height=iPx)
684
-
685
- self.formatBox.addWidget(self.lblHScene, 4, 0)
686
- self.formatBox.addWidget(self.fmtHScene, 4, 1)
687
- self.formatBox.addWidget(self.btnHScene, 4, 2)
688
- self.formatBox.addWidget(self.hdeHScene, 4, 3)
689
- self.formatBox.addWidget(self.swtHScene, 4, 4)
672
+ self.lblAScene = QLabel(self._build.getLabel("headings.fmtAltScene"), self)
673
+ self.fmtAScene = QLineEdit("", self)
674
+ self.fmtAScene.setReadOnly(True)
675
+ self.btnAScene = NIconToolButton(self, iSz, "edit")
676
+ self.btnAScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE))
677
+ self.hdeAScene = QLabel(trHide, self)
678
+ self.hdeAScene.setIndent(bSp)
679
+ self.swtAScene = NSwitch(self, height=iPx)
680
+
681
+ self.formatBox.addWidget(self.lblAScene, 4, 0)
682
+ self.formatBox.addWidget(self.fmtAScene, 4, 1)
683
+ self.formatBox.addWidget(self.btnAScene, 4, 2)
684
+ self.formatBox.addWidget(self.hdeAScene, 4, 3)
685
+ self.formatBox.addWidget(self.swtAScene, 4, 4)
690
686
 
691
687
  # Section Heading
692
688
  self.lblSection = QLabel(self._build.getLabel("headings.fmtSection"), self)
693
689
  self.fmtSection = QLineEdit("", self)
694
690
  self.fmtSection.setReadOnly(True)
695
- self.btnSection = QToolButton(self)
696
- self.btnSection.setIcon(SHARED.theme.getIcon("edit"))
691
+ self.btnSection = NIconToolButton(self, iSz, "edit")
697
692
  self.btnSection.clicked.connect(lambda: self._editHeading(self.EDIT_SECTION))
698
- self.hdeSection = QLabel(self.tr("Hide"), self)
693
+ self.hdeSection = QLabel(trHide, self)
699
694
  self.hdeSection.setIndent(bSp)
700
695
  self.swtSection = NSwitch(self, height=iPx)
701
696
 
@@ -708,7 +703,7 @@ class _HeadingsTab(NScrollablePage):
708
703
  # Edit Form
709
704
  # =========
710
705
 
711
- self.lblEditForm = QLabel(self.tr("Editing: {0}").format(self.tr("None")))
706
+ self.lblEditForm = QLabel(self.tr("Editing: {0}").format(self.tr("None")), self)
712
707
 
713
708
  self.editTextBox = QPlainTextEdit(self)
714
709
  self.editTextBox.setFixedHeight(5*iPx)
@@ -764,12 +759,12 @@ class _HeadingsTab(NScrollablePage):
764
759
  self.layoutMatrix.addWidget(self.layoutHeading, 0, 0, 1, 5)
765
760
 
766
761
  # Title Layout
767
- self.mtxTitle = QLabel(self._build.getLabel("headings.fmtTitle"))
762
+ self.mtxTitle = QLabel(self._build.getLabel("headings.fmtTitle"), self)
768
763
  self.centerTitle = NSwitch(self, height=iPx)
769
764
  self.breakTitle = NSwitch(self, height=iPx)
770
- lblCenterT = QLabel(self.tr("Centre"))
765
+ lblCenterT = QLabel(self.tr("Centre"), self)
771
766
  lblCenterT.setIndent(sSp)
772
- lblBreakT = QLabel(self.tr("Page Break"))
767
+ lblBreakT = QLabel(self.tr("Page Break"), self)
773
768
  lblBreakT.setIndent(sSp)
774
769
 
775
770
  self.layoutMatrix.addWidget(self.mtxTitle, 1, 0)
@@ -779,12 +774,12 @@ class _HeadingsTab(NScrollablePage):
779
774
  self.layoutMatrix.addWidget(self.breakTitle, 1, 4)
780
775
 
781
776
  # Chapter Layout
782
- self.mtxChapter = QLabel(self._build.getLabel("headings.fmtChapter"))
777
+ self.mtxChapter = QLabel(self._build.getLabel("headings.fmtChapter"), self)
783
778
  self.centerChapter = NSwitch(self, height=iPx)
784
779
  self.breakChapter = NSwitch(self, height=iPx)
785
- lblCenterC = QLabel(self.tr("Centre"))
780
+ lblCenterC = QLabel(self.tr("Centre"), self)
786
781
  lblCenterC.setIndent(sSp)
787
- lblBreakC = QLabel(self.tr("Page Break"))
782
+ lblBreakC = QLabel(self.tr("Page Break"), self)
788
783
  lblBreakC.setIndent(sSp)
789
784
 
790
785
  self.layoutMatrix.addWidget(self.mtxChapter, 2, 0)
@@ -794,12 +789,12 @@ class _HeadingsTab(NScrollablePage):
794
789
  self.layoutMatrix.addWidget(self.breakChapter, 2, 4)
795
790
 
796
791
  # Scene Layout
797
- self.mtxScene = QLabel(self._build.getLabel("headings.fmtScene"))
792
+ self.mtxScene = QLabel(self._build.getLabel("headings.fmtScene"), self)
798
793
  self.centerScene = NSwitch(self, height=iPx)
799
794
  self.breakScene = NSwitch(self, height=iPx)
800
- lblCenterS = QLabel(self.tr("Centre"))
795
+ lblCenterS = QLabel(self.tr("Centre"), self)
801
796
  lblCenterS.setIndent(sSp)
802
- lblBreakS = QLabel(self.tr("Page Break"))
797
+ lblBreakS = QLabel(self.tr("Page Break"), self)
803
798
  lblBreakS.setIndent(sSp)
804
799
 
805
800
  self.layoutMatrix.addWidget(self.mtxScene, 3, 0)
@@ -831,14 +826,14 @@ class _HeadingsTab(NScrollablePage):
831
826
  self.fmtChapter.setText(self._build.getStr("headings.fmtChapter"))
832
827
  self.fmtUnnumbered.setText(self._build.getStr("headings.fmtUnnumbered"))
833
828
  self.fmtScene.setText(self._build.getStr("headings.fmtScene"))
834
- self.fmtHScene.setText(self._build.getStr("headings.fmtHardScene"))
829
+ self.fmtAScene.setText(self._build.getStr("headings.fmtAltScene"))
835
830
  self.fmtSection.setText(self._build.getStr("headings.fmtSection"))
836
831
 
837
832
  self.swtTitle.setChecked(self._build.getBool("headings.hideTitle"))
838
833
  self.swtChapter.setChecked(self._build.getBool("headings.hideChapter"))
839
834
  self.swtUnnumbered.setChecked(self._build.getBool("headings.hideUnnumbered"))
840
835
  self.swtScene.setChecked(self._build.getBool("headings.hideScene"))
841
- self.swtHScene.setChecked(self._build.getBool("headings.hideHardScene"))
836
+ self.swtAScene.setChecked(self._build.getBool("headings.hideAltScene"))
842
837
  self.swtSection.setChecked(self._build.getBool("headings.hideSection"))
843
838
 
844
839
  self.centerTitle.setChecked(self._build.getBool("headings.centerTitle"))
@@ -855,7 +850,7 @@ class _HeadingsTab(NScrollablePage):
855
850
  self._build.setValue("headings.hideChapter", self.swtChapter.isChecked())
856
851
  self._build.setValue("headings.hideUnnumbered", self.swtUnnumbered.isChecked())
857
852
  self._build.setValue("headings.hideScene", self.swtScene.isChecked())
858
- self._build.setValue("headings.hideHardScene", self.swtHScene.isChecked())
853
+ self._build.setValue("headings.hideAltScene", self.swtAScene.isChecked())
859
854
  self._build.setValue("headings.hideSection", self.swtSection.isChecked())
860
855
 
861
856
  self._build.setValue("headings.centerTitle", self.centerTitle.isChecked())
@@ -895,8 +890,8 @@ class _HeadingsTab(NScrollablePage):
895
890
  text = self.fmtScene.text()
896
891
  label = self._build.getLabel("headings.fmtScene")
897
892
  elif heading == self.EDIT_HSCENE:
898
- text = self.fmtHScene.text()
899
- label = self._build.getLabel("headings.fmtHardScene")
893
+ text = self.fmtAScene.text()
894
+ label = self._build.getLabel("headings.fmtAltScene")
900
895
  elif heading == self.EDIT_SECTION:
901
896
  text = self.fmtSection.text()
902
897
  label = self._build.getLabel("headings.fmtSection")
@@ -933,8 +928,8 @@ class _HeadingsTab(NScrollablePage):
933
928
  self.fmtScene.setText(text)
934
929
  self._build.setValue("headings.fmtScene", text)
935
930
  elif heading == self.EDIT_HSCENE:
936
- self.fmtHScene.setText(text)
937
- self._build.setValue("headings.fmtHardScene", text)
931
+ self.fmtAScene.setText(text)
932
+ self._build.setValue("headings.fmtAltScene", text)
938
933
  elif heading == self.EDIT_SECTION:
939
934
  self.fmtSection.setText(text)
940
935
  self._build.setValue("headings.fmtSection", text)
@@ -982,7 +977,8 @@ class _ContentTab(NScrollableForm):
982
977
 
983
978
  self._build = build
984
979
 
985
- iPx = SHARED.theme.baseIconSize
980
+ iPx = SHARED.theme.baseIconHeight
981
+ iSz = SHARED.theme.baseIconSize
986
982
 
987
983
  # Text Content
988
984
  self.incBodyText = NSwitch(self, height=iPx)
@@ -999,10 +995,8 @@ class _ContentTab(NScrollableForm):
999
995
  lambda keyword=keyword: self._updateIgnoredKeywords(keyword)
1000
996
  )
1001
997
 
1002
- self.ignoredKeywordsButton = QToolButton(self)
1003
- self.ignoredKeywordsButton.setIcon(SHARED.theme.getIcon("add"))
998
+ self.ignoredKeywordsButton = NIconToolButton(self, iSz, "add")
1004
999
  self.ignoredKeywordsButton.setMenu(self.mnKeywords)
1005
- self.ignoredKeywordsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
1006
1000
 
1007
1001
  self.addGroupLabel(self._build.getLabel("text.grpContent"))
1008
1002
  self.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText)
@@ -1066,12 +1060,11 @@ class _FormatTab(NScrollableForm):
1066
1060
  def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
1067
1061
  super().__init__(parent=buildMain)
1068
1062
 
1069
- self.buildMain = buildMain
1070
-
1071
1063
  self._build = build
1072
1064
  self._unitScale = 1.0
1073
1065
 
1074
- iPx = SHARED.theme.baseIconSize
1066
+ iPx = SHARED.theme.baseIconHeight
1067
+ iSz = SHARED.theme.baseIconSize
1075
1068
  spW = 6*SHARED.theme.textNWidth
1076
1069
  dbW = 8*SHARED.theme.textNWidth
1077
1070
 
@@ -1083,8 +1076,7 @@ class _FormatTab(NScrollableForm):
1083
1076
  # Font Family
1084
1077
  self.textFont = QLineEdit(self)
1085
1078
  self.textFont.setReadOnly(True)
1086
- self.btnTextFont = QPushButton("...")
1087
- self.btnTextFont.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("...")))
1079
+ self.btnTextFont = NIconToolButton(self, iSz, "more")
1088
1080
  self.btnTextFont.clicked.connect(self._selectFont)
1089
1081
  self.addRow(
1090
1082
  self._build.getLabel("format.textFont"), self.textFont,
@@ -1318,7 +1310,7 @@ class _FormatTab(NScrollableForm):
1318
1310
  return
1319
1311
 
1320
1312
  @pyqtSlot()
1321
- def _pageSizeValueChanged(self):
1313
+ def _pageSizeValueChanged(self) -> None:
1322
1314
  """The user has changed the page size spin boxes, so we flip
1323
1315
  the page size box to Custom.
1324
1316
  """
@@ -1337,7 +1329,8 @@ class _OutputTab(NScrollableForm):
1337
1329
 
1338
1330
  self._build = build
1339
1331
 
1340
- iPx = SHARED.theme.baseIconSize
1332
+ iPx = SHARED.theme.baseIconHeight
1333
+ iSz = SHARED.theme.baseIconSize
1341
1334
  spW = 6*SHARED.theme.textNWidth
1342
1335
 
1343
1336
  # Open Document
@@ -1348,8 +1341,7 @@ class _OutputTab(NScrollableForm):
1348
1341
 
1349
1342
  self.odtPageHeader = QLineEdit(self)
1350
1343
  self.odtPageHeader.setMinimumWidth(CONFIG.pxInt(200))
1351
- self.btnPageHeader = QToolButton(self)
1352
- self.btnPageHeader.setIcon(SHARED.theme.getIcon("revert"))
1344
+ self.btnPageHeader = NIconToolButton(self, iSz, "revert")
1353
1345
  self.btnPageHeader.clicked.connect(self._resetPageHeader)
1354
1346
  self.addRow(
1355
1347
  self._build.getLabel("odt.pageHeader"), self.odtPageHeader,
@@ -1395,6 +1387,7 @@ class _OutputTab(NScrollableForm):
1395
1387
  self.htmlAddStyles.setChecked(self._build.getBool("html.addStyles"))
1396
1388
  self.htmlPreserveTabs.setChecked(self._build.getBool("html.preserveTabs"))
1397
1389
  self.mdPreserveBreaks.setChecked(self._build.getBool("md.preserveBreaks"))
1390
+ self.odtPageHeader.setCursorPosition(0)
1398
1391
  return
1399
1392
 
1400
1393
  def saveContent(self) -> None:
@@ -26,8 +26,8 @@ from __future__ import annotations
26
26
  import math
27
27
  import logging
28
28
 
29
+ from PyQt5.QtCore import pyqtSlot
29
30
  from PyQt5.QtGui import QCloseEvent
30
- from PyQt5.QtCore import QSize, Qt, pyqtSlot
31
31
  from PyQt5.QtWidgets import (
32
32
  QAbstractItemView, QDialog, QDialogButtonBox, QFormLayout, QGridLayout,
33
33
  QHBoxLayout, QLabel, QSpinBox, QStackedWidget, QTreeWidget,
@@ -37,10 +37,11 @@ from PyQt5.QtWidgets import (
37
37
  from novelwriter import CONFIG, SHARED
38
38
  from novelwriter.common import formatTime, numberToRoman
39
39
  from novelwriter.constants import nwUnicode
40
- from novelwriter.extensions.switch import NSwitch
41
40
  from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
42
- from novelwriter.extensions.pagedsidebar import NPagedSideBar
43
41
  from novelwriter.extensions.novelselector import NovelSelector
42
+ from novelwriter.extensions.pagedsidebar import NPagedSideBar
43
+ from novelwriter.extensions.switch import NSwitch
44
+ from novelwriter.types import QtAlignRight, QtDecoration, QtDialogClose
44
45
 
45
46
  logger = logging.getLogger(__name__)
46
47
 
@@ -94,7 +95,7 @@ class GuiNovelDetails(QDialog):
94
95
  self.mainStack.addWidget(self.contentsPage)
95
96
 
96
97
  # Buttons
97
- self.buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
98
+ self.buttonBox = QDialogButtonBox(QtDialogClose, self)
98
99
  self.buttonBox.rejected.connect(self.close)
99
100
 
100
101
  # Assemble
@@ -309,7 +310,8 @@ class _ContentsPage(NFixedPage):
309
310
  self._data = []
310
311
  self._currentRoot = None
311
312
 
312
- iPx = SHARED.theme.baseIconSize
313
+ iPx = SHARED.theme.baseIconHeight
314
+ iSz = SHARED.theme.baseIconSize
313
315
  hPx = CONFIG.pxInt(12)
314
316
  vPx = CONFIG.pxInt(4)
315
317
  options = SHARED.project.options
@@ -322,7 +324,7 @@ class _ContentsPage(NFixedPage):
322
324
 
323
325
  # Contents Tree
324
326
  self.tocTree = QTreeWidget(self)
325
- self.tocTree.setIconSize(QSize(iPx, iPx))
327
+ self.tocTree.setIconSize(iSz)
326
328
  self.tocTree.setIndentation(0)
327
329
  self.tocTree.setColumnCount(6)
328
330
  self.tocTree.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
@@ -337,10 +339,10 @@ class _ContentsPage(NFixedPage):
337
339
 
338
340
  treeHeadItem = self.tocTree.headerItem()
339
341
  if treeHeadItem:
340
- treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignmentFlag.AlignRight)
341
- treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignmentFlag.AlignRight)
342
- treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignmentFlag.AlignRight)
343
- treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignmentFlag.AlignRight)
342
+ treeHeadItem.setTextAlignment(self.C_WORDS, QtAlignRight)
343
+ treeHeadItem.setTextAlignment(self.C_PAGES, QtAlignRight)
344
+ treeHeadItem.setTextAlignment(self.C_PAGE, QtAlignRight)
345
+ treeHeadItem.setTextAlignment(self.C_PROG, QtAlignRight)
344
346
 
345
347
  treeHeader = self.tocTree.header()
346
348
  treeHeader.setStretchLastSection(True)
@@ -364,7 +366,7 @@ class _ContentsPage(NFixedPage):
364
366
  countFrom = options.getInt("GuiNovelDetails", "countFrom", 1)
365
367
  clearDouble = options.getBool("GuiNovelDetails", "clearDouble", True)
366
368
 
367
- self.wpLabel = QLabel(self.tr("Words per page"))
369
+ self.wpLabel = QLabel(self.tr("Words per page"), self)
368
370
 
369
371
  self.wpValue = QSpinBox(self)
370
372
  self.wpValue.setMinimum(10)
@@ -373,7 +375,7 @@ class _ContentsPage(NFixedPage):
373
375
  self.wpValue.setValue(wordsPerPage)
374
376
  self.wpValue.valueChanged.connect(self._populateTree)
375
377
 
376
- self.poLabel = QLabel(self.tr("First page offset"))
378
+ self.poLabel = QLabel(self.tr("First page offset"), self)
377
379
 
378
380
  self.poValue = QSpinBox(self)
379
381
  self.poValue.setMinimum(1)
@@ -382,7 +384,7 @@ class _ContentsPage(NFixedPage):
382
384
  self.poValue.setValue(countFrom)
383
385
  self.poValue.valueChanged.connect(self._populateTree)
384
386
 
385
- self.dblLabel = QLabel(self.tr("Chapters on odd pages"))
387
+ self.dblLabel = QLabel(self.tr("Chapters on odd pages"), self)
386
388
 
387
389
  self.dblValue = NSwitch(self, height=iPx)
388
390
  self.dblValue.setChecked(clearDouble)
@@ -483,17 +485,17 @@ class _ContentsPage(NFixedPage):
483
485
  if tTitle.strip() == "":
484
486
  tTitle = self.tr("Untitled")
485
487
 
486
- newItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
488
+ newItem.setData(self.C_TITLE, QtDecoration, hDec)
487
489
  newItem.setText(self.C_TITLE, tTitle)
488
490
  newItem.setText(self.C_WORDS, f"{wCount:n}")
489
491
  newItem.setText(self.C_PAGES, f"{pCount:n}")
490
492
  newItem.setText(self.C_PAGE, progPage)
491
493
  newItem.setText(self.C_PROG, progText)
492
494
 
493
- newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
494
- newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
495
- newItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
496
- newItem.setTextAlignment(self.C_PROG, Qt.AlignRight)
495
+ newItem.setTextAlignment(self.C_WORDS, QtAlignRight)
496
+ newItem.setTextAlignment(self.C_PAGES, QtAlignRight)
497
+ newItem.setTextAlignment(self.C_PAGE, QtAlignRight)
498
+ newItem.setTextAlignment(self.C_PROG, QtAlignRight)
497
499
 
498
500
  # Make pages and titles/partitions stand out
499
501
  if tLevel < 2: