novelWriter 2.3rc1__py3-none-any.whl → 2.4b1__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.
- {novelWriter-2.3rc1.dist-info → novelWriter-2.4b1.dist-info}/METADATA +1 -1
- {novelWriter-2.3rc1.dist-info → novelWriter-2.4b1.dist-info}/RECORD +99 -85
- {novelWriter-2.3rc1.dist-info → novelWriter-2.4b1.dist-info}/WHEEL +1 -1
- novelWriter-2.4b1.dist-info/entry_points.txt +2 -0
- novelwriter/__init__.py +5 -5
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
- novelwriter/assets/i18n/project_nl_NL.json +11 -0
- novelwriter/assets/i18n/project_pt_BR.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +7 -0
- novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +1 -1
- novelwriter/assets/icons/typicons_dark/typ_refresh.svg +1 -1
- novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_times.svg +1 -1
- novelwriter/assets/icons/typicons_light/icons.conf +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +7 -0
- novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +1 -1
- novelwriter/assets/icons/typicons_light/typ_refresh.svg +1 -1
- novelwriter/assets/icons/typicons_light/typ_search-grey.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_times.svg +1 -1
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/cyberpunk_night.conf +26 -0
- novelwriter/assets/syntax/default_dark.conf +1 -0
- novelwriter/assets/syntax/default_light.conf +1 -0
- novelwriter/assets/syntax/grey_dark.conf +1 -0
- novelwriter/assets/syntax/grey_light.conf +1 -0
- novelwriter/assets/syntax/light_owl.conf +1 -0
- novelwriter/assets/syntax/night_owl.conf +1 -0
- novelwriter/assets/syntax/solarized_dark.conf +1 -0
- novelwriter/assets/syntax/solarized_light.conf +1 -0
- novelwriter/assets/syntax/tango.conf +23 -0
- novelwriter/assets/syntax/tomorrow.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
- novelwriter/assets/text/credits_en.htm +25 -23
- novelwriter/assets/themes/cyberpunk_night.conf +29 -0
- novelwriter/common.py +1 -1
- novelwriter/config.py +35 -12
- novelwriter/constants.py +5 -6
- novelwriter/core/buildsettings.py +60 -40
- novelwriter/core/coretools.py +98 -13
- novelwriter/core/docbuild.py +74 -7
- novelwriter/core/document.py +24 -3
- novelwriter/core/index.py +31 -112
- novelwriter/core/project.py +11 -15
- novelwriter/core/projectxml.py +2 -1
- novelwriter/core/sessions.py +2 -2
- novelwriter/core/status.py +4 -4
- novelwriter/core/storage.py +16 -6
- novelwriter/core/tohtml.py +22 -25
- novelwriter/core/tokenizer.py +416 -236
- novelwriter/core/tomd.py +17 -8
- novelwriter/core/toodt.py +65 -7
- novelwriter/core/tree.py +8 -8
- novelwriter/dialogs/about.py +2 -2
- novelwriter/dialogs/docsplit.py +7 -8
- novelwriter/dialogs/preferences.py +3 -6
- novelwriter/dialogs/wordlist.py +1 -1
- novelwriter/enum.py +17 -14
- novelwriter/extensions/configlayout.py +22 -0
- novelwriter/extensions/modified.py +20 -2
- novelwriter/extensions/versioninfo.py +1 -1
- novelwriter/gui/doceditor.py +257 -279
- novelwriter/gui/dochighlight.py +29 -25
- novelwriter/gui/docviewer.py +139 -148
- novelwriter/gui/docviewerpanel.py +4 -24
- novelwriter/gui/editordocument.py +12 -1
- novelwriter/gui/itemdetails.py +6 -6
- novelwriter/gui/mainmenu.py +37 -17
- novelwriter/gui/noveltree.py +11 -19
- novelwriter/gui/outline.py +43 -20
- novelwriter/gui/projtree.py +88 -88
- novelwriter/gui/search.py +316 -0
- novelwriter/gui/sidebar.py +25 -30
- novelwriter/gui/theme.py +68 -8
- novelwriter/guimain.py +183 -178
- novelwriter/shared.py +26 -1
- novelwriter/text/__init__.py +3 -0
- novelwriter/text/counting.py +137 -0
- novelwriter/tools/manuscript.py +344 -55
- novelwriter/tools/manussettings.py +214 -71
- novelwriter/tools/noveldetails.py +1 -1
- novelwriter/tools/welcome.py +8 -9
- novelWriter-2.3rc1.dist-info/entry_points.txt +0 -5
- {novelWriter-2.3rc1.dist-info → novelWriter-2.4b1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.3rc1.dist-info → novelWriter-2.4b1.dist-info}/top_level.txt +0 -0
novelwriter/gui/projtree.py
CHANGED
@@ -38,20 +38,22 @@ from PyQt5.QtGui import (
|
|
38
38
|
from PyQt5.QtCore import QPoint, QTimer, Qt, QSize, pyqtSignal, pyqtSlot
|
39
39
|
from PyQt5.QtWidgets import (
|
40
40
|
QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
|
41
|
-
QLabel, QMenu, QShortcut, QSizePolicy,
|
42
|
-
|
41
|
+
QLabel, QMenu, QShortcut, QSizePolicy, QTreeWidget, QTreeWidgetItem,
|
42
|
+
QVBoxLayout, QWidget
|
43
43
|
)
|
44
44
|
|
45
45
|
from novelwriter import CONFIG, SHARED
|
46
|
-
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout
|
47
46
|
from novelwriter.common import minmax
|
48
47
|
from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels
|
49
|
-
from novelwriter.core.item import NWItem
|
50
48
|
from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
|
49
|
+
from novelwriter.core.item import NWItem
|
51
50
|
from novelwriter.dialogs.docmerge import GuiDocMerge
|
52
51
|
from novelwriter.dialogs.docsplit import GuiDocSplit
|
53
52
|
from novelwriter.dialogs.editlabel import GuiEditLabel
|
54
53
|
from novelwriter.dialogs.projectsettings import GuiProjectSettings
|
54
|
+
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout
|
55
|
+
from novelwriter.extensions.modified import NIconToolButton
|
56
|
+
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
|
55
57
|
|
56
58
|
if TYPE_CHECKING: # pragma: no cover
|
57
59
|
from novelwriter.guimain import GuiMain
|
@@ -142,7 +144,6 @@ class GuiProjectView(QWidget):
|
|
142
144
|
self.requestDeleteItem = self.projTree.requestDeleteItem
|
143
145
|
self.getSelectedHandle = self.projTree.getSelectedHandle
|
144
146
|
self.changedSince = self.projTree.changedSince
|
145
|
-
self.createNewNote = self.projTree.createNewNote
|
146
147
|
|
147
148
|
return
|
148
149
|
|
@@ -240,6 +241,12 @@ class GuiProjectView(QWidget):
|
|
240
241
|
self.projBar.buildQuickLinksMenu()
|
241
242
|
return
|
242
243
|
|
244
|
+
@pyqtSlot(str, nwItemClass)
|
245
|
+
def createNewNote(self, tag: str, itemClass: nwItemClass) -> None:
|
246
|
+
"""Process new not request."""
|
247
|
+
self.projTree.createNewNote(tag, itemClass)
|
248
|
+
return
|
249
|
+
|
243
250
|
# END Class GuiProjectView
|
244
251
|
|
245
252
|
|
@@ -263,29 +270,26 @@ class GuiProjectToolBar(QWidget):
|
|
263
270
|
self.setAutoFillBackground(True)
|
264
271
|
|
265
272
|
# Widget Label
|
266
|
-
self.viewLabel = QLabel(
|
273
|
+
self.viewLabel = QLabel(self.tr("Project Content"))
|
274
|
+
self.viewLabel.setFont(SHARED.theme.guiFontB)
|
267
275
|
self.viewLabel.setContentsMargins(0, 0, 0, 0)
|
268
276
|
self.viewLabel.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
269
277
|
|
270
278
|
# Quick Links
|
271
279
|
self.mQuick = QMenu(self)
|
272
280
|
|
273
|
-
self.tbQuick =
|
281
|
+
self.tbQuick = NIconToolButton(self, iPx)
|
274
282
|
self.tbQuick.setToolTip("%s [Ctrl+L]" % self.tr("Quick Links"))
|
275
283
|
self.tbQuick.setShortcut("Ctrl+L")
|
276
|
-
self.tbQuick.setIconSize(QSize(iPx, iPx))
|
277
284
|
self.tbQuick.setMenu(self.mQuick)
|
278
|
-
self.tbQuick.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
279
285
|
|
280
286
|
# Move Buttons
|
281
|
-
self.tbMoveU =
|
287
|
+
self.tbMoveU = NIconToolButton(self, iPx)
|
282
288
|
self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up"))
|
283
|
-
self.tbMoveU.setIconSize(QSize(iPx, iPx))
|
284
289
|
self.tbMoveU.clicked.connect(lambda: self.projTree.moveTreeItem(-1))
|
285
290
|
|
286
|
-
self.tbMoveD =
|
291
|
+
self.tbMoveD = NIconToolButton(self, iPx)
|
287
292
|
self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down"))
|
288
|
-
self.tbMoveD.setIconSize(QSize(iPx, iPx))
|
289
293
|
self.tbMoveD.clicked.connect(lambda: self.projTree.moveTreeItem(1))
|
290
294
|
|
291
295
|
# Add Item Menu
|
@@ -324,12 +328,10 @@ class GuiProjectToolBar(QWidget):
|
|
324
328
|
self.mAddRoot = self.mAdd.addMenu(trConst(nwLabels.ITEM_DESCRIPTION["root"]))
|
325
329
|
self._buildRootMenu()
|
326
330
|
|
327
|
-
self.tbAdd =
|
331
|
+
self.tbAdd = NIconToolButton(self, iPx)
|
328
332
|
self.tbAdd.setToolTip("%s [Ctrl+N]" % self.tr("Add Item"))
|
329
333
|
self.tbAdd.setShortcut("Ctrl+N")
|
330
|
-
self.tbAdd.setIconSize(QSize(iPx, iPx))
|
331
334
|
self.tbAdd.setMenu(self.mAdd)
|
332
|
-
self.tbAdd.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
333
335
|
|
334
336
|
# More Options Menu
|
335
337
|
self.mMore = QMenu(self)
|
@@ -343,11 +345,9 @@ class GuiProjectToolBar(QWidget):
|
|
343
345
|
self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash"))
|
344
346
|
self.aEmptyTrash.triggered.connect(lambda: self.projTree.emptyTrash())
|
345
347
|
|
346
|
-
self.tbMore =
|
348
|
+
self.tbMore = NIconToolButton(self, iPx)
|
347
349
|
self.tbMore.setToolTip(self.tr("More Options"))
|
348
|
-
self.tbMore.setIconSize(QSize(iPx, iPx))
|
349
350
|
self.tbMore.setMenu(self.mMore)
|
350
|
-
self.tbMore.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
351
351
|
|
352
352
|
# Assemble
|
353
353
|
self.outerBox = QHBoxLayout()
|
@@ -377,18 +377,12 @@ class GuiProjectToolBar(QWidget):
|
|
377
377
|
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
378
378
|
self.setPalette(qPalette)
|
379
379
|
|
380
|
-
|
381
|
-
buttonStyle
|
382
|
-
"QToolButton {{padding: {0}px; border: none; background: transparent;}} "
|
383
|
-
"QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}"
|
384
|
-
).format(CONFIG.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue())
|
385
|
-
buttonStyleMenu = f"{buttonStyle} QToolButton::menu-indicator {{image: none;}}"
|
386
|
-
|
387
|
-
self.tbQuick.setStyleSheet(buttonStyleMenu)
|
380
|
+
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
381
|
+
self.tbQuick.setStyleSheet(buttonStyle)
|
388
382
|
self.tbMoveU.setStyleSheet(buttonStyle)
|
389
383
|
self.tbMoveD.setStyleSheet(buttonStyle)
|
390
|
-
self.tbAdd.setStyleSheet(
|
391
|
-
self.tbMore.setStyleSheet(
|
384
|
+
self.tbAdd.setStyleSheet(buttonStyle)
|
385
|
+
self.tbMore.setStyleSheet(buttonStyle)
|
392
386
|
|
393
387
|
self.tbQuick.setIcon(SHARED.theme.getIcon("bookmark"))
|
394
388
|
self.tbMoveU.setIcon(SHARED.theme.getIcon("up"))
|
@@ -505,10 +499,15 @@ class GuiProjectTree(QTreeWidget):
|
|
505
499
|
self.mainGui = projView.mainGui
|
506
500
|
|
507
501
|
# Internal Variables
|
508
|
-
self._treeMap = {}
|
502
|
+
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
509
503
|
self._timeChanged = 0.0
|
510
504
|
self._popAlert = None
|
511
505
|
|
506
|
+
# Cached Translations
|
507
|
+
self.trActive = self.tr("Active")
|
508
|
+
self.trInactive = self.tr("Inactive")
|
509
|
+
self.trPermDelete = self.tr("Permanently delete {0} file(s) from Trash?")
|
510
|
+
|
512
511
|
# Build GUI
|
513
512
|
# =========
|
514
513
|
|
@@ -555,10 +554,6 @@ class GuiProjectTree(QTreeWidget):
|
|
555
554
|
trRoot = self.invisibleRootItem()
|
556
555
|
trRoot.setFlags(trRoot.flags() ^ Qt.ItemFlag.ItemIsDropEnabled)
|
557
556
|
|
558
|
-
# Cached values
|
559
|
-
self._lblActive = self.tr("Active")
|
560
|
-
self._lblInactive = self.tr("Inactive")
|
561
|
-
|
562
557
|
# Set selection options
|
563
558
|
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
564
559
|
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
@@ -605,18 +600,18 @@ class GuiProjectTree(QTreeWidget):
|
|
605
600
|
self._timeChanged = 0.0
|
606
601
|
return
|
607
602
|
|
608
|
-
def createNewNote(self, tag: str, itemClass: nwItemClass
|
603
|
+
def createNewNote(self, tag: str, itemClass: nwItemClass) -> None:
|
609
604
|
"""Create a new note. This function is used by the document
|
610
605
|
editor to create note files for unknown tags.
|
611
606
|
"""
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
607
|
+
if itemClass != nwItemClass.NO_CLASS:
|
608
|
+
if not (rHandle := SHARED.project.tree.findRoot(itemClass)):
|
609
|
+
self.newTreeItem(nwItemType.ROOT, itemClass)
|
610
|
+
rHandle = SHARED.project.tree.findRoot(itemClass)
|
611
|
+
if rHandle and (tHandle := SHARED.project.newFile(tag, rHandle)):
|
616
612
|
SHARED.project.writeNewFile(tHandle, 1, False, f"@tag: {tag}\n\n")
|
617
613
|
self.revealNewTreeItem(tHandle, wordCount=True)
|
618
|
-
|
619
|
-
return False
|
614
|
+
return
|
620
615
|
|
621
616
|
def newTreeItem(self, itemType: nwItemType, itemClass: nwItemClass | None = None,
|
622
617
|
hLevel: int = 1, isNote: bool = False, copyDoc: str | None = None) -> bool:
|
@@ -902,10 +897,7 @@ class GuiProjectTree(QTreeWidget):
|
|
902
897
|
SHARED.info(self.tr("The Trash folder is already empty."))
|
903
898
|
return False
|
904
899
|
|
905
|
-
|
906
|
-
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
|
907
|
-
)
|
908
|
-
if not msgYes:
|
900
|
+
if not SHARED.question(self.trPermDelete.format(nTrash)):
|
909
901
|
logger.info("Action cancelled by user")
|
910
902
|
return False
|
911
903
|
|
@@ -1052,7 +1044,7 @@ class GuiProjectTree(QTreeWidget):
|
|
1052
1044
|
|
1053
1045
|
if nwItem.isFileType():
|
1054
1046
|
iconName = "checked" if nwItem.isActive else "unchecked"
|
1055
|
-
toolTip = self.
|
1047
|
+
toolTip = self.trActive if nwItem.isActive else self.trInactive
|
1056
1048
|
trItem.setToolTip(self.C_ACTIVE, toolTip)
|
1057
1049
|
else:
|
1058
1050
|
iconName = "noncheckable"
|
@@ -1129,9 +1121,8 @@ class GuiProjectTree(QTreeWidget):
|
|
1129
1121
|
"""Get the currently selected handle. If multiple items are
|
1130
1122
|
selected, return the first.
|
1131
1123
|
"""
|
1132
|
-
|
1133
|
-
|
1134
|
-
return selItem[0].data(self.C_DATA, self.D_HANDLE)
|
1124
|
+
if items := self.selectedItems():
|
1125
|
+
return items[0].data(self.C_DATA, self.D_HANDLE)
|
1135
1126
|
return None
|
1136
1127
|
|
1137
1128
|
def setSelectedHandle(self, tHandle: str | None, doScroll: bool = False) -> bool:
|
@@ -1143,9 +1134,8 @@ class GuiProjectTree(QTreeWidget):
|
|
1143
1134
|
if tHandle in self._treeMap:
|
1144
1135
|
self.setCurrentItem(self._treeMap[tHandle])
|
1145
1136
|
|
1146
|
-
|
1147
|
-
|
1148
|
-
self.scrollTo(selIndex[0], QAbstractItemView.ScrollHint.PositionAtCenter)
|
1137
|
+
if (indexes := self.selectedIndexes()) and doScroll:
|
1138
|
+
self.scrollTo(indexes[0], QAbstractItemView.ScrollHint.PositionAtCenter)
|
1149
1139
|
|
1150
1140
|
return True
|
1151
1141
|
|
@@ -1160,10 +1150,8 @@ class GuiProjectTree(QTreeWidget):
|
|
1160
1150
|
|
1161
1151
|
def openContextOnSelected(self) -> bool:
|
1162
1152
|
"""Open the context menu on the current selected item."""
|
1163
|
-
|
1164
|
-
|
1165
|
-
pos = self.visualItemRect(selItem[0]).center()
|
1166
|
-
return self._openContextMenu(pos)
|
1153
|
+
if items := self.selectedItems():
|
1154
|
+
return self._openContextMenu(self.visualItemRect(items[0]).center())
|
1167
1155
|
return False
|
1168
1156
|
|
1169
1157
|
def changedSince(self, checkTime: float) -> bool:
|
@@ -1746,7 +1734,7 @@ class _TreeContextMenu(QMenu):
|
|
1746
1734
|
|
1747
1735
|
self._item = nwItem
|
1748
1736
|
self._handle = nwItem.itemHandle
|
1749
|
-
self._items: list[
|
1737
|
+
self._items: list[NWItem] = []
|
1750
1738
|
|
1751
1739
|
logger.debug("Ready: _TreeContextMenu")
|
1752
1740
|
|
@@ -1799,13 +1787,17 @@ class _TreeContextMenu(QMenu):
|
|
1799
1787
|
|
1800
1788
|
return
|
1801
1789
|
|
1802
|
-
def buildMultiSelectMenu(self,
|
1790
|
+
def buildMultiSelectMenu(self, handles: list[str]) -> None:
|
1803
1791
|
"""Build the multi-select menu."""
|
1804
|
-
self._items =
|
1792
|
+
self._items = []
|
1793
|
+
for tHandle in handles:
|
1794
|
+
if (tItem := SHARED.project.tree[tHandle]):
|
1795
|
+
self._items.append(tItem)
|
1796
|
+
|
1805
1797
|
self._itemActive(True)
|
1806
1798
|
self._itemStatusImport(True)
|
1807
1799
|
self.addSeparator()
|
1808
|
-
self.
|
1800
|
+
self._multiMoveToTrash()
|
1809
1801
|
return
|
1810
1802
|
|
1811
1803
|
##
|
@@ -1836,7 +1828,7 @@ class _TreeContextMenu(QMenu):
|
|
1836
1828
|
|
1837
1829
|
def _itemHeader(self) -> None:
|
1838
1830
|
"""Check if there is a header that can be used for rename."""
|
1839
|
-
if hItem := SHARED.project.index.
|
1831
|
+
if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"):
|
1840
1832
|
action = self.addAction(self.tr("Rename to Heading"))
|
1841
1833
|
action.triggered.connect(
|
1842
1834
|
lambda: self.projTree.renameTreeItem(self._handle, hItem.title)
|
@@ -1847,9 +1839,9 @@ class _TreeContextMenu(QMenu):
|
|
1847
1839
|
"""Add Active/Inactive actions."""
|
1848
1840
|
if multi:
|
1849
1841
|
mSub = self.addMenu(self.tr("Set Active to ..."))
|
1850
|
-
aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self.
|
1842
|
+
aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self.projTree.trActive)
|
1851
1843
|
aOne.triggered.connect(lambda: self._iterItemActive(True))
|
1852
|
-
aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self.
|
1844
|
+
aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self.projTree.trInactive)
|
1853
1845
|
aTwo.triggered.connect(lambda: self._iterItemActive(False))
|
1854
1846
|
else:
|
1855
1847
|
action = self.addAction(self.tr("Toggle Active"))
|
@@ -1935,7 +1927,7 @@ class _TreeContextMenu(QMenu):
|
|
1935
1927
|
action.triggered.connect(lambda: tree._mergeDocuments(tHandle, True))
|
1936
1928
|
|
1937
1929
|
if isFile:
|
1938
|
-
action = menu.addAction(self.tr("Split Document by
|
1930
|
+
action = menu.addAction(self.tr("Split Document by Headings"))
|
1939
1931
|
action.triggered.connect(lambda: tree._splitDocument(tHandle))
|
1940
1932
|
|
1941
1933
|
return
|
@@ -1949,11 +1941,9 @@ class _TreeContextMenu(QMenu):
|
|
1949
1941
|
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, True))
|
1950
1942
|
action = self.addAction(self.tr("Collapse All"))
|
1951
1943
|
action.triggered.connect(lambda: tree.setExpandedFromHandle(tHandle, False))
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
action = self.addAction(self.tr("Duplicate Document"))
|
1956
|
-
action.triggered.connect(lambda: tree._duplicateFromHandle(tHandle))
|
1944
|
+
|
1945
|
+
action = self.addAction(self.tr("Duplicate"))
|
1946
|
+
action.triggered.connect(lambda: tree._duplicateFromHandle(tHandle))
|
1957
1947
|
|
1958
1948
|
if self._item.itemClass == nwItemClass.TRASH or isRoot or (isFolder and not hasChild):
|
1959
1949
|
action = self.addAction(self.tr("Delete Permanently"))
|
@@ -1964,10 +1954,14 @@ class _TreeContextMenu(QMenu):
|
|
1964
1954
|
|
1965
1955
|
return
|
1966
1956
|
|
1967
|
-
def
|
1957
|
+
def _multiMoveToTrash(self) -> None:
|
1968
1958
|
"""Add move to Trash action."""
|
1969
|
-
|
1970
|
-
if
|
1959
|
+
areTrash = [i.itemClass == nwItemClass.TRASH for i in self._items]
|
1960
|
+
if all(areTrash):
|
1961
|
+
action = self.addAction(self.tr("Delete Permanently"))
|
1962
|
+
action.triggered.connect(self._iterPermDelete)
|
1963
|
+
elif not any(areTrash):
|
1964
|
+
action = self.addAction(self.tr("Move to Trash"))
|
1971
1965
|
action.triggered.connect(self._iterMoveToTrash)
|
1972
1966
|
return
|
1973
1967
|
|
@@ -1979,10 +1973,19 @@ class _TreeContextMenu(QMenu):
|
|
1979
1973
|
def _iterMoveToTrash(self) -> None:
|
1980
1974
|
"""Iterate through files and move them to Trash."""
|
1981
1975
|
if SHARED.question(self.tr("Move {0} items to Trash?").format(len(self._items))):
|
1982
|
-
for
|
1983
|
-
tItem
|
1984
|
-
|
1985
|
-
|
1976
|
+
for tItem in self._items:
|
1977
|
+
if tItem.isFileType() and tItem.itemClass != nwItemClass.TRASH:
|
1978
|
+
self.projTree.moveItemToTrash(tItem.itemHandle, askFirst=False, flush=False)
|
1979
|
+
self.projTree.saveTreeOrder()
|
1980
|
+
return
|
1981
|
+
|
1982
|
+
@pyqtSlot()
|
1983
|
+
def _iterPermDelete(self) -> None:
|
1984
|
+
"""Iterate through files and delete them."""
|
1985
|
+
if SHARED.question(self.projTree.trPermDelete.format(len(self._items))):
|
1986
|
+
for tItem in self._items:
|
1987
|
+
if tItem.isFileType() and tItem.itemClass == nwItemClass.TRASH:
|
1988
|
+
self.projTree.permDeleteItem(tItem.itemHandle, askFirst=False, flush=False)
|
1986
1989
|
self.projTree.saveTreeOrder()
|
1987
1990
|
return
|
1988
1991
|
|
@@ -2000,12 +2003,11 @@ class _TreeContextMenu(QMenu):
|
|
2000
2003
|
|
2001
2004
|
def _iterItemActive(self, isActive: bool) -> None:
|
2002
2005
|
"""Set the active status of multiple items."""
|
2003
|
-
for
|
2004
|
-
tItem = SHARED.project.tree[tHandle]
|
2006
|
+
for tItem in self._items:
|
2005
2007
|
if tItem and tItem.isFileType():
|
2006
2008
|
tItem.setActive(isActive)
|
2007
|
-
self.projTree.setTreeItemValues(
|
2008
|
-
self.projTree._alertTreeChange(
|
2009
|
+
self.projTree.setTreeItemValues(tItem.itemHandle)
|
2010
|
+
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
2009
2011
|
return
|
2010
2012
|
|
2011
2013
|
def _changeItemStatus(self, key: str) -> None:
|
@@ -2017,12 +2019,11 @@ class _TreeContextMenu(QMenu):
|
|
2017
2019
|
|
2018
2020
|
def _iterSetItemStatus(self, key: str) -> None:
|
2019
2021
|
"""Change the status value for multiple items."""
|
2020
|
-
for
|
2021
|
-
tItem = SHARED.project.tree[tHandle]
|
2022
|
+
for tItem in self._items:
|
2022
2023
|
if tItem and tItem.isNovelLike():
|
2023
2024
|
tItem.setStatus(key)
|
2024
|
-
self.projTree.setTreeItemValues(
|
2025
|
-
self.projTree._alertTreeChange(
|
2025
|
+
self.projTree.setTreeItemValues(tItem.itemHandle)
|
2026
|
+
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
2026
2027
|
return
|
2027
2028
|
|
2028
2029
|
def _changeItemImport(self, key: str) -> None:
|
@@ -2034,12 +2035,11 @@ class _TreeContextMenu(QMenu):
|
|
2034
2035
|
|
2035
2036
|
def _iterSetItemImport(self, key: str) -> None:
|
2036
2037
|
"""Change the status value for multiple items."""
|
2037
|
-
for
|
2038
|
-
tItem = SHARED.project.tree[tHandle]
|
2038
|
+
for tItem in self._items:
|
2039
2039
|
if tItem and not tItem.isNovelLike():
|
2040
2040
|
tItem.setImport(key)
|
2041
|
-
self.projTree.setTreeItemValues(
|
2042
|
-
self.projTree._alertTreeChange(
|
2041
|
+
self.projTree.setTreeItemValues(tItem.itemHandle)
|
2042
|
+
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
2043
2043
|
return
|
2044
2044
|
|
2045
2045
|
def _changeItemLayout(self, itemLayout: nwItemLayout) -> None:
|