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
 
| 
         @@ -21,7 +21,7 @@ General Public License for more details. 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       23 
23 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       24 
     | 
    
         
            -
            """
         
     | 
| 
      
 24 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       25 
25 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
            import csv
         
     | 
| 
         @@ -33,21 +33,21 @@ from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot 
     | 
|
| 
       33 
33 
     | 
    
         
             
            from PyQt6.QtGui import QCloseEvent, QColor
         
     | 
| 
       34 
34 
     | 
    
         
             
            from PyQt6.QtWidgets import (
         
     | 
| 
       35 
35 
     | 
    
         
             
                QAbstractItemView, QApplication, QColorDialog, QDialogButtonBox,
         
     | 
| 
       36 
     | 
    
         
            -
                QFileDialog, QGridLayout, QHBoxLayout, QLineEdit, QMenu, 
     | 
| 
       37 
     | 
    
         
            -
                QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
         
     | 
| 
      
 36 
     | 
    
         
            +
                QFileDialog, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
         
     | 
| 
      
 37 
     | 
    
         
            +
                QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
         
     | 
| 
       38 
38 
     | 
    
         
             
            )
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
       41 
41 
     | 
    
         
             
            from novelwriter.common import formatFileFilter, qtAddAction, qtLambda, simplified
         
     | 
| 
       42 
42 
     | 
    
         
             
            from novelwriter.constants import nwLabels, trConst
         
     | 
| 
       43 
     | 
    
         
            -
            from novelwriter.core.status import NWStatus, StatusEntry
         
     | 
| 
       44 
     | 
    
         
            -
            from novelwriter.enum import nwStatusShape
         
     | 
| 
      
 43 
     | 
    
         
            +
            from novelwriter.core.status import CUSTOM_COL, NWStatus, StatusEntry
         
     | 
| 
      
 44 
     | 
    
         
            +
            from novelwriter.enum import nwStandardButton, nwStatusShape
         
     | 
| 
       45 
45 
     | 
    
         
             
            from novelwriter.extensions.configlayout import NColorLabel, NFixedPage, NScrollableForm
         
     | 
| 
       46 
46 
     | 
    
         
             
            from novelwriter.extensions.modified import NComboBox, NDialog, NIconToolButton
         
     | 
| 
       47 
47 
     | 
    
         
             
            from novelwriter.extensions.pagedsidebar import NPagedSideBar
         
     | 
| 
       48 
48 
     | 
    
         
             
            from novelwriter.extensions.switch import NSwitch
         
     | 
| 
       49 
49 
     | 
    
         
             
            from novelwriter.types import (
         
     | 
| 
       50 
     | 
    
         
            -
                 
     | 
| 
      
 50 
     | 
    
         
            +
                QtRoleAccept, QtRoleReject, QtSizeMinimum, QtSizeMinimumExpanding,
         
     | 
| 
       51 
51 
     | 
    
         
             
                QtUserRole
         
     | 
| 
       52 
52 
     | 
    
         
             
            )
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
         @@ -55,6 +55,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
            class GuiProjectSettings(NDialog):
         
     | 
| 
      
 58 
     | 
    
         
            +
                """GUI: Project Settings DIalog."""
         
     | 
| 
       58 
59 
     | 
    
         | 
| 
       59 
60 
     | 
    
         
             
                PAGE_SETTINGS = 0
         
     | 
| 
       60 
61 
     | 
    
         
             
                PAGE_STATUS   = 1
         
     | 
| 
         @@ -94,9 +95,15 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       94 
95 
     | 
    
         
             
                    self.sidebar.buttonClicked.connect(self._sidebarClicked)
         
     | 
| 
       95 
96 
     | 
    
         | 
| 
       96 
97 
     | 
    
         
             
                    # Buttons
         
     | 
| 
       97 
     | 
    
         
            -
                    self. 
     | 
| 
       98 
     | 
    
         
            -
                    self. 
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
                    self.btnSave = SHARED.theme.getStandardButton(nwStandardButton.SAVE, self)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    self.btnSave.clicked.connect(self._doSave)
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    self.btnCancel = SHARED.theme.getStandardButton(nwStandardButton.CANCEL, self)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    self.btnCancel.clicked.connect(self.reject)
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                    self.btnBox = QDialogButtonBox(self)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnSave, QtRoleAccept)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnCancel, QtRoleReject)
         
     | 
| 
       100 
107 
     | 
    
         | 
| 
       101 
108 
     | 
    
         
             
                    # Content
         
     | 
| 
       102 
109 
     | 
    
         
             
                    SHARED.project.countStatus()
         
     | 
| 
         @@ -125,7 +132,7 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       125 
132 
     | 
    
         
             
                    self.outerBox = QVBoxLayout()
         
     | 
| 
       126 
133 
     | 
    
         
             
                    self.outerBox.addLayout(self.topBox)
         
     | 
| 
       127 
134 
     | 
    
         
             
                    self.outerBox.addLayout(self.mainBox)
         
     | 
| 
       128 
     | 
    
         
            -
                    self.outerBox.addWidget(self. 
     | 
| 
      
 135 
     | 
    
         
            +
                    self.outerBox.addWidget(self.btnBox)
         
     | 
| 
       129 
136 
     | 
    
         
             
                    self.outerBox.setSpacing(8)
         
     | 
| 
       130 
137 
     | 
    
         | 
| 
       131 
138 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
         @@ -137,11 +144,8 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       137 
144 
     | 
    
         | 
| 
       138 
145 
     | 
    
         
             
                    logger.debug("Ready: GuiProjectSettings")
         
     | 
| 
       139 
146 
     | 
    
         | 
| 
       140 
     | 
    
         
            -
                    return
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
147 
     | 
    
         
             
                def __del__(self) -> None:  # pragma: no cover
         
     | 
| 
       143 
148 
     | 
    
         
             
                    logger.debug("Delete: GuiProjectSettings")
         
     | 
| 
       144 
     | 
    
         
            -
                    return
         
     | 
| 
       145 
149 
     | 
    
         | 
| 
       146 
150 
     | 
    
         
             
                ##
         
     | 
| 
       147 
151 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -152,7 +156,6 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       152 
156 
     | 
    
         
             
                    self._saveSettings()
         
     | 
| 
       153 
157 
     | 
    
         
             
                    event.accept()
         
     | 
| 
       154 
158 
     | 
    
         
             
                    self.softDelete()
         
     | 
| 
       155 
     | 
    
         
            -
                    return
         
     | 
| 
       156 
159 
     | 
    
         | 
| 
       157 
160 
     | 
    
         
             
                ##
         
     | 
| 
       158 
161 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -169,7 +172,6 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       169 
172 
     | 
    
         
             
                        self.mainStack.setCurrentWidget(self.importPage)
         
     | 
| 
       170 
173 
     | 
    
         
             
                    elif pageId == self.PAGE_REPLACE:
         
     | 
| 
       171 
174 
     | 
    
         
             
                        self.mainStack.setCurrentWidget(self.replacePage)
         
     | 
| 
       172 
     | 
    
         
            -
                    return
         
     | 
| 
       173 
175 
     | 
    
         | 
| 
       174 
176 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       175 
177 
     | 
    
         
             
                def _doSave(self) -> None:
         
     | 
| 
         @@ -203,8 +205,6 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       203 
205 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       204 
206 
     | 
    
         
             
                    self.close()
         
     | 
| 
       205 
207 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
                    return
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
208 
     | 
    
         
             
                ##
         
     | 
| 
       209 
209 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
       210 
210 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -223,8 +223,6 @@ class GuiProjectSettings(NDialog): 
     | 
|
| 
       223 
223 
     | 
    
         
             
                    options.setValue("GuiProjectSettings", "importColW", importColW)
         
     | 
| 
       224 
224 
     | 
    
         
             
                    options.setValue("GuiProjectSettings", "replaceColW", replaceColW)
         
     | 
| 
       225 
225 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
                    return
         
     | 
| 
       227 
     | 
    
         
            -
             
     | 
| 
       228 
226 
     | 
    
         | 
| 
       229 
227 
     | 
    
         
             
            class _SettingsPage(NScrollableForm):
         
     | 
| 
       230 
228 
     | 
    
         | 
| 
         @@ -295,8 +293,6 @@ class _SettingsPage(NScrollableForm): 
     | 
|
| 
       295 
293 
     | 
    
         | 
| 
       296 
294 
     | 
    
         
             
                    self.finalise()
         
     | 
| 
       297 
295 
     | 
    
         | 
| 
       298 
     | 
    
         
            -
                    return
         
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
296 
     | 
    
         | 
| 
       301 
297 
     | 
    
         
             
            class _StatusPage(NFixedPage):
         
     | 
| 
       302 
298 
     | 
    
         | 
| 
         @@ -326,6 +322,7 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       326 
322 
     | 
    
         
             
                    self._changed = False
         
     | 
| 
       327 
323 
     | 
    
         
             
                    self._color = QColor(100, 100, 100)
         
     | 
| 
       328 
324 
     | 
    
         
             
                    self._shape = nwStatusShape.SQUARE
         
     | 
| 
      
 325 
     | 
    
         
            +
                    self._theme = CUSTOM_COL
         
     | 
| 
       329 
326 
     | 
    
         
             
                    self._icons = {}
         
     | 
| 
       330 
327 
     | 
    
         | 
| 
       331 
328 
     | 
    
         
             
                    self._iPx = SHARED.theme.baseIconHeight
         
     | 
| 
         @@ -359,36 +356,51 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       359 
356 
     | 
    
         
             
                        self._addItem(key, StatusEntry.duplicate(entry))
         
     | 
| 
       360 
357 
     | 
    
         | 
| 
       361 
358 
     | 
    
         
             
                    # List Controls
         
     | 
| 
       362 
     | 
    
         
            -
                    self.addButton = NIconToolButton(self, iSz, "add", " 
     | 
| 
      
 359 
     | 
    
         
            +
                    self.addButton = NIconToolButton(self, iSz, "add", "add")
         
     | 
| 
       363 
360 
     | 
    
         
             
                    self.addButton.setToolTip(self.tr("Add Label"))
         
     | 
| 
       364 
361 
     | 
    
         
             
                    self.addButton.clicked.connect(self._onItemCreate)
         
     | 
| 
       365 
362 
     | 
    
         | 
| 
       366 
     | 
    
         
            -
                    self.delButton = NIconToolButton(self, iSz, "remove", " 
     | 
| 
      
 363 
     | 
    
         
            +
                    self.delButton = NIconToolButton(self, iSz, "remove", "remove")
         
     | 
| 
       367 
364 
     | 
    
         
             
                    self.delButton.setToolTip(self.tr("Delete Label"))
         
     | 
| 
       368 
365 
     | 
    
         
             
                    self.delButton.clicked.connect(self._onItemDelete)
         
     | 
| 
       369 
366 
     | 
    
         | 
| 
       370 
     | 
    
         
            -
                    self.upButton = NIconToolButton(self, iSz, "chevron_up", " 
     | 
| 
      
 367 
     | 
    
         
            +
                    self.upButton = NIconToolButton(self, iSz, "chevron_up", "action")
         
     | 
| 
       371 
368 
     | 
    
         
             
                    self.upButton.setToolTip(self.tr("Move Up"))
         
     | 
| 
       372 
369 
     | 
    
         
             
                    self.upButton.clicked.connect(qtLambda(self._moveItem, -1))
         
     | 
| 
       373 
370 
     | 
    
         | 
| 
       374 
     | 
    
         
            -
                    self.downButton = NIconToolButton(self, iSz, "chevron_down", " 
     | 
| 
      
 371 
     | 
    
         
            +
                    self.downButton = NIconToolButton(self, iSz, "chevron_down", "action")
         
     | 
| 
       375 
372 
     | 
    
         
             
                    self.downButton.setToolTip(self.tr("Move Down"))
         
     | 
| 
       376 
373 
     | 
    
         
             
                    self.downButton.clicked.connect(qtLambda(self._moveItem, 1))
         
     | 
| 
       377 
374 
     | 
    
         | 
| 
       378 
     | 
    
         
            -
                    self.importButton = NIconToolButton(self, iSz, "import", " 
     | 
| 
      
 375 
     | 
    
         
            +
                    self.importButton = NIconToolButton(self, iSz, "import", "apply")
         
     | 
| 
       379 
376 
     | 
    
         
             
                    self.importButton.setToolTip(self.tr("Import Labels"))
         
     | 
| 
       380 
377 
     | 
    
         
             
                    self.importButton.clicked.connect(self._importLabels)
         
     | 
| 
       381 
378 
     | 
    
         | 
| 
       382 
     | 
    
         
            -
                    self.exportButton = NIconToolButton(self, iSz, "export", " 
     | 
| 
      
 379 
     | 
    
         
            +
                    self.exportButton = NIconToolButton(self, iSz, "export", "action")
         
     | 
| 
       383 
380 
     | 
    
         
             
                    self.exportButton.setToolTip(self.tr("Export Labels"))
         
     | 
| 
       384 
381 
     | 
    
         
             
                    self.exportButton.clicked.connect(self._exportLabels)
         
     | 
| 
       385 
382 
     | 
    
         | 
| 
       386 
383 
     | 
    
         
             
                    # Edit Form
         
     | 
| 
       387 
     | 
    
         
            -
                    self. 
     | 
| 
       388 
     | 
    
         
            -
                    self. 
     | 
| 
       389 
     | 
    
         
            -
                    self. 
     | 
| 
       390 
     | 
    
         
            -
                    self. 
     | 
| 
       391 
     | 
    
         
            -
                    self. 
     | 
| 
      
 384 
     | 
    
         
            +
                    self.editName = QLineEdit(self)
         
     | 
| 
      
 385 
     | 
    
         
            +
                    self.editName.setMaxLength(40)
         
     | 
| 
      
 386 
     | 
    
         
            +
                    self.editName.setPlaceholderText(self.tr("Select item to edit"))
         
     | 
| 
      
 387 
     | 
    
         
            +
                    self.editName.setEnabled(False)
         
     | 
| 
      
 388 
     | 
    
         
            +
                    self.editName.textEdited.connect(self._onNameEdit)
         
     | 
| 
      
 389 
     | 
    
         
            +
             
     | 
| 
      
 390 
     | 
    
         
            +
                    self.labelName = QLabel(self.tr("Label"), self)
         
     | 
| 
      
 391 
     | 
    
         
            +
                    self.labelName.setBuddy(self.editName)
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
                    # Icon Colours
         
     | 
| 
      
 394 
     | 
    
         
            +
                    self.iconColor = NComboBox(self)
         
     | 
| 
      
 395 
     | 
    
         
            +
                    self.iconColor.setMinimumWidth(200)
         
     | 
| 
      
 396 
     | 
    
         
            +
                    self.iconColor.setEnabled(False)
         
     | 
| 
      
 397 
     | 
    
         
            +
                    self.iconColor.addItem(self.tr("Custom"), CUSTOM_COL)
         
     | 
| 
      
 398 
     | 
    
         
            +
                    for key, label in nwLabels.THEME_COLORS.items():
         
     | 
| 
      
 399 
     | 
    
         
            +
                        self.iconColor.addItem(trConst(label), key)
         
     | 
| 
      
 400 
     | 
    
         
            +
                    self.iconColor.currentIndexChanged.connect(self._onThemeSelect)
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                    self.labelColor = QLabel(self.tr("Colour"), self)
         
     | 
| 
      
 403 
     | 
    
         
            +
                    self.labelColor.setBuddy(self.iconColor)
         
     | 
| 
       392 
404 
     | 
    
         | 
| 
       393 
405 
     | 
    
         
             
                    buttonStyle = (
         
     | 
| 
       394 
406 
     | 
    
         
             
                        "QToolButton {padding: 0 4px;} "
         
     | 
| 
         @@ -425,6 +437,9 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       425 
437 
     | 
    
         
             
                    self.shapeButton.setStyleSheet(buttonStyle)
         
     | 
| 
       426 
438 
     | 
    
         
             
                    self.shapeButton.setEnabled(False)
         
     | 
| 
       427 
439 
     | 
    
         | 
| 
      
 440 
     | 
    
         
            +
                    self.labelShape = QLabel(self.tr("Shape"), self)
         
     | 
| 
      
 441 
     | 
    
         
            +
                    self.labelShape.setBuddy(self.iconColor)
         
     | 
| 
      
 442 
     | 
    
         
            +
             
     | 
| 
       428 
443 
     | 
    
         
             
                    # Assemble
         
     | 
| 
       429 
444 
     | 
    
         
             
                    self.listControls = QVBoxLayout()
         
     | 
| 
       430 
445 
     | 
    
         
             
                    self.listControls.addWidget(self.addButton)
         
     | 
| 
         @@ -435,10 +450,15 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       435 
450 
     | 
    
         
             
                    self.listControls.addWidget(self.importButton)
         
     | 
| 
       436 
451 
     | 
    
         
             
                    self.listControls.addWidget(self.exportButton)
         
     | 
| 
       437 
452 
     | 
    
         | 
| 
       438 
     | 
    
         
            -
                    self.editBox =  
     | 
| 
       439 
     | 
    
         
            -
                    self.editBox.addWidget(self. 
     | 
| 
       440 
     | 
    
         
            -
                    self.editBox.addWidget(self. 
     | 
| 
       441 
     | 
    
         
            -
                    self.editBox.addWidget(self. 
     | 
| 
      
 453 
     | 
    
         
            +
                    self.editBox = QGridLayout()
         
     | 
| 
      
 454 
     | 
    
         
            +
                    self.editBox.addWidget(self.labelName, 0, 0)
         
     | 
| 
      
 455 
     | 
    
         
            +
                    self.editBox.addWidget(self.editName, 0, 1, 1, 5)
         
     | 
| 
      
 456 
     | 
    
         
            +
                    self.editBox.addWidget(self.labelColor, 1, 0)
         
     | 
| 
      
 457 
     | 
    
         
            +
                    self.editBox.addWidget(self.iconColor, 1, 1)
         
     | 
| 
      
 458 
     | 
    
         
            +
                    self.editBox.addWidget(self.colorButton, 1, 2)
         
     | 
| 
      
 459 
     | 
    
         
            +
                    self.editBox.addWidget(self.labelShape, 1, 3)
         
     | 
| 
      
 460 
     | 
    
         
            +
                    self.editBox.addWidget(self.shapeButton, 1, 4)
         
     | 
| 
      
 461 
     | 
    
         
            +
                    self.editBox.setColumnStretch(5, 1)
         
     | 
| 
       442 
462 
     | 
    
         | 
| 
       443 
463 
     | 
    
         
             
                    self.innerBox = QGridLayout()
         
     | 
| 
       444 
464 
     | 
    
         
             
                    self.innerBox.addWidget(self.listBox, 0, 0)
         
     | 
| 
         @@ -454,8 +474,6 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       454 
474 
     | 
    
         
             
                    self.setCentralLayout(self.outerBox)
         
     | 
| 
       455 
475 
     | 
    
         
             
                    self._setButtonIcons()
         
     | 
| 
       456 
476 
     | 
    
         | 
| 
       457 
     | 
    
         
            -
                    return
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
477 
     | 
    
         
             
                @property
         
     | 
| 
       460 
478 
     | 
    
         
             
                def changed(self) -> bool:
         
     | 
| 
       461 
479 
     | 
    
         
             
                    """The user changed these settings."""
         
     | 
| 
         @@ -494,16 +512,22 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       494 
512 
     | 
    
         
             
                        entry.name = name
         
     | 
| 
       495 
513 
     | 
    
         
             
                        item.setText(self.C_LABEL, name)
         
     | 
| 
       496 
514 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       497 
     | 
    
         
            -
             
     | 
| 
      
 515 
     | 
    
         
            +
             
     | 
| 
      
 516 
     | 
    
         
            +
                @pyqtSlot(int)
         
     | 
| 
      
 517 
     | 
    
         
            +
                def _onThemeSelect(self, index: int) -> None:
         
     | 
| 
      
 518 
     | 
    
         
            +
                    """Update the colour handling on theme selection change."""
         
     | 
| 
      
 519 
     | 
    
         
            +
                    self._theme = str(self.iconColor.currentData())
         
     | 
| 
      
 520 
     | 
    
         
            +
                    self._setButtonIcons()
         
     | 
| 
      
 521 
     | 
    
         
            +
                    self._updateIcon()
         
     | 
| 
       498 
522 
     | 
    
         | 
| 
       499 
523 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       500 
524 
     | 
    
         
             
                def _onColorSelect(self) -> None:
         
     | 
| 
       501 
525 
     | 
    
         
             
                    """Open a dialog to select the status icon colour."""
         
     | 
| 
       502 
526 
     | 
    
         
             
                    if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
         
     | 
| 
       503 
527 
     | 
    
         
             
                        self._color = color
         
     | 
| 
      
 528 
     | 
    
         
            +
                        self._theme = CUSTOM_COL
         
     | 
| 
       504 
529 
     | 
    
         
             
                        self._setButtonIcons()
         
     | 
| 
       505 
530 
     | 
    
         
             
                        self._updateIcon()
         
     | 
| 
       506 
     | 
    
         
            -
                    return
         
     | 
| 
       507 
531 
     | 
    
         | 
| 
       508 
532 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       509 
533 
     | 
    
         
             
                def _onItemCreate(self) -> None:
         
     | 
| 
         @@ -511,9 +535,9 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       511 
535 
     | 
    
         
             
                    color = QColor(100, 100, 100)
         
     | 
| 
       512 
536 
     | 
    
         
             
                    shape = nwStatusShape.SQUARE
         
     | 
| 
       513 
537 
     | 
    
         
             
                    icon = NWStatus.createIcon(self._iPx, color, shape)
         
     | 
| 
       514 
     | 
    
         
            -
                     
     | 
| 
      
 538 
     | 
    
         
            +
                    theme = str(self.iconColor.currentData())
         
     | 
| 
      
 539 
     | 
    
         
            +
                    self._addItem(None, StatusEntry(self.tr("New Item"), color, theme, shape, icon, 0))
         
     | 
| 
       515 
540 
     | 
    
         
             
                    self._changed = True
         
     | 
| 
       516 
     | 
    
         
            -
                    return
         
     | 
| 
       517 
541 
     | 
    
         | 
| 
       518 
542 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       519 
543 
     | 
    
         
             
                def _onItemDelete(self) -> None:
         
     | 
| 
         @@ -526,7 +550,6 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       526 
550 
     | 
    
         
             
                        else:
         
     | 
| 
       527 
551 
     | 
    
         
             
                            self.listBox.takeTopLevelItem(iRow)
         
     | 
| 
       528 
552 
     | 
    
         
             
                            self._changed = True
         
     | 
| 
       529 
     | 
    
         
            -
                    return
         
     | 
| 
       530 
553 
     | 
    
         | 
| 
       531 
554 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       532 
555 
     | 
    
         
             
                def _onSelectionChanged(self) -> None:
         
     | 
| 
         @@ -537,25 +560,28 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       537 
560 
     | 
    
         
             
                        entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY)
         
     | 
| 
       538 
561 
     | 
    
         
             
                        self._color = entry.color
         
     | 
| 
       539 
562 
     | 
    
         
             
                        self._shape = entry.shape
         
     | 
| 
      
 563 
     | 
    
         
            +
                        self._theme = entry.theme
         
     | 
| 
       540 
564 
     | 
    
         
             
                        self._setButtonIcons()
         
     | 
| 
       541 
565 
     | 
    
         | 
| 
       542 
     | 
    
         
            -
                        self. 
     | 
| 
       543 
     | 
    
         
            -
                        self. 
     | 
| 
       544 
     | 
    
         
            -
                        self. 
     | 
| 
      
 566 
     | 
    
         
            +
                        self.editName.setText(entry.name)
         
     | 
| 
      
 567 
     | 
    
         
            +
                        self.editName.selectAll()
         
     | 
| 
      
 568 
     | 
    
         
            +
                        self.editName.setFocus()
         
     | 
| 
       545 
569 
     | 
    
         | 
| 
       546 
     | 
    
         
            -
                        self. 
     | 
| 
      
 570 
     | 
    
         
            +
                        self.editName.setEnabled(True)
         
     | 
| 
      
 571 
     | 
    
         
            +
                        self.iconColor.setEnabled(True)
         
     | 
| 
       547 
572 
     | 
    
         
             
                        self.colorButton.setEnabled(True)
         
     | 
| 
       548 
573 
     | 
    
         
             
                        self.shapeButton.setEnabled(True)
         
     | 
| 
       549 
574 
     | 
    
         
             
                    else:
         
     | 
| 
       550 
575 
     | 
    
         
             
                        self._color = QColor(100, 100, 100)
         
     | 
| 
       551 
576 
     | 
    
         
             
                        self._shape = nwStatusShape.SQUARE
         
     | 
| 
      
 577 
     | 
    
         
            +
                        self._theme = CUSTOM_COL
         
     | 
| 
       552 
578 
     | 
    
         
             
                        self._setButtonIcons()
         
     | 
| 
       553 
     | 
    
         
            -
                        self. 
     | 
| 
      
 579 
     | 
    
         
            +
                        self.editName.setText("")
         
     | 
| 
       554 
580 
     | 
    
         | 
| 
       555 
     | 
    
         
            -
                        self. 
     | 
| 
      
 581 
     | 
    
         
            +
                        self.editName.setEnabled(False)
         
     | 
| 
      
 582 
     | 
    
         
            +
                        self.iconColor.setEnabled(False)
         
     | 
| 
       556 
583 
     | 
    
         
             
                        self.colorButton.setEnabled(False)
         
     | 
| 
       557 
584 
     | 
    
         
             
                        self.shapeButton.setEnabled(False)
         
     | 
| 
       558 
     | 
    
         
            -
                    return
         
     | 
| 
       559 
585 
     | 
    
         | 
| 
       560 
586 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       561 
587 
     | 
    
         
             
                def _importLabels(self) -> None:
         
     | 
| 
         @@ -592,7 +618,6 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       592 
618 
     | 
    
         
             
                                        writer.writerow([entry.shape.name, entry.color.name(), entry.name])
         
     | 
| 
       593 
619 
     | 
    
         
             
                        except Exception as exc:
         
     | 
| 
       594 
620 
     | 
    
         
             
                            SHARED.error("Could not write file.", exc=exc)
         
     | 
| 
       595 
     | 
    
         
            -
                    return
         
     | 
| 
       596 
621 
     | 
    
         | 
| 
       597 
622 
     | 
    
         
             
                ##
         
     | 
| 
       598 
623 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -603,19 +628,18 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       603 
628 
     | 
    
         
             
                    self._shape = shape
         
     | 
| 
       604 
629 
     | 
    
         
             
                    self._setButtonIcons()
         
     | 
| 
       605 
630 
     | 
    
         
             
                    self._updateIcon()
         
     | 
| 
       606 
     | 
    
         
            -
                    return
         
     | 
| 
       607 
631 
     | 
    
         | 
| 
       608 
632 
     | 
    
         
             
                def _updateIcon(self) -> None:
         
     | 
| 
       609 
633 
     | 
    
         
             
                    """Apply changes made to a status icon."""
         
     | 
| 
       610 
634 
     | 
    
         
             
                    if item := self._getSelectedItem():
         
     | 
| 
       611 
     | 
    
         
            -
                        icon = NWStatus.createIcon(self._iPx, self. 
     | 
| 
      
 635 
     | 
    
         
            +
                        icon = NWStatus.createIcon(self._iPx, self._pickColor(), self._shape)
         
     | 
| 
       612 
636 
     | 
    
         
             
                        entry: StatusEntry = item.data(self.C_DATA, self.D_ENTRY)
         
     | 
| 
       613 
637 
     | 
    
         
             
                        entry.color = self._color
         
     | 
| 
       614 
638 
     | 
    
         
             
                        entry.shape = self._shape
         
     | 
| 
      
 639 
     | 
    
         
            +
                        entry.theme = self._theme
         
     | 
| 
       615 
640 
     | 
    
         
             
                        entry.icon = icon
         
     | 
| 
       616 
641 
     | 
    
         
             
                        item.setIcon(self.C_LABEL, icon)
         
     | 
| 
       617 
642 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       618 
     | 
    
         
            -
                    return
         
     | 
| 
       619 
643 
     | 
    
         | 
| 
       620 
644 
     | 
    
         
             
                def _addItem(self, key: str | None, entry: StatusEntry) -> None:
         
     | 
| 
       621 
645 
     | 
    
         
             
                    """Add a status item to the list."""
         
     | 
| 
         @@ -626,7 +650,6 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       626 
650 
     | 
    
         
             
                    item.setData(self.C_DATA, self.D_KEY, key)
         
     | 
| 
       627 
651 
     | 
    
         
             
                    item.setData(self.C_DATA, self.D_ENTRY, entry)
         
     | 
| 
       628 
652 
     | 
    
         
             
                    self.listBox.addTopLevelItem(item)
         
     | 
| 
       629 
     | 
    
         
            -
                    return
         
     | 
| 
       630 
653 
     | 
    
         | 
| 
       631 
654 
     | 
    
         
             
                def _moveItem(self, step: int) -> None:
         
     | 
| 
       632 
655 
     | 
    
         
             
                    """Move and item up or down step."""
         
     | 
| 
         @@ -639,7 +662,6 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       639 
662 
     | 
    
         
             
                            self.listBox.clearSelection()
         
     | 
| 
       640 
663 
     | 
    
         
             
                            cItem.setSelected(True)
         
     | 
| 
       641 
664 
     | 
    
         
             
                            self._changed = True
         
     | 
| 
       642 
     | 
    
         
            -
                    return
         
     | 
| 
       643 
665 
     | 
    
         | 
| 
       644 
666 
     | 
    
         
             
                def _getSelectedItem(self) -> QTreeWidgetItem | None:
         
     | 
| 
       645 
667 
     | 
    
         
             
                    """Get the currently selected item."""
         
     | 
| 
         @@ -658,10 +680,16 @@ class _StatusPage(NFixedPage): 
     | 
|
| 
       658 
680 
     | 
    
         | 
| 
       659 
681 
     | 
    
         
             
                def _setButtonIcons(self) -> None:
         
     | 
| 
       660 
682 
     | 
    
         
             
                    """Set the colour of the colour button."""
         
     | 
| 
       661 
     | 
    
         
            -
                    icon = NWStatus.createIcon(self._iPx, self. 
     | 
| 
      
 683 
     | 
    
         
            +
                    icon = NWStatus.createIcon(self._iPx, self._pickColor(), nwStatusShape.SQUARE)
         
     | 
| 
      
 684 
     | 
    
         
            +
                    self.iconColor.setCurrentData(self._theme, CUSTOM_COL)
         
     | 
| 
       662 
685 
     | 
    
         
             
                    self.colorButton.setIcon(icon)
         
     | 
| 
       663 
686 
     | 
    
         
             
                    self.shapeButton.setIcon(self._icons[self._shape])
         
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
      
 687 
     | 
    
         
            +
             
     | 
| 
      
 688 
     | 
    
         
            +
                def _pickColor(self) -> QColor:
         
     | 
| 
      
 689 
     | 
    
         
            +
                    """Get the correct colour value based on selections."""
         
     | 
| 
      
 690 
     | 
    
         
            +
                    if self._theme == CUSTOM_COL:
         
     | 
| 
      
 691 
     | 
    
         
            +
                        return self._color
         
     | 
| 
      
 692 
     | 
    
         
            +
                    return SHARED.theme.getBaseColor(self._theme)
         
     | 
| 
       665 
693 
     | 
    
         | 
| 
       666 
694 
     | 
    
         | 
| 
       667 
695 
     | 
    
         
             
            class _ReplacePage(NFixedPage):
         
     | 
| 
         @@ -701,10 +729,10 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       701 
729 
     | 
    
         
             
                    self.listBox.setSortingEnabled(True)
         
     | 
| 
       702 
730 
     | 
    
         | 
| 
       703 
731 
     | 
    
         
             
                    # List Controls
         
     | 
| 
       704 
     | 
    
         
            -
                    self.addButton = NIconToolButton(self, iSz, "add", " 
     | 
| 
      
 732 
     | 
    
         
            +
                    self.addButton = NIconToolButton(self, iSz, "add", "add")
         
     | 
| 
       705 
733 
     | 
    
         
             
                    self.addButton.clicked.connect(self._onEntryCreated)
         
     | 
| 
       706 
734 
     | 
    
         | 
| 
       707 
     | 
    
         
            -
                    self.delButton = NIconToolButton(self, iSz, "remove", " 
     | 
| 
      
 735 
     | 
    
         
            +
                    self.delButton = NIconToolButton(self, iSz, "remove", "remove")
         
     | 
| 
       708 
736 
     | 
    
         
             
                    self.delButton.clicked.connect(self._onEntryDeleted)
         
     | 
| 
       709 
737 
     | 
    
         | 
| 
       710 
738 
     | 
    
         
             
                    # Edit Form
         
     | 
| 
         @@ -743,8 +771,6 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       743 
771 
     | 
    
         | 
| 
       744 
772 
     | 
    
         
             
                    self.setCentralLayout(self.outerBox)
         
     | 
| 
       745 
773 
     | 
    
         | 
| 
       746 
     | 
    
         
            -
                    return
         
     | 
| 
       747 
     | 
    
         
            -
             
     | 
| 
       748 
774 
     | 
    
         
             
                @property
         
     | 
| 
       749 
775 
     | 
    
         
             
                def changed(self) -> bool:
         
     | 
| 
       750 
776 
     | 
    
         
             
                    """The user changed these settings."""
         
     | 
| 
         @@ -777,7 +803,6 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       777 
803 
     | 
    
         
             
                    if (item := self._getSelectedItem()) and (key := self._stripKey(text)):
         
     | 
| 
       778 
804 
     | 
    
         
             
                        item.setText(self.C_KEY, f"<{key}>")
         
     | 
| 
       779 
805 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       780 
     | 
    
         
            -
                    return
         
     | 
| 
       781 
806 
     | 
    
         | 
| 
       782 
807 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       783 
808 
     | 
    
         
             
                def _onValueEdit(self, text: str) -> None:
         
     | 
| 
         @@ -785,7 +810,6 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       785 
810 
     | 
    
         
             
                    if item := self._getSelectedItem():
         
     | 
| 
       786 
811 
     | 
    
         
             
                        item.setText(self.C_REPL, text)
         
     | 
| 
       787 
812 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       788 
     | 
    
         
            -
                    return
         
     | 
| 
       789 
813 
     | 
    
         | 
| 
       790 
814 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       791 
815 
     | 
    
         
             
                def _onSelectionChanged(self) -> None:
         
     | 
| 
         @@ -804,14 +828,12 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       804 
828 
     | 
    
         
             
                        self.editValue.setText("")
         
     | 
| 
       805 
829 
     | 
    
         
             
                        self.editKey.setEnabled(False)
         
     | 
| 
       806 
830 
     | 
    
         
             
                        self.editValue.setEnabled(False)
         
     | 
| 
       807 
     | 
    
         
            -
                    return
         
     | 
| 
       808 
831 
     | 
    
         | 
| 
       809 
832 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       810 
833 
     | 
    
         
             
                def _onEntryCreated(self) -> None:
         
     | 
| 
       811 
834 
     | 
    
         
             
                    """Add a new list entry."""
         
     | 
| 
       812 
835 
     | 
    
         
             
                    key = f"<keyword{self.listBox.topLevelItemCount() + 1:d}>"
         
     | 
| 
       813 
836 
     | 
    
         
             
                    self.listBox.addTopLevelItem(QTreeWidgetItem([key, ""]))
         
     | 
| 
       814 
     | 
    
         
            -
                    return
         
     | 
| 
       815 
837 
     | 
    
         | 
| 
       816 
838 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       817 
839 
     | 
    
         
             
                def _onEntryDeleted(self) -> None:
         
     | 
| 
         @@ -819,7 +841,6 @@ class _ReplacePage(NFixedPage): 
     | 
|
| 
       819 
841 
     | 
    
         
             
                    if item := self._getSelectedItem():
         
     | 
| 
       820 
842 
     | 
    
         
             
                        self.listBox.takeTopLevelItem(self.listBox.indexOfTopLevelItem(item))
         
     | 
| 
       821 
843 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       822 
     | 
    
         
            -
                    return
         
     | 
| 
       823 
844 
     | 
    
         | 
| 
       824 
845 
     | 
    
         
             
                ##
         
     | 
| 
       825 
846 
     | 
    
         
             
                #  Internal Functions
         
     | 
    
        novelwriter/dialogs/quotes.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
         
     | 
| 
         @@ -32,10 +32,12 @@ from PyQt6.QtWidgets import ( 
     | 
|
| 
       32 
32 
     | 
    
         
             
                QListWidgetItem, QVBoxLayout, QWidget
         
     | 
| 
       33 
33 
     | 
    
         
             
            )
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
      
 35 
     | 
    
         
            +
            from novelwriter import SHARED
         
     | 
| 
       35 
36 
     | 
    
         
             
            from novelwriter.constants import nwQuotes, trConst
         
     | 
| 
      
 37 
     | 
    
         
            +
            from novelwriter.enum import nwStandardButton
         
     | 
| 
       36 
38 
     | 
    
         
             
            from novelwriter.extensions.modified import NDialog
         
     | 
| 
       37 
39 
     | 
    
         
             
            from novelwriter.types import (
         
     | 
| 
       38 
     | 
    
         
            -
                QtAccepted, QtAlignCenter, QtAlignTop,  
     | 
| 
      
 40 
     | 
    
         
            +
                QtAccepted, QtAlignCenter, QtAlignTop, QtRoleAccept, QtRoleReject,
         
     | 
| 
       39 
41 
     | 
    
         
             
                QtUserRole
         
     | 
| 
       40 
42 
     | 
    
         
             
            )
         
     | 
| 
       41 
43 
     | 
    
         | 
| 
         @@ -43,6 +45,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       43 
45 
     | 
    
         | 
| 
       44 
46 
     | 
    
         | 
| 
       45 
47 
     | 
    
         
             
            class GuiQuoteSelect(NDialog):
         
     | 
| 
      
 48 
     | 
    
         
            +
                """GUI: Quote Selector Dialog."""
         
     | 
| 
       46 
49 
     | 
    
         | 
| 
       47 
50 
     | 
    
         
             
                _selected = ""
         
     | 
| 
       48 
51 
     | 
    
         | 
| 
         @@ -90,9 +93,15 @@ class GuiQuoteSelect(NDialog): 
     | 
|
| 
       90 
93 
     | 
    
         
             
                    self.listBox.setMinimumHeight(150)
         
     | 
| 
       91 
94 
     | 
    
         | 
| 
       92 
95 
     | 
    
         
             
                    # Buttons
         
     | 
| 
       93 
     | 
    
         
            -
                    self. 
     | 
| 
       94 
     | 
    
         
            -
                    self. 
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
      
 96 
     | 
    
         
            +
                    self.btnOk = SHARED.theme.getStandardButton(nwStandardButton.OK, self)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    self.btnOk.clicked.connect(self.accept)
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                    self.btnCancel = SHARED.theme.getStandardButton(nwStandardButton.CANCEL, self)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    self.btnCancel.clicked.connect(self.reject)
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    self.btnBox = QDialogButtonBox(self)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnOk, QtRoleAccept)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnCancel, QtRoleReject)
         
     | 
| 
       96 
105 
     | 
    
         | 
| 
       97 
106 
     | 
    
         
             
                    # Assemble
         
     | 
| 
       98 
107 
     | 
    
         
             
                    self.labelBox.addWidget(self.previewLabel, 0, QtAlignTop)
         
     | 
| 
         @@ -102,17 +111,14 @@ class GuiQuoteSelect(NDialog): 
     | 
|
| 
       102 
111 
     | 
    
         
             
                    self.innerBox.addWidget(self.listBox)
         
     | 
| 
       103 
112 
     | 
    
         | 
| 
       104 
113 
     | 
    
         
             
                    self.outerBox.addLayout(self.innerBox)
         
     | 
| 
       105 
     | 
    
         
            -
                    self.outerBox.addWidget(self. 
     | 
| 
      
 114 
     | 
    
         
            +
                    self.outerBox.addWidget(self.btnBox)
         
     | 
| 
       106 
115 
     | 
    
         | 
| 
       107 
116 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
       108 
117 
     | 
    
         | 
| 
       109 
118 
     | 
    
         
             
                    logger.debug("Ready: GuiQuoteSelect")
         
     | 
| 
       110 
119 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                    return
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
120 
     | 
    
         
             
                def __del__(self) -> None:  # pragma: no cover
         
     | 
| 
       114 
121 
     | 
    
         
             
                    logger.debug("Delete: GuiQuoteSelect")
         
     | 
| 
       115 
     | 
    
         
            -
                    return
         
     | 
| 
       116 
122 
     | 
    
         | 
| 
       117 
123 
     | 
    
         
             
                @property
         
     | 
| 
       118 
124 
     | 
    
         
             
                def selectedQuote(self) -> str:
         
     | 
| 
         @@ -140,4 +146,3 @@ class GuiQuoteSelect(NDialog): 
     | 
|
| 
       140 
146 
     | 
    
         
             
                        quote = items[0].data(self.D_KEY)
         
     | 
| 
       141 
147 
     | 
    
         
             
                        self.previewLabel.setText(quote)
         
     | 
| 
       142 
148 
     | 
    
         
             
                        self._selected = quote
         
     | 
| 
       143 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/dialogs/wordlist.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
         
     | 
| 
         @@ -37,9 +37,10 @@ from PyQt6.QtWidgets import ( 
     | 
|
| 
       37 
37 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
       38 
38 
     | 
    
         
             
            from novelwriter.common import formatFileFilter
         
     | 
| 
       39 
39 
     | 
    
         
             
            from novelwriter.core.spellcheck import UserDictionary
         
     | 
| 
      
 40 
     | 
    
         
            +
            from novelwriter.enum import nwStandardButton
         
     | 
| 
       40 
41 
     | 
    
         
             
            from novelwriter.extensions.configlayout import NColorLabel
         
     | 
| 
       41 
42 
     | 
    
         
             
            from novelwriter.extensions.modified import NDialog, NIconToolButton
         
     | 
| 
       42 
     | 
    
         
            -
            from novelwriter.types import  
     | 
| 
      
 43 
     | 
    
         
            +
            from novelwriter.types import QtRoleAccept, QtRoleDestruct
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
       44 
45 
     | 
    
         
             
            if TYPE_CHECKING:
         
     | 
| 
       45 
46 
     | 
    
         
             
                from PyQt6.QtGui import QCloseEvent
         
     | 
| 
         @@ -48,6 +49,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       48 
49 
     | 
    
         | 
| 
       49 
50 
     | 
    
         | 
| 
       50 
51 
     | 
    
         
             
            class GuiWordList(NDialog):
         
     | 
| 
      
 52 
     | 
    
         
            +
                """GUI: User Dictionary Edit Tool."""
         
     | 
| 
       51 
53 
     | 
    
         | 
| 
       52 
54 
     | 
    
         
             
                newWordListReady = pyqtSignal()
         
     | 
| 
       53 
55 
     | 
    
         | 
| 
         @@ -73,11 +75,11 @@ class GuiWordList(NDialog): 
     | 
|
| 
       73 
75 
     | 
    
         
             
                        scale=NColorLabel.HEADER_SCALE
         
     | 
| 
       74 
76 
     | 
    
         
             
                    )
         
     | 
| 
       75 
77 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                    self.importButton = NIconToolButton(self, iSz, "import", " 
     | 
| 
      
 78 
     | 
    
         
            +
                    self.importButton = NIconToolButton(self, iSz, "import", "apply")
         
     | 
| 
       77 
79 
     | 
    
         
             
                    self.importButton.setToolTip(self.tr("Import words from text file"))
         
     | 
| 
       78 
80 
     | 
    
         
             
                    self.importButton.clicked.connect(self._importWords)
         
     | 
| 
       79 
81 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                    self.exportButton = NIconToolButton(self, iSz, "export", " 
     | 
| 
      
 82 
     | 
    
         
            +
                    self.exportButton = NIconToolButton(self, iSz, "export", "action")
         
     | 
| 
       81 
83 
     | 
    
         
             
                    self.exportButton.setToolTip(self.tr("Export words to text file"))
         
     | 
| 
       82 
84 
     | 
    
         
             
                    self.exportButton.clicked.connect(self._exportWords)
         
     | 
| 
       83 
85 
     | 
    
         | 
| 
         @@ -95,11 +97,11 @@ class GuiWordList(NDialog): 
     | 
|
| 
       95 
97 
     | 
    
         
             
                    # Add/Remove Form
         
     | 
| 
       96 
98 
     | 
    
         
             
                    self.newEntry = QLineEdit(self)
         
     | 
| 
       97 
99 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
                    self.addButton = NIconToolButton(self, iSz, "add", " 
     | 
| 
      
 100 
     | 
    
         
            +
                    self.addButton = NIconToolButton(self, iSz, "add", "add")
         
     | 
| 
       99 
101 
     | 
    
         
             
                    self.addButton.setToolTip(self.tr("Add Word"))
         
     | 
| 
       100 
102 
     | 
    
         
             
                    self.addButton.clicked.connect(self._doAdd)
         
     | 
| 
       101 
103 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
                    self.delButton = NIconToolButton(self, iSz, "remove", " 
     | 
| 
      
 104 
     | 
    
         
            +
                    self.delButton = NIconToolButton(self, iSz, "remove", "remove")
         
     | 
| 
       103 
105 
     | 
    
         
             
                    self.delButton.setToolTip(self.tr("Remove Word"))
         
     | 
| 
       104 
106 
     | 
    
         
             
                    self.delButton.clicked.connect(self._doDelete)
         
     | 
| 
       105 
107 
     | 
    
         | 
| 
         @@ -109,9 +111,15 @@ class GuiWordList(NDialog): 
     | 
|
| 
       109 
111 
     | 
    
         
             
                    self.editBox.addWidget(self.delButton, 0)
         
     | 
| 
       110 
112 
     | 
    
         | 
| 
       111 
113 
     | 
    
         
             
                    # Buttons
         
     | 
| 
       112 
     | 
    
         
            -
                    self. 
     | 
| 
       113 
     | 
    
         
            -
                    self. 
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
      
 114 
     | 
    
         
            +
                    self.btnSave = SHARED.theme.getStandardButton(nwStandardButton.SAVE, self)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    self.btnSave.clicked.connect(self._doSave)
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                    self.btnClose = SHARED.theme.getStandardButton(nwStandardButton.CLOSE, self)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    self.btnClose.clicked.connect(self.reject)
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                    self.btnBox = QDialogButtonBox(self)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnSave, QtRoleAccept)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    self.btnBox.addButton(self.btnClose, QtRoleDestruct)
         
     | 
| 
       115 
123 
     | 
    
         | 
| 
       116 
124 
     | 
    
         
             
                    # Assemble
         
     | 
| 
       117 
125 
     | 
    
         
             
                    self.outerBox = QVBoxLayout()
         
     | 
| 
         @@ -119,7 +127,7 @@ class GuiWordList(NDialog): 
     | 
|
| 
       119 
127 
     | 
    
         
             
                    self.outerBox.addWidget(self.listBox, 1)
         
     | 
| 
       120 
128 
     | 
    
         
             
                    self.outerBox.addLayout(self.editBox, 0)
         
     | 
| 
       121 
129 
     | 
    
         
             
                    self.outerBox.addSpacing(12)
         
     | 
| 
       122 
     | 
    
         
            -
                    self.outerBox.addWidget(self. 
     | 
| 
      
 130 
     | 
    
         
            +
                    self.outerBox.addWidget(self.btnBox, 0)
         
     | 
| 
       123 
131 
     | 
    
         
             
                    self.outerBox.setSpacing(4)
         
     | 
| 
       124 
132 
     | 
    
         | 
| 
       125 
133 
     | 
    
         
             
                    self.setLayout(self.outerBox)
         
     | 
| 
         @@ -128,11 +136,8 @@ class GuiWordList(NDialog): 
     | 
|
| 
       128 
136 
     | 
    
         | 
| 
       129 
137 
     | 
    
         
             
                    logger.debug("Ready: GuiWordList")
         
     | 
| 
       130 
138 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                    return
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
139 
     | 
    
         
             
                def __del__(self) -> None:  # pragma: no cover
         
     | 
| 
       134 
140 
     | 
    
         
             
                    logger.debug("Delete: GuiWordList")
         
     | 
| 
       135 
     | 
    
         
            -
                    return
         
     | 
| 
       136 
141 
     | 
    
         | 
| 
       137 
142 
     | 
    
         
             
                ##
         
     | 
| 
       138 
143 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -143,7 +148,6 @@ class GuiWordList(NDialog): 
     | 
|
| 
       143 
148 
     | 
    
         
             
                    self._saveGuiSettings()
         
     | 
| 
       144 
149 
     | 
    
         
             
                    event.accept()
         
     | 
| 
       145 
150 
     | 
    
         
             
                    self.softDelete()
         
     | 
| 
       146 
     | 
    
         
            -
                    return
         
     | 
| 
       147 
151 
     | 
    
         | 
| 
       148 
152 
     | 
    
         
             
                ##
         
     | 
| 
       149 
153 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -159,14 +163,12 @@ class GuiWordList(NDialog): 
     | 
|
| 
       159 
163 
     | 
    
         
             
                    if items := self.listBox.findItems(word, Qt.MatchFlag.MatchExactly):
         
     | 
| 
       160 
164 
     | 
    
         
             
                        self.listBox.setCurrentItem(items[0])
         
     | 
| 
       161 
165 
     | 
    
         
             
                        self.listBox.scrollToItem(items[0], QAbstractItemView.ScrollHint.PositionAtCenter)
         
     | 
| 
       162 
     | 
    
         
            -
                    return
         
     | 
| 
       163 
166 
     | 
    
         | 
| 
       164 
167 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       165 
168 
     | 
    
         
             
                def _doDelete(self) -> None:
         
     | 
| 
       166 
169 
     | 
    
         
             
                    """Delete the selected items."""
         
     | 
| 
       167 
170 
     | 
    
         
             
                    for item in self.listBox.selectedItems():
         
     | 
| 
       168 
171 
     | 
    
         
             
                        self.listBox.takeItem(self.listBox.row(item))
         
     | 
| 
       169 
     | 
    
         
            -
                    return
         
     | 
| 
       170 
172 
     | 
    
         | 
| 
       171 
173 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       172 
174 
     | 
    
         
             
                def _doSave(self) -> None:
         
     | 
| 
         @@ -178,7 +180,6 @@ class GuiWordList(NDialog): 
     | 
|
| 
       178 
180 
     | 
    
         
             
                    self.newWordListReady.emit()
         
     | 
| 
       179 
181 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       180 
182 
     | 
    
         
             
                    self.close()
         
     | 
| 
       181 
     | 
    
         
            -
                    return
         
     | 
| 
       182 
183 
     | 
    
         | 
| 
       183 
184 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       184 
185 
     | 
    
         
             
                def _importWords(self) -> None:
         
     | 
| 
         @@ -213,7 +214,6 @@ class GuiWordList(NDialog): 
     | 
|
| 
       213 
214 
     | 
    
         
             
                                fo.write("\n".join(self._listWords()))
         
     | 
| 
       214 
215 
     | 
    
         
             
                        except Exception as exc:
         
     | 
| 
       215 
216 
     | 
    
         
             
                            SHARED.error("Could not write file.", exc=exc)
         
     | 
| 
       216 
     | 
    
         
            -
                    return
         
     | 
| 
       217 
217 
     | 
    
         | 
| 
       218 
218 
     | 
    
         
             
                ##
         
     | 
| 
       219 
219 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -226,7 +226,6 @@ class GuiWordList(NDialog): 
     | 
|
| 
       226 
226 
     | 
    
         
             
                    self.listBox.clear()
         
     | 
| 
       227 
227 
     | 
    
         
             
                    for word in userDict:
         
     | 
| 
       228 
228 
     | 
    
         
             
                        self.listBox.addItem(word)
         
     | 
| 
       229 
     | 
    
         
            -
                    return
         
     | 
| 
       230 
229 
     | 
    
         | 
| 
       231 
230 
     | 
    
         
             
                def _saveGuiSettings(self) -> None:
         
     | 
| 
       232 
231 
     | 
    
         
             
                    """Save GUI settings."""
         
     | 
| 
         @@ -234,14 +233,12 @@ class GuiWordList(NDialog): 
     | 
|
| 
       234 
233 
     | 
    
         
             
                    pOptions = SHARED.project.options
         
     | 
| 
       235 
234 
     | 
    
         
             
                    pOptions.setValue("GuiWordList", "winWidth",  self.width())
         
     | 
| 
       236 
235 
     | 
    
         
             
                    pOptions.setValue("GuiWordList", "winHeight", self.height())
         
     | 
| 
       237 
     | 
    
         
            -
                    return
         
     | 
| 
       238 
236 
     | 
    
         | 
| 
       239 
237 
     | 
    
         
             
                def _addWord(self, word: str) -> None:
         
     | 
| 
       240 
238 
     | 
    
         
             
                    """Add a single word to the list."""
         
     | 
| 
       241 
239 
     | 
    
         
             
                    if word and not self.listBox.findItems(word, Qt.MatchFlag.MatchExactly):
         
     | 
| 
       242 
240 
     | 
    
         
             
                        self.listBox.addItem(word)
         
     | 
| 
       243 
241 
     | 
    
         
             
                        self._changed = True
         
     | 
| 
       244 
     | 
    
         
            -
                    return
         
     | 
| 
       245 
242 
     | 
    
         | 
| 
       246 
243 
     | 
    
         
             
                def _listWords(self) -> list[str]:
         
     | 
| 
       247 
244 
     | 
    
         
             
                    """List all words in the list box."""
         
     |