novelWriter 2.7.5__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 +160 -225
 - 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 +23 -13
 - {novelwriter-2.7.5.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.5.dist-info/RECORD +0 -163
 - {novelwriter-2.7.5.dist-info → novelwriter-2.8b1.dist-info}/WHEEL +0 -0
 - {novelwriter-2.7.5.dist-info → novelwriter-2.8b1.dist-info}/entry_points.txt +0 -0
 - {novelwriter-2.7.5.dist-info → novelwriter-2.8b1.dist-info}/licenses/LICENSE.md +0 -0
 - {novelwriter-2.7.5.dist-info → novelwriter-2.8b1.dist-info}/licenses/setup/LICENSE-Apache-2.0.txt +0 -0
 - {novelwriter-2.7.5.dist-info → novelwriter-2.8b1.dist-info}/top_level.txt +0 -0
 
| 
         @@ -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
         
     | 
| 
         @@ -49,6 +49,10 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
51 
     | 
    
         
             
            class GuiDocViewerPanel(QWidget):
         
     | 
| 
      
 52 
     | 
    
         
            +
                """GUI: Document Viewer Panel.
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                The panel of project meta data below the viewer.
         
     | 
| 
      
 55 
     | 
    
         
            +
                """
         
     | 
| 
       52 
56 
     | 
    
         | 
| 
       53 
57 
     | 
    
         
             
                openDocumentRequest = pyqtSignal(str, Enum, str, bool)
         
     | 
| 
       54 
58 
     | 
    
         
             
                loadDocumentTagRequest = pyqtSignal(str, Enum)
         
     | 
| 
         @@ -96,15 +100,15 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       96 
100 
     | 
    
         | 
| 
       97 
101 
     | 
    
         
             
                    logger.debug("Ready: GuiDocViewerPanel")
         
     | 
| 
       98 
102 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                    return
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
103 
     | 
    
         
             
                ##
         
     | 
| 
       102 
104 
     | 
    
         
             
                #  Methods
         
     | 
| 
       103 
105 
     | 
    
         
             
                ##
         
     | 
| 
       104 
106 
     | 
    
         | 
| 
       105 
107 
     | 
    
         
             
                def updateTheme(self, updateTabs: bool = True) -> None:
         
     | 
| 
       106 
108 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
       107 
     | 
    
         
            -
                     
     | 
| 
      
 109 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocViewerPanel")
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                    self.optsButton.setThemeIcon("more_vertical", "default")
         
     | 
| 
       108 
112 
     | 
    
         
             
                    self.optsButton.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON))
         
     | 
| 
       109 
113 
     | 
    
         
             
                    self.mainTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
         
     | 
| 
       110 
114 
     | 
    
         
             
                    if updateTabs:
         
     | 
| 
         @@ -113,7 +117,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       113 
117 
     | 
    
         
             
                        for tab in self.kwTabs.values():
         
     | 
| 
       114 
118 
     | 
    
         
             
                            tab.updateTheme()
         
     | 
| 
       115 
119 
     | 
    
         
             
                        self._loadAllTags()
         
     | 
| 
       116 
     | 
    
         
            -
                    return
         
     | 
| 
       117 
120 
     | 
    
         | 
| 
       118 
121 
     | 
    
         
             
                def openProjectTasks(self) -> None:
         
     | 
| 
       119 
122 
     | 
    
         
             
                    """Run open project tasks."""
         
     | 
| 
         @@ -124,7 +127,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       124 
127 
     | 
    
         
             
                        for key, value in colWidths.items():
         
     | 
| 
       125 
128 
     | 
    
         
             
                            if key in self.kwTabs and isinstance(value, list):
         
     | 
| 
       126 
129 
     | 
    
         
             
                                self.kwTabs[key].setColumnWidths(value)
         
     | 
| 
       127 
     | 
    
         
            -
                    return
         
     | 
| 
       128 
130 
     | 
    
         | 
| 
       129 
131 
     | 
    
         
             
                def closeProjectTasks(self) -> None:
         
     | 
| 
       130 
132 
     | 
    
         
             
                    """Run close project tasks."""
         
     | 
| 
         @@ -133,7 +135,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       133 
135 
     | 
    
         
             
                    hideInactive = self.aInactive.isChecked()
         
     | 
| 
       134 
136 
     | 
    
         
             
                    SHARED.project.options.setValue("GuiDocViewerPanel", "colWidths", colWidths)
         
     | 
| 
       135 
137 
     | 
    
         
             
                    SHARED.project.options.setValue("GuiDocViewerPanel", "hideInactive", hideInactive)
         
     | 
| 
       136 
     | 
    
         
            -
                    return
         
     | 
| 
       137 
138 
     | 
    
         | 
| 
       138 
139 
     | 
    
         
             
                ##
         
     | 
| 
       139 
140 
     | 
    
         
             
                #  Public Slots
         
     | 
| 
         @@ -145,7 +146,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       145 
146 
     | 
    
         
             
                    self.tabBackRefs.clearContent()
         
     | 
| 
       146 
147 
     | 
    
         
             
                    for cTab in self.kwTabs.values():
         
     | 
| 
       147 
148 
     | 
    
         
             
                        cTab.clearContent()
         
     | 
| 
       148 
     | 
    
         
            -
                    return
         
     | 
| 
       149 
149 
     | 
    
         | 
| 
       150 
150 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       151 
151 
     | 
    
         
             
                def indexHasAppeared(self) -> None:
         
     | 
| 
         @@ -153,7 +153,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       153 
153 
     | 
    
         
             
                    self._loadAllTags()
         
     | 
| 
       154 
154 
     | 
    
         
             
                    self._updateTabVisibility()
         
     | 
| 
       155 
155 
     | 
    
         
             
                    self.updateHandle(self._lastHandle)
         
     | 
| 
       156 
     | 
    
         
            -
                    return
         
     | 
| 
       157 
156 
     | 
    
         | 
| 
       158 
157 
     | 
    
         
             
                @pyqtSlot(str, Enum)
         
     | 
| 
       159 
158 
     | 
    
         
             
                def onProjectItemChanged(self, tHandle: str, change: nwChange) -> None:
         
     | 
| 
         @@ -168,14 +167,12 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       168 
167 
     | 
    
         
             
                            else:
         
     | 
| 
       169 
168 
     | 
    
         
             
                                self.kwTabs[tClass].removeEntry(key)
         
     | 
| 
       170 
169 
     | 
    
         
             
                    self._updateTabVisibility()
         
     | 
| 
       171 
     | 
    
         
            -
                    return
         
     | 
| 
       172 
170 
     | 
    
         | 
| 
       173 
171 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       174 
172 
     | 
    
         
             
                def updateHandle(self, tHandle: str | None) -> None:
         
     | 
| 
       175 
173 
     | 
    
         
             
                    """Update the document handle."""
         
     | 
| 
       176 
174 
     | 
    
         
             
                    self._lastHandle = tHandle
         
     | 
| 
       177 
175 
     | 
    
         
             
                    self.tabBackRefs.refreshContent(tHandle or None)
         
     | 
| 
       178 
     | 
    
         
            -
                    return
         
     | 
| 
       179 
176 
     | 
    
         | 
| 
       180 
177 
     | 
    
         
             
                @pyqtSlot(list, list)
         
     | 
| 
       181 
178 
     | 
    
         
             
                def updateChangedTags(self, updated: list[str], deleted: list[str]) -> None:
         
     | 
| 
         @@ -191,14 +188,12 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       191 
188 
     | 
    
         
             
                        else:
         
     | 
| 
       192 
189 
     | 
    
         
             
                            logger.warning("Could not remove tag '%s' from view panel", key)
         
     | 
| 
       193 
190 
     | 
    
         
             
                    self._updateTabVisibility()
         
     | 
| 
       194 
     | 
    
         
            -
                    return
         
     | 
| 
       195 
191 
     | 
    
         | 
| 
       196 
192 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       197 
193 
     | 
    
         
             
                def updateStatusLabels(self, kind: str) -> None:
         
     | 
| 
       198 
194 
     | 
    
         
             
                    """Update the importance labels."""
         
     | 
| 
       199 
195 
     | 
    
         
             
                    if kind == "i":
         
     | 
| 
       200 
196 
     | 
    
         
             
                        self._loadAllTags()
         
     | 
| 
       201 
     | 
    
         
            -
                    return
         
     | 
| 
       202 
197 
     | 
    
         | 
| 
       203 
198 
     | 
    
         
             
                ##
         
     | 
| 
       204 
199 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -212,7 +207,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       212 
207 
     | 
    
         
             
                        cTab.clearContent()
         
     | 
| 
       213 
208 
     | 
    
         
             
                    self._loadAllTags()
         
     | 
| 
       214 
209 
     | 
    
         
             
                    self._updateTabVisibility()
         
     | 
| 
       215 
     | 
    
         
            -
                    return
         
     | 
| 
       216 
210 
     | 
    
         | 
| 
       217 
211 
     | 
    
         
             
                ##
         
     | 
| 
       218 
212 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -222,7 +216,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       222 
216 
     | 
    
         
             
                    """Hide class tabs with no content."""
         
     | 
| 
       223 
217 
     | 
    
         
             
                    for tClass, cTab in self.kwTabs.items():
         
     | 
| 
       224 
218 
     | 
    
         
             
                        self.mainTabs.setTabVisible(self.idTabs[tClass], cTab.countEntries() > 0)
         
     | 
| 
       225 
     | 
    
         
            -
                    return
         
     | 
| 
       226 
219 
     | 
    
         | 
| 
       227 
220 
     | 
    
         
             
                def _loadAllTags(self) -> None:
         
     | 
| 
       228 
221 
     | 
    
         
             
                    """Load all tags into the tabs."""
         
     | 
| 
         @@ -230,7 +223,6 @@ class GuiDocViewerPanel(QWidget): 
     | 
|
| 
       230 
223 
     | 
    
         
             
                    for key, name, tClass, iItem, hItem in data:
         
     | 
| 
       231 
224 
     | 
    
         
             
                        if tClass in self.kwTabs and iItem and hItem:
         
     | 
| 
       232 
225 
     | 
    
         
             
                            self.kwTabs[tClass].addUpdateEntry(key, name, iItem, hItem)
         
     | 
| 
       233 
     | 
    
         
            -
                    return
         
     | 
| 
       234 
226 
     | 
    
         | 
| 
       235 
227 
     | 
    
         | 
| 
       236 
228 
     | 
    
         
             
            class _ViewPanelBackRefs(QTreeWidget):
         
     | 
| 
         @@ -271,30 +263,28 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       271 
263 
     | 
    
         
             
                        header.setSectionsMovable(False)
         
     | 
| 
       272 
264 
     | 
    
         | 
| 
       273 
265 
     | 
    
         
             
                    # Cache Icons Locally
         
     | 
| 
       274 
     | 
    
         
            -
                    self._editIcon = SHARED.theme.getIcon("edit", " 
     | 
| 
       275 
     | 
    
         
            -
                    self._viewIcon = SHARED.theme.getIcon("view", " 
     | 
| 
      
 266 
     | 
    
         
            +
                    self._editIcon = SHARED.theme.getIcon("edit", "change")
         
     | 
| 
      
 267 
     | 
    
         
            +
                    self._viewIcon = SHARED.theme.getIcon("view", "action")
         
     | 
| 
       276 
268 
     | 
    
         | 
| 
       277 
269 
     | 
    
         
             
                    # Signals
         
     | 
| 
       278 
270 
     | 
    
         
             
                    self.clicked.connect(self._treeItemClicked)
         
     | 
| 
       279 
271 
     | 
    
         
             
                    self.doubleClicked.connect(self._treeItemDoubleClicked)
         
     | 
| 
       280 
272 
     | 
    
         | 
| 
       281 
     | 
    
         
            -
                    return
         
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
       283 
273 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       284 
274 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
       285 
     | 
    
         
            -
                     
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
      
 275 
     | 
    
         
            +
                    logger.debug("Theme Update: _ViewPanelBackRefs")
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                    self._editIcon = SHARED.theme.getIcon("edit", "change")
         
     | 
| 
      
 278 
     | 
    
         
            +
                    self._viewIcon = SHARED.theme.getIcon("view", "action")
         
     | 
| 
       287 
279 
     | 
    
         
             
                    for i in range(self.topLevelItemCount()):
         
     | 
| 
       288 
280 
     | 
    
         
             
                        if item := self.topLevelItem(i):
         
     | 
| 
       289 
281 
     | 
    
         
             
                            item.setIcon(self.C_EDIT, self._editIcon)
         
     | 
| 
       290 
282 
     | 
    
         
             
                            item.setIcon(self.C_VIEW, self._viewIcon)
         
     | 
| 
       291 
     | 
    
         
            -
                    return
         
     | 
| 
       292 
283 
     | 
    
         | 
| 
       293 
284 
     | 
    
         
             
                def clearContent(self) -> None:
         
     | 
| 
       294 
285 
     | 
    
         
             
                    """Clear the widget."""
         
     | 
| 
       295 
286 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       296 
287 
     | 
    
         
             
                    self._treeMap = {}
         
     | 
| 
       297 
     | 
    
         
            -
                    return
         
     | 
| 
       298 
288 
     | 
    
         | 
| 
       299 
289 
     | 
    
         
             
                def refreshContent(self, dHandle: str | None) -> None:
         
     | 
| 
       300 
290 
     | 
    
         
             
                    """Update the content."""
         
     | 
| 
         @@ -303,7 +293,6 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       303 
293 
     | 
    
         
             
                        refs = SHARED.project.index.getBackReferenceList(dHandle)
         
     | 
| 
       304 
294 
     | 
    
         
             
                        for tHandle, (sTitle, hItem) in refs.items():
         
     | 
| 
       305 
295 
     | 
    
         
             
                            self._setTreeItemValues(tHandle, sTitle, hItem)
         
     | 
| 
       306 
     | 
    
         
            -
                    return
         
     | 
| 
       307 
296 
     | 
    
         | 
| 
       308 
297 
     | 
    
         
             
                def refreshDocument(self, tHandle: str) -> None:
         
     | 
| 
       309 
298 
     | 
    
         
             
                    """Refresh document meta data."""
         
     | 
| 
         @@ -311,7 +300,6 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       311 
300 
     | 
    
         
             
                        for sTitle, hItem in iItem.items():
         
     | 
| 
       312 
301 
     | 
    
         
             
                            if f"{tHandle}:{sTitle}" in self._treeMap:
         
     | 
| 
       313 
302 
     | 
    
         
             
                                self._setTreeItemValues(tHandle, sTitle, hItem)
         
     | 
| 
       314 
     | 
    
         
            -
                    return
         
     | 
| 
       315 
303 
     | 
    
         | 
| 
       316 
304 
     | 
    
         
             
                ##
         
     | 
| 
       317 
305 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -325,7 +313,6 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       325 
313 
     | 
    
         
             
                        self._parent.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, "", True)
         
     | 
| 
       326 
314 
     | 
    
         
             
                    elif index.column() == self.C_VIEW:
         
     | 
| 
       327 
315 
     | 
    
         
             
                        self._parent.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, "", True)
         
     | 
| 
       328 
     | 
    
         
            -
                    return
         
     | 
| 
       329 
316 
     | 
    
         | 
| 
       330 
317 
     | 
    
         
             
                @pyqtSlot("QModelIndex")
         
     | 
| 
       331 
318 
     | 
    
         
             
                def _treeItemDoubleClicked(self, index: QModelIndex) -> None:
         
     | 
| 
         @@ -333,7 +320,6 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       333 
320 
     | 
    
         
             
                    tHandle = index.siblingAtColumn(self.C_DATA).data(self.D_HANDLE)
         
     | 
| 
       334 
321 
     | 
    
         
             
                    if index.column() not in (self.C_EDIT, self.C_VIEW):
         
     | 
| 
       335 
322 
     | 
    
         
             
                        self._parent.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, "", True)
         
     | 
| 
       336 
     | 
    
         
            -
                    return
         
     | 
| 
       337 
323 
     | 
    
         | 
| 
       338 
324 
     | 
    
         
             
                ##
         
     | 
| 
       339 
325 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -362,8 +348,6 @@ class _ViewPanelBackRefs(QTreeWidget): 
     | 
|
| 
       362 
348 
     | 
    
         
             
                            self.addTopLevelItem(trItem)
         
     | 
| 
       363 
349 
     | 
    
         
             
                            self._treeMap[tKey] = trItem
         
     | 
| 
       364 
350 
     | 
    
         | 
| 
       365 
     | 
    
         
            -
                    return
         
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
       367 
351 
     | 
    
         | 
| 
       368 
352 
     | 
    
         
             
            class _ViewPanelKeyWords(QTreeWidget):
         
     | 
| 
       369 
353 
     | 
    
         | 
| 
         @@ -418,14 +402,13 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       418 
402 
     | 
    
         
             
                    self.clicked.connect(self._treeItemClicked)
         
     | 
| 
       419 
403 
     | 
    
         
             
                    self.doubleClicked.connect(self._treeItemDoubleClicked)
         
     | 
| 
       420 
404 
     | 
    
         | 
| 
       421 
     | 
    
         
            -
                    return
         
     | 
| 
       422 
     | 
    
         
            -
             
     | 
| 
       423 
405 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       424 
406 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
      
 407 
     | 
    
         
            +
                    logger.debug("Theme Update: _ViewPanelKeyWords")
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
       425 
409 
     | 
    
         
             
                    self._classIcon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[self._class], "root")
         
     | 
| 
       426 
     | 
    
         
            -
                    self._editIcon = SHARED.theme.getIcon("edit", " 
     | 
| 
       427 
     | 
    
         
            -
                    self._viewIcon = SHARED.theme.getIcon("view", " 
     | 
| 
       428 
     | 
    
         
            -
                    return
         
     | 
| 
      
 410 
     | 
    
         
            +
                    self._editIcon = SHARED.theme.getIcon("edit", "change")
         
     | 
| 
      
 411 
     | 
    
         
            +
                    self._viewIcon = SHARED.theme.getIcon("view", "action")
         
     | 
| 
       429 
412 
     | 
    
         | 
| 
       430 
413 
     | 
    
         
             
                def countEntries(self) -> int:
         
     | 
| 
       431 
414 
     | 
    
         
             
                    """Return the number of items in the list."""
         
     | 
| 
         @@ -435,7 +418,6 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       435 
418 
     | 
    
         
             
                    """Clear the list."""
         
     | 
| 
       436 
419 
     | 
    
         
             
                    self._treeMap = {}
         
     | 
| 
       437 
420 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       438 
     | 
    
         
            -
                    return
         
     | 
| 
       439 
421 
     | 
    
         | 
| 
       440 
422 
     | 
    
         
             
                def addUpdateEntry(self, tag: str, name: str, iItem: IndexNode, hItem: IndexHeading) -> None:
         
     | 
| 
       441 
423 
     | 
    
         
             
                    """Add a new entry, or update an existing one."""
         
     | 
| 
         @@ -470,8 +452,6 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       470 
452 
     | 
    
         
             
                        self.addTopLevelItem(trItem)
         
     | 
| 
       471 
453 
     | 
    
         
             
                        self._treeMap[tag] = trItem
         
     | 
| 
       472 
454 
     | 
    
         | 
| 
       473 
     | 
    
         
            -
                    return
         
     | 
| 
       474 
     | 
    
         
            -
             
     | 
| 
       475 
455 
     | 
    
         
             
                def removeEntry(self, tag: str) -> bool:
         
     | 
| 
       476 
456 
     | 
    
         
             
                    """Remove a tag from the list."""
         
     | 
| 
       477 
457 
     | 
    
         
             
                    if tag in self._treeMap:
         
     | 
| 
         @@ -487,7 +467,6 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       487 
467 
     | 
    
         
             
                        self.setColumnWidth(self.C_IMPORT, checkInt(widths[1], 100))
         
     | 
| 
       488 
468 
     | 
    
         
             
                        self.setColumnWidth(self.C_DOC,    checkInt(widths[2], 100))
         
     | 
| 
       489 
469 
     | 
    
         
             
                        self.setColumnWidth(self.C_TITLE,  checkInt(widths[3], 100))
         
     | 
| 
       490 
     | 
    
         
            -
                    return
         
     | 
| 
       491 
470 
     | 
    
         | 
| 
       492 
471 
     | 
    
         
             
                def getColumnWidths(self) -> list[int]:
         
     | 
| 
       493 
472 
     | 
    
         
             
                    """Get the widths of the user-adjustable columns."""
         
     | 
| 
         @@ -510,7 +489,6 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       510 
489 
     | 
    
         
             
                        self._parent.loadDocumentTagRequest.emit(tag, nwDocMode.EDIT)
         
     | 
| 
       511 
490 
     | 
    
         
             
                    elif index.column() == self.C_VIEW:
         
     | 
| 
       512 
491 
     | 
    
         
             
                        self._parent.loadDocumentTagRequest.emit(tag, nwDocMode.VIEW)
         
     | 
| 
       513 
     | 
    
         
            -
                    return
         
     | 
| 
       514 
492 
     | 
    
         | 
| 
       515 
493 
     | 
    
         
             
                @pyqtSlot("QModelIndex")
         
     | 
| 
       516 
494 
     | 
    
         
             
                def _treeItemDoubleClicked(self, index: QModelIndex) -> None:
         
     | 
| 
         @@ -518,4 +496,3 @@ class _ViewPanelKeyWords(QTreeWidget): 
     | 
|
| 
       518 
496 
     | 
    
         
             
                    tag = index.siblingAtColumn(self.C_DATA).data(self.D_TAG)
         
     | 
| 
       519 
497 
     | 
    
         
             
                    if index.column() not in (self.C_EDIT, self.C_VIEW):
         
     | 
| 
       520 
498 
     | 
    
         
             
                        self._parent.loadDocumentTagRequest.emit(tag, nwDocMode.VIEW)
         
     | 
| 
       521 
     | 
    
         
            -
                    return
         
     | 
| 
         @@ -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
         
     | 
| 
         @@ -42,6 +42,11 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            class GuiTextDocument(QTextDocument):
         
     | 
| 
      
 45 
     | 
    
         
            +
                """Custom: Modified QTextDocument.
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                A special text document format that incorporates a few additional
         
     | 
| 
      
 48 
     | 
    
         
            +
                features including spell checking.
         
     | 
| 
      
 49 
     | 
    
         
            +
                """
         
     | 
| 
       45 
50 
     | 
    
         | 
| 
       46 
51 
     | 
    
         
             
                def __init__(self, parent: QObject) -> None:
         
     | 
| 
       47 
52 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
         @@ -52,11 +57,8 @@ class GuiTextDocument(QTextDocument): 
     | 
|
| 
       52 
57 
     | 
    
         | 
| 
       53 
58 
     | 
    
         
             
                    logger.debug("Ready: GuiTextDocument")
         
     | 
| 
       54 
59 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                    return
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
60 
     | 
    
         
             
                def __del__(self) -> None:  # pragma: no cover
         
     | 
| 
       58 
61 
     | 
    
         
             
                    logger.debug("Delete: GuiTextDocument")
         
     | 
| 
       59 
     | 
    
         
            -
                    return
         
     | 
| 
       60 
62 
     | 
    
         | 
| 
       61 
63 
     | 
    
         
             
                ##
         
     | 
| 
       62 
64 
     | 
    
         
             
                #  Properties
         
     | 
| 
         @@ -96,8 +98,6 @@ class GuiTextDocument(QTextDocument): 
     | 
|
| 
       96 
98 
     | 
    
         
             
                    logger.debug("Loaded %d text blocks in %.3f ms", count, 1000*(tMid - tStart))
         
     | 
| 
       97 
99 
     | 
    
         
             
                    logger.debug("Highlighted document in %.3f ms", 1000*(tEnd - tMid))
         
     | 
| 
       98 
100 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                    return
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
101 
     | 
    
         
             
                def metaDataAtPos(self, pos: int) -> tuple[str, str]:
         
     | 
| 
       102 
102 
     | 
    
         
             
                    """Check if there is meta data available at a given position in
         
     | 
| 
       103 
103 
     | 
    
         
             
                    the document, and if so, return it.
         
     | 
| 
         @@ -113,7 +113,7 @@ class GuiTextDocument(QTextDocument): 
     | 
|
| 
       113 
113 
     | 
    
         
             
                                    return cData, cType
         
     | 
| 
       114 
114 
     | 
    
         
             
                    return "", ""
         
     | 
| 
       115 
115 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
                def spellErrorAtPos(self, pos: int) -> tuple[str, int,  
     | 
| 
      
 116 
     | 
    
         
            +
                def spellErrorAtPos(self, pos: int) -> tuple[str, int, list[str]]:
         
     | 
| 
       117 
117 
     | 
    
         
             
                    """Check if there is a misspelled word at a given position in
         
     | 
| 
       118 
118 
     | 
    
         
             
                    the document, and if so, return it.
         
     | 
| 
       119 
119 
     | 
    
         
             
                    """
         
     | 
| 
         @@ -122,15 +122,11 @@ class GuiTextDocument(QTextDocument): 
     | 
|
| 
       122 
122 
     | 
    
         
             
                    block = cursor.block()
         
     | 
| 
       123 
123 
     | 
    
         
             
                    data = block.userData()
         
     | 
| 
       124 
124 
     | 
    
         
             
                    if block.isValid() and isinstance(data, TextBlockData):
         
     | 
| 
       125 
     | 
    
         
            -
                         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
                                if cPos <= check <= cEnd:
         
     | 
| 
       131 
     | 
    
         
            -
                                    word = text[cPos:cEnd]
         
     | 
| 
       132 
     | 
    
         
            -
                                    return word, cPos, cLen, SHARED.spelling.suggestWords(word)
         
     | 
| 
       133 
     | 
    
         
            -
                    return "", -1, -1, []
         
     | 
| 
      
 125 
     | 
    
         
            +
                        if (check := pos - block.position()) >= 0:
         
     | 
| 
      
 126 
     | 
    
         
            +
                            for start, end, word in data.spellErrors:
         
     | 
| 
      
 127 
     | 
    
         
            +
                                if start <= check <= end:
         
     | 
| 
      
 128 
     | 
    
         
            +
                                    return word, start, SHARED.spelling.suggestWords(word)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    return "", -1, []
         
     | 
| 
       134 
130 
     | 
    
         | 
| 
       135 
131 
     | 
    
         
             
                def iterBlockByType(self, cType: int, maxCount: int = 1000) -> Iterable[QTextBlock]:
         
     | 
| 
       136 
132 
     | 
    
         
             
                    """Iterate over all text blocks of a given type."""
         
     | 
| 
         @@ -150,4 +146,3 @@ class GuiTextDocument(QTextDocument): 
     | 
|
| 
       150 
146 
     | 
    
         
             
                def setSpellCheckState(self, state: bool) -> None:
         
     | 
| 
       151 
147 
     | 
    
         
             
                    """Set the spell check state of the syntax highlighter."""
         
     | 
| 
       152 
148 
     | 
    
         
             
                    self._syntax.setSpellCheck(state)
         
     | 
| 
       153 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/gui/itemdetails.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
         
     | 
| 
         @@ -43,6 +43,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
            class GuiItemDetails(QWidget):
         
     | 
| 
      
 46 
     | 
    
         
            +
                """GUI: Project Item Details Panel."""
         
     | 
| 
       46 
47 
     | 
    
         | 
| 
       47 
48 
     | 
    
         
             
                def __init__(self, parent: QWidget) -> None:
         
     | 
| 
       48 
49 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
         @@ -190,8 +191,6 @@ class GuiItemDetails(QWidget): 
     | 
|
| 
       190 
191 
     | 
    
         | 
| 
       191 
192 
     | 
    
         
             
                    logger.debug("Ready: GuiItemDetails")
         
     | 
| 
       192 
193 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                    return
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
194 
     | 
    
         
             
                ###
         
     | 
| 
       196 
195 
     | 
    
         
             
                #  Class Methods
         
     | 
| 
       197 
196 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -210,7 +209,6 @@ class GuiItemDetails(QWidget): 
     | 
|
| 
       210 
209 
     | 
    
         
             
                    self.cCountData.clear()
         
     | 
| 
       211 
210 
     | 
    
         
             
                    self.wCountData.clear()
         
     | 
| 
       212 
211 
     | 
    
         
             
                    self.pCountData.clear()
         
     | 
| 
       213 
     | 
    
         
            -
                    return
         
     | 
| 
       214 
212 
     | 
    
         | 
| 
       215 
213 
     | 
    
         
             
                def refreshDetails(self) -> None:
         
     | 
| 
       216 
214 
     | 
    
         
             
                    """Reload the content of the details panel."""
         
     | 
| 
         @@ -218,8 +216,8 @@ class GuiItemDetails(QWidget): 
     | 
|
| 
       218 
216 
     | 
    
         | 
| 
       219 
217 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       220 
218 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
      
 219 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiItemDetails")
         
     | 
| 
       221 
220 
     | 
    
         
             
                    self.updateViewBox(self._handle)
         
     | 
| 
       222 
     | 
    
         
            -
                    return
         
     | 
| 
       223 
221 
     | 
    
         | 
| 
       224 
222 
     | 
    
         
             
                def updateViewBox(self, tHandle: str | None) -> None:
         
     | 
| 
       225 
223 
     | 
    
         
             
                    """Populate the details box from a given handle."""
         
     | 
| 
         @@ -233,14 +231,8 @@ class GuiItemDetails(QWidget): 
     | 
|
| 
       233 
231 
     | 
    
         
             
                    # Label
         
     | 
| 
       234 
232 
     | 
    
         
             
                    # =====
         
     | 
| 
       235 
233 
     | 
    
         | 
| 
       236 
     | 
    
         
            -
                     
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                            self.labelIcon.setPixmap(SHARED.theme.getPixmap("checked", (iPx, iPx), "green"))
         
     | 
| 
       239 
     | 
    
         
            -
                        else:
         
     | 
| 
       240 
     | 
    
         
            -
                            self.labelIcon.setPixmap(SHARED.theme.getPixmap("unchecked", (iPx, iPx), "red"))
         
     | 
| 
       241 
     | 
    
         
            -
                    else:
         
     | 
| 
       242 
     | 
    
         
            -
                        self.labelIcon.setPixmap(SHARED.theme.getPixmap("noncheckable", (iPx, iPx), "faded"))
         
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
      
 234 
     | 
    
         
            +
                    _, icon = nwItem.getActiveStatus()
         
     | 
| 
      
 235 
     | 
    
         
            +
                    self.labelIcon.setPixmap(icon.pixmap(iPx, iPx))
         
     | 
| 
       244 
236 
     | 
    
         
             
                    self.labelData.setText(elide(nwItem.itemName, 100))
         
     | 
| 
       245 
237 
     | 
    
         | 
| 
       246 
238 
     | 
    
         
             
                    # Status
         
     | 
| 
         @@ -289,4 +281,3 @@ class GuiItemDetails(QWidget): 
     | 
|
| 
       289 
281 
     | 
    
         
             
                            self.updateViewBox(tHandle)
         
     | 
| 
       290 
282 
     | 
    
         
             
                        elif change == nwChange.DELETE:
         
     | 
| 
       291 
283 
     | 
    
         
             
                            self.updateViewBox(None)
         
     | 
| 
       292 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/gui/mainmenu.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
         
     | 
| 
         @@ -82,8 +82,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       82 
82 
     | 
    
         | 
| 
       83 
83 
     | 
    
         
             
                    logger.debug("Ready: GuiMainMenu")
         
     | 
| 
       84 
84 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                    return
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
85 
     | 
    
         
             
                ##
         
     | 
| 
       88 
86 
     | 
    
         
             
                #  Public Slots
         
     | 
| 
       89 
87 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -92,7 +90,18 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       92 
90 
     | 
    
         
             
                def setSpellCheckState(self, state: bool) -> None:
         
     | 
| 
       93 
91 
     | 
    
         
             
                    """Forward spell check check state to its action."""
         
     | 
| 
       94 
92 
     | 
    
         
             
                    self.aSpellCheck.setChecked(state)
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                @pyqtSlot()
         
     | 
| 
      
 95 
     | 
    
         
            +
                def updateSpellCheckLanguages(self) -> None:
         
     | 
| 
      
 96 
     | 
    
         
            +
                    """Update the list of available spell check languages."""
         
     | 
| 
      
 97 
     | 
    
         
            +
                    self.mSelectLanguage.clear()
         
     | 
| 
      
 98 
     | 
    
         
            +
                    languages = SHARED.spelling.listDictionaries()
         
     | 
| 
      
 99 
     | 
    
         
            +
                    languages.insert(0, ("None", self.tr("Default")))
         
     | 
| 
      
 100 
     | 
    
         
            +
                    for tag, language in languages:
         
     | 
| 
      
 101 
     | 
    
         
            +
                        aSpell = QAction(self.mSelectLanguage)
         
     | 
| 
      
 102 
     | 
    
         
            +
                        aSpell.setText(language)
         
     | 
| 
      
 103 
     | 
    
         
            +
                        aSpell.triggered.connect(qtLambda(self._changeSpelling, tag))
         
     | 
| 
      
 104 
     | 
    
         
            +
                        self.mSelectLanguage.addAction(aSpell)
         
     | 
| 
       96 
105 
     | 
    
         | 
| 
       97 
106 
     | 
    
         
             
                ##
         
     | 
| 
       98 
107 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -105,21 +114,18 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       105 
114 
     | 
    
         
             
                    decision, just pass a None to the function and let it decide.
         
     | 
| 
       106 
115 
     | 
    
         
             
                    """
         
     | 
| 
       107 
116 
     | 
    
         
             
                    self.mainGui.docEditor.toggleSpellCheck(None)
         
     | 
| 
       108 
     | 
    
         
            -
                    return
         
     | 
| 
       109 
117 
     | 
    
         | 
| 
       110 
118 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       111 
119 
     | 
    
         
             
                def _openUserManualFile(self) -> None:
         
     | 
| 
       112 
120 
     | 
    
         
             
                    """Open the documentation in PDF format."""
         
     | 
| 
       113 
121 
     | 
    
         
             
                    if isinstance(CONFIG.pdfDocs, Path):
         
     | 
| 
       114 
122 
     | 
    
         
             
                        openExternalPath(CONFIG.pdfDocs)
         
     | 
| 
       115 
     | 
    
         
            -
                    return
         
     | 
| 
       116 
123 
     | 
    
         | 
| 
       117 
124 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       118 
125 
     | 
    
         
             
                def _changeSpelling(self, language: str) -> None:
         
     | 
| 
       119 
126 
     | 
    
         
             
                    """Change the spell check language."""
         
     | 
| 
       120 
127 
     | 
    
         
             
                    SHARED.project.data.setSpellLang(language)
         
     | 
| 
       121 
128 
     | 
    
         
             
                    SHARED.updateSpellCheckLanguage()
         
     | 
| 
       122 
     | 
    
         
            -
                    return
         
     | 
| 
       123 
129 
     | 
    
         | 
| 
       124 
130 
     | 
    
         
             
                ##
         
     | 
| 
       125 
131 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -188,8 +194,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       188 
194 
     | 
    
         
             
                    self.aExitNW.triggered.connect(qtLambda(self.mainGui.closeMain))
         
     | 
| 
       189 
195 
     | 
    
         
             
                    self.mainGui.addAction(self.aExitNW)
         
     | 
| 
       190 
196 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
                    return
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
197 
     | 
    
         
             
                def _buildDocumentMenu(self) -> None:
         
     | 
| 
       194 
198 
     | 
    
         
             
                    """Assemble the Document menu."""
         
     | 
| 
       195 
199 
     | 
    
         
             
                    # Document
         
     | 
| 
         @@ -236,8 +240,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       236 
240 
     | 
    
         
             
                    self.aImportFile = qtAddAction(self.docuMenu, self.tr("Import Text from File"))
         
     | 
| 
       237 
241 
     | 
    
         
             
                    self.aImportFile.triggered.connect(qtLambda(self.mainGui.importDocument))
         
     | 
| 
       238 
242 
     | 
    
         | 
| 
       239 
     | 
    
         
            -
                    return
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
243 
     | 
    
         
             
                def _buildEditMenu(self) -> None:
         
     | 
| 
       242 
244 
     | 
    
         
             
                    """Assemble the Edit menu."""
         
     | 
| 
       243 
245 
     | 
    
         
             
                    # Edit
         
     | 
| 
         @@ -305,8 +307,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       305 
307 
     | 
    
         
             
                    )
         
     | 
| 
       306 
308 
     | 
    
         
             
                    self.mainGui.addAction(self.aSelectPar)
         
     | 
| 
       307 
309 
     | 
    
         | 
| 
       308 
     | 
    
         
            -
                    return
         
     | 
| 
       309 
     | 
    
         
            -
             
     | 
| 
       310 
310 
     | 
    
         
             
                def _buildViewMenu(self) -> None:
         
     | 
| 
       311 
311 
     | 
    
         
             
                    """Assemble the View menu."""
         
     | 
| 
       312 
312 
     | 
    
         
             
                    # View
         
     | 
| 
         @@ -318,6 +318,7 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       318 
318 
     | 
    
         
             
                    self.aFocusTree.triggered.connect(
         
     | 
| 
       319 
319 
     | 
    
         
             
                        lambda: self.requestFocusChange.emit(nwFocus.TREE)
         
     | 
| 
       320 
320 
     | 
    
         
             
                    )
         
     | 
| 
      
 321 
     | 
    
         
            +
                    self.mainGui.addAction(self.aFocusTree)
         
     | 
| 
       321 
322 
     | 
    
         | 
| 
       322 
323 
     | 
    
         
             
                    # View > Document Editor
         
     | 
| 
       323 
324 
     | 
    
         
             
                    self.aFocusDocument = qtAddAction(self.viewMenu, self.tr("Go to Document"))
         
     | 
| 
         @@ -332,6 +333,7 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       332 
333 
     | 
    
         
             
                    self.aFocusOutline.triggered.connect(
         
     | 
| 
       333 
334 
     | 
    
         
             
                        lambda: self.requestFocusChange.emit(nwFocus.OUTLINE)
         
     | 
| 
       334 
335 
     | 
    
         
             
                    )
         
     | 
| 
      
 336 
     | 
    
         
            +
                    self.mainGui.addAction(self.aFocusOutline)
         
     | 
| 
       335 
337 
     | 
    
         | 
| 
       336 
338 
     | 
    
         
             
                    # View > Separator
         
     | 
| 
       337 
339 
     | 
    
         
             
                    self.viewMenu.addSeparator()
         
     | 
| 
         @@ -365,8 +367,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       365 
367 
     | 
    
         
             
                    self.aFullScreen.triggered.connect(self.mainGui.toggleFullScreenMode)
         
     | 
| 
       366 
368 
     | 
    
         
             
                    self.mainGui.addAction(self.aFullScreen)
         
     | 
| 
       367 
369 
     | 
    
         | 
| 
       368 
     | 
    
         
            -
                    return
         
     | 
| 
       369 
     | 
    
         
            -
             
     | 
| 
       370 
370 
     | 
    
         
             
                def _buildInsertMenu(self) -> None:
         
     | 
| 
       371 
371 
     | 
    
         
             
                    """Assemble the Insert menu."""
         
     | 
| 
       372 
372 
     | 
    
         
             
                    # Insert
         
     | 
| 
         @@ -644,8 +644,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       644 
644 
     | 
    
         
             
                        lambda: self.requestDocInsert.emit(nwDocInsert.FOOTNOTE)
         
     | 
| 
       645 
645 
     | 
    
         
             
                    )
         
     | 
| 
       646 
646 
     | 
    
         | 
| 
       647 
     | 
    
         
            -
                    return
         
     | 
| 
       648 
     | 
    
         
            -
             
     | 
| 
       649 
647 
     | 
    
         
             
                def _buildFormatMenu(self) -> None:
         
     | 
| 
       650 
648 
     | 
    
         
             
                    """Assemble the Format menu."""
         
     | 
| 
       651 
649 
     | 
    
         
             
                    # Format
         
     | 
| 
         @@ -675,6 +673,14 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       675 
673 
     | 
    
         
             
                    )
         
     | 
| 
       676 
674 
     | 
    
         
             
                    self.mainGui.addAction(self.aFmtStrike)
         
     | 
| 
       677 
675 
     | 
    
         | 
| 
      
 676 
     | 
    
         
            +
                    # Format > Highlight
         
     | 
| 
      
 677 
     | 
    
         
            +
                    self.aFmtMark = qtAddAction(self.fmtMenu, self.tr("Highlight"))
         
     | 
| 
      
 678 
     | 
    
         
            +
                    self.aFmtMark.setShortcut("Ctrl+M")
         
     | 
| 
      
 679 
     | 
    
         
            +
                    self.aFmtMark.triggered.connect(
         
     | 
| 
      
 680 
     | 
    
         
            +
                        lambda: self.requestDocAction.emit(nwDocAction.MD_MARK)
         
     | 
| 
      
 681 
     | 
    
         
            +
                    )
         
     | 
| 
      
 682 
     | 
    
         
            +
                    self.mainGui.addAction(self.aFmtStrike)
         
     | 
| 
      
 683 
     | 
    
         
            +
             
     | 
| 
       678 
684 
     | 
    
         
             
                    # Edit > Separator
         
     | 
| 
       679 
685 
     | 
    
         
             
                    self.fmtMenu.addSeparator()
         
     | 
| 
       680 
686 
     | 
    
         | 
| 
         @@ -891,8 +897,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       891 
897 
     | 
    
         
             
                        lambda: self.requestDocAction.emit(nwDocAction.RM_BREAKS)
         
     | 
| 
       892 
898 
     | 
    
         
             
                    )
         
     | 
| 
       893 
899 
     | 
    
         | 
| 
       894 
     | 
    
         
            -
                    return
         
     | 
| 
       895 
     | 
    
         
            -
             
     | 
| 
       896 
900 
     | 
    
         
             
                def _buildSearchMenu(self) -> None:
         
     | 
| 
       897 
901 
     | 
    
         
             
                    """Assemble the Search menu."""
         
     | 
| 
       898 
902 
     | 
    
         
             
                    # Search
         
     | 
| 
         @@ -938,8 +942,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       938 
942 
     | 
    
         
             
                    self.aFindProj.setShortcut("Ctrl+Shift+F")
         
     | 
| 
       939 
943 
     | 
    
         
             
                    self.aFindProj.triggered.connect(qtLambda(self.requestViewChange.emit, nwView.SEARCH))
         
     | 
| 
       940 
944 
     | 
    
         | 
| 
       941 
     | 
    
         
            -
                    return
         
     | 
| 
       942 
     | 
    
         
            -
             
     | 
| 
       943 
945 
     | 
    
         
             
                def _buildToolsMenu(self) -> None:
         
     | 
| 
       944 
946 
     | 
    
         
             
                    """Assemble the Tools menu."""
         
     | 
| 
       945 
947 
     | 
    
         
             
                    # Tools
         
     | 
| 
         @@ -954,13 +956,7 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       954 
956 
     | 
    
         
             
                    self.mainGui.addAction(self.aSpellCheck)
         
     | 
| 
       955 
957 
     | 
    
         | 
| 
       956 
958 
     | 
    
         
             
                    self.mSelectLanguage = qtAddMenu(self.toolsMenu, self.tr("Spell Check Language"))
         
     | 
| 
       957 
     | 
    
         
            -
                     
     | 
| 
       958 
     | 
    
         
            -
                    languages.insert(0, ("None", self.tr("Default")))
         
     | 
| 
       959 
     | 
    
         
            -
                    for tag, language in languages:
         
     | 
| 
       960 
     | 
    
         
            -
                        aSpell = QAction(self.mSelectLanguage)
         
     | 
| 
       961 
     | 
    
         
            -
                        aSpell.setText(language)
         
     | 
| 
       962 
     | 
    
         
            -
                        aSpell.triggered.connect(qtLambda(self._changeSpelling, tag))
         
     | 
| 
       963 
     | 
    
         
            -
                        self.mSelectLanguage.addAction(aSpell)
         
     | 
| 
      
 959 
     | 
    
         
            +
                    self.updateSpellCheckLanguages()
         
     | 
| 
       964 
960 
     | 
    
         | 
| 
       965 
961 
     | 
    
         
             
                    # Tools > Re-Run Spell Check
         
     | 
| 
       966 
962 
     | 
    
         
             
                    self.aReRunSpell = qtAddAction(self.toolsMenu, self.tr("Re-Run Spell Check"))
         
     | 
| 
         @@ -1009,8 +1005,6 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       1009 
1005 
     | 
    
         
             
                    self.aPreferences.triggered.connect(self.mainGui.showPreferencesDialog)
         
     | 
| 
       1010 
1006 
     | 
    
         
             
                    self.mainGui.addAction(self.aPreferences)
         
     | 
| 
       1011 
1007 
     | 
    
         | 
| 
       1012 
     | 
    
         
            -
                    return
         
     | 
| 
       1013 
     | 
    
         
            -
             
     | 
| 
       1014 
1008 
     | 
    
         
             
                def _buildHelpMenu(self) -> None:
         
     | 
| 
       1015 
1009 
     | 
    
         
             
                    """Assemble the Help menu."""
         
     | 
| 
       1016 
1010 
     | 
    
         
             
                    # Help
         
     | 
| 
         @@ -1056,5 +1050,3 @@ class GuiMainMenu(QMenuBar): 
     | 
|
| 
       1056 
1050 
     | 
    
         
             
                    # Document > Main Website
         
     | 
| 
       1057 
1051 
     | 
    
         
             
                    self.aWebsite = qtAddAction(self.helpMenu, self.tr("The novelWriter Website"))
         
     | 
| 
       1058 
1052 
     | 
    
         
             
                    self.aWebsite.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_WEB))
         
     | 
| 
       1059 
     | 
    
         
            -
             
     | 
| 
       1060 
     | 
    
         
            -
                    return
         
     |