novelWriter 2.5rc1__py3-none-any.whl → 2.5.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 (40) hide show
  1. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/METADATA +1 -1
  2. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/RECORD +40 -38
  3. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +3 -3
  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_pl_PL.json +116 -0
  17. novelwriter/assets/manual.pdf +0 -0
  18. novelwriter/assets/sample.zip +0 -0
  19. novelwriter/assets/text/credits_en.htm +52 -44
  20. novelwriter/common.py +10 -0
  21. novelwriter/core/project.py +15 -4
  22. novelwriter/core/status.py +4 -1
  23. novelwriter/core/storage.py +6 -1
  24. novelwriter/core/tokenizer.py +5 -5
  25. novelwriter/core/toqdoc.py +13 -13
  26. novelwriter/dialogs/preferences.py +14 -27
  27. novelwriter/dialogs/projectsettings.py +6 -10
  28. novelwriter/extensions/configlayout.py +18 -3
  29. novelwriter/extensions/statusled.py +12 -2
  30. novelwriter/gui/doceditor.py +3 -3
  31. novelwriter/gui/docviewer.py +3 -1
  32. novelwriter/gui/docviewerpanel.py +7 -0
  33. novelwriter/gui/outline.py +1 -0
  34. novelwriter/gui/projtree.py +66 -49
  35. novelwriter/guimain.py +50 -42
  36. novelwriter/shared.py +9 -0
  37. novelwriter/tools/welcome.py +9 -0
  38. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/LICENSE.md +0 -0
  39. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/entry_points.txt +0 -0
  40. {novelWriter-2.5rc1.dist-info → novelWriter-2.5.1.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,7 @@ from __future__ import annotations
26
26
  import logging
27
27
 
28
28
  from PyQt5.QtGui import (
29
- QColor, QFont, QFontMetrics, QTextBlockFormat, QTextCharFormat,
29
+ QColor, QFont, QFontMetricsF, QTextBlockFormat, QTextCharFormat,
30
30
  QTextCursor, QTextDocument
31
31
  )
32
32
 
@@ -99,19 +99,19 @@ class ToQTextDocument(Tokenizer):
99
99
  self._document.clear()
100
100
  self._document.setDefaultFont(self._textFont)
101
101
 
102
- qMetric = QFontMetrics(self._textFont)
103
- mScale = qMetric.height()
102
+ qMetric = QFontMetricsF(self._textFont)
103
+ mPx = qMetric.ascent() # 1 em in pixels
104
104
  fPt = self._textFont.pointSizeF()
105
105
 
106
106
  # Scaled Sizes
107
107
  # ============
108
108
 
109
109
  self._mHead = {
110
- self.T_TITLE: (mScale * self._marginTitle[0], mScale * self._marginTitle[1]),
111
- self.T_HEAD1: (mScale * self._marginHead1[0], mScale * self._marginHead1[1]),
112
- self.T_HEAD2: (mScale * self._marginHead2[0], mScale * self._marginHead2[1]),
113
- self.T_HEAD3: (mScale * self._marginHead3[0], mScale * self._marginHead3[1]),
114
- self.T_HEAD4: (mScale * self._marginHead4[0], mScale * self._marginHead4[1]),
110
+ self.T_TITLE: (mPx * self._marginTitle[0], mPx * self._marginTitle[1]),
111
+ self.T_HEAD1: (mPx * self._marginHead1[0], mPx * self._marginHead1[1]),
112
+ self.T_HEAD2: (mPx * self._marginHead2[0], mPx * self._marginHead2[1]),
113
+ self.T_HEAD3: (mPx * self._marginHead3[0], mPx * self._marginHead3[1]),
114
+ self.T_HEAD4: (mPx * self._marginHead4[0], mPx * self._marginHead4[1]),
115
115
  }
116
116
 
117
117
  self._sHead = {
@@ -122,12 +122,12 @@ class ToQTextDocument(Tokenizer):
122
122
  self.T_HEAD4: nwHeaders.H_SIZES.get(4, 1.0) * fPt,
123
123
  }
124
124
 
125
- self._mText = (mScale * self._marginText[0], mScale * self._marginText[1])
126
- self._mMeta = (mScale * self._marginMeta[0], mScale * self._marginMeta[1])
127
- self._mSep = (mScale * self._marginSep[0], mScale * self._marginSep[1])
125
+ self._mText = (mPx * self._marginText[0], mPx * self._marginText[1])
126
+ self._mMeta = (mPx * self._marginMeta[0], mPx * self._marginMeta[1])
127
+ self._mSep = (mPx * self._marginSep[0], mPx * self._marginSep[1])
128
128
 
129
- self._mIndent = mScale * 2.0
130
- self._tIndent = mScale * self._firstWidth
129
+ self._mIndent = mPx * 2.0
130
+ self._tIndent = mPx * self._firstWidth
131
131
 
132
132
  # Block Format
133
133
  # ============
@@ -29,12 +29,12 @@ import logging
29
29
  from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
30
30
  from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence
31
31
  from PyQt5.QtWidgets import (
32
- QAbstractButton, QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout,
33
- QLineEdit, QPushButton, QVBoxLayout, QWidget
32
+ QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit,
33
+ QPushButton, QVBoxLayout, QWidget
34
34
  )
35
35
 
36
36
  from novelwriter import CONFIG, SHARED
37
- from novelwriter.common import describeFont
37
+ from novelwriter.common import describeFont, uniqueCompact
38
38
  from novelwriter.constants import nwUnicode
39
39
  from novelwriter.dialogs.quotes import GuiQuoteSelect
40
40
  from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
@@ -43,10 +43,7 @@ from novelwriter.extensions.modified import (
43
43
  )
44
44
  from novelwriter.extensions.pagedsidebar import NPagedSideBar
45
45
  from novelwriter.extensions.switch import NSwitch
46
- from novelwriter.types import (
47
- QtAlignCenter, QtDialogApply, QtDialogClose, QtDialogSave, QtRoleAccept,
48
- QtRoleApply, QtRoleReject
49
- )
46
+ from novelwriter.types import QtAlignCenter, QtDialogCancel, QtDialogSave
50
47
 
51
48
  logger = logging.getLogger(__name__)
52
49
 
@@ -89,8 +86,9 @@ class GuiPreferences(NDialog):
89
86
  self.mainForm.setHelpTextStyle(SHARED.theme.helpText)
90
87
 
91
88
  # Buttons
92
- self.buttonBox = QDialogButtonBox(QtDialogApply | QtDialogSave | QtDialogClose, self)
93
- self.buttonBox.clicked.connect(self._dialogButtonClicked)
89
+ self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogCancel, self)
90
+ self.buttonBox.accepted.connect(self._doSave)
91
+ self.buttonBox.rejected.connect(self.reject)
94
92
 
95
93
  # Assemble
96
94
  self.searchBox = QHBoxLayout()
@@ -784,19 +782,6 @@ class GuiPreferences(NDialog):
784
782
  # Private Slots
785
783
  ##
786
784
 
787
- @pyqtSlot("QAbstractButton*")
788
- def _dialogButtonClicked(self, button: QAbstractButton) -> None:
789
- """Handle button clicks from the dialog button box."""
790
- role = self.buttonBox.buttonRole(button)
791
- if role == QtRoleApply:
792
- self._saveValues()
793
- elif role == QtRoleAccept:
794
- self._saveValues()
795
- self.close()
796
- elif role == QtRoleReject:
797
- self.close()
798
- return
799
-
800
785
  @pyqtSlot(int)
801
786
  def _sidebarClicked(self, section: int) -> None:
802
787
  """Process a user request to switch page."""
@@ -897,7 +882,7 @@ class GuiPreferences(NDialog):
897
882
  CONFIG.setPreferencesWinSize(self.width(), self.height())
898
883
  return
899
884
 
900
- def _saveValues(self) -> None:
885
+ def _doSave(self) -> None:
901
886
  """Save the values set in the form."""
902
887
  updateTheme = False
903
888
  needsRestart = False
@@ -967,8 +952,8 @@ class GuiPreferences(NDialog):
967
952
  # Text Highlighting
968
953
  dialogueStyle = self.dialogStyle.currentData()
969
954
  allowOpenDial = self.allowOpenDial.isChecked()
970
- narratorBreak = self.narratorBreak.text()
971
- dialogueLine = self.dialogLine.text()
955
+ narratorBreak = self.narratorBreak.text().strip()
956
+ dialogueLine = self.dialogLine.text().strip()
972
957
  altDialogOpen = self.altDialogOpen.text()
973
958
  altDialogClose = self.altDialogClose.text()
974
959
  highlightEmph = self.highlightEmph.isChecked()
@@ -998,8 +983,8 @@ class GuiPreferences(NDialog):
998
983
  CONFIG.doReplaceDQuote = self.doReplaceDQuote.isChecked()
999
984
  CONFIG.doReplaceDash = self.doReplaceDash.isChecked()
1000
985
  CONFIG.doReplaceDots = self.doReplaceDots.isChecked()
1001
- CONFIG.fmtPadBefore = self.fmtPadBefore.text().strip()
1002
- CONFIG.fmtPadAfter = self.fmtPadAfter.text().strip()
986
+ CONFIG.fmtPadBefore = uniqueCompact(self.fmtPadBefore.text())
987
+ CONFIG.fmtPadAfter = uniqueCompact(self.fmtPadAfter.text())
1003
988
  CONFIG.fmtPadThin = self.fmtPadThin.isChecked()
1004
989
 
1005
990
  # Quotation Style
@@ -1012,4 +997,6 @@ class GuiPreferences(NDialog):
1012
997
  CONFIG.saveConfig()
1013
998
  self.newPreferencesReady.emit(needsRestart, refreshTree, updateTheme, updateSyntax)
1014
999
 
1000
+ self.close()
1001
+
1015
1002
  return
@@ -58,7 +58,7 @@ class GuiProjectSettings(NDialog):
58
58
  PAGE_IMPORT = 2
59
59
  PAGE_REPLACE = 3
60
60
 
61
- newProjectSettingsReady = pyqtSignal(bool)
61
+ newProjectSettingsReady = pyqtSignal()
62
62
 
63
63
  def __init__(self, parent: QWidget, gotoPage: int = PAGE_SETTINGS) -> None:
64
64
  super().__init__(parent=parent)
@@ -175,7 +175,7 @@ class GuiProjectSettings(NDialog):
175
175
  projAuthor = self.settingsPage.projAuthor.text()
176
176
  projLang = self.settingsPage.projLang.currentData()
177
177
  spellLang = self.settingsPage.spellLang.currentData()
178
- doBackup = not self.settingsPage.doBackup.isChecked()
178
+ doBackup = not self.settingsPage.noBackup.isChecked()
179
179
 
180
180
  project.data.setName(projName)
181
181
  project.data.setAuthor(projAuthor)
@@ -183,23 +183,19 @@ class GuiProjectSettings(NDialog):
183
183
  project.data.setSpellLang(spellLang)
184
184
  project.setProjectLang(projLang)
185
185
 
186
- rebuildTrees = False
187
-
188
186
  if self.statusPage.changed:
189
187
  logger.debug("Updating status labels")
190
188
  project.data.itemStatus.update(self.statusPage.getNewList())
191
- rebuildTrees = True
192
189
 
193
190
  if self.importPage.changed:
194
191
  logger.debug("Updating importance labels")
195
192
  project.data.itemImport.update(self.importPage.getNewList())
196
- rebuildTrees = True
197
193
 
198
194
  if self.replacePage.changed:
199
195
  logger.debug("Updating auto-replace settings")
200
196
  project.data.setAutoReplace(self.replacePage.getNewList())
201
197
 
202
- self.newProjectSettingsReady.emit(rebuildTrees)
198
+ self.newProjectSettingsReady.emit()
203
199
  QApplication.processEvents()
204
200
  self.close()
205
201
 
@@ -289,10 +285,10 @@ class _SettingsPage(NScrollableForm):
289
285
  self.spellLang.setCurrentIndex(idx)
290
286
 
291
287
  # Backup on Close
292
- self.doBackup = NSwitch(self)
293
- self.doBackup.setChecked(not data.doBackup)
288
+ self.noBackup = NSwitch(self)
289
+ self.noBackup.setChecked(not data.doBackup)
294
290
  self.addRow(
295
- self.tr("Disable backup on close"), self.doBackup,
291
+ self.tr("Disable backup on close"), self.noBackup,
296
292
  self.tr("Overrides main preferences.")
297
293
  )
298
294
 
@@ -281,13 +281,28 @@ class NColourLabel(QLabel):
281
281
 
282
282
  return
283
283
 
284
+ def setTextColors(self, *, color: QColor | None = None, faded: QColor | None = None) -> None:
285
+ """Set or update the text colours."""
286
+ self._color = color or self._color
287
+ self._faded = faded or self._faded
288
+ self._refeshTextColor()
289
+ return
290
+
284
291
  def setColorState(self, state: bool) -> None:
285
292
  """Change the colour state."""
286
293
  if self._state is not state:
287
294
  self._state = state
288
- colour = self.palette()
289
- colour.setColor(QPalette.ColorRole.WindowText, self._color if state else self._faded)
290
- self.setPalette(colour)
295
+ self._refeshTextColor()
296
+ return
297
+
298
+ def _refeshTextColor(self) -> None:
299
+ """Refresh the colour of the text on the label."""
300
+ palette = self.palette()
301
+ palette.setColor(
302
+ QPalette.ColorRole.WindowText,
303
+ self._color if self._state else self._faded,
304
+ )
305
+ self.setPalette(palette)
291
306
  return
292
307
 
293
308
 
@@ -28,6 +28,7 @@ import logging
28
28
  from PyQt5.QtGui import QColor, QPainter, QPaintEvent
29
29
  from PyQt5.QtWidgets import QAbstractButton, QWidget
30
30
 
31
+ from novelwriter import CONFIG
31
32
  from novelwriter.enum import nwTrinary
32
33
  from novelwriter.types import QtBlack, QtPaintAnitAlias
33
34
 
@@ -36,6 +37,10 @@ logger = logging.getLogger(__name__)
36
37
 
37
38
  class StatusLED(QAbstractButton):
38
39
 
40
+ __slots__ = (
41
+ "_neutral", "_postitve", "_negative", "_color", "_state", "_bPx"
42
+ )
43
+
39
44
  def __init__(self, sW: int, sH: int, parent: QWidget | None = None) -> None:
40
45
  super().__init__(parent=parent)
41
46
  self._neutral = QtBlack
@@ -43,6 +48,7 @@ class StatusLED(QAbstractButton):
43
48
  self._negative = QtBlack
44
49
  self._color = QtBlack
45
50
  self._state = nwTrinary.NEUTRAL
51
+ self._bPx = CONFIG.pxInt(1)
46
52
  self.setFixedWidth(sW)
47
53
  self.setFixedHeight(sH)
48
54
  return
@@ -76,8 +82,12 @@ class StatusLED(QAbstractButton):
76
82
  """Draw the LED."""
77
83
  painter = QPainter(self)
78
84
  painter.setRenderHint(QtPaintAnitAlias, True)
79
- painter.setPen(self.palette().dark().color())
85
+ painter.setPen(self.palette().windowText().color())
80
86
  painter.setBrush(self._color)
81
87
  painter.setOpacity(1.0)
82
- painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
88
+ painter.drawEllipse(
89
+ self._bPx, self._bPx,
90
+ self.width() - 2*self._bPx,
91
+ self.height() - 2*self._bPx
92
+ )
83
93
  return
@@ -2919,10 +2919,10 @@ class GuiDocEditHeader(QWidget):
2919
2919
  palette.setColor(QPalette.ColorRole.Window, SHARED.theme.colBack)
2920
2920
  palette.setColor(QPalette.ColorRole.WindowText, SHARED.theme.colText)
2921
2921
  palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText)
2922
-
2923
2922
  self.setPalette(palette)
2924
- self.itemTitle.setPalette(palette)
2925
-
2923
+ self.itemTitle.setTextColors(
2924
+ color=palette.windowText().color(), faded=SHARED.theme.fadedText
2925
+ )
2926
2926
  return
2927
2927
 
2928
2928
  def changeFocusState(self, state: bool) -> None:
@@ -741,7 +741,9 @@ class GuiDocViewHeader(QWidget):
741
741
  palette.setColor(QPalette.ColorRole.WindowText, SHARED.theme.colText)
742
742
  palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText)
743
743
  self.setPalette(palette)
744
- self.itemTitle.setPalette(palette)
744
+ self.itemTitle.setTextColors(
745
+ color=palette.windowText().color(), faded=SHARED.theme.fadedText
746
+ )
745
747
  return
746
748
 
747
749
  def changeFocusState(self, state: bool) -> None:
@@ -189,6 +189,13 @@ class GuiDocViewerPanel(QWidget):
189
189
  self._updateTabVisibility()
190
190
  return
191
191
 
192
+ @pyqtSlot(str)
193
+ def updateStatusLabels(self, kind: str) -> None:
194
+ """Update the importance labels."""
195
+ if kind == "i":
196
+ self._loadAllTags()
197
+ return
198
+
192
199
  ##
193
200
  # Private Slots
194
201
  ##
@@ -268,6 +268,7 @@ class GuiOutlineToolBar(QToolBar):
268
268
  self.aExport.setIcon(SHARED.theme.getIcon("export"))
269
269
  self.tbColumns.setIcon(SHARED.theme.getIcon("menu"))
270
270
  self.tbColumns.setStyleSheet("QToolButton::menu-indicator {image: none;}")
271
+ self.novelLabel.setTextColors(color=self.palette().windowText().color())
271
272
  return
272
273
 
273
274
  def populateNovelList(self) -> None:
@@ -166,6 +166,7 @@ class GuiProjectView(QWidget):
166
166
 
167
167
  def openProjectTasks(self) -> None:
168
168
  """Run open project tasks."""
169
+ self.populateTree()
169
170
  self.projBar.buildQuickLinksMenu()
170
171
  self.projBar.setEnabled(True)
171
172
  return
@@ -213,7 +214,8 @@ class GuiProjectView(QWidget):
213
214
  @pyqtSlot(str)
214
215
  def updateItemValues(self, tHandle: str) -> None:
215
216
  """Update tree item."""
216
- self.projTree.setTreeItemValues(tHandle)
217
+ if nwItem := SHARED.project.tree[tHandle]:
218
+ self.projTree.setTreeItemValues(nwItem)
217
219
  return
218
220
 
219
221
  @pyqtSlot(str)
@@ -242,6 +244,12 @@ class GuiProjectView(QWidget):
242
244
  self.projTree.createNewNote(tag, itemClass)
243
245
  return
244
246
 
247
+ @pyqtSlot(str)
248
+ def refreshUserLabels(self, kind: str) -> None:
249
+ """Refresh status or importance labels."""
250
+ self.projTree.refreshUserLabels(kind)
251
+ return
252
+
245
253
 
246
254
  class GuiProjectToolBar(QWidget):
247
255
 
@@ -792,11 +800,11 @@ class GuiProjectTree(QTreeWidget):
792
800
 
793
801
  def renameTreeItem(self, tHandle: str, name: str = "") -> None:
794
802
  """Open a dialog to edit the label of an item."""
795
- if tItem := SHARED.project.tree[tHandle]:
796
- newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
803
+ if nwItem := SHARED.project.tree[tHandle]:
804
+ newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or nwItem.itemName)
797
805
  if dlgOk:
798
- tItem.setName(newLabel)
799
- self.setTreeItemValues(tHandle)
806
+ nwItem.setName(newLabel)
807
+ self.setTreeItemValues(nwItem)
800
808
  self._alertTreeChange(tHandle, flush=False)
801
809
  return
802
810
 
@@ -1010,44 +1018,52 @@ class GuiProjectTree(QTreeWidget):
1010
1018
 
1011
1019
  return True
1012
1020
 
1013
- def setTreeItemValues(self, tHandle: str) -> None:
1014
- """Set the name and flag values for a tree item from a handle in
1015
- the project tree. Does not trigger a tree change as the data is
1016
- already coming from the project tree.
1021
+ def refreshUserLabels(self, kind: str) -> None:
1022
+ """Refresh status or importance labels."""
1023
+ if kind == "s":
1024
+ for nwItem in SHARED.project.tree:
1025
+ if nwItem.isNovelLike():
1026
+ self.setTreeItemValues(nwItem)
1027
+ elif kind == "i":
1028
+ for nwItem in SHARED.project.tree:
1029
+ if not nwItem.isNovelLike():
1030
+ self.setTreeItemValues(nwItem)
1031
+ return
1032
+
1033
+ def setTreeItemValues(self, nwItem: NWItem | None) -> None:
1034
+ """Set the name and flag values for a tree item in the project
1035
+ tree. Does not trigger a tree change as the data is already
1036
+ coming from project data.
1017
1037
  """
1018
- trItem = self._getTreeItem(tHandle)
1019
- nwItem = SHARED.project.tree[tHandle]
1020
- if trItem is None or nwItem is None:
1021
- return
1022
-
1023
- itemStatus, statusIcon = nwItem.getImportStatus()
1024
- hLevel = nwItem.mainHeading
1025
- itemIcon = SHARED.theme.getItemIcon(
1026
- nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
1027
- )
1038
+ if isinstance(nwItem, NWItem) and (trItem := self._getTreeItem(nwItem.itemHandle)):
1039
+ itemStatus, statusIcon = nwItem.getImportStatus()
1040
+ hLevel = nwItem.mainHeading
1041
+ itemIcon = SHARED.theme.getItemIcon(
1042
+ nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
1043
+ )
1028
1044
 
1029
- trItem.setIcon(self.C_NAME, itemIcon)
1030
- trItem.setText(self.C_NAME, nwItem.itemName)
1031
- trItem.setIcon(self.C_STATUS, statusIcon)
1032
- trItem.setToolTip(self.C_STATUS, itemStatus)
1045
+ trItem.setIcon(self.C_NAME, itemIcon)
1046
+ trItem.setText(self.C_NAME, nwItem.itemName)
1047
+ trItem.setIcon(self.C_STATUS, statusIcon)
1048
+ trItem.setToolTip(self.C_STATUS, itemStatus)
1033
1049
 
1034
- if nwItem.isFileType():
1035
- iconName = "checked" if nwItem.isActive else "unchecked"
1036
- toolTip = self.trActive if nwItem.isActive else self.trInactive
1037
- trItem.setToolTip(self.C_ACTIVE, toolTip)
1038
- else:
1039
- iconName = "noncheckable"
1050
+ if nwItem.isFileType():
1051
+ iconName = "checked" if nwItem.isActive else "unchecked"
1052
+ toolTip = self.trActive if nwItem.isActive else self.trInactive
1053
+ trItem.setToolTip(self.C_ACTIVE, toolTip)
1054
+ else:
1055
+ iconName = "noncheckable"
1040
1056
 
1041
- trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))
1057
+ trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))
1042
1058
 
1043
- if CONFIG.emphLabels and nwItem.isDocumentLayout():
1044
- trFont = trItem.font(self.C_NAME)
1045
- trFont.setBold(hLevel == "H1" or hLevel == "H2")
1046
- trFont.setUnderline(hLevel == "H1")
1047
- trItem.setFont(self.C_NAME, trFont)
1059
+ if CONFIG.emphLabels and nwItem.isDocumentLayout():
1060
+ trFont = trItem.font(self.C_NAME)
1061
+ trFont.setBold(hLevel == "H1" or hLevel == "H2")
1062
+ trFont.setUnderline(hLevel == "H1")
1063
+ trItem.setFont(self.C_NAME, trFont)
1048
1064
 
1049
- # Emit Refresh Signal
1050
- self.itemRefreshed.emit(tHandle, nwItem, itemIcon)
1065
+ # Emit Refresh Signal
1066
+ self.itemRefreshed.emit(nwItem.itemHandle, nwItem, itemIcon)
1051
1067
 
1052
1068
  return
1053
1069
 
@@ -1353,7 +1369,8 @@ class GuiProjectTree(QTreeWidget):
1353
1369
  SHARED.project.index.deleteHandle(mHandle)
1354
1370
  else:
1355
1371
  SHARED.project.index.reIndexHandle(mHandle)
1356
- self.setTreeItemValues(mHandle)
1372
+ if mItem := SHARED.project.tree[mHandle]:
1373
+ self.setTreeItemValues(mItem)
1357
1374
 
1358
1375
  # Update word count
1359
1376
  self.propagateCount(tHandle, nwItemS.wordCount, countChildren=True)
@@ -1594,7 +1611,7 @@ class GuiProjectTree(QTreeWidget):
1594
1611
 
1595
1612
  self._treeMap[tHandle] = newItem
1596
1613
  self.propagateCount(tHandle, nwItem.wordCount, countChildren=True)
1597
- self.setTreeItemValues(tHandle)
1614
+ self.setTreeItemValues(nwItem)
1598
1615
  newItem.setExpanded(nwItem.isExpanded)
1599
1616
 
1600
1617
  return newItem
@@ -1971,7 +1988,7 @@ class _TreeContextMenu(QMenu):
1971
1988
  def _toggleItemActive(self) -> None:
1972
1989
  """Toggle the active status of an item."""
1973
1990
  self._item.setActive(not self._item.isActive)
1974
- self.projTree.setTreeItemValues(self._handle)
1991
+ self.projTree.setTreeItemValues(self._item)
1975
1992
  self.projTree._alertTreeChange(self._handle, flush=False)
1976
1993
  return
1977
1994
 
@@ -1984,14 +2001,14 @@ class _TreeContextMenu(QMenu):
1984
2001
  for tItem in self._items:
1985
2002
  if tItem and tItem.isFileType():
1986
2003
  tItem.setActive(isActive)
1987
- self.projTree.setTreeItemValues(tItem.itemHandle)
2004
+ self.projTree.setTreeItemValues(tItem)
1988
2005
  self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
1989
2006
  return
1990
2007
 
1991
2008
  def _changeItemStatus(self, key: str) -> None:
1992
2009
  """Set a new status value of an item."""
1993
2010
  self._item.setStatus(key)
1994
- self.projTree.setTreeItemValues(self._handle)
2011
+ self.projTree.setTreeItemValues(self._item)
1995
2012
  self.projTree._alertTreeChange(self._handle, flush=False)
1996
2013
  return
1997
2014
 
@@ -2000,14 +2017,14 @@ class _TreeContextMenu(QMenu):
2000
2017
  for tItem in self._items:
2001
2018
  if tItem and tItem.isNovelLike():
2002
2019
  tItem.setStatus(key)
2003
- self.projTree.setTreeItemValues(tItem.itemHandle)
2020
+ self.projTree.setTreeItemValues(tItem)
2004
2021
  self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
2005
2022
  return
2006
2023
 
2007
2024
  def _changeItemImport(self, key: str) -> None:
2008
2025
  """Set a new importance value of an item."""
2009
2026
  self._item.setImport(key)
2010
- self.projTree.setTreeItemValues(self._handle)
2027
+ self.projTree.setTreeItemValues(self._item)
2011
2028
  self.projTree._alertTreeChange(self._handle, flush=False)
2012
2029
  return
2013
2030
 
@@ -2016,7 +2033,7 @@ class _TreeContextMenu(QMenu):
2016
2033
  for tItem in self._items:
2017
2034
  if tItem and not tItem.isNovelLike():
2018
2035
  tItem.setImport(key)
2019
- self.projTree.setTreeItemValues(tItem.itemHandle)
2036
+ self.projTree.setTreeItemValues(tItem)
2020
2037
  self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
2021
2038
  return
2022
2039
 
@@ -2024,11 +2041,11 @@ class _TreeContextMenu(QMenu):
2024
2041
  """Set a new item layout value of an item."""
2025
2042
  if itemLayout == nwItemLayout.DOCUMENT and self._item.documentAllowed():
2026
2043
  self._item.setLayout(nwItemLayout.DOCUMENT)
2027
- self.projTree.setTreeItemValues(self._handle)
2044
+ self.projTree.setTreeItemValues(self._item)
2028
2045
  self.projTree._alertTreeChange(self._handle, flush=False)
2029
2046
  elif itemLayout == nwItemLayout.NOTE:
2030
2047
  self._item.setLayout(nwItemLayout.NOTE)
2031
- self.projTree.setTreeItemValues(self._handle)
2048
+ self.projTree.setTreeItemValues(self._item)
2032
2049
  self.projTree._alertTreeChange(self._handle, flush=False)
2033
2050
  return
2034
2051
 
@@ -2042,12 +2059,12 @@ class _TreeContextMenu(QMenu):
2042
2059
  if msgYes and itemLayout == nwItemLayout.DOCUMENT and self._item.documentAllowed():
2043
2060
  self._item.setType(nwItemType.FILE)
2044
2061
  self._item.setLayout(nwItemLayout.DOCUMENT)
2045
- self.projTree.setTreeItemValues(self._handle)
2062
+ self.projTree.setTreeItemValues(self._item)
2046
2063
  self.projTree._alertTreeChange(self._handle, flush=False)
2047
2064
  elif msgYes and itemLayout == nwItemLayout.NOTE:
2048
2065
  self._item.setType(nwItemType.FILE)
2049
2066
  self._item.setLayout(nwItemLayout.NOTE)
2050
- self.projTree.setTreeItemValues(self._handle)
2067
+ self.projTree.setTreeItemValues(self._item)
2051
2068
  self.projTree._alertTreeChange(self._handle, flush=False)
2052
2069
  else:
2053
2070
  logger.info("Folder conversion cancelled")