novelWriter 2.5.1__py3-none-any.whl → 2.6b1__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.5.1.dist-info → novelWriter-2.6b1.dist-info}/METADATA +2 -1
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/RECORD +61 -56
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/WHEEL +1 -1
 - novelwriter/__init__.py +3 -3
 - novelwriter/assets/i18n/project_en_GB.json +1 -0
 - novelwriter/assets/icons/typicons_dark/icons.conf +1 -0
 - novelwriter/assets/icons/typicons_dark/mixed_copy.svg +4 -0
 - novelwriter/assets/icons/typicons_light/icons.conf +1 -0
 - novelwriter/assets/icons/typicons_light/mixed_copy.svg +4 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/assets/themes/default_light.conf +2 -2
 - novelwriter/common.py +63 -0
 - novelwriter/config.py +10 -3
 - novelwriter/constants.py +153 -60
 - novelwriter/core/buildsettings.py +66 -39
 - novelwriter/core/coretools.py +34 -22
 - novelwriter/core/docbuild.py +130 -169
 - novelwriter/core/index.py +29 -18
 - novelwriter/core/item.py +2 -2
 - novelwriter/core/options.py +4 -1
 - novelwriter/core/spellcheck.py +9 -14
 - novelwriter/dialogs/preferences.py +45 -32
 - novelwriter/dialogs/projectsettings.py +3 -3
 - novelwriter/enum.py +29 -23
 - novelwriter/extensions/configlayout.py +24 -11
 - novelwriter/extensions/modified.py +13 -1
 - novelwriter/extensions/pagedsidebar.py +5 -5
 - novelwriter/formats/shared.py +155 -0
 - novelwriter/formats/todocx.py +1195 -0
 - novelwriter/formats/tohtml.py +452 -0
 - novelwriter/{core → formats}/tokenizer.py +483 -485
 - novelwriter/formats/tomarkdown.py +217 -0
 - novelwriter/{core → formats}/toodt.py +270 -320
 - novelwriter/formats/toqdoc.py +436 -0
 - novelwriter/formats/toraw.py +91 -0
 - novelwriter/gui/doceditor.py +240 -193
 - novelwriter/gui/dochighlight.py +96 -84
 - novelwriter/gui/docviewer.py +56 -30
 - novelwriter/gui/docviewerpanel.py +3 -3
 - novelwriter/gui/editordocument.py +17 -2
 - novelwriter/gui/itemdetails.py +8 -4
 - novelwriter/gui/mainmenu.py +121 -60
 - novelwriter/gui/noveltree.py +35 -37
 - novelwriter/gui/outline.py +186 -238
 - novelwriter/gui/projtree.py +142 -131
 - novelwriter/gui/sidebar.py +7 -6
 - novelwriter/gui/theme.py +5 -4
 - novelwriter/guimain.py +43 -155
 - novelwriter/shared.py +14 -4
 - novelwriter/text/counting.py +2 -0
 - novelwriter/text/patterns.py +155 -59
 - novelwriter/tools/manusbuild.py +1 -1
 - novelwriter/tools/manuscript.py +121 -78
 - novelwriter/tools/manussettings.py +403 -260
 - novelwriter/tools/welcome.py +4 -4
 - novelwriter/tools/writingstats.py +3 -3
 - novelwriter/types.py +16 -6
 - novelwriter/core/tohtml.py +0 -530
 - novelwriter/core/tomarkdown.py +0 -252
 - novelwriter/core/toqdoc.py +0 -419
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/LICENSE.md +0 -0
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/entry_points.txt +0 -0
 - {novelWriter-2.5.1.dist-info → novelWriter-2.6b1.dist-info}/top_level.txt +0 -0
 
    
        novelwriter/gui/projtree.py
    CHANGED
    
    | 
         @@ -29,7 +29,6 @@ from __future__ import annotations 
     | 
|
| 
       29 
29 
     | 
    
         
             
            import logging
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            from enum import Enum
         
     | 
| 
       32 
     | 
    
         
            -
            from time import time
         
     | 
| 
       33 
32 
     | 
    
         | 
| 
       34 
33 
     | 
    
         
             
            from PyQt5.QtCore import QPoint, Qt, QTimer, pyqtSignal, pyqtSlot
         
     | 
| 
       35 
34 
     | 
    
         
             
            from PyQt5.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
         
     | 
| 
         @@ -39,8 +38,8 @@ from PyQt5.QtWidgets import ( 
     | 
|
| 
       39 
38 
     | 
    
         
             
            )
         
     | 
| 
       40 
39 
     | 
    
         | 
| 
       41 
40 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
       42 
     | 
    
         
            -
            from novelwriter.common import minmax
         
     | 
| 
       43 
     | 
    
         
            -
            from novelwriter.constants import  
     | 
| 
      
 41 
     | 
    
         
            +
            from novelwriter.common import minmax, qtLambda
         
     | 
| 
      
 42 
     | 
    
         
            +
            from novelwriter.constants import nwLabels, nwStyles, nwUnicode, trConst
         
     | 
| 
       44 
43 
     | 
    
         
             
            from novelwriter.core.coretools import DocDuplicator, DocMerger, DocSplitter
         
     | 
| 
       45 
44 
     | 
    
         
             
            from novelwriter.core.item import NWItem
         
     | 
| 
       46 
45 
     | 
    
         
             
            from novelwriter.dialogs.docmerge import GuiDocMerge
         
     | 
| 
         @@ -51,8 +50,8 @@ from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType 
     | 
|
| 
       51 
50 
     | 
    
         
             
            from novelwriter.extensions.modified import NIconToolButton
         
     | 
| 
       52 
51 
     | 
    
         
             
            from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
         
     | 
| 
       53 
52 
     | 
    
         
             
            from novelwriter.types import (
         
     | 
| 
       54 
     | 
    
         
            -
                QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle,  
     | 
| 
       55 
     | 
    
         
            -
                QtUserRole
         
     | 
| 
      
 53 
     | 
    
         
            +
                QtAlignLeft, QtAlignRight, QtMouseLeft, QtMouseMiddle, QtScrollAlwaysOff,
         
     | 
| 
      
 54 
     | 
    
         
            +
                QtScrollAsNeeded, QtSizeExpanding, QtUserRole
         
     | 
| 
       56 
55 
     | 
    
         
             
            )
         
     | 
| 
       57 
56 
     | 
    
         | 
| 
       58 
57 
     | 
    
         
             
            logger = logging.getLogger(__name__)
         
     | 
| 
         @@ -97,37 +96,37 @@ class GuiProjectView(QWidget): 
     | 
|
| 
       97 
96 
     | 
    
         
             
                    self.keyMoveUp = QShortcut(self.projTree)
         
     | 
| 
       98 
97 
     | 
    
         
             
                    self.keyMoveUp.setKey("Ctrl+Up")
         
     | 
| 
       99 
98 
     | 
    
         
             
                    self.keyMoveUp.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       100 
     | 
    
         
            -
                    self.keyMoveUp.activated.connect( 
     | 
| 
      
 99 
     | 
    
         
            +
                    self.keyMoveUp.activated.connect(qtLambda(self.projTree.moveTreeItem, -1))
         
     | 
| 
       101 
100 
     | 
    
         | 
| 
       102 
101 
     | 
    
         
             
                    self.keyMoveDn = QShortcut(self.projTree)
         
     | 
| 
       103 
102 
     | 
    
         
             
                    self.keyMoveDn.setKey("Ctrl+Down")
         
     | 
| 
       104 
103 
     | 
    
         
             
                    self.keyMoveDn.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       105 
     | 
    
         
            -
                    self.keyMoveDn.activated.connect( 
     | 
| 
      
 104 
     | 
    
         
            +
                    self.keyMoveDn.activated.connect(qtLambda(self.projTree.moveTreeItem, 1))
         
     | 
| 
       106 
105 
     | 
    
         | 
| 
       107 
106 
     | 
    
         
             
                    self.keyGoPrev = QShortcut(self.projTree)
         
     | 
| 
       108 
107 
     | 
    
         
             
                    self.keyGoPrev.setKey("Alt+Up")
         
     | 
| 
       109 
108 
     | 
    
         
             
                    self.keyGoPrev.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       110 
     | 
    
         
            -
                    self.keyGoPrev.activated.connect( 
     | 
| 
      
 109 
     | 
    
         
            +
                    self.keyGoPrev.activated.connect(qtLambda(self.projTree.moveToNextItem, -1))
         
     | 
| 
       111 
110 
     | 
    
         | 
| 
       112 
111 
     | 
    
         
             
                    self.keyGoNext = QShortcut(self.projTree)
         
     | 
| 
       113 
112 
     | 
    
         
             
                    self.keyGoNext.setKey("Alt+Down")
         
     | 
| 
       114 
113 
     | 
    
         
             
                    self.keyGoNext.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       115 
     | 
    
         
            -
                    self.keyGoNext.activated.connect( 
     | 
| 
      
 114 
     | 
    
         
            +
                    self.keyGoNext.activated.connect(qtLambda(self.projTree.moveToNextItem, 1))
         
     | 
| 
       116 
115 
     | 
    
         | 
| 
       117 
116 
     | 
    
         
             
                    self.keyGoUp = QShortcut(self.projTree)
         
     | 
| 
       118 
117 
     | 
    
         
             
                    self.keyGoUp.setKey("Alt+Left")
         
     | 
| 
       119 
118 
     | 
    
         
             
                    self.keyGoUp.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       120 
     | 
    
         
            -
                    self.keyGoUp.activated.connect( 
     | 
| 
      
 119 
     | 
    
         
            +
                    self.keyGoUp.activated.connect(qtLambda(self.projTree.moveToLevel, -1))
         
     | 
| 
       121 
120 
     | 
    
         | 
| 
       122 
121 
     | 
    
         
             
                    self.keyGoDown = QShortcut(self.projTree)
         
     | 
| 
       123 
122 
     | 
    
         
             
                    self.keyGoDown.setKey("Alt+Right")
         
     | 
| 
       124 
123 
     | 
    
         
             
                    self.keyGoDown.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       125 
     | 
    
         
            -
                    self.keyGoDown.activated.connect( 
     | 
| 
      
 124 
     | 
    
         
            +
                    self.keyGoDown.activated.connect(qtLambda(self.projTree.moveToLevel, 1))
         
     | 
| 
       126 
125 
     | 
    
         | 
| 
       127 
126 
     | 
    
         
             
                    self.keyContext = QShortcut(self.projTree)
         
     | 
| 
       128 
127 
     | 
    
         
             
                    self.keyContext.setKey("Ctrl+.")
         
     | 
| 
       129 
128 
     | 
    
         
             
                    self.keyContext.setContext(Qt.ShortcutContext.WidgetShortcut)
         
     | 
| 
       130 
     | 
    
         
            -
                    self.keyContext.activated.connect( 
     | 
| 
      
 129 
     | 
    
         
            +
                    self.keyContext.activated.connect(self.projTree.openContextMenu)
         
     | 
| 
       131 
130 
     | 
    
         | 
| 
       132 
131 
     | 
    
         
             
                    # Signals
         
     | 
| 
       133 
132 
     | 
    
         
             
                    self.selectedItemChanged.connect(self.projBar.treeSelectionChanged)
         
     | 
| 
         @@ -138,7 +137,6 @@ class GuiProjectView(QWidget): 
     | 
|
| 
       138 
137 
     | 
    
         
             
                    self.emptyTrash = self.projTree.emptyTrash
         
     | 
| 
       139 
138 
     | 
    
         
             
                    self.requestDeleteItem = self.projTree.requestDeleteItem
         
     | 
| 
       140 
139 
     | 
    
         
             
                    self.getSelectedHandle = self.projTree.getSelectedHandle
         
     | 
| 
       141 
     | 
    
         
            -
                    self.changedSince = self.projTree.changedSince
         
     | 
| 
       142 
140 
     | 
    
         | 
| 
       143 
141 
     | 
    
         
             
                    return
         
     | 
| 
       144 
142 
     | 
    
         | 
| 
         @@ -211,6 +209,12 @@ class GuiProjectView(QWidget): 
     | 
|
| 
       211 
209 
     | 
    
         
             
                    self.projTree.setSelectedHandle(tHandle, doScroll=doScroll)
         
     | 
| 
       212 
210 
     | 
    
         
             
                    return
         
     | 
| 
       213 
211 
     | 
    
         | 
| 
      
 212 
     | 
    
         
            +
                @pyqtSlot(str)
         
     | 
| 
      
 213 
     | 
    
         
            +
                def setActiveHandle(self, tHandle: str | None) -> None:
         
     | 
| 
      
 214 
     | 
    
         
            +
                    """Highlight the active handle."""
         
     | 
| 
      
 215 
     | 
    
         
            +
                    self.projTree.setActiveHandle(tHandle)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    return
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
       214 
218 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       215 
219 
     | 
    
         
             
                def updateItemValues(self, tHandle: str) -> None:
         
     | 
| 
       216 
220 
     | 
    
         
             
                    """Update tree item."""
         
     | 
| 
         @@ -286,38 +290,38 @@ class GuiProjectToolBar(QWidget): 
     | 
|
| 
       286 
290 
     | 
    
         
             
                    # Move Buttons
         
     | 
| 
       287 
291 
     | 
    
         
             
                    self.tbMoveU = NIconToolButton(self, iSz)
         
     | 
| 
       288 
292 
     | 
    
         
             
                    self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up"))
         
     | 
| 
       289 
     | 
    
         
            -
                    self.tbMoveU.clicked.connect( 
     | 
| 
      
 293 
     | 
    
         
            +
                    self.tbMoveU.clicked.connect(qtLambda(self.projTree.moveTreeItem, -1))
         
     | 
| 
       290 
294 
     | 
    
         | 
| 
       291 
295 
     | 
    
         
             
                    self.tbMoveD = NIconToolButton(self, iSz)
         
     | 
| 
       292 
296 
     | 
    
         
             
                    self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down"))
         
     | 
| 
       293 
     | 
    
         
            -
                    self.tbMoveD.clicked.connect( 
     | 
| 
      
 297 
     | 
    
         
            +
                    self.tbMoveD.clicked.connect(qtLambda(self.projTree.moveTreeItem, 1))
         
     | 
| 
       294 
298 
     | 
    
         | 
| 
       295 
299 
     | 
    
         
             
                    # Add Item Menu
         
     | 
| 
       296 
300 
     | 
    
         
             
                    self.mAdd = QMenu(self)
         
     | 
| 
       297 
301 
     | 
    
         | 
| 
       298 
302 
     | 
    
         
             
                    self.aAddEmpty = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["document"]))
         
     | 
| 
       299 
303 
     | 
    
         
             
                    self.aAddEmpty.triggered.connect(
         
     | 
| 
       300 
     | 
    
         
            -
                         
     | 
| 
      
 304 
     | 
    
         
            +
                        qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=0, isNote=False)
         
     | 
| 
       301 
305 
     | 
    
         
             
                    )
         
     | 
| 
       302 
306 
     | 
    
         | 
| 
       303 
307 
     | 
    
         
             
                    self.aAddChap = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h2"]))
         
     | 
| 
       304 
308 
     | 
    
         
             
                    self.aAddChap.triggered.connect(
         
     | 
| 
       305 
     | 
    
         
            -
                         
     | 
| 
      
 309 
     | 
    
         
            +
                        qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=2, isNote=False)
         
     | 
| 
       306 
310 
     | 
    
         
             
                    )
         
     | 
| 
       307 
311 
     | 
    
         | 
| 
       308 
312 
     | 
    
         
             
                    self.aAddScene = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h3"]))
         
     | 
| 
       309 
313 
     | 
    
         
             
                    self.aAddScene.triggered.connect(
         
     | 
| 
       310 
     | 
    
         
            -
                         
     | 
| 
      
 314 
     | 
    
         
            +
                        qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=3, isNote=False)
         
     | 
| 
       311 
315 
     | 
    
         
             
                    )
         
     | 
| 
       312 
316 
     | 
    
         | 
| 
       313 
317 
     | 
    
         
             
                    self.aAddNote = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["note"]))
         
     | 
| 
       314 
318 
     | 
    
         
             
                    self.aAddNote.triggered.connect(
         
     | 
| 
       315 
     | 
    
         
            -
                         
     | 
| 
      
 319 
     | 
    
         
            +
                        qtLambda(self.projTree.newTreeItem, nwItemType.FILE, hLevel=1, isNote=True)
         
     | 
| 
       316 
320 
     | 
    
         
             
                    )
         
     | 
| 
       317 
321 
     | 
    
         | 
| 
       318 
322 
     | 
    
         
             
                    self.aAddFolder = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["folder"]))
         
     | 
| 
       319 
323 
     | 
    
         
             
                    self.aAddFolder.triggered.connect(
         
     | 
| 
       320 
     | 
    
         
            -
                         
     | 
| 
      
 324 
     | 
    
         
            +
                        qtLambda(self.projTree.newTreeItem, nwItemType.FOLDER)
         
     | 
| 
       321 
325 
     | 
    
         
             
                    )
         
     | 
| 
       322 
326 
     | 
    
         | 
| 
       323 
327 
     | 
    
         
             
                    self.mTemplates = _UpdatableMenu(self.mAdd)
         
     | 
| 
         @@ -337,13 +341,17 @@ class GuiProjectToolBar(QWidget): 
     | 
|
| 
       337 
341 
     | 
    
         
             
                    self.mMore = QMenu(self)
         
     | 
| 
       338 
342 
     | 
    
         | 
| 
       339 
343 
     | 
    
         
             
                    self.aExpand = self.mMore.addAction(self.tr("Expand All"))
         
     | 
| 
       340 
     | 
    
         
            -
                    self.aExpand.triggered.connect( 
     | 
| 
      
 344 
     | 
    
         
            +
                    self.aExpand.triggered.connect(
         
     | 
| 
      
 345 
     | 
    
         
            +
                        qtLambda(self.projTree.setExpandedFromHandle, None, True)
         
     | 
| 
      
 346 
     | 
    
         
            +
                    )
         
     | 
| 
       341 
347 
     | 
    
         | 
| 
       342 
348 
     | 
    
         
             
                    self.aCollapse = self.mMore.addAction(self.tr("Collapse All"))
         
     | 
| 
       343 
     | 
    
         
            -
                    self.aCollapse.triggered.connect( 
     | 
| 
      
 349 
     | 
    
         
            +
                    self.aCollapse.triggered.connect(
         
     | 
| 
      
 350 
     | 
    
         
            +
                        qtLambda(self.projTree.setExpandedFromHandle, None, False)
         
     | 
| 
      
 351 
     | 
    
         
            +
                    )
         
     | 
| 
       344 
352 
     | 
    
         | 
| 
       345 
353 
     | 
    
         
             
                    self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash"))
         
     | 
| 
       346 
     | 
    
         
            -
                    self.aEmptyTrash.triggered.connect( 
     | 
| 
      
 354 
     | 
    
         
            +
                    self.aEmptyTrash.triggered.connect(qtLambda(self.projTree.emptyTrash))
         
     | 
| 
       347 
355 
     | 
    
         | 
| 
       348 
356 
     | 
    
         
             
                    self.tbMore = NIconToolButton(self, iSz)
         
     | 
| 
       349 
357 
     | 
    
         
             
                    self.tbMore.setToolTip(self.tr("More Options"))
         
     | 
| 
         @@ -416,7 +424,7 @@ class GuiProjectToolBar(QWidget): 
     | 
|
| 
       416 
424 
     | 
    
         
             
                        action.setData(tHandle)
         
     | 
| 
       417 
425 
     | 
    
         
             
                        action.setIcon(SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass]))
         
     | 
| 
       418 
426 
     | 
    
         
             
                        action.triggered.connect(
         
     | 
| 
       419 
     | 
    
         
            -
                             
     | 
| 
      
 427 
     | 
    
         
            +
                            qtLambda(self.projView.setSelectedHandle, tHandle, doScroll=True)
         
     | 
| 
       420 
428 
     | 
    
         
             
                        )
         
     | 
| 
       421 
429 
     | 
    
         
             
                    return
         
     | 
| 
       422 
430 
     | 
    
         | 
| 
         @@ -455,7 +463,9 @@ class GuiProjectToolBar(QWidget): 
     | 
|
| 
       455 
463 
     | 
    
         
             
                    def addClass(itemClass: nwItemClass) -> None:
         
     | 
| 
       456 
464 
     | 
    
         
             
                        aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass]))
         
     | 
| 
       457 
465 
     | 
    
         
             
                        aNew.setIcon(SHARED.theme.getIcon(nwLabels.CLASS_ICON[itemClass]))
         
     | 
| 
       458 
     | 
    
         
            -
                        aNew.triggered.connect( 
     | 
| 
      
 466 
     | 
    
         
            +
                        aNew.triggered.connect(
         
     | 
| 
      
 467 
     | 
    
         
            +
                            qtLambda(self.projTree.newTreeItem, nwItemType.ROOT, itemClass)
         
     | 
| 
      
 468 
     | 
    
         
            +
                        )
         
     | 
| 
       459 
469 
     | 
    
         
             
                        self.mAddRoot.addAction(aNew)
         
     | 
| 
       460 
470 
     | 
    
         
             
                        return
         
     | 
| 
       461 
471 
     | 
    
         | 
| 
         @@ -498,8 +508,8 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       498 
508 
     | 
    
         | 
| 
       499 
509 
     | 
    
         
             
                    # Internal Variables
         
     | 
| 
       500 
510 
     | 
    
         
             
                    self._treeMap: dict[str, QTreeWidgetItem] = {}
         
     | 
| 
       501 
     | 
    
         
            -
                    self._timeChanged = 0.0
         
     | 
| 
       502 
511 
     | 
    
         
             
                    self._popAlert = None
         
     | 
| 
      
 512 
     | 
    
         
            +
                    self._actHandle = None
         
     | 
| 
       503 
513 
     | 
    
         | 
| 
       504 
514 
     | 
    
         
             
                    # Cached Translations
         
     | 
| 
       505 
515 
     | 
    
         
             
                    self.trActive = self.tr("Active")
         
     | 
| 
         @@ -511,7 +521,7 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       511 
521 
     | 
    
         | 
| 
       512 
522 
     | 
    
         
             
                    # Context Menu
         
     | 
| 
       513 
523 
     | 
    
         
             
                    self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
         
     | 
| 
       514 
     | 
    
         
            -
                    self.customContextMenuRequested.connect(self. 
     | 
| 
      
 524 
     | 
    
         
            +
                    self.customContextMenuRequested.connect(self.openContextMenu)
         
     | 
| 
       515 
525 
     | 
    
         | 
| 
       516 
526 
     | 
    
         
             
                    # Tree Settings
         
     | 
| 
       517 
527 
     | 
    
         
             
                    iPx = SHARED.theme.baseIconHeight
         
     | 
| 
         @@ -578,13 +588,13 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       578 
588 
     | 
    
         
             
                    """Set or update tree widget settings."""
         
     | 
| 
       579 
589 
     | 
    
         
             
                    # Scroll bars
         
     | 
| 
       580 
590 
     | 
    
         
             
                    if CONFIG.hideVScroll:
         
     | 
| 
       581 
     | 
    
         
            -
                        self.setVerticalScrollBarPolicy( 
     | 
| 
      
 591 
     | 
    
         
            +
                        self.setVerticalScrollBarPolicy(QtScrollAlwaysOff)
         
     | 
| 
       582 
592 
     | 
    
         
             
                    else:
         
     | 
| 
       583 
     | 
    
         
            -
                        self.setVerticalScrollBarPolicy( 
     | 
| 
      
 593 
     | 
    
         
            +
                        self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
         
     | 
| 
       584 
594 
     | 
    
         
             
                    if CONFIG.hideHScroll:
         
     | 
| 
       585 
     | 
    
         
            -
                        self.setHorizontalScrollBarPolicy( 
     | 
| 
      
 595 
     | 
    
         
            +
                        self.setHorizontalScrollBarPolicy(QtScrollAlwaysOff)
         
     | 
| 
       586 
596 
     | 
    
         
             
                    else:
         
     | 
| 
       587 
     | 
    
         
            -
                        self.setHorizontalScrollBarPolicy( 
     | 
| 
      
 597 
     | 
    
         
            +
                        self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
         
     | 
| 
       588 
598 
     | 
    
         
             
                    return
         
     | 
| 
       589 
599 
     | 
    
         | 
| 
       590 
600 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -595,7 +605,6 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       595 
605 
     | 
    
         
             
                    """Clear the GUI content and the related map."""
         
     | 
| 
       596 
606 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       597 
607 
     | 
    
         
             
                    self._treeMap = {}
         
     | 
| 
       598 
     | 
    
         
            -
                    self._timeChanged = 0.0
         
     | 
| 
       599 
608 
     | 
    
         
             
                    return
         
     | 
| 
       600 
609 
     | 
    
         | 
| 
       601 
610 
     | 
    
         
             
                def createNewNote(self, tag: str, itemClass: nwItemClass) -> None:
         
     | 
| 
         @@ -642,7 +651,7 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       642 
651 
     | 
    
         | 
| 
       643 
652 
     | 
    
         
             
                        # Collect some information about the selected item
         
     | 
| 
       644 
653 
     | 
    
         
             
                        qItem = self._getTreeItem(sHandle)
         
     | 
| 
       645 
     | 
    
         
            -
                        sLevel =  
     | 
| 
      
 654 
     | 
    
         
            +
                        sLevel = nwStyles.H_LEVEL.get(pItem.mainHeading, 0)
         
     | 
| 
       646 
655 
     | 
    
         
             
                        sIsParent = False if qItem is None else qItem.childCount() > 0
         
     | 
| 
       647 
656 
     | 
    
         | 
| 
       648 
657 
     | 
    
         
             
                        if SHARED.project.tree.isTrash(sHandle):
         
     | 
| 
         @@ -1114,12 +1123,10 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       1114 
1123 
     | 
    
         
             
                    """
         
     | 
| 
       1115 
1124 
     | 
    
         
             
                    logger.debug("Building the project tree ...")
         
     | 
| 
       1116 
1125 
     | 
    
         
             
                    self.clearTree()
         
     | 
| 
       1117 
     | 
    
         
            -
                    count = 0
         
     | 
| 
       1118 
1126 
     | 
    
         
             
                    for nwItem in SHARED.project.iterProjectItems():
         
     | 
| 
       1119 
     | 
    
         
            -
                        count += 1
         
     | 
| 
       1120 
1127 
     | 
    
         
             
                        self._addTreeItem(nwItem)
         
     | 
| 
       1121 
     | 
    
         
            -
                     
     | 
| 
       1122 
     | 
    
         
            -
             
     | 
| 
      
 1128 
     | 
    
         
            +
                    self.setActiveHandle(self._actHandle)
         
     | 
| 
      
 1129 
     | 
    
         
            +
                    logger.info("%d item(s) added to the project tree", len(self._treeMap))
         
     | 
| 
       1123 
1130 
     | 
    
         
             
                    return
         
     | 
| 
       1124 
1131 
     | 
    
         | 
| 
       1125 
1132 
     | 
    
         
             
                def getSelectedHandle(self) -> str | None:
         
     | 
| 
         @@ -1130,38 +1137,78 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       1130 
1137 
     | 
    
         
             
                        return items[0].data(self.C_DATA, self.D_HANDLE)
         
     | 
| 
       1131 
1138 
     | 
    
         
             
                    return None
         
     | 
| 
       1132 
1139 
     | 
    
         | 
| 
       1133 
     | 
    
         
            -
                def setSelectedHandle(self, tHandle: str | None, doScroll: bool = False) ->  
     | 
| 
      
 1140 
     | 
    
         
            +
                def setSelectedHandle(self, tHandle: str | None, doScroll: bool = False) -> None:
         
     | 
| 
       1134 
1141 
     | 
    
         
             
                    """Set a specific handle as the selected item."""
         
     | 
| 
       1135 
     | 
    
         
            -
                    tItem = self._getTreeItem(tHandle)
         
     | 
| 
       1136 
     | 
    
         
            -
                    if tItem is None:
         
     | 
| 
       1137 
     | 
    
         
            -
                        return False
         
     | 
| 
       1138 
     | 
    
         
            -
             
     | 
| 
       1139 
1142 
     | 
    
         
             
                    if tHandle in self._treeMap:
         
     | 
| 
       1140 
1143 
     | 
    
         
             
                        self.setCurrentItem(self._treeMap[tHandle])
         
     | 
| 
      
 1144 
     | 
    
         
            +
                        if (indexes := self.selectedIndexes()) and doScroll:
         
     | 
| 
      
 1145 
     | 
    
         
            +
                            self.scrollTo(indexes[0], QAbstractItemView.ScrollHint.PositionAtCenter)
         
     | 
| 
      
 1146 
     | 
    
         
            +
                    return
         
     | 
| 
       1141 
1147 
     | 
    
         | 
| 
       1142 
     | 
    
         
            -
             
     | 
| 
       1143 
     | 
    
         
            -
             
     | 
| 
       1144 
     | 
    
         
            -
             
     | 
| 
       1145 
     | 
    
         
            -
                     
     | 
| 
      
 1148 
     | 
    
         
            +
                def setActiveHandle(self, tHandle: str | None) -> None:
         
     | 
| 
      
 1149 
     | 
    
         
            +
                    """Highlight the rows associated with a given handle."""
         
     | 
| 
      
 1150 
     | 
    
         
            +
                    brushOn = self.palette().alternateBase()
         
     | 
| 
      
 1151 
     | 
    
         
            +
                    brushOff = self.palette().base()
         
     | 
| 
      
 1152 
     | 
    
         
            +
                    if (pHandle := self._actHandle) and (item := self._treeMap.get(pHandle)):
         
     | 
| 
      
 1153 
     | 
    
         
            +
                        for i in range(self.columnCount()):
         
     | 
| 
      
 1154 
     | 
    
         
            +
                            item.setBackground(i, brushOff)
         
     | 
| 
      
 1155 
     | 
    
         
            +
                    if tHandle and (item := self._treeMap.get(tHandle)):
         
     | 
| 
      
 1156 
     | 
    
         
            +
                        for i in range(self.columnCount()):
         
     | 
| 
      
 1157 
     | 
    
         
            +
                            item.setBackground(i, brushOn)
         
     | 
| 
      
 1158 
     | 
    
         
            +
                    self._actHandle = tHandle or None
         
     | 
| 
      
 1159 
     | 
    
         
            +
                    return
         
     | 
| 
       1146 
1160 
     | 
    
         | 
| 
       1147 
1161 
     | 
    
         
             
                def setExpandedFromHandle(self, tHandle: str | None, isExpanded: bool) -> None:
         
     | 
| 
       1148 
1162 
     | 
    
         
             
                    """Iterate through items below tHandle and change expanded
         
     | 
| 
       1149 
1163 
     | 
    
         
             
                    status for all child items. If tHandle is None, it affects the
         
     | 
| 
       1150 
1164 
     | 
    
         
             
                    entire tree.
         
     | 
| 
       1151 
1165 
     | 
    
         
             
                    """
         
     | 
| 
       1152 
     | 
    
         
            -
                     
     | 
| 
       1153 
     | 
    
         
            -
                    self._recursiveSetExpanded( 
     | 
| 
      
 1166 
     | 
    
         
            +
                    item = self._getTreeItem(tHandle) or self.invisibleRootItem()
         
     | 
| 
      
 1167 
     | 
    
         
            +
                    self._recursiveSetExpanded(item, isExpanded)
         
     | 
| 
       1154 
1168 
     | 
    
         
             
                    return
         
     | 
| 
       1155 
1169 
     | 
    
         | 
| 
       1156 
     | 
    
         
            -
                 
     | 
| 
       1157 
     | 
    
         
            -
             
     | 
| 
       1158 
     | 
    
         
            -
             
     | 
| 
       1159 
     | 
    
         
            -
             
     | 
| 
       1160 
     | 
    
         
            -
             
     | 
| 
      
 1170 
     | 
    
         
            +
                ##
         
     | 
| 
      
 1171 
     | 
    
         
            +
                #  Public Slots
         
     | 
| 
      
 1172 
     | 
    
         
            +
                ##
         
     | 
| 
      
 1173 
     | 
    
         
            +
             
     | 
| 
      
 1174 
     | 
    
         
            +
                @pyqtSlot()
         
     | 
| 
      
 1175 
     | 
    
         
            +
                @pyqtSlot("QPoint")
         
     | 
| 
      
 1176 
     | 
    
         
            +
                def openContextMenu(self, clickPos: QPoint | None = None) -> None:
         
     | 
| 
      
 1177 
     | 
    
         
            +
                    """The user right clicked an element in the project tree, so we
         
     | 
| 
      
 1178 
     | 
    
         
            +
                    open a context menu in-place.
         
     | 
| 
      
 1179 
     | 
    
         
            +
                    """
         
     | 
| 
      
 1180 
     | 
    
         
            +
                    if clickPos is None and (items := self.selectedItems()):
         
     | 
| 
      
 1181 
     | 
    
         
            +
                        clickPos = self.visualItemRect(items[0]).center()
         
     | 
| 
      
 1182 
     | 
    
         
            +
             
     | 
| 
      
 1183 
     | 
    
         
            +
                    if clickPos is not None:
         
     | 
| 
      
 1184 
     | 
    
         
            +
                        tItem = None
         
     | 
| 
      
 1185 
     | 
    
         
            +
                        tHandle = None
         
     | 
| 
      
 1186 
     | 
    
         
            +
                        hasChild = False
         
     | 
| 
      
 1187 
     | 
    
         
            +
                        sItem = self.itemAt(clickPos)
         
     | 
| 
      
 1188 
     | 
    
         
            +
                        sItems = self.selectedItems()
         
     | 
| 
      
 1189 
     | 
    
         
            +
                        if isinstance(sItem, QTreeWidgetItem):
         
     | 
| 
      
 1190 
     | 
    
         
            +
                            tHandle = sItem.data(self.C_DATA, self.D_HANDLE)
         
     | 
| 
      
 1191 
     | 
    
         
            +
                            tItem = SHARED.project.tree[tHandle]
         
     | 
| 
      
 1192 
     | 
    
         
            +
                            hasChild = sItem.childCount() > 0
         
     | 
| 
      
 1193 
     | 
    
         
            +
             
     | 
| 
      
 1194 
     | 
    
         
            +
                        if tItem is None or tHandle is None:
         
     | 
| 
      
 1195 
     | 
    
         
            +
                            logger.debug("No item found")
         
     | 
| 
      
 1196 
     | 
    
         
            +
                            return
         
     | 
| 
      
 1197 
     | 
    
         
            +
             
     | 
| 
      
 1198 
     | 
    
         
            +
                        ctxMenu = _TreeContextMenu(self, tItem)
         
     | 
| 
      
 1199 
     | 
    
         
            +
                        trashHandle = SHARED.project.tree.trashRoot
         
     | 
| 
      
 1200 
     | 
    
         
            +
                        if trashHandle and tHandle == trashHandle:
         
     | 
| 
      
 1201 
     | 
    
         
            +
                            ctxMenu.buildTrashMenu()
         
     | 
| 
      
 1202 
     | 
    
         
            +
                        elif len(sItems) > 1:
         
     | 
| 
      
 1203 
     | 
    
         
            +
                            handles = [str(x.data(self.C_DATA, self.D_HANDLE)) for x in sItems]
         
     | 
| 
      
 1204 
     | 
    
         
            +
                            ctxMenu.buildMultiSelectMenu(handles)
         
     | 
| 
      
 1205 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 1206 
     | 
    
         
            +
                            ctxMenu.buildSingleSelectMenu(hasChild)
         
     | 
| 
       1161 
1207 
     | 
    
         | 
| 
       1162 
     | 
    
         
            -
             
     | 
| 
       1163 
     | 
    
         
            -
             
     | 
| 
       1164 
     | 
    
         
            -
             
     | 
| 
      
 1208 
     | 
    
         
            +
                        ctxMenu.exec(self.viewport().mapToGlobal(clickPos))
         
     | 
| 
      
 1209 
     | 
    
         
            +
                        ctxMenu.deleteLater()
         
     | 
| 
      
 1210 
     | 
    
         
            +
             
     | 
| 
      
 1211 
     | 
    
         
            +
                    return
         
     | 
| 
       1165 
1212 
     | 
    
         | 
| 
       1166 
1213 
     | 
    
         
             
                ##
         
     | 
| 
       1167 
1214 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -1204,40 +1251,6 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       1204 
1251 
     | 
    
         | 
| 
       1205 
1252 
     | 
    
         
             
                    return
         
     | 
| 
       1206 
1253 
     | 
    
         | 
| 
       1207 
     | 
    
         
            -
                @pyqtSlot("QPoint")
         
     | 
| 
       1208 
     | 
    
         
            -
                def _openContextMenu(self, clickPos: QPoint) -> bool:
         
     | 
| 
       1209 
     | 
    
         
            -
                    """The user right clicked an element in the project tree, so we
         
     | 
| 
       1210 
     | 
    
         
            -
                    open a context menu in-place.
         
     | 
| 
       1211 
     | 
    
         
            -
                    """
         
     | 
| 
       1212 
     | 
    
         
            -
                    tItem = None
         
     | 
| 
       1213 
     | 
    
         
            -
                    tHandle = None
         
     | 
| 
       1214 
     | 
    
         
            -
                    hasChild = False
         
     | 
| 
       1215 
     | 
    
         
            -
                    sItem = self.itemAt(clickPos)
         
     | 
| 
       1216 
     | 
    
         
            -
                    sItems = self.selectedItems()
         
     | 
| 
       1217 
     | 
    
         
            -
                    if isinstance(sItem, QTreeWidgetItem):
         
     | 
| 
       1218 
     | 
    
         
            -
                        tHandle = sItem.data(self.C_DATA, self.D_HANDLE)
         
     | 
| 
       1219 
     | 
    
         
            -
                        tItem = SHARED.project.tree[tHandle]
         
     | 
| 
       1220 
     | 
    
         
            -
                        hasChild = sItem.childCount() > 0
         
     | 
| 
       1221 
     | 
    
         
            -
             
     | 
| 
       1222 
     | 
    
         
            -
                    if tItem is None or tHandle is None:
         
     | 
| 
       1223 
     | 
    
         
            -
                        logger.debug("No item found")
         
     | 
| 
       1224 
     | 
    
         
            -
                        return False
         
     | 
| 
       1225 
     | 
    
         
            -
             
     | 
| 
       1226 
     | 
    
         
            -
                    ctxMenu = _TreeContextMenu(self, tItem)
         
     | 
| 
       1227 
     | 
    
         
            -
                    trashHandle = SHARED.project.tree.trashRoot
         
     | 
| 
       1228 
     | 
    
         
            -
                    if trashHandle and tHandle == trashHandle:
         
     | 
| 
       1229 
     | 
    
         
            -
                        ctxMenu.buildTrashMenu()
         
     | 
| 
       1230 
     | 
    
         
            -
                    elif len(sItems) > 1:
         
     | 
| 
       1231 
     | 
    
         
            -
                        handles = [str(x.data(self.C_DATA, self.D_HANDLE)) for x in sItems]
         
     | 
| 
       1232 
     | 
    
         
            -
                        ctxMenu.buildMultiSelectMenu(handles)
         
     | 
| 
       1233 
     | 
    
         
            -
                    else:
         
     | 
| 
       1234 
     | 
    
         
            -
                        ctxMenu.buildSingleSelectMenu(hasChild)
         
     | 
| 
       1235 
     | 
    
         
            -
             
     | 
| 
       1236 
     | 
    
         
            -
                    ctxMenu.exec(self.viewport().mapToGlobal(clickPos))
         
     | 
| 
       1237 
     | 
    
         
            -
                    ctxMenu.deleteLater()
         
     | 
| 
       1238 
     | 
    
         
            -
             
     | 
| 
       1239 
     | 
    
         
            -
                    return True
         
     | 
| 
       1240 
     | 
    
         
            -
             
     | 
| 
       1241 
1254 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1242 
1255 
     | 
    
         
             
                def _doAutoScroll(self) -> None:
         
     | 
| 
       1243 
1256 
     | 
    
         
             
                    """Scroll one item up or down based on direction value."""
         
     | 
| 
         @@ -1377,11 +1390,6 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       1377 
1390 
     | 
    
         | 
| 
       1378 
1391 
     | 
    
         
             
                    return
         
     | 
| 
       1379 
1392 
     | 
    
         | 
| 
       1380 
     | 
    
         
            -
                def _getItemWordCount(self, tHandle: str) -> int:
         
     | 
| 
       1381 
     | 
    
         
            -
                    """Return the word count of a given item handle."""
         
     | 
| 
       1382 
     | 
    
         
            -
                    tItem = self._getTreeItem(tHandle)
         
     | 
| 
       1383 
     | 
    
         
            -
                    return int(tItem.data(self.C_DATA, self.D_WORDS)) if tItem else 0
         
     | 
| 
       1384 
     | 
    
         
            -
             
     | 
| 
       1385 
1393 
     | 
    
         
             
                def _getTreeItem(self, tHandle: str | None) -> QTreeWidgetItem | None:
         
     | 
| 
       1386 
1394 
     | 
    
         
             
                    """Return the QTreeWidgetItem of a given item handle."""
         
     | 
| 
       1387 
1395 
     | 
    
         
             
                    return self._treeMap.get(tHandle, None) if tHandle else None
         
     | 
| 
         @@ -1638,7 +1646,6 @@ class GuiProjectTree(QTreeWidget): 
     | 
|
| 
       1638 
1646 
     | 
    
         
             
                    signals. A flush is only needed if an item is moved, created or
         
     | 
| 
       1639 
1647 
     | 
    
         
             
                    deleted.
         
     | 
| 
       1640 
1648 
     | 
    
         
             
                    """
         
     | 
| 
       1641 
     | 
    
         
            -
                    self._timeChanged = time()
         
     | 
| 
       1642 
1649 
     | 
    
         
             
                    SHARED.project.setProjectChanged(True)
         
     | 
| 
       1643 
1650 
     | 
    
         
             
                    if flush:
         
     | 
| 
       1644 
1651 
     | 
    
         
             
                        self.saveTreeOrder()
         
     | 
| 
         @@ -1765,7 +1772,7 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1765 
1772 
     | 
    
         | 
| 
       1766 
1773 
     | 
    
         
             
                    # Edit Item Settings
         
     | 
| 
       1767 
1774 
     | 
    
         
             
                    action = self.addAction(self.tr("Rename"))
         
     | 
| 
       1768 
     | 
    
         
            -
                    action.triggered.connect( 
     | 
| 
      
 1775 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(self.projTree.renameTreeItem, self._handle))
         
     | 
| 
       1769 
1776 
     | 
    
         
             
                    if isFile:
         
     | 
| 
       1770 
1777 
     | 
    
         
             
                        self._itemHeader()
         
     | 
| 
       1771 
1778 
     | 
    
         
             
                        self._itemActive(False)
         
     | 
| 
         @@ -1801,13 +1808,15 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1801 
1808 
     | 
    
         
             
                def _docActions(self) -> None:
         
     | 
| 
       1802 
1809 
     | 
    
         
             
                    """Add document actions."""
         
     | 
| 
       1803 
1810 
     | 
    
         
             
                    action = self.addAction(self.tr("Open Document"))
         
     | 
| 
       1804 
     | 
    
         
            -
                    action.triggered.connect(
         
     | 
| 
       1805 
     | 
    
         
            -
                         
     | 
| 
       1806 
     | 
    
         
            -
             
     | 
| 
      
 1811 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(
         
     | 
| 
      
 1812 
     | 
    
         
            +
                        self.projView.openDocumentRequest.emit,
         
     | 
| 
      
 1813 
     | 
    
         
            +
                        self._handle, nwDocMode.EDIT, "", True
         
     | 
| 
      
 1814 
     | 
    
         
            +
                    ))
         
     | 
| 
       1807 
1815 
     | 
    
         
             
                    action = self.addAction(self.tr("View Document"))
         
     | 
| 
       1808 
     | 
    
         
            -
                    action.triggered.connect(
         
     | 
| 
       1809 
     | 
    
         
            -
                         
     | 
| 
       1810 
     | 
    
         
            -
             
     | 
| 
      
 1816 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(
         
     | 
| 
      
 1817 
     | 
    
         
            +
                        self.projView.openDocumentRequest.emit,
         
     | 
| 
      
 1818 
     | 
    
         
            +
                        self._handle, nwDocMode.VIEW, "", False
         
     | 
| 
      
 1819 
     | 
    
         
            +
                    ))
         
     | 
| 
       1811 
1820 
     | 
    
         
             
                    return
         
     | 
| 
       1812 
1821 
     | 
    
         | 
| 
       1813 
1822 
     | 
    
         
             
                def _itemCreation(self) -> None:
         
     | 
| 
         @@ -1826,7 +1835,7 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1826 
1835 
     | 
    
         
             
                    if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"):
         
     | 
| 
       1827 
1836 
     | 
    
         
             
                        action = self.addAction(self.tr("Rename to Heading"))
         
     | 
| 
       1828 
1837 
     | 
    
         
             
                        action.triggered.connect(
         
     | 
| 
       1829 
     | 
    
         
            -
                             
     | 
| 
      
 1838 
     | 
    
         
            +
                            qtLambda(self.projTree.renameTreeItem, self._handle, hItem.title)
         
     | 
| 
       1830 
1839 
     | 
    
         
             
                        )
         
     | 
| 
       1831 
1840 
     | 
    
         
             
                    return
         
     | 
| 
       1832 
1841 
     | 
    
         | 
| 
         @@ -1835,9 +1844,9 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1835 
1844 
     | 
    
         
             
                    if multi:
         
     | 
| 
       1836 
1845 
     | 
    
         
             
                        mSub = self.addMenu(self.tr("Set Active to ..."))
         
     | 
| 
       1837 
1846 
     | 
    
         
             
                        aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self.projTree.trActive)
         
     | 
| 
       1838 
     | 
    
         
            -
                        aOne.triggered.connect( 
     | 
| 
      
 1847 
     | 
    
         
            +
                        aOne.triggered.connect(qtLambda(self._iterItemActive, True))
         
     | 
| 
       1839 
1848 
     | 
    
         
             
                        aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self.projTree.trInactive)
         
     | 
| 
       1840 
     | 
    
         
            -
                        aTwo.triggered.connect( 
     | 
| 
      
 1849 
     | 
    
         
            +
                        aTwo.triggered.connect(qtLambda(self._iterItemActive, False))
         
     | 
| 
       1841 
1850 
     | 
    
         
             
                    else:
         
     | 
| 
       1842 
1851 
     | 
    
         
             
                        action = self.addAction(self.tr("Toggle Active"))
         
     | 
| 
       1843 
1852 
     | 
    
         
             
                        action.triggered.connect(self._toggleItemActive)
         
     | 
| 
         @@ -1848,37 +1857,39 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1848 
1857 
     | 
    
         
             
                    if self._item.isNovelLike():
         
     | 
| 
       1849 
1858 
     | 
    
         
             
                        menu = self.addMenu(self.tr("Set Status to ..."))
         
     | 
| 
       1850 
1859 
     | 
    
         
             
                        current = self._item.itemStatus
         
     | 
| 
       1851 
     | 
    
         
            -
                        for  
     | 
| 
      
 1860 
     | 
    
         
            +
                        for key, entry in SHARED.project.data.itemStatus.iterItems():
         
     | 
| 
       1852 
1861 
     | 
    
         
             
                            name = entry.name
         
     | 
| 
       1853 
1862 
     | 
    
         
             
                            if not multi and current == key:
         
     | 
| 
       1854 
1863 
     | 
    
         
             
                                name += f" ({nwUnicode.U_CHECK})"
         
     | 
| 
       1855 
1864 
     | 
    
         
             
                            action = menu.addAction(entry.icon, name)
         
     | 
| 
       1856 
1865 
     | 
    
         
             
                            if multi:
         
     | 
| 
       1857 
     | 
    
         
            -
                                action.triggered.connect( 
     | 
| 
      
 1866 
     | 
    
         
            +
                                action.triggered.connect(qtLambda(self._iterSetItemStatus, key))
         
     | 
| 
       1858 
1867 
     | 
    
         
             
                            else:
         
     | 
| 
       1859 
     | 
    
         
            -
                                action.triggered.connect( 
     | 
| 
      
 1868 
     | 
    
         
            +
                                action.triggered.connect(qtLambda(self._changeItemStatus, key))
         
     | 
| 
       1860 
1869 
     | 
    
         
             
                        menu.addSeparator()
         
     | 
| 
       1861 
1870 
     | 
    
         
             
                        action = menu.addAction(self.tr("Manage Labels ..."))
         
     | 
| 
       1862 
     | 
    
         
            -
                        action.triggered.connect(
         
     | 
| 
       1863 
     | 
    
         
            -
                             
     | 
| 
       1864 
     | 
    
         
            -
             
     | 
| 
      
 1871 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(
         
     | 
| 
      
 1872 
     | 
    
         
            +
                            self.projView.projectSettingsRequest.emit,
         
     | 
| 
      
 1873 
     | 
    
         
            +
                            GuiProjectSettings.PAGE_STATUS
         
     | 
| 
      
 1874 
     | 
    
         
            +
                        ))
         
     | 
| 
       1865 
1875 
     | 
    
         
             
                    else:
         
     | 
| 
       1866 
1876 
     | 
    
         
             
                        menu = self.addMenu(self.tr("Set Importance to ..."))
         
     | 
| 
       1867 
1877 
     | 
    
         
             
                        current = self._item.itemImport
         
     | 
| 
       1868 
     | 
    
         
            -
                        for  
     | 
| 
      
 1878 
     | 
    
         
            +
                        for key, entry in SHARED.project.data.itemImport.iterItems():
         
     | 
| 
       1869 
1879 
     | 
    
         
             
                            name = entry.name
         
     | 
| 
       1870 
1880 
     | 
    
         
             
                            if not multi and current == key:
         
     | 
| 
       1871 
1881 
     | 
    
         
             
                                name += f" ({nwUnicode.U_CHECK})"
         
     | 
| 
       1872 
1882 
     | 
    
         
             
                            action = menu.addAction(entry.icon, name)
         
     | 
| 
       1873 
1883 
     | 
    
         
             
                            if multi:
         
     | 
| 
       1874 
     | 
    
         
            -
                                action.triggered.connect( 
     | 
| 
      
 1884 
     | 
    
         
            +
                                action.triggered.connect(qtLambda(self._iterSetItemImport, key))
         
     | 
| 
       1875 
1885 
     | 
    
         
             
                            else:
         
     | 
| 
       1876 
     | 
    
         
            -
                                action.triggered.connect( 
     | 
| 
      
 1886 
     | 
    
         
            +
                                action.triggered.connect(qtLambda(self._changeItemImport, key))
         
     | 
| 
       1877 
1887 
     | 
    
         
             
                        menu.addSeparator()
         
     | 
| 
       1878 
1888 
     | 
    
         
             
                        action = menu.addAction(self.tr("Manage Labels ..."))
         
     | 
| 
       1879 
     | 
    
         
            -
                        action.triggered.connect(
         
     | 
| 
       1880 
     | 
    
         
            -
                             
     | 
| 
       1881 
     | 
    
         
            -
             
     | 
| 
      
 1889 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(
         
     | 
| 
      
 1890 
     | 
    
         
            +
                            self.projView.projectSettingsRequest.emit,
         
     | 
| 
      
 1891 
     | 
    
         
            +
                            GuiProjectSettings.PAGE_IMPORT
         
     | 
| 
      
 1892 
     | 
    
         
            +
                        ))
         
     | 
| 
       1882 
1893 
     | 
    
         
             
                    return
         
     | 
| 
       1883 
1894 
     | 
    
         | 
| 
       1884 
1895 
     | 
    
         
             
                def _itemTransform(self, isFile: bool, isFolder: bool, hasChild: bool) -> None:
         
     | 
| 
         @@ -1897,33 +1908,33 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1897 
1908 
     | 
    
         | 
| 
       1898 
1909 
     | 
    
         
             
                    if isNoteFile and self._item.documentAllowed():
         
     | 
| 
       1899 
1910 
     | 
    
         
             
                        action = menu.addAction(self.tr("Convert to {0}").format(trDoc))
         
     | 
| 
       1900 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1911 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(self._changeItemLayout, loDoc))
         
     | 
| 
       1901 
1912 
     | 
    
         | 
| 
       1902 
1913 
     | 
    
         
             
                    if isDocFile:
         
     | 
| 
       1903 
1914 
     | 
    
         
             
                        action = menu.addAction(self.tr("Convert to {0}").format(trNote))
         
     | 
| 
       1904 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1915 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(self._changeItemLayout, loNote))
         
     | 
| 
       1905 
1916 
     | 
    
         | 
| 
       1906 
1917 
     | 
    
         
             
                    if isFolder and self._item.documentAllowed():
         
     | 
| 
       1907 
1918 
     | 
    
         
             
                        action = menu.addAction(self.tr("Convert to {0}").format(trDoc))
         
     | 
| 
       1908 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1919 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(self._covertFolderToFile, loDoc))
         
     | 
| 
       1909 
1920 
     | 
    
         | 
| 
       1910 
1921 
     | 
    
         
             
                    if isFolder:
         
     | 
| 
       1911 
1922 
     | 
    
         
             
                        action = menu.addAction(self.tr("Convert to {0}").format(trNote))
         
     | 
| 
       1912 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1923 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(self._covertFolderToFile, loNote))
         
     | 
| 
       1913 
1924 
     | 
    
         | 
| 
       1914 
1925 
     | 
    
         
             
                    if hasChild and isFile:
         
     | 
| 
       1915 
1926 
     | 
    
         
             
                        action = menu.addAction(self.tr("Merge Child Items into Self"))
         
     | 
| 
       1916 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1927 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree._mergeDocuments, tHandle, False))
         
     | 
| 
       1917 
1928 
     | 
    
         
             
                        action = menu.addAction(self.tr("Merge Child Items into New"))
         
     | 
| 
       1918 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1929 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree._mergeDocuments, tHandle, True))
         
     | 
| 
       1919 
1930 
     | 
    
         | 
| 
       1920 
1931 
     | 
    
         
             
                    if hasChild and isFolder:
         
     | 
| 
       1921 
1932 
     | 
    
         
             
                        action = menu.addAction(self.tr("Merge Documents in Folder"))
         
     | 
| 
       1922 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1933 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree._mergeDocuments, tHandle, True))
         
     | 
| 
       1923 
1934 
     | 
    
         | 
| 
       1924 
1935 
     | 
    
         
             
                    if isFile:
         
     | 
| 
       1925 
1936 
     | 
    
         
             
                        action = menu.addAction(self.tr("Split Document by Headings"))
         
     | 
| 
       1926 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1937 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree._splitDocument, tHandle))
         
     | 
| 
       1927 
1938 
     | 
    
         | 
| 
       1928 
1939 
     | 
    
         
             
                    return
         
     | 
| 
       1929 
1940 
     | 
    
         | 
| 
         @@ -1933,19 +1944,19 @@ class _TreeContextMenu(QMenu): 
     | 
|
| 
       1933 
1944 
     | 
    
         
             
                    tHandle = self._handle
         
     | 
| 
       1934 
1945 
     | 
    
         
             
                    if hasChild:
         
     | 
| 
       1935 
1946 
     | 
    
         
             
                        action = self.addAction(self.tr("Expand All"))
         
     | 
| 
       1936 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1947 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree.setExpandedFromHandle, tHandle, True))
         
     | 
| 
       1937 
1948 
     | 
    
         
             
                        action = self.addAction(self.tr("Collapse All"))
         
     | 
| 
       1938 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1949 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree.setExpandedFromHandle, tHandle, False))
         
     | 
| 
       1939 
1950 
     | 
    
         | 
| 
       1940 
1951 
     | 
    
         
             
                    action = self.addAction(self.tr("Duplicate"))
         
     | 
| 
       1941 
     | 
    
         
            -
                    action.triggered.connect( 
     | 
| 
      
 1952 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(tree._duplicateFromHandle, tHandle))
         
     | 
| 
       1942 
1953 
     | 
    
         | 
| 
       1943 
1954 
     | 
    
         
             
                    if self._item.itemClass == nwItemClass.TRASH or isRoot or (isFolder and not hasChild):
         
     | 
| 
       1944 
1955 
     | 
    
         
             
                        action = self.addAction(self.tr("Delete Permanently"))
         
     | 
| 
       1945 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1956 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree.permDeleteItem, tHandle))
         
     | 
| 
       1946 
1957 
     | 
    
         
             
                    else:
         
     | 
| 
       1947 
1958 
     | 
    
         
             
                        action = self.addAction(self.tr("Move to Trash"))
         
     | 
| 
       1948 
     | 
    
         
            -
                        action.triggered.connect( 
     | 
| 
      
 1959 
     | 
    
         
            +
                        action.triggered.connect(qtLambda(tree.moveItemToTrash, tHandle))
         
     | 
| 
       1949 
1960 
     | 
    
         | 
| 
       1950 
1961 
     | 
    
         
             
                    return
         
     | 
| 
       1951 
1962 
     | 
    
         | 
    
        novelwriter/gui/sidebar.py
    CHANGED
    
    | 
         @@ -32,6 +32,7 @@ from PyQt5.QtGui import QPalette 
     | 
|
| 
       32 
32 
     | 
    
         
             
            from PyQt5.QtWidgets import QMenu, QVBoxLayout, QWidget
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
      
 35 
     | 
    
         
            +
            from novelwriter.common import qtLambda
         
     | 
| 
       35 
36 
     | 
    
         
             
            from novelwriter.enum import nwView
         
     | 
| 
       36 
37 
     | 
    
         
             
            from novelwriter.extensions.eventfilters import StatusTipFilter
         
     | 
| 
       37 
38 
     | 
    
         
             
            from novelwriter.extensions.modified import NIconToolButton
         
     | 
| 
         @@ -54,7 +55,7 @@ class GuiSideBar(QWidget): 
     | 
|
| 
       54 
55 
     | 
    
         | 
| 
       55 
56 
     | 
    
         
             
                    self.mainGui = mainGui
         
     | 
| 
       56 
57 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                    iPx = int(1. 
     | 
| 
      
 58 
     | 
    
         
            +
                    iPx = int(1.25*SHARED.theme.baseButtonHeight)
         
     | 
| 
       58 
59 
     | 
    
         
             
                    iSz = QSize(iPx, iPx)
         
     | 
| 
       59 
60 
     | 
    
         | 
| 
       60 
61 
     | 
    
         
             
                    self.setContentsMargins(0, 0, 0, 0)
         
     | 
| 
         @@ -63,19 +64,19 @@ class GuiSideBar(QWidget): 
     | 
|
| 
       63 
64 
     | 
    
         
             
                    # Buttons
         
     | 
| 
       64 
65 
     | 
    
         
             
                    self.tbProject = NIconToolButton(self, iSz)
         
     | 
| 
       65 
66 
     | 
    
         
             
                    self.tbProject.setToolTip("{0} [Ctrl+T]".format(self.tr("Project Tree View")))
         
     | 
| 
       66 
     | 
    
         
            -
                    self.tbProject.clicked.connect( 
     | 
| 
      
 67 
     | 
    
         
            +
                    self.tbProject.clicked.connect(qtLambda(self.requestViewChange.emit, nwView.PROJECT))
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
       68 
69 
     | 
    
         
             
                    self.tbNovel = NIconToolButton(self, iSz)
         
     | 
| 
       69 
70 
     | 
    
         
             
                    self.tbNovel.setToolTip("{0} [Ctrl+T]".format(self.tr("Novel Tree View")))
         
     | 
| 
       70 
     | 
    
         
            -
                    self.tbNovel.clicked.connect( 
     | 
| 
      
 71 
     | 
    
         
            +
                    self.tbNovel.clicked.connect(qtLambda(self.requestViewChange.emit, nwView.NOVEL))
         
     | 
| 
       71 
72 
     | 
    
         | 
| 
       72 
73 
     | 
    
         
             
                    self.tbSearch = NIconToolButton(self, iSz)
         
     | 
| 
       73 
74 
     | 
    
         
             
                    self.tbSearch.setToolTip("{0} [Ctrl+Shift+F]".format(self.tr("Project Search")))
         
     | 
| 
       74 
     | 
    
         
            -
                    self.tbSearch.clicked.connect( 
     | 
| 
      
 75 
     | 
    
         
            +
                    self.tbSearch.clicked.connect(qtLambda(self.requestViewChange.emit, nwView.SEARCH))
         
     | 
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
                    self.tbOutline = NIconToolButton(self, iSz)
         
     | 
| 
       77 
78 
     | 
    
         
             
                    self.tbOutline.setToolTip("{0} [Ctrl+Shift+T]".format(self.tr("Novel Outline View")))
         
     | 
| 
       78 
     | 
    
         
            -
                    self.tbOutline.clicked.connect( 
     | 
| 
      
 79 
     | 
    
         
            +
                    self.tbOutline.clicked.connect(qtLambda(self.requestViewChange.emit, nwView.OUTLINE))
         
     | 
| 
       79 
80 
     | 
    
         | 
| 
       80 
81 
     | 
    
         
             
                    self.tbBuild = NIconToolButton(self, iSz)
         
     | 
| 
       81 
82 
     | 
    
         
             
                    self.tbBuild.setToolTip("{0} [F5]".format(self.tr("Build Manuscript")))
         
     | 
| 
         @@ -113,7 +114,7 @@ class GuiSideBar(QWidget): 
     | 
|
| 
       113 
114 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbStats)
         
     | 
| 
       114 
115 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbSettings)
         
     | 
| 
       115 
116 
     | 
    
         
             
                    self.outerBox.setContentsMargins(0, 0, 0, 0)
         
     | 
| 
       116 
     | 
    
         
            -
                    self.outerBox.setSpacing(CONFIG.pxInt( 
     | 
| 
      
 117 
     | 
    
         
            +
                    self.outerBox.setSpacing(CONFIG.pxInt(6))
         
     | 
| 
       117 
118 
     | 
    
         | 
| 
       118 
119 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
       119 
120 
     | 
    
         
             
                    self.updateTheme()
         
     | 
    
        novelwriter/gui/theme.py
    CHANGED
    
    | 
         @@ -503,10 +503,11 @@ class GuiIcons: 
     | 
|
| 
       503 
503 
     | 
    
         
             
                    "fmt_strike-md", "fmt_subscript", "fmt_superscript", "fmt_underline",
         
     | 
| 
       504 
504 
     | 
    
         | 
| 
       505 
505 
     | 
    
         
             
                    # General Button Icons
         
     | 
| 
       506 
     | 
    
         
            -
                    "add", "add_document", "backward", "bookmark", "browse", "checked", "close", " 
     | 
| 
       507 
     | 
    
         
            -
                    "document", "down", "edit", "export", "font", "forward", "import", "list", 
     | 
| 
       508 
     | 
    
         
            -
                    "menu", "minimise", "more", "noncheckable", "open", "panel", "quote", 
     | 
| 
       509 
     | 
    
         
            -
                    " 
     | 
| 
      
 506 
     | 
    
         
            +
                    "add", "add_document", "backward", "bookmark", "browse", "checked", "close", "copy",
         
     | 
| 
      
 507 
     | 
    
         
            +
                    "cross", "document", "down", "edit", "export", "font", "forward", "import", "list",
         
     | 
| 
      
 508 
     | 
    
         
            +
                    "maximise", "menu", "minimise", "more", "noncheckable", "open", "panel", "quote",
         
     | 
| 
      
 509 
     | 
    
         
            +
                    "refresh", "remove", "revert", "search_replace", "search", "settings", "star", "unchecked",
         
     | 
| 
      
 510 
     | 
    
         
            +
                    "up", "view",
         
     | 
| 
       510 
511 
     | 
    
         | 
| 
       511 
512 
     | 
    
         
             
                    # Switches
         
     | 
| 
       512 
513 
     | 
    
         
             
                    "sticky-on", "sticky-off",
         
     |