novelWriter 2.7.4__py3-none-any.whl → 2.8b1__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/__init__.py +8 -7
 - novelwriter/assets/icons/font_awesome.icons +22 -4
 - novelwriter/assets/icons/material_filled_normal.icons +20 -2
 - novelwriter/assets/icons/material_filled_thin.icons +20 -2
 - novelwriter/assets/icons/material_rounded_normal.icons +20 -2
 - novelwriter/assets/icons/material_rounded_thin.icons +20 -2
 - novelwriter/assets/icons/material_sharp_normal.icons +20 -2
 - novelwriter/assets/icons/material_sharp_thin.icons +20 -2
 - novelwriter/assets/icons/remix_filled.icons +20 -2
 - novelwriter/assets/icons/remix_outline.icons +20 -2
 - novelwriter/assets/images/welcome.webp +0 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/manual_fr.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/assets/text/credits_en.htm +61 -11
 - novelwriter/assets/themes/aura.conf +97 -0
 - novelwriter/assets/themes/aura_bright.conf +95 -0
 - novelwriter/assets/themes/aura_soft.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_light.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_light.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_light.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_light.conf +97 -0
 - novelwriter/assets/themes/blue_streak_dark.conf +97 -0
 - novelwriter/assets/themes/blue_streak_light.conf +97 -0
 - novelwriter/assets/themes/castle_day.conf +95 -0
 - novelwriter/assets/themes/castle_night.conf +95 -0
 - novelwriter/assets/themes/catppuccin_latte.conf +97 -0
 - novelwriter/assets/themes/catppuccin_mocha.conf +97 -0
 - novelwriter/assets/themes/chalky_soil.conf +95 -0
 - novelwriter/assets/themes/chernozem.conf +95 -0
 - novelwriter/assets/themes/cyberpunk_night.conf +88 -40
 - novelwriter/assets/themes/default_dark.conf +89 -41
 - novelwriter/assets/themes/default_light.conf +89 -41
 - novelwriter/assets/themes/dracula.conf +91 -42
 - novelwriter/assets/themes/espresso.conf +97 -0
 - novelwriter/assets/themes/everforest_dark.conf +97 -0
 - novelwriter/assets/themes/everforest_light.conf +97 -0
 - novelwriter/assets/themes/floral_daydream.conf +95 -0
 - novelwriter/assets/themes/floral_midnight.conf +95 -0
 - novelwriter/assets/themes/full_moon.conf +95 -0
 - novelwriter/assets/themes/grey_dark.conf +97 -0
 - novelwriter/assets/themes/grey_light.conf +97 -0
 - novelwriter/assets/themes/horizon_dark.conf +97 -0
 - novelwriter/assets/themes/horizon_light.conf +97 -0
 - novelwriter/assets/themes/jewel_case_dark.conf +95 -0
 - novelwriter/assets/themes/jewel_case_light.conf +95 -0
 - novelwriter/assets/themes/lcars.conf +97 -0
 - novelwriter/assets/themes/light_owl.conf +117 -0
 - novelwriter/assets/themes/new_moon.conf +97 -0
 - novelwriter/assets/themes/night_owl.conf +117 -0
 - novelwriter/assets/themes/noctis.conf +129 -0
 - novelwriter/assets/themes/noctis_lux.conf +129 -0
 - novelwriter/assets/themes/nord.conf +97 -0
 - novelwriter/assets/themes/nordlicht.conf +95 -0
 - novelwriter/assets/themes/otium_dark.conf +95 -0
 - novelwriter/assets/themes/otium_light.conf +95 -0
 - novelwriter/assets/themes/paragon.conf +96 -0
 - novelwriter/assets/themes/primer_light.conf +97 -0
 - novelwriter/assets/themes/primer_night.conf +97 -0
 - novelwriter/assets/themes/rose_pine.conf +97 -0
 - novelwriter/assets/themes/rose_pine_dawn.conf +97 -0
 - novelwriter/assets/themes/ruby_day.conf +95 -0
 - novelwriter/assets/themes/ruby_night.conf +95 -0
 - novelwriter/assets/themes/selenium_dark.conf +95 -0
 - novelwriter/assets/themes/selenium_light.conf +95 -0
 - novelwriter/assets/themes/sepia_dark.conf +95 -0
 - novelwriter/assets/themes/sepia_light.conf +95 -0
 - novelwriter/assets/themes/snazzy.conf +102 -40
 - novelwriter/assets/themes/solarized_dark.conf +108 -40
 - novelwriter/assets/themes/solarized_light.conf +108 -40
 - novelwriter/assets/themes/sultana_light.conf +95 -0
 - novelwriter/assets/themes/sultana_night.conf +95 -0
 - novelwriter/assets/themes/tango_dark.conf +111 -0
 - novelwriter/assets/themes/tango_light.conf +111 -0
 - novelwriter/assets/themes/tomorrow.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_blue.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_bright.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_eighties.conf +117 -0
 - novelwriter/assets/themes/vivid_black_green.conf +97 -0
 - novelwriter/assets/themes/vivid_black_red.conf +97 -0
 - novelwriter/assets/themes/vivid_white_green.conf +97 -0
 - novelwriter/assets/themes/vivid_white_red.conf +97 -0
 - novelwriter/assets/themes/warpgate.conf +96 -0
 - novelwriter/assets/themes/waterlily_dark.conf +95 -0
 - novelwriter/assets/themes/waterlily_light.conf +95 -0
 - novelwriter/common.py +47 -17
 - novelwriter/config.py +57 -62
 - novelwriter/constants.py +32 -6
 - novelwriter/core/buildsettings.py +3 -23
 - novelwriter/core/coretools.py +21 -25
 - novelwriter/core/docbuild.py +4 -9
 - novelwriter/core/document.py +2 -6
 - novelwriter/core/index.py +33 -53
 - novelwriter/core/indexdata.py +17 -22
 - novelwriter/core/item.py +11 -35
 - novelwriter/core/itemmodel.py +5 -21
 - novelwriter/core/novelmodel.py +3 -7
 - novelwriter/core/options.py +3 -4
 - novelwriter/core/project.py +31 -21
 - novelwriter/core/projectdata.py +2 -21
 - novelwriter/core/projectxml.py +13 -21
 - novelwriter/core/sessions.py +2 -4
 - novelwriter/core/spellcheck.py +12 -13
 - novelwriter/core/status.py +27 -20
 - novelwriter/core/storage.py +5 -10
 - novelwriter/core/tree.py +6 -15
 - novelwriter/dialogs/about.py +9 -10
 - novelwriter/dialogs/docmerge.py +17 -14
 - novelwriter/dialogs/docsplit.py +18 -14
 - novelwriter/dialogs/editlabel.py +15 -9
 - novelwriter/dialogs/preferences.py +69 -68
 - novelwriter/dialogs/projectsettings.py +88 -67
 - novelwriter/dialogs/quotes.py +15 -10
 - novelwriter/dialogs/wordlist.py +18 -21
 - novelwriter/enum.py +75 -30
 - novelwriter/error.py +6 -11
 - novelwriter/extensions/configlayout.py +8 -34
 - novelwriter/extensions/eventfilters.py +3 -3
 - novelwriter/extensions/modified.py +87 -32
 - novelwriter/extensions/novelselector.py +13 -12
 - novelwriter/extensions/pagedsidebar.py +10 -18
 - novelwriter/extensions/progressbars.py +5 -11
 - novelwriter/extensions/statusled.py +3 -6
 - novelwriter/extensions/switch.py +8 -11
 - novelwriter/extensions/switchbox.py +2 -11
 - novelwriter/extensions/versioninfo.py +6 -7
 - novelwriter/formats/shared.py +10 -2
 - novelwriter/formats/todocx.py +15 -37
 - novelwriter/formats/tohtml.py +52 -61
 - novelwriter/formats/tokenizer.py +33 -64
 - novelwriter/formats/tomarkdown.py +4 -11
 - novelwriter/formats/toodt.py +12 -71
 - novelwriter/formats/toqdoc.py +11 -21
 - novelwriter/formats/toraw.py +2 -6
 - novelwriter/gui/doceditor.py +207 -245
 - novelwriter/gui/dochighlight.py +142 -101
 - novelwriter/gui/docviewer.py +53 -84
 - novelwriter/gui/docviewerpanel.py +18 -41
 - novelwriter/gui/editordocument.py +12 -17
 - novelwriter/gui/itemdetails.py +5 -14
 - novelwriter/gui/mainmenu.py +24 -32
 - novelwriter/gui/noveltree.py +13 -51
 - novelwriter/gui/outline.py +20 -61
 - novelwriter/gui/projtree.py +40 -96
 - novelwriter/gui/search.py +9 -24
 - novelwriter/gui/sidebar.py +54 -22
 - novelwriter/gui/statusbar.py +7 -22
 - novelwriter/gui/theme.py +482 -368
 - novelwriter/guimain.py +87 -101
 - novelwriter/shared.py +79 -48
 - novelwriter/splash.py +9 -5
 - novelwriter/text/comments.py +1 -1
 - novelwriter/text/counting.py +9 -5
 - novelwriter/text/patterns.py +20 -15
 - novelwriter/tools/dictionaries.py +18 -16
 - novelwriter/tools/lipsum.py +15 -17
 - novelwriter/tools/manusbuild.py +25 -45
 - novelwriter/tools/manuscript.py +94 -95
 - novelwriter/tools/manussettings.py +149 -104
 - novelwriter/tools/noveldetails.py +10 -24
 - novelwriter/tools/welcome.py +24 -72
 - novelwriter/tools/writingstats.py +17 -26
 - novelwriter/types.py +25 -13
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/METADATA +7 -7
 - novelwriter-2.8b1.dist-info/RECORD +212 -0
 - novelwriter/assets/images/welcome-dark.jpg +0 -0
 - novelwriter/assets/images/welcome-light.jpg +0 -0
 - novelwriter/assets/syntax/cyberpunk_night.conf +0 -28
 - novelwriter/assets/syntax/default_dark.conf +0 -42
 - novelwriter/assets/syntax/default_light.conf +0 -42
 - novelwriter/assets/syntax/dracula.conf +0 -44
 - novelwriter/assets/syntax/grey_dark.conf +0 -29
 - novelwriter/assets/syntax/grey_light.conf +0 -29
 - novelwriter/assets/syntax/light_owl.conf +0 -49
 - novelwriter/assets/syntax/night_owl.conf +0 -49
 - novelwriter/assets/syntax/snazzy.conf +0 -42
 - novelwriter/assets/syntax/solarized_dark.conf +0 -29
 - novelwriter/assets/syntax/solarized_light.conf +0 -29
 - novelwriter/assets/syntax/tango.conf +0 -39
 - novelwriter/assets/syntax/tomorrow.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_blue.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_bright.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_eighties.conf +0 -49
 - novelwriter/assets/themes/default.conf +0 -3
 - novelwriter-2.7.4.dist-info/RECORD +0 -163
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/WHEEL +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/entry_points.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/LICENSE.md +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/setup/LICENSE-Apache-2.0.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/top_level.txt +0 -0
 
    
        novelwriter/tools/manuscript.py
    CHANGED
    
    | 
         @@ -20,7 +20,7 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            import logging
         
     | 
| 
         @@ -36,9 +36,9 @@ from PyQt6.QtGui import ( 
     | 
|
| 
       36 
36 
     | 
    
         
             
            from PyQt6.QtPrintSupport import QPrinter, QPrintPreviewDialog
         
     | 
| 
       37 
37 
     | 
    
         
             
            from PyQt6.QtWidgets import (
         
     | 
| 
       38 
38 
     | 
    
         
             
                QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
         
     | 
| 
       39 
     | 
    
         
            -
                QLabel, QListWidget, QListWidgetItem,  
     | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
       41 
     | 
    
         
            -
                 
     | 
| 
      
 39 
     | 
    
         
            +
                QLabel, QListWidget, QListWidgetItem, QSplitter, QStackedWidget,
         
     | 
| 
      
 40 
     | 
    
         
            +
                QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
         
     | 
| 
      
 41 
     | 
    
         
            +
                QWidget
         
     | 
| 
       42 
42 
     | 
    
         
             
            )
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
         @@ -46,6 +46,7 @@ from novelwriter.common import fuzzyTime, qtLambda 
     | 
|
| 
       46 
46 
     | 
    
         
             
            from novelwriter.constants import nwHeadFmt, nwLabels, nwStats, nwUnicode, trStats
         
     | 
| 
       47 
47 
     | 
    
         
             
            from novelwriter.core.buildsettings import BuildCollection, BuildSettings
         
     | 
| 
       48 
48 
     | 
    
         
             
            from novelwriter.core.docbuild import NWBuildDocument
         
     | 
| 
      
 49 
     | 
    
         
            +
            from novelwriter.enum import nwStandardButton
         
     | 
| 
       49 
50 
     | 
    
         
             
            from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
         
     | 
| 
       50 
51 
     | 
    
         
             
            from novelwriter.extensions.progressbars import NProgressCircle
         
     | 
| 
       51 
52 
     | 
    
         
             
            from novelwriter.extensions.switch import NSwitch
         
     | 
| 
         @@ -66,7 +67,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       66 
67 
     | 
    
         | 
| 
       67 
68 
     | 
    
         | 
| 
       68 
69 
     | 
    
         
             
            class GuiManuscript(NToolDialog):
         
     | 
| 
       69 
     | 
    
         
            -
                """GUI Tools: Manuscript Tool
         
     | 
| 
      
 70 
     | 
    
         
            +
                """GUI Tools: Manuscript Tool.
         
     | 
| 
       70 
71 
     | 
    
         | 
| 
       71 
72 
     | 
    
         
             
                The dialog displays all the users build definitions, a preview panel
         
     | 
| 
       72 
73 
     | 
    
         
             
                for the manuscript, and can trigger the actual build dialog to build
         
     | 
| 
         @@ -91,39 +92,29 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       91 
92 
     | 
    
         
             
                    iPx = SHARED.theme.baseIconHeight
         
     | 
| 
       92 
93 
     | 
    
         
             
                    iSz = SHARED.theme.baseIconSize
         
     | 
| 
       93 
94 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 95 
     | 
    
         
            +
                    options = SHARED.project.options
         
     | 
| 
       95 
96 
     | 
    
         
             
                    self.resize(
         
     | 
| 
       96 
     | 
    
         
            -
                         
     | 
| 
       97 
     | 
    
         
            -
                         
     | 
| 
      
 97 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "winWidth", 900),
         
     | 
| 
      
 98 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "winHeight", 600),
         
     | 
| 
       98 
99 
     | 
    
         
             
                    )
         
     | 
| 
       99 
100 
     | 
    
         | 
| 
       100 
101 
     | 
    
         
             
                    # Build Controls
         
     | 
| 
       101 
102 
     | 
    
         
             
                    # ==============
         
     | 
| 
       102 
103 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
                     
     | 
| 
       104 
     | 
    
         
            -
                    qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
         
     | 
| 
       105 
     | 
    
         
            -
                    self.setPalette(qPalette)
         
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
                    buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    self.tbAdd = NIconToolButton(self, iSz, "add", "green")
         
     | 
| 
      
 104 
     | 
    
         
            +
                    self.tbAdd = NIconToolButton(self, iSz)
         
     | 
| 
       110 
105 
     | 
    
         
             
                    self.tbAdd.setToolTip(self.tr("Add New Build"))
         
     | 
| 
       111 
     | 
    
         
            -
                    self.tbAdd.setStyleSheet(buttonStyle)
         
     | 
| 
       112 
106 
     | 
    
         
             
                    self.tbAdd.clicked.connect(self._createNewBuild)
         
     | 
| 
       113 
107 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                    self.tbDel = NIconToolButton(self, iSz 
     | 
| 
      
 108 
     | 
    
         
            +
                    self.tbDel = NIconToolButton(self, iSz)
         
     | 
| 
       115 
109 
     | 
    
         
             
                    self.tbDel.setToolTip(self.tr("Delete Selected Build"))
         
     | 
| 
       116 
     | 
    
         
            -
                    self.tbDel.setStyleSheet(buttonStyle)
         
     | 
| 
       117 
110 
     | 
    
         
             
                    self.tbDel.clicked.connect(self._deleteSelectedBuild)
         
     | 
| 
       118 
111 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
                    self.tbCopy = NIconToolButton(self, iSz 
     | 
| 
      
 112 
     | 
    
         
            +
                    self.tbCopy = NIconToolButton(self, iSz)
         
     | 
| 
       120 
113 
     | 
    
         
             
                    self.tbCopy.setToolTip(self.tr("Duplicate Selected Build"))
         
     | 
| 
       121 
     | 
    
         
            -
                    self.tbCopy.setStyleSheet(buttonStyle)
         
     | 
| 
       122 
114 
     | 
    
         
             
                    self.tbCopy.clicked.connect(self._copySelectedBuild)
         
     | 
| 
       123 
115 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                    self.tbEdit = NIconToolButton(self, iSz 
     | 
| 
      
 116 
     | 
    
         
            +
                    self.tbEdit = NIconToolButton(self, iSz)
         
     | 
| 
       125 
117 
     | 
    
         
             
                    self.tbEdit.setToolTip(self.tr("Edit Selected Build"))
         
     | 
| 
       126 
     | 
    
         
            -
                    self.tbEdit.setStyleSheet(buttonStyle)
         
     | 
| 
       127 
118 
     | 
    
         
             
                    self.tbEdit.clicked.connect(self._editSelectedBuild)
         
     | 
| 
       128 
119 
     | 
    
         | 
| 
       129 
120 
     | 
    
         
             
                    self.lblBuilds = QLabel("<b>{0}</b>".format(self.tr("Builds")), self)
         
     | 
| 
         @@ -151,36 +142,35 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       151 
142 
     | 
    
         
             
                    # ============
         
     | 
| 
       152 
143 
     | 
    
         | 
| 
       153 
144 
     | 
    
         
             
                    self.buildDetails = _DetailsWidget(self)
         
     | 
| 
       154 
     | 
    
         
            -
                    self.buildDetails.setColumnWidth( 
     | 
| 
      
 145 
     | 
    
         
            +
                    self.buildDetails.setColumnWidth(options.getInt("GuiManuscript", "detailsWidth", 100))
         
     | 
| 
       155 
146 
     | 
    
         | 
| 
       156 
147 
     | 
    
         
             
                    self.buildOutline = _OutlineWidget(self)
         
     | 
| 
       157 
148 
     | 
    
         | 
| 
       158 
149 
     | 
    
         
             
                    self.detailsTabs = QTabWidget(self)
         
     | 
| 
       159 
150 
     | 
    
         
             
                    self.detailsTabs.addTab(self.buildDetails, self.tr("Details"))
         
     | 
| 
       160 
151 
     | 
    
         
             
                    self.detailsTabs.addTab(self.buildOutline, self.tr("Outline"))
         
     | 
| 
       161 
     | 
    
         
            -
                    self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
         
     | 
| 
       162 
152 
     | 
    
         | 
| 
       163 
153 
     | 
    
         
             
                    self.buildSplit = QSplitter(Qt.Orientation.Vertical, self)
         
     | 
| 
       164 
154 
     | 
    
         
             
                    self.buildSplit.addWidget(self.buildList)
         
     | 
| 
       165 
155 
     | 
    
         
             
                    self.buildSplit.addWidget(self.detailsTabs)
         
     | 
| 
       166 
156 
     | 
    
         
             
                    self.buildSplit.setSizes([
         
     | 
| 
       167 
     | 
    
         
            -
                         
     | 
| 
       168 
     | 
    
         
            -
                         
     | 
| 
      
 157 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "listHeight", 50),
         
     | 
| 
      
 158 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "detailsHeight", 50),
         
     | 
| 
       169 
159 
     | 
    
         
             
                    ])
         
     | 
| 
       170 
160 
     | 
    
         | 
| 
       171 
161 
     | 
    
         
             
                    # Process Controls
         
     | 
| 
       172 
162 
     | 
    
         
             
                    # ================
         
     | 
| 
       173 
163 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
                    self.btnPreview =  
     | 
| 
      
 164 
     | 
    
         
            +
                    self.btnPreview = SHARED.theme.getStandardButton(nwStandardButton.PREVIEW, self)
         
     | 
| 
       175 
165 
     | 
    
         
             
                    self.btnPreview.clicked.connect(self._generatePreview)
         
     | 
| 
       176 
166 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
                    self.btnPrint =  
     | 
| 
      
 167 
     | 
    
         
            +
                    self.btnPrint = SHARED.theme.getStandardButton(nwStandardButton.PRINT, self)
         
     | 
| 
       178 
168 
     | 
    
         
             
                    self.btnPrint.clicked.connect(self._printDocument)
         
     | 
| 
       179 
169 
     | 
    
         | 
| 
       180 
     | 
    
         
            -
                    self.btnBuild =  
     | 
| 
      
 170 
     | 
    
         
            +
                    self.btnBuild = SHARED.theme.getStandardButton(nwStandardButton.BUILD, self)
         
     | 
| 
       181 
171 
     | 
    
         
             
                    self.btnBuild.clicked.connect(self._buildManuscript)
         
     | 
| 
       182 
172 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
                    self.btnClose =  
     | 
| 
      
 173 
     | 
    
         
            +
                    self.btnClose = SHARED.theme.getStandardButton(nwStandardButton.CLOSE, self)
         
     | 
| 
       184 
174 
     | 
    
         
             
                    self.btnClose.clicked.connect(qtLambda(self.close))
         
     | 
| 
       185 
175 
     | 
    
         | 
| 
       186 
176 
     | 
    
         
             
                    self.processBox = QGridLayout()
         
     | 
| 
         @@ -193,7 +183,7 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       193 
183 
     | 
    
         
             
                    # ===============
         
     | 
| 
       194 
184 
     | 
    
         | 
| 
       195 
185 
     | 
    
         
             
                    self.swtNewPage = NSwitch(self, height=iPx)
         
     | 
| 
       196 
     | 
    
         
            -
                    self.swtNewPage.setChecked( 
     | 
| 
      
 186 
     | 
    
         
            +
                    self.swtNewPage.setChecked(options.getBool("GuiManuscript", "showNewPage", True))
         
     | 
| 
       197 
187 
     | 
    
         
             
                    self.swtNewPage.clicked.connect(self._generatePreview)
         
     | 
| 
       198 
188 
     | 
    
         | 
| 
       199 
189 
     | 
    
         
             
                    self.lblNewPage = QLabel(self.tr("Show Page Breaks"), self)
         
     | 
| 
         @@ -236,8 +226,8 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       236 
226 
     | 
    
         
             
                    self.mainSplit.setStretchFactor(0, 0)
         
     | 
| 
       237 
227 
     | 
    
         
             
                    self.mainSplit.setStretchFactor(1, 1)
         
     | 
| 
       238 
228 
     | 
    
         
             
                    self.mainSplit.setSizes([
         
     | 
| 
       239 
     | 
    
         
            -
                         
     | 
| 
       240 
     | 
    
         
            -
                         
     | 
| 
      
 229 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "optsWidth", 225),
         
     | 
| 
      
 230 
     | 
    
         
            +
                        options.getInt("GuiManuscript", "viewWidth", 675),
         
     | 
| 
       241 
231 
     | 
    
         
             
                    ])
         
     | 
| 
       242 
232 
     | 
    
         | 
| 
       243 
233 
     | 
    
         
             
                    self.outerBox = QVBoxLayout()
         
     | 
| 
         @@ -246,16 +236,15 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       246 
236 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
       247 
237 
     | 
    
         
             
                    self.setSizeGripEnabled(True)
         
     | 
| 
       248 
238 
     | 
    
         | 
| 
      
 239 
     | 
    
         
            +
                    self.updateTheme(init=True)
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
       249 
241 
     | 
    
         
             
                    # Signals
         
     | 
| 
       250 
242 
     | 
    
         
             
                    self.buildOutline.outlineEntryClicked.connect(self.docPreview.navigateTo)
         
     | 
| 
       251 
243 
     | 
    
         | 
| 
       252 
244 
     | 
    
         
             
                    logger.debug("Ready: GuiManuscript")
         
     | 
| 
       253 
245 
     | 
    
         | 
| 
       254 
     | 
    
         
            -
                    return
         
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
246 
     | 
    
         
             
                def __del__(self) -> None:  # pragma: no cover
         
     | 
| 
       257 
247 
     | 
    
         
             
                    logger.debug("Delete: GuiManuscript")
         
     | 
| 
       258 
     | 
    
         
            -
                    return
         
     | 
| 
       259 
248 
     | 
    
         | 
| 
       260 
249 
     | 
    
         
             
                def loadContent(self) -> None:
         
     | 
| 
       261 
250 
     | 
    
         
             
                    """Load dialog content from project data."""
         
     | 
| 
         @@ -272,7 +261,36 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       272 
261 
     | 
    
         
             
                        self.buildList.setCurrentItem(self._buildMap[selected])
         
     | 
| 
       273 
262 
     | 
    
         
             
                        QTimer.singleShot(200, self._generatePreview)
         
     | 
| 
       274 
263 
     | 
    
         | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
      
 264 
     | 
    
         
            +
                def updateTheme(self, *, init: bool = False) -> None:
         
     | 
| 
      
 265 
     | 
    
         
            +
                    """Update theme elements."""
         
     | 
| 
      
 266 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiManuscript, init=%s", init)
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                    if not init:
         
     | 
| 
      
 269 
     | 
    
         
            +
                        self.btnPreview.updateIcon()
         
     | 
| 
      
 270 
     | 
    
         
            +
                        self.btnPrint.updateIcon()
         
     | 
| 
      
 271 
     | 
    
         
            +
                        self.btnBuild.updateIcon()
         
     | 
| 
      
 272 
     | 
    
         
            +
                        self.btnClose.updateIcon()
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
      
 274 
     | 
    
         
            +
                    self.tbAdd.setThemeIcon("add", "add")
         
     | 
| 
      
 275 
     | 
    
         
            +
                    self.tbDel.setThemeIcon("remove", "remove")
         
     | 
| 
      
 276 
     | 
    
         
            +
                    self.tbCopy.setThemeIcon("copy", "action")
         
     | 
| 
      
 277 
     | 
    
         
            +
                    self.tbEdit.setThemeIcon("edit", "change")
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                    buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
         
     | 
| 
      
 280 
     | 
    
         
            +
                    self.tbAdd.setStyleSheet(buttonStyle)
         
     | 
| 
      
 281 
     | 
    
         
            +
                    self.tbDel.setStyleSheet(buttonStyle)
         
     | 
| 
      
 282 
     | 
    
         
            +
                    self.tbCopy.setStyleSheet(buttonStyle)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    self.tbEdit.setStyleSheet(buttonStyle)
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                    self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                    self.buildDetails.updateTheme()
         
     | 
| 
      
 288 
     | 
    
         
            +
                    self.buildOutline.updateTheme()
         
     | 
| 
      
 289 
     | 
    
         
            +
                    self.docPreview.updateTheme()
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                    for obj in SHARED.mainGui.children():
         
     | 
| 
      
 292 
     | 
    
         
            +
                        if isinstance(obj, GuiBuildSettings):
         
     | 
| 
      
 293 
     | 
    
         
            +
                            obj.updateTheme()
         
     | 
| 
       276 
294 
     | 
    
         | 
| 
       277 
295 
     | 
    
         
             
                ##
         
     | 
| 
       278 
296 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -290,7 +308,6 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       290 
308 
     | 
    
         
             
                            obj.close()
         
     | 
| 
       291 
309 
     | 
    
         
             
                    event.accept()
         
     | 
| 
       292 
310 
     | 
    
         
             
                    self.softDelete()
         
     | 
| 
       293 
     | 
    
         
            -
                    return
         
     | 
| 
       294 
311 
     | 
    
         | 
| 
       295 
312 
     | 
    
         
             
                ##
         
     | 
| 
       296 
313 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -302,14 +319,12 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       302 
319 
     | 
    
         
             
                    build = BuildSettings()
         
     | 
| 
       303 
320 
     | 
    
         
             
                    build.setName(self.tr("My Manuscript"))
         
     | 
| 
       304 
321 
     | 
    
         
             
                    self._openSettingsDialog(build)
         
     | 
| 
       305 
     | 
    
         
            -
                    return
         
     | 
| 
       306 
322 
     | 
    
         | 
| 
       307 
323 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       308 
324 
     | 
    
         
             
                def _editSelectedBuild(self) -> None:
         
     | 
| 
       309 
325 
     | 
    
         
             
                    """Edit the currently selected build settings entry."""
         
     | 
| 
       310 
326 
     | 
    
         
             
                    if build := self._getSelectedBuild():
         
     | 
| 
       311 
327 
     | 
    
         
             
                        self._openSettingsDialog(build)
         
     | 
| 
       312 
     | 
    
         
            -
                    return
         
     | 
| 
       313 
328 
     | 
    
         | 
| 
       314 
329 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       315 
330 
     | 
    
         
             
                def _copySelectedBuild(self) -> None:
         
     | 
| 
         @@ -320,14 +335,12 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       320 
335 
     | 
    
         
             
                        self._updateBuildsList()
         
     | 
| 
       321 
336 
     | 
    
         
             
                        if item := self._buildMap.get(new.buildID):
         
     | 
| 
       322 
337 
     | 
    
         
             
                            item.setSelected(True)
         
     | 
| 
       323 
     | 
    
         
            -
                    return
         
     | 
| 
       324 
338 
     | 
    
         | 
| 
       325 
339 
     | 
    
         
             
                @pyqtSlot("QListWidgetItem*", "QListWidgetItem*")
         
     | 
| 
       326 
340 
     | 
    
         
             
                def _updateBuildDetails(self, current: QListWidgetItem, previous: QListWidgetItem) -> None:
         
     | 
| 
       327 
341 
     | 
    
         
             
                    """Process change of build selection to update the details."""
         
     | 
| 
       328 
342 
     | 
    
         
             
                    if current and (build := self._builds.getBuild(current.data(self.D_KEY))):
         
     | 
| 
       329 
343 
     | 
    
         
             
                        self.buildDetails.updateInfo(build)
         
     | 
| 
       330 
     | 
    
         
            -
                    return
         
     | 
| 
       331 
344 
     | 
    
         | 
| 
       332 
345 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       333 
346 
     | 
    
         
             
                def _deleteSelectedBuild(self) -> None:
         
     | 
| 
         @@ -338,16 +351,17 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       338 
351 
     | 
    
         
             
                                dialog.close()
         
     | 
| 
       339 
352 
     | 
    
         
             
                            self._builds.removeBuild(build.buildID)
         
     | 
| 
       340 
353 
     | 
    
         
             
                            self._updateBuildsList()
         
     | 
| 
       341 
     | 
    
         
            -
                    return
         
     | 
| 
       342 
354 
     | 
    
         | 
| 
       343 
     | 
    
         
            -
                @pyqtSlot(BuildSettings)
         
     | 
| 
       344 
     | 
    
         
            -
                def _processNewSettings(self, build: BuildSettings) -> None:
         
     | 
| 
      
 355 
     | 
    
         
            +
                @pyqtSlot(BuildSettings, bool)
         
     | 
| 
      
 356 
     | 
    
         
            +
                def _processNewSettings(self, build: BuildSettings, refreshPreview: bool) -> None:
         
     | 
| 
       345 
357 
     | 
    
         
             
                    """Process new build settings from the settings dialog."""
         
     | 
| 
       346 
358 
     | 
    
         
             
                    self._builds.setBuild(build)
         
     | 
| 
       347 
359 
     | 
    
         
             
                    self._updateBuildItem(build)
         
     | 
| 
       348 
     | 
    
         
            -
                    if  
     | 
| 
       349 
     | 
    
         
            -
                        self. 
     | 
| 
       350 
     | 
    
         
            -
             
     | 
| 
      
 360 
     | 
    
         
            +
                    if refreshPreview:
         
     | 
| 
      
 361 
     | 
    
         
            +
                        self.buildList.setCurrentItem(self._buildMap[build.buildID])
         
     | 
| 
      
 362 
     | 
    
         
            +
                        self._generatePreview()
         
     | 
| 
      
 363 
     | 
    
         
            +
                    elif (item := self.buildList.currentItem()) and item.data(self.D_KEY) == build.buildID:
         
     | 
| 
      
 364 
     | 
    
         
            +
                        self._updateBuildDetails(item, item)
         
     | 
| 
       351 
365 
     | 
    
         | 
| 
       352 
366 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       353 
367 
     | 
    
         
             
                def _generatePreview(self) -> None:
         
     | 
| 
         @@ -399,15 +413,12 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       399 
413 
     | 
    
         
             
                        if build.changed:
         
     | 
| 
       400 
414 
     | 
    
         
             
                            self._builds.setBuild(build)
         
     | 
| 
       401 
415 
     | 
    
         | 
| 
       402 
     | 
    
         
            -
                    return
         
     | 
| 
       403 
     | 
    
         
            -
             
     | 
| 
       404 
416 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       405 
417 
     | 
    
         
             
                def _printDocument(self) -> None:
         
     | 
| 
       406 
418 
     | 
    
         
             
                    """Open the print preview dialog."""
         
     | 
| 
       407 
419 
     | 
    
         
             
                    preview = QPrintPreviewDialog(self)
         
     | 
| 
       408 
420 
     | 
    
         
             
                    preview.paintRequested.connect(self.docPreview.printPreview)
         
     | 
| 
       409 
421 
     | 
    
         
             
                    preview.exec()
         
     | 
| 
       410 
     | 
    
         
            -
                    return
         
     | 
| 
       411 
422 
     | 
    
         | 
| 
       412 
423 
     | 
    
         
             
                ##
         
     | 
| 
       413 
424 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -456,8 +467,6 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       456 
467 
     | 
    
         
             
                    pOptions.setValue("GuiManuscript", "showNewPage", showNewPage)
         
     | 
| 
       457 
468 
     | 
    
         
             
                    pOptions.saveSettings()
         
     | 
| 
       458 
469 
     | 
    
         | 
| 
       459 
     | 
    
         
            -
                    return
         
     | 
| 
       460 
     | 
    
         
            -
             
     | 
| 
       461 
470 
     | 
    
         
             
                def _openSettingsDialog(self, build: BuildSettings) -> None:
         
     | 
| 
       462 
471 
     | 
    
         
             
                    """Open the build settings dialog."""
         
     | 
| 
       463 
472 
     | 
    
         
             
                    if dialog := self._findSettingsDialog(build.buildID):
         
     | 
| 
         @@ -478,11 +487,10 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       478 
487 
     | 
    
         
             
                    for key, name in self._builds.builds():
         
     | 
| 
       479 
488 
     | 
    
         
             
                        bItem = QListWidgetItem()
         
     | 
| 
       480 
489 
     | 
    
         
             
                        bItem.setText(name)
         
     | 
| 
       481 
     | 
    
         
            -
                        bItem.setIcon(SHARED.theme.getIcon("build_settings", " 
     | 
| 
      
 490 
     | 
    
         
            +
                        bItem.setIcon(SHARED.theme.getIcon("build_settings", "action"))
         
     | 
| 
       482 
491 
     | 
    
         
             
                        bItem.setData(self.D_KEY, key)
         
     | 
| 
       483 
492 
     | 
    
         
             
                        self.buildList.addItem(bItem)
         
     | 
| 
       484 
493 
     | 
    
         
             
                        self._buildMap[key] = bItem
         
     | 
| 
       485 
     | 
    
         
            -
                    return
         
     | 
| 
       486 
494 
     | 
    
         | 
| 
       487 
495 
     | 
    
         
             
                def _updateBuildItem(self, build: BuildSettings) -> None:
         
     | 
| 
       488 
496 
     | 
    
         
             
                    """Update the entry of a specific build item."""
         
     | 
| 
         @@ -490,7 +498,6 @@ class GuiManuscript(NToolDialog): 
     | 
|
| 
       490 
498 
     | 
    
         
             
                        item.setText(build.name)
         
     | 
| 
       491 
499 
     | 
    
         
             
                    else:  # Probably a new item
         
     | 
| 
       492 
500 
     | 
    
         
             
                        self._updateBuildsList()
         
     | 
| 
       493 
     | 
    
         
            -
                    return
         
     | 
| 
       494 
501 
     | 
    
         | 
| 
       495 
502 
     | 
    
         
             
                def _findSettingsDialog(self, buildID: str) -> GuiBuildSettings | None:
         
     | 
| 
       496 
503 
     | 
    
         
             
                    """Return an open build settings dialog for a given build, if
         
     | 
| 
         @@ -508,6 +515,7 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       508 
515 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       509 
516 
     | 
    
         | 
| 
       510 
517 
     | 
    
         
             
                    self._initExpanded = True
         
     | 
| 
      
 518 
     | 
    
         
            +
                    self._build = None
         
     | 
| 
       511 
519 
     | 
    
         | 
| 
       512 
520 
     | 
    
         
             
                    # Tree Widget
         
     | 
| 
       513 
521 
     | 
    
         
             
                    self.listView = QTreeWidget(self)
         
     | 
| 
         @@ -521,8 +529,6 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       521 
529 
     | 
    
         
             
                    self.outerBox.setContentsMargins(0, 0, 0, 0)
         
     | 
| 
       522 
530 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
       523 
531 
     | 
    
         | 
| 
       524 
     | 
    
         
            -
                    return
         
     | 
| 
       525 
     | 
    
         
            -
             
     | 
| 
       526 
532 
     | 
    
         
             
                ##
         
     | 
| 
       527 
533 
     | 
    
         
             
                #  Getters
         
     | 
| 
       528 
534 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -547,7 +553,6 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       547 
553 
     | 
    
         
             
                def setColumnWidth(self, value: int) -> None:
         
     | 
| 
       548 
554 
     | 
    
         
             
                    """Set the width of the first column."""
         
     | 
| 
       549 
555 
     | 
    
         
             
                    self.listView.setColumnWidth(0, value)
         
     | 
| 
       550 
     | 
    
         
            -
                    return
         
     | 
| 
       551 
556 
     | 
    
         | 
| 
       552 
557 
     | 
    
         
             
                def setExpandedState(self, state: list[bool]) -> None:
         
     | 
| 
       553 
558 
     | 
    
         
             
                    """Set the expanded state of each top level item."""
         
     | 
| 
         @@ -556,7 +561,6 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       556 
561 
     | 
    
         
             
                        item = self.listView.topLevelItem(i)
         
     | 
| 
       557 
562 
     | 
    
         
             
                        if isinstance(item, QTreeWidgetItem):
         
     | 
| 
       558 
563 
     | 
    
         
             
                            item.setExpanded((state[i] if i < count else True) and item.childCount() > 0)
         
     | 
| 
       559 
     | 
    
         
            -
                    return
         
     | 
| 
       560 
564 
     | 
    
         | 
| 
       561 
565 
     | 
    
         
             
                ##
         
     | 
| 
       562 
566 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -573,8 +577,8 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       573 
577 
     | 
    
         | 
| 
       574 
578 
     | 
    
         
             
                    self.listView.clear()
         
     | 
| 
       575 
579 
     | 
    
         | 
| 
       576 
     | 
    
         
            -
                    on = SHARED.theme.getIcon("bullet-on", " 
     | 
| 
       577 
     | 
    
         
            -
                    off = SHARED.theme.getIcon("bullet-off", " 
     | 
| 
      
 580 
     | 
    
         
            +
                    on = SHARED.theme.getIcon("bullet-on", "action")
         
     | 
| 
      
 581 
     | 
    
         
            +
                    off = SHARED.theme.getIcon("bullet-off", "action")
         
     | 
| 
       578 
582 
     | 
    
         | 
| 
       579 
583 
     | 
    
         
             
                    # Name
         
     | 
| 
       580 
584 
     | 
    
         
             
                    item = QTreeWidgetItem()
         
     | 
| 
         @@ -634,10 +638,16 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       634 
638 
     | 
    
         
             
                        sub.setIcon(1, on if build.getBool(key) else off)
         
     | 
| 
       635 
639 
     | 
    
         
             
                        item.addChild(sub)
         
     | 
| 
       636 
640 
     | 
    
         | 
| 
      
 641 
     | 
    
         
            +
                    self._build = build
         
     | 
| 
      
 642 
     | 
    
         
            +
             
     | 
| 
       637 
643 
     | 
    
         
             
                    # Restore expanded state
         
     | 
| 
       638 
644 
     | 
    
         
             
                    self.setExpandedState(expanded)
         
     | 
| 
       639 
645 
     | 
    
         | 
| 
       640 
     | 
    
         
            -
             
     | 
| 
      
 646 
     | 
    
         
            +
                def updateTheme(self) -> None:
         
     | 
| 
      
 647 
     | 
    
         
            +
                    """Update theme elements."""
         
     | 
| 
      
 648 
     | 
    
         
            +
                    if self._build:
         
     | 
| 
      
 649 
     | 
    
         
            +
                        logger.debug("Theme Update: _DetailsWidget")
         
     | 
| 
      
 650 
     | 
    
         
            +
                        self.updateInfo(self._build)
         
     | 
| 
       641 
651 
     | 
    
         | 
| 
       642 
652 
     | 
    
         | 
| 
       643 
653 
     | 
    
         
             
            class _OutlineWidget(QWidget):
         
     | 
| 
         @@ -663,11 +673,9 @@ class _OutlineWidget(QWidget): 
     | 
|
| 
       663 
673 
     | 
    
         
             
                    self.outerBox.setContentsMargins(0, 0, 0, 0)
         
     | 
| 
       664 
674 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
       665 
675 
     | 
    
         | 
| 
       666 
     | 
    
         
            -
             
     | 
| 
       667 
     | 
    
         
            -
             
     | 
| 
       668 
     | 
    
         
            -
                def updateOutline(self, data: dict[str, str]) -> None:
         
     | 
| 
      
 676 
     | 
    
         
            +
                def updateOutline(self, data: dict[str, str], *, force: bool = False) -> None:
         
     | 
| 
       669 
677 
     | 
    
         
             
                    """Update the outline."""
         
     | 
| 
       670 
     | 
    
         
            -
                    if isinstance(data, dict) and data != self._outline:
         
     | 
| 
      
 678 
     | 
    
         
            +
                    if isinstance(data, dict) and (data != self._outline or force):
         
     | 
| 
       671 
679 
     | 
    
         
             
                        self.listView.clear()
         
     | 
| 
       672 
680 
     | 
    
         | 
| 
       673 
681 
     | 
    
         
             
                        tFont = self.font()
         
     | 
| 
         @@ -705,7 +713,10 @@ class _OutlineWidget(QWidget): 
     | 
|
| 
       705 
713 
     | 
    
         
             
                        self.listView.setIndentation(SHARED.theme.baseIconHeight if indent else 4)
         
     | 
| 
       706 
714 
     | 
    
         
             
                        self._outline = data
         
     | 
| 
       707 
715 
     | 
    
         | 
| 
       708 
     | 
    
         
            -
             
     | 
| 
      
 716 
     | 
    
         
            +
                def updateTheme(self) -> None:
         
     | 
| 
      
 717 
     | 
    
         
            +
                    """Update theme elements."""
         
     | 
| 
      
 718 
     | 
    
         
            +
                    logger.debug("Theme Update: _OutlineWidget")
         
     | 
| 
      
 719 
     | 
    
         
            +
                    self.updateOutline(self._outline, force=True)
         
     | 
| 
       709 
720 
     | 
    
         | 
| 
       710 
721 
     | 
    
         
             
                ##
         
     | 
| 
       711 
722 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -714,7 +725,6 @@ class _OutlineWidget(QWidget): 
     | 
|
| 
       714 
725 
     | 
    
         
             
                def _onItemClick(self, item: QTreeWidgetItem) -> None:
         
     | 
| 
       715 
726 
     | 
    
         
             
                    """Process tree item click."""
         
     | 
| 
       716 
727 
     | 
    
         
             
                    self.outlineEntryClicked.emit(str(item.data(0, self.D_LINE)))
         
     | 
| 
       717 
     | 
    
         
            -
                    return
         
     | 
| 
       718 
728 
     | 
    
         | 
| 
       719 
729 
     | 
    
         | 
| 
       720 
730 
     | 
    
         
             
            class _PreviewWidget(QTextBrowser):
         
     | 
| 
         @@ -750,17 +760,12 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       750 
760 
     | 
    
         
             
                    self.anchorClicked.connect(self._linkClicked)
         
     | 
| 
       751 
761 
     | 
    
         | 
| 
       752 
762 
     | 
    
         
             
                    # Document Age
         
     | 
| 
       753 
     | 
    
         
            -
                    aPalette = self.palette()
         
     | 
| 
       754 
     | 
    
         
            -
                    aPalette.setColor(QPalette.ColorRole.Window, aPalette.toolTipBase().color())
         
     | 
| 
       755 
     | 
    
         
            -
                    aPalette.setColor(QPalette.ColorRole.WindowText, aPalette.toolTipText().color())
         
     | 
| 
       756 
     | 
    
         
            -
             
     | 
| 
       757 
763 
     | 
    
         
             
                    aFont = self.font()
         
     | 
| 
       758 
764 
     | 
    
         
             
                    aFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
         
     | 
| 
       759 
765 
     | 
    
         | 
| 
       760 
766 
     | 
    
         
             
                    self.ageLabel = QLabel("", self)
         
     | 
| 
       761 
767 
     | 
    
         
             
                    self.ageLabel.setIndent(0)
         
     | 
| 
       762 
768 
     | 
    
         
             
                    self.ageLabel.setFont(aFont)
         
     | 
| 
       763 
     | 
    
         
            -
                    self.ageLabel.setPalette(aPalette)
         
     | 
| 
       764 
769 
     | 
    
         
             
                    self.ageLabel.setAutoFillBackground(True)
         
     | 
| 
       765 
770 
     | 
    
         
             
                    self.ageLabel.setAlignment(QtAlignCenter)
         
     | 
| 
       766 
771 
     | 
    
         
             
                    self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize))
         
     | 
| 
         @@ -779,6 +784,7 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       779 
784 
     | 
    
         
             
                    self._updateDocMargins()
         
     | 
| 
       780 
785 
     | 
    
         
             
                    self._updateBuildAge()
         
     | 
| 
       781 
786 
     | 
    
         | 
| 
      
 787 
     | 
    
         
            +
                    self.updateTheme()
         
     | 
| 
       782 
788 
     | 
    
         
             
                    self.setTextFont(CONFIG.textFont)
         
     | 
| 
       783 
789 
     | 
    
         | 
| 
       784 
790 
     | 
    
         
             
                    # Age Timer
         
     | 
| 
         @@ -787,8 +793,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       787 
793 
     | 
    
         
             
                    self.ageTimer.timeout.connect(self._updateBuildAge)
         
     | 
| 
       788 
794 
     | 
    
         
             
                    self.ageTimer.start()
         
     | 
| 
       789 
795 
     | 
    
         | 
| 
       790 
     | 
    
         
            -
                    return
         
     | 
| 
       791 
     | 
    
         
            -
             
     | 
| 
       792 
796 
     | 
    
         
             
                ##
         
     | 
| 
       793 
797 
     | 
    
         
             
                #  Setters
         
     | 
| 
       794 
798 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -797,7 +801,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       797 
801 
     | 
    
         
             
                    """Set the build name for the document label."""
         
     | 
| 
       798 
802 
     | 
    
         
             
                    self._buildName = name
         
     | 
| 
       799 
803 
     | 
    
         
             
                    self._updateBuildAge()
         
     | 
| 
       800 
     | 
    
         
            -
                    return
         
     | 
| 
       801 
804 
     | 
    
         | 
| 
       802 
805 
     | 
    
         
             
                def setTextFont(self, font: QFont) -> None:
         
     | 
| 
       803 
806 
     | 
    
         
             
                    """Set the text font properties and then reset for sub-widgets.
         
     | 
| 
         @@ -807,7 +810,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       807 
810 
     | 
    
         
             
                    self.setFont(font)
         
     | 
| 
       808 
811 
     | 
    
         
             
                    self.buildProgress.setFont(SHARED.theme.guiFont)
         
     | 
| 
       809 
812 
     | 
    
         
             
                    self.ageLabel.setFont(SHARED.theme.guiFontSmall)
         
     | 
| 
       810 
     | 
    
         
            -
                    return
         
     | 
| 
       811 
813 
     | 
    
         | 
| 
       812 
814 
     | 
    
         
             
                ##
         
     | 
| 
       813 
815 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -823,13 +825,11 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       823 
825 
     | 
    
         
             
                        self._scrollPos = vBar.value()
         
     | 
| 
       824 
826 
     | 
    
         
             
                    self.setPlaceholderText("")
         
     | 
| 
       825 
827 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       826 
     | 
    
         
            -
                    return
         
     | 
| 
       827 
828 
     | 
    
         | 
| 
       828 
829 
     | 
    
         
             
                def buildStep(self, value: int) -> None:
         
     | 
| 
       829 
830 
     | 
    
         
             
                    """Update the progress bar value."""
         
     | 
| 
       830 
831 
     | 
    
         
             
                    self.buildProgress.setValue(value)
         
     | 
| 
       831 
832 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       832 
     | 
    
         
            -
                    return
         
     | 
| 
       833 
833 
     | 
    
         | 
| 
       834 
834 
     | 
    
         
             
                def setContent(self, document: QTextDocument) -> None:
         
     | 
| 
       835 
835 
     | 
    
         
             
                    """Set the content of the preview widget."""
         
     | 
| 
         @@ -850,7 +850,14 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       850 
850 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       851 
851 
     | 
    
         
             
                    QTimer.singleShot(300, self._postUpdate)
         
     | 
| 
       852 
852 
     | 
    
         | 
| 
       853 
     | 
    
         
            -
             
     | 
| 
      
 853 
     | 
    
         
            +
                def updateTheme(self) -> None:
         
     | 
| 
      
 854 
     | 
    
         
            +
                    """Update theme elements."""
         
     | 
| 
      
 855 
     | 
    
         
            +
                    logger.debug("Theme Update: _PreviewWidget")
         
     | 
| 
      
 856 
     | 
    
         
            +
             
     | 
| 
      
 857 
     | 
    
         
            +
                    palette = QApplication.palette()
         
     | 
| 
      
 858 
     | 
    
         
            +
                    palette.setColor(QPalette.ColorRole.Window, palette.toolTipBase().color())
         
     | 
| 
      
 859 
     | 
    
         
            +
                    palette.setColor(QPalette.ColorRole.WindowText, palette.toolTipText().color())
         
     | 
| 
      
 860 
     | 
    
         
            +
                    self.ageLabel.setPalette(palette)
         
     | 
| 
       854 
861 
     | 
    
         | 
| 
       855 
862 
     | 
    
         
             
                ##
         
     | 
| 
       856 
863 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -860,7 +867,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       860 
867 
     | 
    
         
             
                    """Capture resize and update the document margins."""
         
     | 
| 
       861 
868 
     | 
    
         
             
                    super().resizeEvent(event)
         
     | 
| 
       862 
869 
     | 
    
         
             
                    self._updateDocMargins()
         
     | 
| 
       863 
     | 
    
         
            -
                    return
         
     | 
| 
       864 
870 
     | 
    
         | 
| 
       865 
871 
     | 
    
         
             
                ##
         
     | 
| 
       866 
872 
     | 
    
         
             
                #  Public Slots
         
     | 
| 
         @@ -874,14 +880,12 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       874 
880 
     | 
    
         
             
                        printer.setPageOrientation(QPageLayout.Orientation.Portrait)
         
     | 
| 
       875 
881 
     | 
    
         
             
                        document.print(printer)
         
     | 
| 
       876 
882 
     | 
    
         
             
                        QApplication.restoreOverrideCursor()
         
     | 
| 
       877 
     | 
    
         
            -
                    return
         
     | 
| 
       878 
883 
     | 
    
         | 
| 
       879 
884 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       880 
885 
     | 
    
         
             
                def navigateTo(self, anchor: str) -> None:
         
     | 
| 
       881 
886 
     | 
    
         
             
                    """Go to a specific #link in the document."""
         
     | 
| 
       882 
887 
     | 
    
         
             
                    logger.debug("Moving to anchor '#%s'", anchor)
         
     | 
| 
       883 
888 
     | 
    
         
             
                    self.setSource(QUrl(f"#{anchor}"))
         
     | 
| 
       884 
     | 
    
         
            -
                    return
         
     | 
| 
       885 
889 
     | 
    
         | 
| 
       886 
890 
     | 
    
         
             
                ##
         
     | 
| 
       887 
891 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -896,7 +900,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       896 
900 
     | 
    
         
             
                            self.navigateTo(link.lstrip("#"))
         
     | 
| 
       897 
901 
     | 
    
         
             
                        elif link.startswith("http"):
         
     | 
| 
       898 
902 
     | 
    
         
             
                            QDesktopServices.openUrl(QUrl(url))
         
     | 
| 
       899 
     | 
    
         
            -
                    return
         
     | 
| 
       900 
903 
     | 
    
         | 
| 
       901 
904 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       902 
905 
     | 
    
         
             
                def _updateBuildAge(self) -> None:
         
     | 
| 
         @@ -909,7 +912,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       909 
912 
     | 
    
         
             
                        ))
         
     | 
| 
       910 
913 
     | 
    
         
             
                    else:
         
     | 
| 
       911 
914 
     | 
    
         
             
                        self.ageLabel.setText("<b>{0}</b>".format(self.tr("No Preview")))
         
     | 
| 
       912 
     | 
    
         
            -
                    return
         
     | 
| 
       913 
915 
     | 
    
         | 
| 
       914 
916 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       915 
917 
     | 
    
         
             
                def _postUpdate(self) -> None:
         
     | 
| 
         @@ -917,7 +919,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       917 
919 
     | 
    
         
             
                    self.buildProgress.setVisible(False)
         
     | 
| 
       918 
920 
     | 
    
         
             
                    if vBar := self.verticalScrollBar():
         
     | 
| 
       919 
921 
     | 
    
         
             
                        vBar.setValue(self._scrollPos)
         
     | 
| 
       920 
     | 
    
         
            -
                    return
         
     | 
| 
       921 
922 
     | 
    
         | 
| 
       922 
923 
     | 
    
         
             
                ##
         
     | 
| 
       923 
924 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -936,7 +937,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       936 
937 
     | 
    
         
             
                    self.ageLabel.setGeometry(tB, tB, vW, tH)
         
     | 
| 
       937 
938 
     | 
    
         
             
                    self.setViewportMargins(0, tH, 0, 0)
         
     | 
| 
       938 
939 
     | 
    
         
             
                    self.buildProgress.move((vW-pS)//2, (vH-pS)//2)
         
     | 
| 
       939 
     | 
    
         
            -
                    return
         
     | 
| 
       940 
940 
     | 
    
         | 
| 
       941 
941 
     | 
    
         | 
| 
       942 
942 
     | 
    
         
             
            class _StatsWidget(QWidget):
         
     | 
| 
         @@ -951,7 +951,7 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       951 
951 
     | 
    
         
             
                    self.minWidget = QWidget(self)
         
     | 
| 
       952 
952 
     | 
    
         
             
                    self.maxWidget = QWidget(self)
         
     | 
| 
       953 
953 
     | 
    
         | 
| 
       954 
     | 
    
         
            -
                    self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize 
     | 
| 
      
 954 
     | 
    
         
            +
                    self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize)
         
     | 
| 
       955 
955 
     | 
    
         
             
                    self.toggleButton.toggled.connect(self._toggleView)
         
     | 
| 
       956 
956 
     | 
    
         | 
| 
       957 
957 
     | 
    
         
             
                    self._buildBottomPanel()
         
     | 
| 
         @@ -966,11 +966,10 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       966 
966 
     | 
    
         
             
                    self.outerBox.setContentsMargins(0, 0, 0, 0)
         
     | 
| 
       967 
967 
     | 
    
         | 
| 
       968 
968 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
      
 969 
     | 
    
         
            +
                    self.updateTheme()
         
     | 
| 
       969 
970 
     | 
    
         | 
| 
       970 
971 
     | 
    
         
             
                    self._toggleView(False)
         
     | 
| 
       971 
972 
     | 
    
         | 
| 
       972 
     | 
    
         
            -
                    return
         
     | 
| 
       973 
     | 
    
         
            -
             
     | 
| 
       974 
973 
     | 
    
         
             
                def updateStats(self, data: dict[str, int]) -> None:
         
     | 
| 
       975 
974 
     | 
    
         
             
                    """Update the stats values from a Tokenizer stats dict."""
         
     | 
| 
       976 
975 
     | 
    
         
             
                    # Minimal
         
     | 
| 
         @@ -992,7 +991,10 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       992 
991 
     | 
    
         
             
                    self.maxHeadWordChars.setText(f"{data.get(nwStats.WCHARS_TITLE, 0):n}")
         
     | 
| 
       993 
992 
     | 
    
         
             
                    self.maxTextWordChars.setText(f"{data.get(nwStats.WCHARS_TEXT, 0):n}")
         
     | 
| 
       994 
993 
     | 
    
         | 
| 
       995 
     | 
    
         
            -
             
     | 
| 
      
 994 
     | 
    
         
            +
                def updateTheme(self) -> None:
         
     | 
| 
      
 995 
     | 
    
         
            +
                    """Update theme elements."""
         
     | 
| 
      
 996 
     | 
    
         
            +
                    logger.debug("Theme Update: _StatsWidget")
         
     | 
| 
      
 997 
     | 
    
         
            +
                    self.toggleButton.setThemeIcon("unfold", "default")
         
     | 
| 
       996 
998 
     | 
    
         | 
| 
       997 
999 
     | 
    
         
             
                ##
         
     | 
| 
       998 
1000 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -1013,7 +1015,6 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1013 
1015 
     | 
    
         
             
                    self.minWidget.adjustSize()
         
     | 
| 
       1014 
1016 
     | 
    
         
             
                    self.mainStack.adjustSize()
         
     | 
| 
       1015 
1017 
     | 
    
         
             
                    self.adjustSize()
         
     | 
| 
       1016 
     | 
    
         
            -
                    return
         
     | 
| 
       1017 
1018 
     | 
    
         | 
| 
       1018 
1019 
     | 
    
         
             
                ##
         
     | 
| 
       1019 
1020 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -1105,5 +1106,3 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1105 
1106 
     | 
    
         | 
| 
       1106 
1107 
     | 
    
         
             
                    self.minWidget.setLayout(self.minLayout)
         
     | 
| 
       1107 
1108 
     | 
    
         
             
                    self.maxWidget.setLayout(self.maxLayout)
         
     | 
| 
       1108 
     | 
    
         
            -
             
     | 
| 
       1109 
     | 
    
         
            -
                    return
         
     |