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
 
    
        novelwriter/gui/doceditor.py
    CHANGED
    
    | 
         @@ -29,7 +29,7 @@ General Public License for more details. 
     | 
|
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       31 
31 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       32 
     | 
    
         
            -
            """
         
     | 
| 
      
 32 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       33 
33 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
            import bisect
         
     | 
| 
         @@ -46,11 +46,11 @@ from PyQt6.QtGui import ( 
     | 
|
| 
       46 
46 
     | 
    
         
             
                QAction, QCursor, QDragEnterEvent, QDragMoveEvent, QDropEvent,
         
     | 
| 
       47 
47 
     | 
    
         
             
                QInputMethodEvent, QKeyEvent, QKeySequence, QMouseEvent, QPalette, QPixmap,
         
     | 
| 
       48 
48 
     | 
    
         
             
                QResizeEvent, QShortcut, QTextBlock, QTextCursor, QTextDocument,
         
     | 
| 
       49 
     | 
    
         
            -
                QTextOption
         
     | 
| 
      
 49 
     | 
    
         
            +
                QTextFormat, QTextOption
         
     | 
| 
       50 
50 
     | 
    
         
             
            )
         
     | 
| 
       51 
51 
     | 
    
         
             
            from PyQt6.QtWidgets import (
         
     | 
| 
       52 
52 
     | 
    
         
             
                QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
         
     | 
| 
       53 
     | 
    
         
            -
                QPlainTextEdit, QToolBar, QVBoxLayout, QWidget
         
     | 
| 
      
 53 
     | 
    
         
            +
                QPlainTextEdit, QTextEdit, QToolBar, QVBoxLayout, QWidget
         
     | 
| 
       54 
54 
     | 
    
         
             
            )
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
         @@ -77,7 +77,8 @@ from novelwriter.types import ( 
     | 
|
| 
       77 
77 
     | 
    
         
             
                QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop,
         
     | 
| 
       78 
78 
     | 
    
         
             
                QtAlignRight, QtImCursorRectangle, QtKeepAnchor, QtModCtrl, QtModNone,
         
     | 
| 
       79 
79 
     | 
    
         
             
                QtModShift, QtMouseLeft, QtMoveAnchor, QtMoveLeft, QtMoveRight,
         
     | 
| 
       80 
     | 
    
         
            -
                QtScrollAlwaysOff, QtScrollAsNeeded
         
     | 
| 
      
 80 
     | 
    
         
            +
                QtScrollAlwaysOff, QtScrollAsNeeded, QtSelectBlock, QtSelectDocument,
         
     | 
| 
      
 81 
     | 
    
         
            +
                QtSelectWord, QtTransparent
         
     | 
| 
       81 
82 
     | 
    
         
             
            )
         
     | 
| 
       82 
83 
     | 
    
         | 
| 
       83 
84 
     | 
    
         
             
            logger = logging.getLogger(__name__)
         
     | 
| 
         @@ -99,7 +100,7 @@ class _TagAction(IntFlag): 
     | 
|
| 
       99 
100 
     | 
    
         | 
| 
       100 
101 
     | 
    
         | 
| 
       101 
102 
     | 
    
         
             
            class GuiDocEditor(QPlainTextEdit):
         
     | 
| 
       102 
     | 
    
         
            -
                """Gui Widget: Main Document Editor"""
         
     | 
| 
      
 103 
     | 
    
         
            +
                """Gui Widget: Main Document Editor."""
         
     | 
| 
       103 
104 
     | 
    
         | 
| 
       104 
105 
     | 
    
         
             
                __slots__ = (
         
     | 
| 
       105 
106 
     | 
    
         
             
                    "_autoReplace", "_completer", "_doReplace", "_docChanged", "_docHandle", "_followTag1",
         
     | 
| 
         @@ -147,6 +148,8 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       147 
148 
     | 
    
         
             
                    self._lastActive = 0.0    # Timestamp of last activity
         
     | 
| 
       148 
149 
     | 
    
         
             
                    self._lastFind   = None   # Position of the last found search word
         
     | 
| 
       149 
150 
     | 
    
         
             
                    self._doReplace  = False  # Switch to temporarily disable auto-replace
         
     | 
| 
      
 151 
     | 
    
         
            +
                    self._lineColor  = QtTransparent
         
     | 
| 
      
 152 
     | 
    
         
            +
                    self._selection  = QTextEdit.ExtraSelection()
         
     | 
| 
       150 
153 
     | 
    
         | 
| 
       151 
154 
     | 
    
         
             
                    # Auto-Replace
         
     | 
| 
       152 
155 
     | 
    
         
             
                    self._autoReplace = TextAutoReplace()
         
     | 
| 
         @@ -235,8 +238,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       235 
238 
     | 
    
         | 
| 
       236 
239 
     | 
    
         
             
                    logger.debug("Ready: GuiDocEditor")
         
     | 
| 
       237 
240 
     | 
    
         | 
| 
       238 
     | 
    
         
            -
                    return
         
     | 
| 
       239 
     | 
    
         
            -
             
     | 
| 
       240 
241 
     | 
    
         
             
                ##
         
     | 
| 
       241 
242 
     | 
    
         
             
                #  Properties
         
     | 
| 
       242 
243 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -285,18 +286,18 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       285 
286 
     | 
    
         
             
                    self.docHeader.clearHeader()
         
     | 
| 
       286 
287 
     | 
    
         
             
                    self.docFooter.setHandle(self._docHandle)
         
     | 
| 
       287 
288 
     | 
    
         
             
                    self.docToolBar.setVisible(False)
         
     | 
| 
      
 289 
     | 
    
         
            +
                    self.setExtraSelections([])
         
     | 
| 
       288 
290 
     | 
    
         | 
| 
       289 
291 
     | 
    
         
             
                    self.itemHandleChanged.emit("")
         
     | 
| 
       290 
292 
     | 
    
         | 
| 
       291 
     | 
    
         
            -
                    return
         
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
293 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       294 
294 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
      
 295 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocEditor")
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
       295 
297 
     | 
    
         
             
                    self.docSearch.updateTheme()
         
     | 
| 
       296 
298 
     | 
    
         
             
                    self.docHeader.updateTheme()
         
     | 
| 
       297 
299 
     | 
    
         
             
                    self.docFooter.updateTheme()
         
     | 
| 
       298 
300 
     | 
    
         
             
                    self.docToolBar.updateTheme()
         
     | 
| 
       299 
     | 
    
         
            -
                    return
         
     | 
| 
       300 
301 
     | 
    
         | 
| 
       301 
302 
     | 
    
         
             
                def updateSyntaxColors(self) -> None:
         
     | 
| 
       302 
303 
     | 
    
         
             
                    """Update the syntax highlighting theme."""
         
     | 
| 
         @@ -317,7 +318,9 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       317 
318 
     | 
    
         
             
                    self.docHeader.matchColors()
         
     | 
| 
       318 
319 
     | 
    
         
             
                    self.docFooter.matchColors()
         
     | 
| 
       319 
320 
     | 
    
         | 
| 
       320 
     | 
    
         
            -
                     
     | 
| 
      
 321 
     | 
    
         
            +
                    self._lineColor = syntax.line
         
     | 
| 
      
 322 
     | 
    
         
            +
                    self._selection.format.setBackground(self._lineColor)
         
     | 
| 
      
 323 
     | 
    
         
            +
                    self._selection.format.setProperty(QTextFormat.Property.FullWidthSelection, True)
         
     | 
| 
       321 
324 
     | 
    
         | 
| 
       322 
325 
     | 
    
         
             
                def initEditor(self) -> None:
         
     | 
| 
       323 
326 
     | 
    
         
             
                    """Initialise or re-initialise the editor with the user's
         
     | 
| 
         @@ -374,6 +377,8 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       374 
377 
     | 
    
         
             
                    # Refresh sizes
         
     | 
| 
       375 
378 
     | 
    
         
             
                    self.setTabStopDistance(CONFIG.tabWidth)
         
     | 
| 
       376 
379 
     | 
    
         
             
                    self.setCursorWidth(CONFIG.cursorWidth)
         
     | 
| 
      
 380 
     | 
    
         
            +
                    self.setExtraSelections([])
         
     | 
| 
      
 381 
     | 
    
         
            +
                    self._cursorMoved()
         
     | 
| 
       377 
382 
     | 
    
         | 
| 
       378 
383 
     | 
    
         
             
                    # If we have a document open, we should refresh it in case the
         
     | 
| 
       379 
384 
     | 
    
         
             
                    # font changed, otherwise we just clear the editor entirely,
         
     | 
| 
         @@ -384,8 +389,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       384 
389 
     | 
    
         
             
                    else:
         
     | 
| 
       385 
390 
     | 
    
         
             
                        self.clearEditor()
         
     | 
| 
       386 
391 
     | 
    
         | 
| 
       387 
     | 
    
         
            -
                    return
         
     | 
| 
       388 
     | 
    
         
            -
             
     | 
| 
       389 
392 
     | 
    
         
             
                def loadText(self, tHandle: str, tLine: int | None = None) -> bool:
         
     | 
| 
       390 
393 
     | 
    
         
             
                    """Load text from a document into the editor. If we have an I/O
         
     | 
| 
       391 
394 
     | 
    
         
             
                    error, we must handle this and clear the editor so that we don't
         
     | 
| 
         @@ -463,7 +466,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       463 
466 
     | 
    
         
             
                    self.updateDocMargins()
         
     | 
| 
       464 
467 
     | 
    
         
             
                    self.setDocumentChanged(True)
         
     | 
| 
       465 
468 
     | 
    
         
             
                    QApplication.restoreOverrideCursor()
         
     | 
| 
       466 
     | 
    
         
            -
                    return
         
     | 
| 
       467 
469 
     | 
    
         | 
| 
       468 
470 
     | 
    
         
             
                def saveText(self) -> bool:
         
     | 
| 
       469 
471 
     | 
    
         
             
                    """Save the text currently in the editor to the NWDocument
         
     | 
| 
         @@ -531,7 +533,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       531 
533 
     | 
    
         
             
                                vBar.setValue(vBar.value() + 1)
         
     | 
| 
       532 
534 
     | 
    
         
             
                                count += 1
         
     | 
| 
       533 
535 
     | 
    
         
             
                        QApplication.processEvents()
         
     | 
| 
       534 
     | 
    
         
            -
                    return
         
     | 
| 
       535 
536 
     | 
    
         | 
| 
       536 
537 
     | 
    
         
             
                def updateDocMargins(self) -> None:
         
     | 
| 
       537 
538 
     | 
    
         
             
                    """Automatically adjust the margins so the text is centred if
         
     | 
| 
         @@ -572,8 +573,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       572 
573 
     | 
    
         
             
                    lM = max(self._vpMargin, fH)
         
     | 
| 
       573 
574 
     | 
    
         
             
                    self.setViewportMargins(tM, uM, tM, lM)
         
     | 
| 
       574 
575 
     | 
    
         | 
| 
       575 
     | 
    
         
            -
                    return
         
     | 
| 
       576 
     | 
    
         
            -
             
     | 
| 
       577 
576 
     | 
    
         
             
                ##
         
     | 
| 
       578 
577 
     | 
    
         
             
                #  Getters
         
     | 
| 
       579 
578 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -583,20 +582,19 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       583 
582 
     | 
    
         
             
                    QTextDocument->toRawText instead of toPlainText. The former preserves
         
     | 
| 
       584 
583 
     | 
    
         
             
                    non-breaking spaces, the latter does not. We still want to get rid of
         
     | 
| 
       585 
584 
     | 
    
         
             
                    paragraph and line separators though.
         
     | 
| 
      
 585 
     | 
    
         
            +
             
     | 
| 
       586 
586 
     | 
    
         
             
                    See: https://doc.qt.io/qt-6/qtextdocument.html#toPlainText
         
     | 
| 
       587 
587 
     | 
    
         
             
                    """
         
     | 
| 
       588 
588 
     | 
    
         
             
                    text = self._qDocument.toRawText()
         
     | 
| 
       589 
589 
     | 
    
         
             
                    text = text.replace(nwUnicode.U_LSEP, "\n")  # Line separators
         
     | 
| 
       590 
     | 
    
         
            -
                     
     | 
| 
       591 
     | 
    
         
            -
                    return text
         
     | 
| 
      
 590 
     | 
    
         
            +
                    return text.replace(nwUnicode.U_PSEP, "\n")  # Paragraph separators
         
     | 
| 
       592 
591 
     | 
    
         | 
| 
       593 
592 
     | 
    
         
             
                def getSelectedText(self) -> str:
         
     | 
| 
       594 
593 
     | 
    
         
             
                    """Get currently selected text."""
         
     | 
| 
       595 
594 
     | 
    
         
             
                    if (cursor := self.textCursor()).hasSelection():
         
     | 
| 
       596 
595 
     | 
    
         
             
                        text = cursor.selectedText()
         
     | 
| 
       597 
596 
     | 
    
         
             
                        text = text.replace(nwUnicode.U_LSEP, "\n")  # Line separators
         
     | 
| 
       598 
     | 
    
         
            -
                         
     | 
| 
       599 
     | 
    
         
            -
                        return text
         
     | 
| 
      
 597 
     | 
    
         
            +
                        return text.replace(nwUnicode.U_PSEP, "\n")  # Paragraph separators
         
     | 
| 
       600 
598 
     | 
    
         
             
                    return ""
         
     | 
| 
       601 
599 
     | 
    
         | 
| 
       602 
600 
     | 
    
         
             
                def getCursorPosition(self) -> int:
         
     | 
| 
         @@ -617,7 +615,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       617 
615 
     | 
    
         
             
                        logger.debug("Document changed status is '%s'", state)
         
     | 
| 
       618 
616 
     | 
    
         
             
                        self._docChanged = state
         
     | 
| 
       619 
617 
     | 
    
         
             
                        self.editedStatusChanged.emit(self._docChanged)
         
     | 
| 
       620 
     | 
    
         
            -
                    return
         
     | 
| 
       621 
618 
     | 
    
         | 
| 
       622 
619 
     | 
    
         
             
                def setCursorPosition(self, position: int) -> None:
         
     | 
| 
       623 
620 
     | 
    
         
             
                    """Move the cursor to a given position in the document."""
         
     | 
| 
         @@ -626,14 +623,12 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       626 
623 
     | 
    
         
             
                        cursor.setPosition(minmax(position, 0, chars-1))
         
     | 
| 
       627 
624 
     | 
    
         
             
                        self.setTextCursor(cursor)
         
     | 
| 
       628 
625 
     | 
    
         
             
                        self.centerCursor()
         
     | 
| 
       629 
     | 
    
         
            -
                    return
         
     | 
| 
       630 
626 
     | 
    
         | 
| 
       631 
627 
     | 
    
         
             
                def saveCursorPosition(self) -> None:
         
     | 
| 
       632 
628 
     | 
    
         
             
                    """Save the cursor position to the current project item."""
         
     | 
| 
       633 
629 
     | 
    
         
             
                    if self._nwItem is not None:
         
     | 
| 
       634 
630 
     | 
    
         
             
                        cursPos = self.getCursorPosition()
         
     | 
| 
       635 
631 
     | 
    
         
             
                        self._nwItem.setCursorPos(cursPos)
         
     | 
| 
       636 
     | 
    
         
            -
                    return
         
     | 
| 
       637 
632 
     | 
    
         | 
| 
       638 
633 
     | 
    
         
             
                def setCursorLine(self, line: int | None) -> None:
         
     | 
| 
       639 
634 
     | 
    
         
             
                    """Move the cursor to a given line in the document."""
         
     | 
| 
         @@ -642,7 +637,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       642 
637 
     | 
    
         
             
                        if block:
         
     | 
| 
       643 
638 
     | 
    
         
             
                            self.setCursorPosition(block.position())
         
     | 
| 
       644 
639 
     | 
    
         
             
                            logger.debug("Cursor moved to line %d", line)
         
     | 
| 
       645 
     | 
    
         
            -
                    return
         
     | 
| 
       646 
640 
     | 
    
         | 
| 
       647 
641 
     | 
    
         
             
                def setCursorSelection(self, start: int, length: int) -> None:
         
     | 
| 
       648 
642 
     | 
    
         
             
                    """Make a text selection."""
         
     | 
| 
         @@ -651,14 +645,15 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       651 
645 
     | 
    
         
             
                        cursor.setPosition(start, QtMoveAnchor)
         
     | 
| 
       652 
646 
     | 
    
         
             
                        cursor.setPosition(start + length, QtKeepAnchor)
         
     | 
| 
       653 
647 
     | 
    
         
             
                        self.setTextCursor(cursor)
         
     | 
| 
       654 
     | 
    
         
            -
                    return
         
     | 
| 
       655 
648 
     | 
    
         | 
| 
       656 
649 
     | 
    
         
             
                ##
         
     | 
| 
       657 
650 
     | 
    
         
             
                #  Spell Checking
         
     | 
| 
       658 
651 
     | 
    
         
             
                ##
         
     | 
| 
       659 
652 
     | 
    
         | 
| 
       660 
653 
     | 
    
         
             
                def toggleSpellCheck(self, state: bool | None) -> None:
         
     | 
| 
       661 
     | 
    
         
            -
                    """ 
     | 
| 
      
 654 
     | 
    
         
            +
                    """Toggle spell checking.
         
     | 
| 
      
 655 
     | 
    
         
            +
             
     | 
| 
      
 656 
     | 
    
         
            +
                    This is the main spell check setting function, and this one
         
     | 
| 
       662 
657 
     | 
    
         
             
                    should call all other setSpellCheck functions in other classes.
         
     | 
| 
       663 
658 
     | 
    
         
             
                    If the spell check state is not defined (None), then toggle the
         
     | 
| 
       664 
659 
     | 
    
         
             
                    current status saved in this class.
         
     | 
| 
         @@ -680,9 +675,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       680 
675 
     | 
    
         
             
                    self.spellCheckStateChanged.emit(state)
         
     | 
| 
       681 
676 
     | 
    
         
             
                    self.spellCheckDocument()
         
     | 
| 
       682 
677 
     | 
    
         | 
| 
       683 
     | 
    
         
            -
                    logger.debug("Spell check is set to '%s'",  
     | 
| 
       684 
     | 
    
         
            -
             
     | 
| 
       685 
     | 
    
         
            -
                    return
         
     | 
| 
      
 678 
     | 
    
         
            +
                    logger.debug("Spell check is set to '%s'", state)
         
     | 
| 
       686 
679 
     | 
    
         | 
| 
       687 
680 
     | 
    
         
             
                def spellCheckDocument(self) -> None:
         
     | 
| 
       688 
681 
     | 
    
         
             
                    """Rerun the highlighter to update spell checking status of the
         
     | 
| 
         @@ -695,7 +688,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       695 
688 
     | 
    
         
             
                    QApplication.restoreOverrideCursor()
         
     | 
| 
       696 
689 
     | 
    
         
             
                    logger.debug("Document highlighted in %.3f ms", 1000*(time() - start))
         
     | 
| 
       697 
690 
     | 
    
         
             
                    self.updateStatusMessage.emit(self.tr("Spell check complete"))
         
     | 
| 
       698 
     | 
    
         
            -
                    return
         
     | 
| 
       699 
691 
     | 
    
         | 
| 
       700 
692 
     | 
    
         
             
                ##
         
     | 
| 
       701 
693 
     | 
    
         
             
                #  General Class Methods
         
     | 
| 
         @@ -735,14 +727,16 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       735 
727 
     | 
    
         
             
                        self._toggleFormat(2, "*")
         
     | 
| 
       736 
728 
     | 
    
         
             
                    elif action == nwDocAction.MD_STRIKE:
         
     | 
| 
       737 
729 
     | 
    
         
             
                        self._toggleFormat(2, "~")
         
     | 
| 
      
 730 
     | 
    
         
            +
                    elif action == nwDocAction.MD_MARK:
         
     | 
| 
      
 731 
     | 
    
         
            +
                        self._toggleFormat(2, "=")
         
     | 
| 
       738 
732 
     | 
    
         
             
                    elif action == nwDocAction.S_QUOTE:
         
     | 
| 
       739 
733 
     | 
    
         
             
                        self._wrapSelection(CONFIG.fmtSQuoteOpen, CONFIG.fmtSQuoteClose)
         
     | 
| 
       740 
734 
     | 
    
         
             
                    elif action == nwDocAction.D_QUOTE:
         
     | 
| 
       741 
735 
     | 
    
         
             
                        self._wrapSelection(CONFIG.fmtDQuoteOpen, CONFIG.fmtDQuoteClose)
         
     | 
| 
       742 
736 
     | 
    
         
             
                    elif action == nwDocAction.SEL_ALL:
         
     | 
| 
       743 
     | 
    
         
            -
                        self._makeSelection( 
     | 
| 
      
 737 
     | 
    
         
            +
                        self._makeSelection(QtSelectDocument)
         
     | 
| 
       744 
738 
     | 
    
         
             
                    elif action == nwDocAction.SEL_PARA:
         
     | 
| 
       745 
     | 
    
         
            -
                        self._makeSelection( 
     | 
| 
      
 739 
     | 
    
         
            +
                        self._makeSelection(QtSelectBlock)
         
     | 
| 
       746 
740 
     | 
    
         
             
                    elif action == nwDocAction.BLOCK_H1:
         
     | 
| 
       747 
741 
     | 
    
         
             
                        self._formatBlock(nwDocAction.BLOCK_H1)
         
     | 
| 
       748 
742 
     | 
    
         
             
                    elif action == nwDocAction.BLOCK_H2:
         
     | 
| 
         @@ -794,7 +788,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       794 
788 
     | 
    
         
             
                    elif action == nwDocAction.SC_SUB:
         
     | 
| 
       795 
789 
     | 
    
         
             
                        self._wrapSelection(nwShortcode.SUB_O, nwShortcode.SUB_C)
         
     | 
| 
       796 
790 
     | 
    
         
             
                    else:
         
     | 
| 
       797 
     | 
    
         
            -
                        logger.debug("Unknown or unsupported document action '%s'",  
     | 
| 
      
 791 
     | 
    
         
            +
                        logger.debug("Unknown or unsupported document action '%s'", action)
         
     | 
| 
       798 
792 
     | 
    
         
             
                        self._allowAutoReplace(True)
         
     | 
| 
       799 
793 
     | 
    
         
             
                        return False
         
     | 
| 
       800 
794 
     | 
    
         | 
| 
         @@ -822,7 +816,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       822 
816 
     | 
    
         
             
                            details=self.tr("File Location: {0}").format(self._nwDocument.fileLocation),
         
     | 
| 
       823 
817 
     | 
    
         
             
                            log=False
         
     | 
| 
       824 
818 
     | 
    
         
             
                        )
         
     | 
| 
       825 
     | 
    
         
            -
                    return
         
     | 
| 
       826 
819 
     | 
    
         | 
| 
       827 
820 
     | 
    
         
             
                def insertText(self, insert: str | nwDocInsert) -> None:
         
     | 
| 
       828 
821 
     | 
    
         
             
                    """Insert a specific type of text at the cursor position."""
         
     | 
| 
         @@ -964,7 +957,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       964 
957 
     | 
    
         
             
                        event.acceptProposedAction()
         
     | 
| 
       965 
958 
     | 
    
         
             
                    else:
         
     | 
| 
       966 
959 
     | 
    
         
             
                        super().dragEnterEvent(event)
         
     | 
| 
       967 
     | 
    
         
            -
                    return
         
     | 
| 
       968 
960 
     | 
    
         | 
| 
       969 
961 
     | 
    
         
             
                def dragMoveEvent(self, event: QDragMoveEvent) -> None:
         
     | 
| 
       970 
962 
     | 
    
         
             
                    """Overload drag move event to handle dragged items."""
         
     | 
| 
         @@ -972,7 +964,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       972 
964 
     | 
    
         
             
                        event.acceptProposedAction()
         
     | 
| 
       973 
965 
     | 
    
         
             
                    else:
         
     | 
| 
       974 
966 
     | 
    
         
             
                        super().dragMoveEvent(event)
         
     | 
| 
       975 
     | 
    
         
            -
                    return
         
     | 
| 
       976 
967 
     | 
    
         | 
| 
       977 
968 
     | 
    
         
             
                def dropEvent(self, event: QDropEvent) -> None:
         
     | 
| 
       978 
969 
     | 
    
         
             
                    """Overload drop event to handle dragged items."""
         
     | 
| 
         @@ -982,7 +973,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       982 
973 
     | 
    
         
             
                                self.openDocumentRequest.emit(handles[0], nwDocMode.EDIT, "", True)
         
     | 
| 
       983 
974 
     | 
    
         
             
                    else:
         
     | 
| 
       984 
975 
     | 
    
         
             
                        super().dropEvent(event)
         
     | 
| 
       985 
     | 
    
         
            -
                    return
         
     | 
| 
       986 
976 
     | 
    
         | 
| 
       987 
977 
     | 
    
         
             
                def focusNextPrevChild(self, _next: bool) -> bool:
         
     | 
| 
       988 
978 
     | 
    
         
             
                    """Capture the focus request from the tab key on the text
         
     | 
| 
         @@ -1009,7 +999,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1009 
999 
     | 
    
         
             
                        else:
         
     | 
| 
       1010 
1000 
     | 
    
         
             
                            self._processTag(cursor)
         
     | 
| 
       1011 
1001 
     | 
    
         
             
                    super().mouseReleaseEvent(event)
         
     | 
| 
       1012 
     | 
    
         
            -
                    return
         
     | 
| 
       1013 
1002 
     | 
    
         | 
| 
       1014 
1003 
     | 
    
         
             
                def resizeEvent(self, event: QResizeEvent) -> None:
         
     | 
| 
       1015 
1004 
     | 
    
         
             
                    """If the text editor is resized, we must make sure the document
         
     | 
| 
         @@ -1017,7 +1006,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1017 
1006 
     | 
    
         
             
                    """
         
     | 
| 
       1018 
1007 
     | 
    
         
             
                    self.updateDocMargins()
         
     | 
| 
       1019 
1008 
     | 
    
         
             
                    super().resizeEvent(event)
         
     | 
| 
       1020 
     | 
    
         
            -
                    return
         
     | 
| 
       1021 
1009 
     | 
    
         | 
| 
       1022 
1010 
     | 
    
         
             
                def inputMethodEvent(self, event: QInputMethodEvent) -> None:
         
     | 
| 
       1023 
1011 
     | 
    
         
             
                    """Handle text being input from CJK input methods."""
         
     | 
| 
         @@ -1045,14 +1033,13 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1045 
1033 
     | 
    
         | 
| 
       1046 
1034 
     | 
    
         
             
                @pyqtSlot(str, Enum)
         
     | 
| 
       1047 
1035 
     | 
    
         
             
                def onProjectItemChanged(self, tHandle: str, change: nwChange) -> None:
         
     | 
| 
       1048 
     | 
    
         
            -
                    """Called when an item label is 
     | 
| 
       1049 
     | 
    
         
            -
                    title bar needs updating 
     | 
| 
      
 1036 
     | 
    
         
            +
                    """Process project item change. Called when an item label is
         
     | 
| 
      
 1037 
     | 
    
         
            +
                    changed to check if the document title bar needs updating.
         
     | 
| 
       1050 
1038 
     | 
    
         
             
                    """
         
     | 
| 
       1051 
1039 
     | 
    
         
             
                    if tHandle == self._docHandle and change == nwChange.UPDATE:
         
     | 
| 
       1052 
1040 
     | 
    
         
             
                        self.docHeader.setHandle(tHandle)
         
     | 
| 
       1053 
1041 
     | 
    
         
             
                        self.docFooter.updateInfo()
         
     | 
| 
       1054 
1042 
     | 
    
         
             
                        self.updateDocMargins()
         
     | 
| 
       1055 
     | 
    
         
            -
                    return
         
     | 
| 
       1056 
1043 
     | 
    
         | 
| 
       1057 
1044 
     | 
    
         
             
                @pyqtSlot(str)
         
     | 
| 
       1058 
1045 
     | 
    
         
             
                def insertKeyWord(self, keyword: str) -> bool:
         
     | 
| 
         @@ -1063,8 +1050,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1063 
1050 
     | 
    
         
             
                        logger.error("Invalid keyword '%s'", keyword)
         
     | 
| 
       1064 
1051 
     | 
    
         
             
                        return False
         
     | 
| 
       1065 
1052 
     | 
    
         
             
                    logger.debug("Inserting keyword '%s'", keyword)
         
     | 
| 
       1066 
     | 
    
         
            -
                     
     | 
| 
       1067 
     | 
    
         
            -
                    return state
         
     | 
| 
      
 1053 
     | 
    
         
            +
                    return self.insertNewBlock(f"{keyword}: ")
         
     | 
| 
       1068 
1054 
     | 
    
         | 
| 
       1069 
1055 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1070 
1056 
     | 
    
         
             
                def toggleSearch(self) -> None:
         
     | 
| 
         @@ -1073,14 +1059,12 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1073 
1059 
     | 
    
         
             
                        self.closeSearch()
         
     | 
| 
       1074 
1060 
     | 
    
         
             
                    else:
         
     | 
| 
       1075 
1061 
     | 
    
         
             
                        self.beginSearch()
         
     | 
| 
       1076 
     | 
    
         
            -
                    return
         
     | 
| 
       1077 
1062 
     | 
    
         | 
| 
       1078 
1063 
     | 
    
         
             
                @pyqtSlot(list, list)
         
     | 
| 
       1079 
1064 
     | 
    
         
             
                def updateChangedTags(self, updated: list[str], deleted: list[str]) -> None:
         
     | 
| 
       1080 
1065 
     | 
    
         
             
                    """Tags have changed, so just in case we rehighlight them."""
         
     | 
| 
       1081 
1066 
     | 
    
         
             
                    if updated or deleted:
         
     | 
| 
       1082 
1067 
     | 
    
         
             
                        self._qDocument.syntaxHighlighter.rehighlightByType(BLOCK_META)
         
     | 
| 
       1083 
     | 
    
         
            -
                    return
         
     | 
| 
       1084 
1068 
     | 
    
         | 
| 
       1085 
1069 
     | 
    
         
             
                ##
         
     | 
| 
       1086 
1070 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -1122,13 +1106,14 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1122 
1106 
     | 
    
         
             
                            if self._autoReplace.process(text, cursor):
         
     | 
| 
       1123 
1107 
     | 
    
         
             
                                self._qDocument.syntaxHighlighter.rehighlightBlock(cursor.block())
         
     | 
| 
       1124 
1108 
     | 
    
         | 
| 
       1125 
     | 
    
         
            -
                    return
         
     | 
| 
       1126 
     | 
    
         
            -
             
     | 
| 
       1127 
1109 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1128 
1110 
     | 
    
         
             
                def _cursorMoved(self) -> None:
         
     | 
| 
       1129 
1111 
     | 
    
         
             
                    """Triggered when the cursor moved in the editor."""
         
     | 
| 
       1130 
1112 
     | 
    
         
             
                    self.docFooter.updateLineCount(self.textCursor())
         
     | 
| 
       1131 
     | 
    
         
            -
                     
     | 
| 
      
 1113 
     | 
    
         
            +
                    if CONFIG.lineHighlight:
         
     | 
| 
      
 1114 
     | 
    
         
            +
                        self._selection.cursor = self.textCursor()
         
     | 
| 
      
 1115 
     | 
    
         
            +
                        self._selection.cursor.clearSelection()
         
     | 
| 
      
 1116 
     | 
    
         
            +
                        self.setExtraSelections([self._selection])
         
     | 
| 
       1132 
1117 
     | 
    
         | 
| 
       1133 
1118 
     | 
    
         
             
                @pyqtSlot(int, int, str)
         
     | 
| 
       1134 
1119 
     | 
    
         
             
                def _insertCompletion(self, pos: int, length: int, text: str) -> None:
         
     | 
| 
         @@ -1140,13 +1125,11 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1140 
1125 
     | 
    
         
             
                        cursor.setPosition(check + length, QtKeepAnchor)
         
     | 
| 
       1141 
1126 
     | 
    
         
             
                        cursor.insertText(text)
         
     | 
| 
       1142 
1127 
     | 
    
         
             
                        self._completer.close()
         
     | 
| 
       1143 
     | 
    
         
            -
                    return
         
     | 
| 
       1144 
1128 
     | 
    
         | 
| 
       1145 
1129 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1146 
1130 
     | 
    
         
             
                def _openContextFromCursor(self) -> None:
         
     | 
| 
       1147 
1131 
     | 
    
         
             
                    """Open the spell check context menu at the cursor."""
         
     | 
| 
       1148 
1132 
     | 
    
         
             
                    self._openContextMenu(self.cursorRect().center())
         
     | 
| 
       1149 
     | 
    
         
            -
                    return
         
     | 
| 
       1150 
1133 
     | 
    
         | 
| 
       1151 
1134 
     | 
    
         
             
                @pyqtSlot("QPoint")
         
     | 
| 
       1152 
1135 
     | 
    
         
             
                def _openContextMenu(self, pos: QPoint) -> None:
         
     | 
| 
         @@ -1194,23 +1177,19 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1194 
1177 
     | 
    
         
             
                    action = qtAddAction(ctxMenu, self.tr("Select All"))
         
     | 
| 
       1195 
1178 
     | 
    
         
             
                    action.triggered.connect(qtLambda(self.docAction, nwDocAction.SEL_ALL))
         
     | 
| 
       1196 
1179 
     | 
    
         
             
                    action = qtAddAction(ctxMenu, self.tr("Select Word"))
         
     | 
| 
       1197 
     | 
    
         
            -
                    action.triggered.connect(qtLambda(
         
     | 
| 
       1198 
     | 
    
         
            -
                        self._makePosSelection, QTextCursor.SelectionType.WordUnderCursor, pos,
         
     | 
| 
       1199 
     | 
    
         
            -
                    ))
         
     | 
| 
      
 1180 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(self._makePosSelection, QtSelectWord, pos))
         
     | 
| 
       1200 
1181 
     | 
    
         
             
                    action = qtAddAction(ctxMenu, self.tr("Select Paragraph"))
         
     | 
| 
       1201 
     | 
    
         
            -
                    action.triggered.connect(qtLambda(
         
     | 
| 
       1202 
     | 
    
         
            -
                        self._makePosSelection, QTextCursor.SelectionType.BlockUnderCursor, pos
         
     | 
| 
       1203 
     | 
    
         
            -
                    ))
         
     | 
| 
      
 1182 
     | 
    
         
            +
                    action.triggered.connect(qtLambda(self._makePosSelection, QtSelectBlock, pos))
         
     | 
| 
       1204 
1183 
     | 
    
         | 
| 
       1205 
1184 
     | 
    
         
             
                    # Spell Checking
         
     | 
| 
       1206 
1185 
     | 
    
         
             
                    if SHARED.project.data.spellCheck:
         
     | 
| 
       1207 
     | 
    
         
            -
                        word,  
     | 
| 
       1208 
     | 
    
         
            -
                        if word and  
     | 
| 
      
 1186 
     | 
    
         
            +
                        word, offset, suggest = self._qDocument.spellErrorAtPos(pCursor.position())
         
     | 
| 
      
 1187 
     | 
    
         
            +
                        if word and offset >= 0:
         
     | 
| 
       1209 
1188 
     | 
    
         
             
                            logger.debug("Word '%s' is misspelled", word)
         
     | 
| 
       1210 
1189 
     | 
    
         
             
                            block = pCursor.block()
         
     | 
| 
       1211 
1190 
     | 
    
         
             
                            sCursor = self.textCursor()
         
     | 
| 
       1212 
     | 
    
         
            -
                            sCursor.setPosition(block.position() +  
     | 
| 
       1213 
     | 
    
         
            -
                            sCursor.movePosition(QtMoveRight, QtKeepAnchor,  
     | 
| 
      
 1191 
     | 
    
         
            +
                            sCursor.setPosition(block.position() + offset)
         
     | 
| 
      
 1192 
     | 
    
         
            +
                            sCursor.movePosition(QtMoveRight, QtKeepAnchor, len(word))
         
     | 
| 
       1214 
1193 
     | 
    
         
             
                            if suggest:
         
     | 
| 
       1215 
1194 
     | 
    
         
             
                                ctxMenu.addSeparator()
         
     | 
| 
       1216 
1195 
     | 
    
         
             
                                qtAddAction(ctxMenu, self.tr("Spelling Suggestion(s)"))
         
     | 
| 
         @@ -1233,8 +1212,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1233 
1212 
     | 
    
         | 
| 
       1234 
1213 
     | 
    
         
             
                    ctxMenu.setParent(None)
         
     | 
| 
       1235 
1214 
     | 
    
         | 
| 
       1236 
     | 
    
         
            -
                    return
         
     | 
| 
       1237 
     | 
    
         
            -
             
     | 
| 
       1238 
1215 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1239 
1216 
     | 
    
         
             
                def _runDocumentTasks(self) -> None:
         
     | 
| 
       1240 
1217 
     | 
    
         
             
                    """Run timer document tasks."""
         
     | 
| 
         @@ -1271,11 +1248,10 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1271 
1248 
     | 
    
         
             
                            if not self.textCursor().hasSelection():
         
     | 
| 
       1272 
1249 
     | 
    
         
             
                                # Selection counter should take precedence (#2155)
         
     | 
| 
       1273 
1250 
     | 
    
         
             
                                self.docFooter.updateMainCount(mCount, False)
         
     | 
| 
       1274 
     | 
    
         
            -
                    return
         
     | 
| 
       1275 
1251 
     | 
    
         | 
| 
       1276 
1252 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1277 
1253 
     | 
    
         
             
                def _updateSelectedStatus(self) -> None:
         
     | 
| 
       1278 
     | 
    
         
            -
                    """ 
     | 
| 
      
 1254 
     | 
    
         
            +
                    """Process user change in text selection. Forward this
         
     | 
| 
       1279 
1255 
     | 
    
         
             
                    information to the footer, and start the selection word counter.
         
     | 
| 
       1280 
1256 
     | 
    
         
             
                    """
         
     | 
| 
       1281 
1257 
     | 
    
         
             
                    if self.textCursor().hasSelection():
         
     | 
| 
         @@ -1284,7 +1260,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1284 
1260 
     | 
    
         
             
                    else:
         
     | 
| 
       1285 
1261 
     | 
    
         
             
                        self._timerSel.stop()
         
     | 
| 
       1286 
1262 
     | 
    
         
             
                        self.docFooter.updateMainCount(0, False)
         
     | 
| 
       1287 
     | 
    
         
            -
                    return
         
     | 
| 
       1288 
1263 
     | 
    
         | 
| 
       1289 
1264 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1290 
1265 
     | 
    
         
             
                def _runSelCounter(self) -> None:
         
     | 
| 
         @@ -1302,14 +1277,12 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1302 
1277 
     | 
    
         
             
                    if self._docHandle and self._nwItem:
         
     | 
| 
       1303 
1278 
     | 
    
         
             
                        self.docFooter.updateMainCount(cCount if CONFIG.useCharCount else wCount, True)
         
     | 
| 
       1304 
1279 
     | 
    
         
             
                        self._timerSel.stop()
         
     | 
| 
       1305 
     | 
    
         
            -
                    return
         
     | 
| 
       1306 
1280 
     | 
    
         | 
| 
       1307 
1281 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1308 
1282 
     | 
    
         
             
                def _closeCurrentDocument(self) -> None:
         
     | 
| 
       1309 
1283 
     | 
    
         
             
                    """Close the document. Forwarded to the main Gui."""
         
     | 
| 
       1310 
1284 
     | 
    
         
             
                    self.closeEditorRequest.emit()
         
     | 
| 
       1311 
1285 
     | 
    
         
             
                    self.docToolBar.setVisible(False)
         
     | 
| 
       1312 
     | 
    
         
            -
                    return
         
     | 
| 
       1313 
1286 
     | 
    
         | 
| 
       1314 
1287 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1315 
1288 
     | 
    
         
             
                def _toggleToolBarVisibility(self) -> None:
         
     | 
| 
         @@ -1317,7 +1290,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1317 
1290 
     | 
    
         
             
                    state = not self.docToolBar.isVisible()
         
     | 
| 
       1318 
1291 
     | 
    
         
             
                    self.docToolBar.setVisible(state)
         
     | 
| 
       1319 
1292 
     | 
    
         
             
                    CONFIG.showEditToolBar = state
         
     | 
| 
       1320 
     | 
    
         
            -
                    return
         
     | 
| 
       1321 
1293 
     | 
    
         | 
| 
       1322 
1294 
     | 
    
         
             
                ##
         
     | 
| 
       1323 
1295 
     | 
    
         
             
                #  Search & Replace
         
     | 
| 
         @@ -1328,14 +1300,12 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1328 
1300 
     | 
    
         
             
                    self.docSearch.setSearchText(self.getSelectedText() or None)
         
     | 
| 
       1329 
1301 
     | 
    
         
             
                    resS, _ = self.findAllOccurences()
         
     | 
| 
       1330 
1302 
     | 
    
         
             
                    self.docSearch.setResultCount(None, len(resS))
         
     | 
| 
       1331 
     | 
    
         
            -
                    return
         
     | 
| 
       1332 
1303 
     | 
    
         | 
| 
       1333 
1304 
     | 
    
         
             
                def beginReplace(self) -> None:
         
     | 
| 
       1334 
1305 
     | 
    
         
             
                    """Initialise the search box and reset the replace text box."""
         
     | 
| 
       1335 
1306 
     | 
    
         
             
                    self.beginSearch()
         
     | 
| 
       1336 
1307 
     | 
    
         
             
                    self.docSearch.setReplaceText("")
         
     | 
| 
       1337 
1308 
     | 
    
         
             
                    self.updateDocMargins()
         
     | 
| 
       1338 
     | 
    
         
            -
                    return
         
     | 
| 
       1339 
1309 
     | 
    
         | 
| 
       1340 
1310 
     | 
    
         
             
                def findNext(self, goBack: bool = False) -> None:
         
     | 
| 
       1341 
1311 
     | 
    
         
             
                    """Search for the next or previous occurrence of the search bar
         
     | 
| 
         @@ -1623,8 +1593,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1623 
1593 
     | 
    
         | 
| 
       1624 
1594 
     | 
    
         
             
                    self.setTextCursor(cursor)
         
     | 
| 
       1625 
1595 
     | 
    
         | 
| 
       1626 
     | 
    
         
            -
                    return
         
     | 
| 
       1627 
     | 
    
         
            -
             
     | 
| 
       1628 
1596 
     | 
    
         
             
                def _replaceQuotes(self, sQuote: str, oQuote: str, cQuote: str) -> None:
         
     | 
| 
       1629 
1597 
     | 
    
         
             
                    """Replace all straight quotes in the selected text."""
         
     | 
| 
       1630 
1598 
     | 
    
         
             
                    cursor = self.textCursor()
         
     | 
| 
         @@ -1781,7 +1749,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1781 
1749 
     | 
    
         
             
                    elif action == nwDocAction.BLOCK_TXT:
         
     | 
| 
       1782 
1750 
     | 
    
         
             
                        text = temp
         
     | 
| 
       1783 
1751 
     | 
    
         
             
                    else:
         
     | 
| 
       1784 
     | 
    
         
            -
                        logger.error("Unknown or unsupported block format requested: '%s'",  
     | 
| 
      
 1752 
     | 
    
         
            +
                        logger.error("Unknown or unsupported block format requested: '%s'", action)
         
     | 
| 
       1785 
1753 
     | 
    
         
             
                        return nwDocAction.NO_ACTION, "", 0
         
     | 
| 
       1786 
1754 
     | 
    
         | 
| 
       1787 
1755 
     | 
    
         
             
                    return action, text, offset
         
     | 
| 
         @@ -1791,7 +1759,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1791 
1759 
     | 
    
         
             
                    cursor = self.textCursor()
         
     | 
| 
       1792 
1760 
     | 
    
         
             
                    block = cursor.block()
         
     | 
| 
       1793 
1761 
     | 
    
         
             
                    if not block.isValid():
         
     | 
| 
       1794 
     | 
    
         
            -
                        logger.debug("Invalid block selected for action '%s'",  
     | 
| 
      
 1762 
     | 
    
         
            +
                        logger.debug("Invalid block selected for action '%s'", action)
         
     | 
| 
       1795 
1763 
     | 
    
         
             
                        return False
         
     | 
| 
       1796 
1764 
     | 
    
         | 
| 
       1797 
1765 
     | 
    
         
             
                    action, text, offset = self._processBlockFormat(action, block.text())
         
     | 
| 
         @@ -1801,7 +1769,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1801 
1769 
     | 
    
         
             
                    pos = cursor.position()
         
     | 
| 
       1802 
1770 
     | 
    
         | 
| 
       1803 
1771 
     | 
    
         
             
                    cursor.beginEditBlock()
         
     | 
| 
       1804 
     | 
    
         
            -
                    self._makeSelection( 
     | 
| 
      
 1772 
     | 
    
         
            +
                    self._makeSelection(QtSelectBlock, cursor)
         
     | 
| 
       1805 
1773 
     | 
    
         
             
                    cursor.insertText(text)
         
     | 
| 
       1806 
1774 
     | 
    
         
             
                    cursor.endEditBlock()
         
     | 
| 
       1807 
1775 
     | 
    
         | 
| 
         @@ -1829,7 +1797,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1829 
1797 
     | 
    
         
             
                        if pAction != nwDocAction.NO_ACTION and blockText.strip():
         
     | 
| 
       1830 
1798 
     | 
    
         
             
                            action = pAction  # First block decides further actions
         
     | 
| 
       1831 
1799 
     | 
    
         
             
                            cursor.setPosition(block.position())
         
     | 
| 
       1832 
     | 
    
         
            -
                            self._makeSelection( 
     | 
| 
      
 1800 
     | 
    
         
            +
                            self._makeSelection(QtSelectBlock, cursor)
         
     | 
| 
       1833 
1801 
     | 
    
         
             
                            cursor.insertText(text)
         
     | 
| 
       1834 
1802 
     | 
    
         
             
                            toggle = False
         
     | 
| 
       1835 
1803 
     | 
    
         | 
| 
         @@ -1849,7 +1817,7 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1849 
1817 
     | 
    
         
             
                    """Strip line breaks within paragraphs in the selected text."""
         
     | 
| 
       1850 
1818 
     | 
    
         
             
                    cursor = self.textCursor()
         
     | 
| 
       1851 
1819 
     | 
    
         
             
                    if not cursor.hasSelection():
         
     | 
| 
       1852 
     | 
    
         
            -
                        cursor.select( 
     | 
| 
      
 1820 
     | 
    
         
            +
                        cursor.select(QtSelectDocument)
         
     | 
| 
       1853 
1821 
     | 
    
         | 
| 
       1854 
1822 
     | 
    
         
             
                    rS = 0
         
     | 
| 
       1855 
1823 
     | 
    
         
             
                    rE = self._qDocument.characterCount()
         
     | 
| 
         @@ -1884,8 +1852,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1884 
1852 
     | 
    
         
             
                    cursor.insertText(cleanText.rstrip() + "\n")
         
     | 
| 
       1885 
1853 
     | 
    
         
             
                    cursor.endEditBlock()
         
     | 
| 
       1886 
1854 
     | 
    
         | 
| 
       1887 
     | 
    
         
            -
                    return
         
     | 
| 
       1888 
     | 
    
         
            -
             
     | 
| 
       1889 
1855 
     | 
    
         
             
                def _insertCommentStructure(self, style: nwComment) -> None:
         
     | 
| 
       1890 
1856 
     | 
    
         
             
                    """Insert a shortcut/comment combo."""
         
     | 
| 
       1891 
1857 
     | 
    
         
             
                    if self._docHandle and style == nwComment.FOOTNOTE:
         
     | 
| 
         @@ -1933,7 +1899,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1933 
1899 
     | 
    
         
             
                    cursor.endEditBlock()
         
     | 
| 
       1934 
1900 
     | 
    
         
             
                    cursor.setPosition(pos)
         
     | 
| 
       1935 
1901 
     | 
    
         
             
                    self.setTextCursor(cursor)
         
     | 
| 
       1936 
     | 
    
         
            -
                    return
         
     | 
| 
       1937 
1902 
     | 
    
         | 
| 
       1938 
1903 
     | 
    
         
             
                def _addWord(self, word: str, block: QTextBlock, save: bool) -> None:
         
     | 
| 
       1939 
1904 
     | 
    
         
             
                    """Slot for the spell check context menu triggered when the user
         
     | 
| 
         @@ -1942,7 +1907,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       1942 
1907 
     | 
    
         
             
                    logger.debug("Added '%s' to project dictionary, %s", word, "saved" if save else "unsaved")
         
     | 
| 
       1943 
1908 
     | 
    
         
             
                    SHARED.spelling.addWord(word, save=save)
         
     | 
| 
       1944 
1909 
     | 
    
         
             
                    self._qDocument.syntaxHighlighter.rehighlightBlock(block)
         
     | 
| 
       1945 
     | 
    
         
            -
                    return
         
     | 
| 
       1946 
1910 
     | 
    
         | 
| 
       1947 
1911 
     | 
    
         
             
                def _processTag(
         
     | 
| 
       1948 
1912 
     | 
    
         
             
                    self, cursor: QTextCursor | None = None, follow: bool = True, create: bool = False
         
     | 
| 
         @@ -2016,7 +1980,6 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       2016 
1980 
     | 
    
         
             
                    if self._docHandle:
         
     | 
| 
       2017 
1981 
     | 
    
         
             
                        text = block.text().lstrip("#").lstrip("!").strip()
         
     | 
| 
       2018 
1982 
     | 
    
         
             
                        self.requestProjectItemRenamed.emit(self._docHandle, text)
         
     | 
| 
       2019 
     | 
    
         
            -
                    return
         
     | 
| 
       2020 
1983 
     | 
    
         | 
| 
       2021 
1984 
     | 
    
         
             
                def _autoSelect(self) -> QTextCursor:
         
     | 
| 
       2022 
1985 
     | 
    
         
             
                    """Return a cursor which may or may not have a selection based
         
     | 
| 
         @@ -2071,10 +2034,10 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       2071 
2034 
     | 
    
         
             
                    cursor.clearSelection()
         
     | 
| 
       2072 
2035 
     | 
    
         
             
                    cursor.select(mode)
         
     | 
| 
       2073 
2036 
     | 
    
         | 
| 
       2074 
     | 
    
         
            -
                    if mode ==  
     | 
| 
      
 2037 
     | 
    
         
            +
                    if mode == QtSelectWord:
         
     | 
| 
       2075 
2038 
     | 
    
         
             
                        cursor = self._autoSelect()
         
     | 
| 
       2076 
2039 
     | 
    
         | 
| 
       2077 
     | 
    
         
            -
                    elif mode ==  
     | 
| 
      
 2040 
     | 
    
         
            +
                    elif mode == QtSelectBlock:
         
     | 
| 
       2078 
2041 
     | 
    
         
             
                        # This selection mode also selects the preceding paragraph
         
     | 
| 
       2079 
2042 
     | 
    
         
             
                        # separator, which we want to avoid.
         
     | 
| 
       2080 
2043 
     | 
    
         
             
                        posS = cursor.selectionStart()
         
     | 
| 
         @@ -2086,14 +2049,11 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       2086 
2049 
     | 
    
         | 
| 
       2087 
2050 
     | 
    
         
             
                    self.setTextCursor(cursor)
         
     | 
| 
       2088 
2051 
     | 
    
         | 
| 
       2089 
     | 
    
         
            -
                    return
         
     | 
| 
       2090 
     | 
    
         
            -
             
     | 
| 
       2091 
2052 
     | 
    
         
             
                def _makePosSelection(self, mode: QTextCursor.SelectionType, pos: QPoint) -> None:
         
     | 
| 
       2092 
2053 
     | 
    
         
             
                    """Select text based on selection mode, but first move cursor."""
         
     | 
| 
       2093 
2054 
     | 
    
         
             
                    cursor = self.cursorForPosition(pos)
         
     | 
| 
       2094 
2055 
     | 
    
         
             
                    self.setTextCursor(cursor)
         
     | 
| 
       2095 
2056 
     | 
    
         
             
                    self._makeSelection(mode)
         
     | 
| 
       2096 
     | 
    
         
            -
                    return
         
     | 
| 
       2097 
2057 
     | 
    
         | 
| 
       2098 
2058 
     | 
    
         
             
                def _allowAutoReplace(self, state: bool) -> None:
         
     | 
| 
       2099 
2059 
     | 
    
         
             
                    """Enable/disable the auto-replace feature temporarily."""
         
     | 
| 
         @@ -2101,11 +2061,10 @@ class GuiDocEditor(QPlainTextEdit): 
     | 
|
| 
       2101 
2061 
     | 
    
         
             
                        self._doReplace = CONFIG.doReplace
         
     | 
| 
       2102 
2062 
     | 
    
         
             
                    else:
         
     | 
| 
       2103 
2063 
     | 
    
         
             
                        self._doReplace = False
         
     | 
| 
       2104 
     | 
    
         
            -
                    return
         
     | 
| 
       2105 
2064 
     | 
    
         | 
| 
       2106 
2065 
     | 
    
         | 
| 
       2107 
2066 
     | 
    
         
             
            class CommandCompleter(QMenu):
         
     | 
| 
       2108 
     | 
    
         
            -
                """GuiWidget: Command Completer Menu
         
     | 
| 
      
 2067 
     | 
    
         
            +
                """GuiWidget: Command Completer Menu.
         
     | 
| 
       2109 
2068 
     | 
    
         | 
| 
       2110 
2069 
     | 
    
         
             
                This is a context menu with options populated from the user's
         
     | 
| 
       2111 
2070 
     | 
    
         
             
                defined tags and keys. It also helps to type the meta data keyword
         
     | 
| 
         @@ -2120,7 +2079,6 @@ class CommandCompleter(QMenu): 
     | 
|
| 
       2120 
2079 
     | 
    
         
             
                def __init__(self, parent: QWidget) -> None:
         
     | 
| 
       2121 
2080 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       2122 
2081 
     | 
    
         
             
                    self._parent = parent
         
     | 
| 
       2123 
     | 
    
         
            -
                    return
         
     | 
| 
       2124 
2082 
     | 
    
         | 
| 
       2125 
2083 
     | 
    
         
             
                def updateMetaText(self, text: str, pos: int) -> bool:
         
     | 
| 
       2126 
2084 
     | 
    
         
             
                    """Update the menu options based on the line of text."""
         
     | 
| 
         @@ -2214,7 +2172,6 @@ class CommandCompleter(QMenu): 
     | 
|
| 
       2214 
2172 
     | 
    
         
             
                    else:
         
     | 
| 
       2215 
2173 
     | 
    
         
             
                        self.close()  # Close to release the event lock before forwarding the key press (#2510)
         
     | 
| 
       2216 
2174 
     | 
    
         
             
                        self._parent.keyPressEvent(event)
         
     | 
| 
       2217 
     | 
    
         
            -
                    return
         
     | 
| 
       2218 
2175 
     | 
    
         | 
| 
       2219 
2176 
     | 
    
         
             
                ##
         
     | 
| 
       2220 
2177 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -2223,11 +2180,10 @@ class CommandCompleter(QMenu): 
     | 
|
| 
       2223 
2180 
     | 
    
         
             
                def _emitComplete(self, pos: int, length: int, value: str) -> None:
         
     | 
| 
       2224 
2181 
     | 
    
         
             
                    """Emit the signal to indicate a selection has been made."""
         
     | 
| 
       2225 
2182 
     | 
    
         
             
                    self.insertText.emit(pos, length, value)
         
     | 
| 
       2226 
     | 
    
         
            -
                    return
         
     | 
| 
       2227 
2183 
     | 
    
         | 
| 
       2228 
2184 
     | 
    
         | 
| 
       2229 
2185 
     | 
    
         
             
            class BackgroundWordCounter(QRunnable):
         
     | 
| 
       2230 
     | 
    
         
            -
                """The Off-GUI Thread Word Counter
         
     | 
| 
      
 2186 
     | 
    
         
            +
                """The Off-GUI Thread Word Counter.
         
     | 
| 
       2231 
2187 
     | 
    
         | 
| 
       2232 
2188 
     | 
    
         
             
                A runnable for the word counter to be run in the thread pool off the
         
     | 
| 
       2233 
2189 
     | 
    
         
             
                main GUI thread.
         
     | 
| 
         @@ -2239,9 +2195,9 @@ class BackgroundWordCounter(QRunnable): 
     | 
|
| 
       2239 
2195 
     | 
    
         
             
                    self._forSelection = forSelection
         
     | 
| 
       2240 
2196 
     | 
    
         
             
                    self._isRunning = False
         
     | 
| 
       2241 
2197 
     | 
    
         
             
                    self.signals = BackgroundWordCounterSignals()
         
     | 
| 
       2242 
     | 
    
         
            -
                    return
         
     | 
| 
       2243 
2198 
     | 
    
         | 
| 
       2244 
2199 
     | 
    
         
             
                def isRunning(self) -> bool:
         
     | 
| 
      
 2200 
     | 
    
         
            +
                    """Return True if the word counter is already running."""
         
     | 
| 
       2245 
2201 
     | 
    
         
             
                    return self._isRunning
         
     | 
| 
       2246 
2202 
     | 
    
         | 
| 
       2247 
2203 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
         @@ -2259,17 +2215,17 @@ class BackgroundWordCounter(QRunnable): 
     | 
|
| 
       2259 
2215 
     | 
    
         
             
                    self.signals.countsReady.emit(cC, wC, pC)
         
     | 
| 
       2260 
2216 
     | 
    
         
             
                    self._isRunning = False
         
     | 
| 
       2261 
2217 
     | 
    
         | 
| 
       2262 
     | 
    
         
            -
                    return
         
     | 
| 
       2263 
     | 
    
         
            -
             
     | 
| 
       2264 
2218 
     | 
    
         | 
| 
       2265 
2219 
     | 
    
         
             
            class BackgroundWordCounterSignals(QObject):
         
     | 
| 
       2266 
2220 
     | 
    
         
             
                """The QRunnable cannot emit a signal, so we need a simple QObject
         
     | 
| 
       2267 
2221 
     | 
    
         
             
                to hold the word counter signal.
         
     | 
| 
       2268 
2222 
     | 
    
         
             
                """
         
     | 
| 
      
 2223 
     | 
    
         
            +
             
     | 
| 
       2269 
2224 
     | 
    
         
             
                countsReady = pyqtSignal(int, int, int)
         
     | 
| 
       2270 
2225 
     | 
    
         | 
| 
       2271 
2226 
     | 
    
         | 
| 
       2272 
2227 
     | 
    
         
             
            class TextAutoReplace:
         
     | 
| 
      
 2228 
     | 
    
         
            +
                """Encapsulates the editor auto replace feature."""
         
     | 
| 
       2273 
2229 
     | 
    
         | 
| 
       2274 
2230 
     | 
    
         
             
                __slots__ = (
         
     | 
| 
       2275 
2231 
     | 
    
         
             
                    "_doPadAfter", "_doPadBefore", "_padAfter", "_padBefore", "_padChar",
         
     | 
| 
         @@ -2279,7 +2235,6 @@ class TextAutoReplace: 
     | 
|
| 
       2279 
2235 
     | 
    
         | 
| 
       2280 
2236 
     | 
    
         
             
                def __init__(self) -> None:
         
     | 
| 
       2281 
2237 
     | 
    
         
             
                    self.initSettings()
         
     | 
| 
       2282 
     | 
    
         
            -
                    return
         
     | 
| 
       2283 
2238 
     | 
    
         | 
| 
       2284 
2239 
     | 
    
         
             
                def initSettings(self) -> None:
         
     | 
| 
       2285 
2240 
     | 
    
         
             
                    """Initialise the auto-replace settings from config."""
         
     | 
| 
         @@ -2298,27 +2253,28 @@ class TextAutoReplace: 
     | 
|
| 
       2298 
2253 
     | 
    
         
             
                    self._padAfter    = CONFIG.fmtPadAfter
         
     | 
| 
       2299 
2254 
     | 
    
         
             
                    self._doPadBefore = bool(CONFIG.fmtPadBefore)
         
     | 
| 
       2300 
2255 
     | 
    
         
             
                    self._doPadAfter  = bool(CONFIG.fmtPadAfter)
         
     | 
| 
       2301 
     | 
    
         
            -
                    return
         
     | 
| 
       2302 
2256 
     | 
    
         | 
| 
       2303 
2257 
     | 
    
         
             
                def process(self, text: str, cursor: QTextCursor) -> bool:
         
     | 
| 
       2304 
2258 
     | 
    
         
             
                    """Auto-replace text elements based on main configuration.
         
     | 
| 
       2305 
2259 
     | 
    
         
             
                    Returns True if anything was changed.
         
     | 
| 
       2306 
2260 
     | 
    
         
             
                    """
         
     | 
| 
       2307 
     | 
    
         
            -
                     
     | 
| 
       2308 
     | 
    
         
            -
                     
     | 
| 
       2309 
     | 
    
         
            -
                     
     | 
| 
      
 2261 
     | 
    
         
            +
                    aPos = cursor.position()
         
     | 
| 
      
 2262 
     | 
    
         
            +
                    bPos = cursor.positionInBlock()
         
     | 
| 
      
 2263 
     | 
    
         
            +
                    block = cursor.block()
         
     | 
| 
      
 2264 
     | 
    
         
            +
                    length = block.length() - 1
         
     | 
| 
      
 2265 
     | 
    
         
            +
                    if length < 1 or bPos-1 > length:
         
     | 
| 
       2310 
2266 
     | 
    
         
             
                        return False
         
     | 
| 
       2311 
2267 
     | 
    
         | 
| 
       2312 
     | 
    
         
            -
                     
     | 
| 
       2313 
     | 
    
         
            -
                     
     | 
| 
       2314 
     | 
    
         
            -
             
     | 
| 
      
 2268 
     | 
    
         
            +
                    cursor.movePosition(QtMoveLeft, QtKeepAnchor, min(4, bPos))
         
     | 
| 
      
 2269 
     | 
    
         
            +
                    last = cursor.selectedText()
         
     | 
| 
      
 2270 
     | 
    
         
            +
                    delete, insert = self._determine(last, bPos)
         
     | 
| 
       2315 
2271 
     | 
    
         | 
| 
       2316 
2272 
     | 
    
         
             
                    check = insert
         
     | 
| 
       2317 
2273 
     | 
    
         
             
                    if self._doPadBefore and check in self._padBefore:
         
     | 
| 
       2318 
2274 
     | 
    
         
             
                        if not (check == ":" and length > 1 and text[0] == "@"):
         
     | 
| 
       2319 
2275 
     | 
    
         
             
                            delete = max(delete, 1)
         
     | 
| 
       2320 
     | 
    
         
            -
                            chkPos =  
     | 
| 
       2321 
     | 
    
         
            -
                            if chkPos >= 0 and  
     | 
| 
      
 2276 
     | 
    
         
            +
                            chkPos = len(last) - delete - 1
         
     | 
| 
      
 2277 
     | 
    
         
            +
                            if chkPos >= 0 and last[chkPos].isspace():
         
     | 
| 
       2322 
2278 
     | 
    
         
             
                                # Strip existing space before inserting a new (#1061)
         
     | 
| 
       2323 
2279 
     | 
    
         
             
                                delete += 1
         
     | 
| 
       2324 
2280 
     | 
    
         
             
                            insert = self._padChar + insert
         
     | 
| 
         @@ -2329,6 +2285,7 @@ class TextAutoReplace: 
     | 
|
| 
       2329 
2285 
     | 
    
         
             
                            insert = insert + self._padChar
         
     | 
| 
       2330 
2286 
     | 
    
         | 
| 
       2331 
2287 
     | 
    
         
             
                    if delete > 0:
         
     | 
| 
      
 2288 
     | 
    
         
            +
                        cursor.setPosition(aPos)
         
     | 
| 
       2332 
2289 
     | 
    
         
             
                        cursor.movePosition(QtMoveLeft, QtKeepAnchor, delete)
         
     | 
| 
       2333 
2290 
     | 
    
         
             
                        cursor.insertText(insert)
         
     | 
| 
       2334 
2291 
     | 
    
         
             
                        return True
         
     | 
| 
         @@ -2337,42 +2294,55 @@ class TextAutoReplace: 
     | 
|
| 
       2337 
2294 
     | 
    
         | 
| 
       2338 
2295 
     | 
    
         
             
                def _determine(self, text: str, pos: int) -> tuple[int, str]:
         
     | 
| 
       2339 
2296 
     | 
    
         
             
                    """Determine what to replace, if anything."""
         
     | 
| 
       2340 
     | 
    
         
            -
                    t1 = text[ 
     | 
| 
       2341 
     | 
    
         
            -
                    t2 = text[ 
     | 
| 
       2342 
     | 
    
         
            -
                    t3 = text[ 
     | 
| 
       2343 
     | 
    
         
            -
                    t4 = text[ 
     | 
| 
       2344 
     | 
    
         
            -
             
     | 
| 
       2345 
     | 
    
         
            -
             
     | 
| 
       2346 
     | 
    
         
            -
                         
     | 
| 
       2347 
     | 
    
         
            -
             
     | 
| 
       2348 
     | 
    
         
            -
                    leading = t2[:1].isspace()
         
     | 
| 
       2349 
     | 
    
         
            -
                    if self._replaceDQuote:
         
     | 
| 
       2350 
     | 
    
         
            -
                        if leading and t2.endswith('"'):
         
     | 
| 
      
 2297 
     | 
    
         
            +
                    t1 = text[-1:]
         
     | 
| 
      
 2298 
     | 
    
         
            +
                    t2 = text[-2:]
         
     | 
| 
      
 2299 
     | 
    
         
            +
                    t3 = text[-3:]
         
     | 
| 
      
 2300 
     | 
    
         
            +
                    t4 = text[-4:]
         
     | 
| 
      
 2301 
     | 
    
         
            +
             
     | 
| 
      
 2302 
     | 
    
         
            +
                    if self._replaceDQuote and t1 == '"':
         
     | 
| 
      
 2303 
     | 
    
         
            +
                        # Process Double Quote
         
     | 
| 
      
 2304 
     | 
    
         
            +
                        if pos == 1:
         
     | 
| 
       2351 
2305 
     | 
    
         
             
                            return 1, self._quoteDO
         
     | 
| 
       2352 
     | 
    
         
            -
                        elif  
     | 
| 
       2353 
     | 
    
         
            -
                             
     | 
| 
       2354 
     | 
    
         
            -
             
     | 
| 
       2355 
     | 
    
         
            -
                             
     | 
| 
       2356 
     | 
    
         
            -
             
     | 
| 
       2357 
     | 
    
         
            -
                             
     | 
| 
       2358 
     | 
    
         
            -
             
     | 
| 
       2359 
     | 
    
         
            -
                             
     | 
| 
       2360 
     | 
    
         
            -
             
     | 
| 
      
 2306 
     | 
    
         
            +
                        elif t2[:1].isspace() and t2.endswith('"'):
         
     | 
| 
      
 2307 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2308 
     | 
    
         
            +
                        elif pos == 2 and t2 == '>"':
         
     | 
| 
      
 2309 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2310 
     | 
    
         
            +
                        elif pos == 3 and t3 == '>>"':
         
     | 
| 
      
 2311 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2312 
     | 
    
         
            +
                        elif pos == 2 and t2 == '_"':
         
     | 
| 
      
 2313 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2314 
     | 
    
         
            +
                        elif t3[:1].isspace() and t3.endswith('_"'):
         
     | 
| 
      
 2315 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2316 
     | 
    
         
            +
                        elif pos == 3 and t3 in ('**"', '=="', '~~"'):
         
     | 
| 
      
 2317 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2318 
     | 
    
         
            +
                        elif t4[:1].isspace() and t4.endswith(('**"', '=="', '~~"')):
         
     | 
| 
      
 2319 
     | 
    
         
            +
                            return 1, self._quoteDO
         
     | 
| 
      
 2320 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 2321 
     | 
    
         
            +
                            return 1, self._quoteDC
         
     | 
| 
       2361 
2322 
     | 
    
         | 
| 
       2362 
     | 
    
         
            -
                    if self._replaceSQuote:
         
     | 
| 
       2363 
     | 
    
         
            -
                         
     | 
| 
      
 2323 
     | 
    
         
            +
                    if self._replaceSQuote and t1 == "'":
         
     | 
| 
      
 2324 
     | 
    
         
            +
                        # Process Single Quote
         
     | 
| 
      
 2325 
     | 
    
         
            +
                        if pos == 1:
         
     | 
| 
       2364 
2326 
     | 
    
         
             
                            return 1, self._quoteSO
         
     | 
| 
       2365 
     | 
    
         
            -
                        elif  
     | 
| 
       2366 
     | 
    
         
            -
                             
     | 
| 
       2367 
     | 
    
         
            -
             
     | 
| 
       2368 
     | 
    
         
            -
                             
     | 
| 
       2369 
     | 
    
         
            -
             
     | 
| 
       2370 
     | 
    
         
            -
                             
     | 
| 
       2371 
     | 
    
         
            -
             
     | 
| 
       2372 
     | 
    
         
            -
                             
     | 
| 
       2373 
     | 
    
         
            -
             
     | 
| 
      
 2327 
     | 
    
         
            +
                        elif t2[:1].isspace() and t2.endswith("'"):
         
     | 
| 
      
 2328 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2329 
     | 
    
         
            +
                        elif pos == 2 and t2 == ">'":
         
     | 
| 
      
 2330 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2331 
     | 
    
         
            +
                        elif pos == 3 and t3 == ">>'":
         
     | 
| 
      
 2332 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2333 
     | 
    
         
            +
                        elif pos == 2 and t2 == "_'":
         
     | 
| 
      
 2334 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2335 
     | 
    
         
            +
                        elif t3[:1].isspace() and t3.endswith("_'"):
         
     | 
| 
      
 2336 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2337 
     | 
    
         
            +
                        elif pos == 3 and t3 in ("**'", "=='", "~~'"):
         
     | 
| 
      
 2338 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2339 
     | 
    
         
            +
                        elif t4[:1].isspace() and t4.endswith(("**'", "=='", "~~'")):
         
     | 
| 
      
 2340 
     | 
    
         
            +
                            return 1, self._quoteSO
         
     | 
| 
      
 2341 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 2342 
     | 
    
         
            +
                            return 1, self._quoteSC
         
     | 
| 
       2374 
2343 
     | 
    
         | 
| 
       2375 
     | 
    
         
            -
                    if self._replaceDash:
         
     | 
| 
      
 2344 
     | 
    
         
            +
                    if self._replaceDash and t1 == "-":
         
     | 
| 
      
 2345 
     | 
    
         
            +
                        # Process Dashes
         
     | 
| 
       2376 
2346 
     | 
    
         
             
                        if t4 == "----":
         
     | 
| 
       2377 
2347 
     | 
    
         
             
                            return 4, "\u2015"  # Horizontal bar
         
     | 
| 
       2378 
2348 
     | 
    
         
             
                        elif t3 == "---":
         
     | 
| 
         @@ -2385,6 +2355,7 @@ class TextAutoReplace: 
     | 
|
| 
       2385 
2355 
     | 
    
         
             
                            return 2, "\u2015"  # Horizontal bar
         
     | 
| 
       2386 
2356 
     | 
    
         | 
| 
       2387 
2357 
     | 
    
         
             
                    if self._replaceDots and t3 == "...":
         
     | 
| 
      
 2358 
     | 
    
         
            +
                        # Process Dots
         
     | 
| 
       2388 
2359 
     | 
    
         
             
                        return 3, "\u2026"  # Ellipsis
         
     | 
| 
       2389 
2360 
     | 
    
         | 
| 
       2390 
2361 
     | 
    
         
             
                    if t1 == "\u2028":  # Line separator
         
     | 
| 
         @@ -2395,7 +2366,7 @@ class TextAutoReplace: 
     | 
|
| 
       2395 
2366 
     | 
    
         | 
| 
       2396 
2367 
     | 
    
         | 
| 
       2397 
2368 
     | 
    
         
             
            class GuiDocToolBar(QWidget):
         
     | 
| 
       2398 
     | 
    
         
            -
                """The Formatting and Options Fold Out Menu
         
     | 
| 
      
 2369 
     | 
    
         
            +
                """The Formatting and Options Fold Out Menu.
         
     | 
| 
       2399 
2370 
     | 
    
         | 
| 
       2400 
2371 
     | 
    
         
             
                Only used by DocEditor, and is opened by the first button in the
         
     | 
| 
       2401 
2372 
     | 
    
         
             
                header.
         
     | 
| 
         @@ -2432,6 +2403,12 @@ class GuiDocToolBar(QWidget): 
     | 
|
| 
       2432 
2403 
     | 
    
         
             
                        qtLambda(self.requestDocAction.emit, nwDocAction.MD_STRIKE)
         
     | 
| 
       2433 
2404 
     | 
    
         
             
                    )
         
     | 
| 
       2434 
2405 
     | 
    
         | 
| 
      
 2406 
     | 
    
         
            +
                    self.tbMarkMD = NIconToolButton(self, iSz)
         
     | 
| 
      
 2407 
     | 
    
         
            +
                    self.tbMarkMD.setToolTip(self.tr("Markdown Highlight"))
         
     | 
| 
      
 2408 
     | 
    
         
            +
                    self.tbMarkMD.clicked.connect(
         
     | 
| 
      
 2409 
     | 
    
         
            +
                        qtLambda(self.requestDocAction.emit, nwDocAction.MD_MARK)
         
     | 
| 
      
 2410 
     | 
    
         
            +
                    )
         
     | 
| 
      
 2411 
     | 
    
         
            +
             
     | 
| 
       2435 
2412 
     | 
    
         
             
                    self.tbBold = NIconToolButton(self, iSz)
         
     | 
| 
       2436 
2413 
     | 
    
         
             
                    self.tbBold.setToolTip(self.tr("Shortcode Bold"))
         
     | 
| 
       2437 
2414 
     | 
    
         
             
                    self.tbBold.clicked.connect(
         
     | 
| 
         @@ -2481,6 +2458,7 @@ class GuiDocToolBar(QWidget): 
     | 
|
| 
       2481 
2458 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbBoldMD)
         
     | 
| 
       2482 
2459 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbItalicMD)
         
     | 
| 
       2483 
2460 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbStrikeMD)
         
     | 
| 
      
 2461 
     | 
    
         
            +
                    self.outerBox.addWidget(self.tbMarkMD)
         
     | 
| 
       2484 
2462 
     | 
    
         
             
                    self.outerBox.addSpacing(4)
         
     | 
| 
       2485 
2463 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbBold)
         
     | 
| 
       2486 
2464 
     | 
    
         
             
                    self.outerBox.addWidget(self.tbItalic)
         
     | 
| 
         @@ -2500,34 +2478,32 @@ class GuiDocToolBar(QWidget): 
     | 
|
| 
       2500 
2478 
     | 
    
         | 
| 
       2501 
2479 
     | 
    
         
             
                    logger.debug("Ready: GuiDocToolBar")
         
     | 
| 
       2502 
2480 
     | 
    
         | 
| 
       2503 
     | 
    
         
            -
                    return
         
     | 
| 
       2504 
     | 
    
         
            -
             
     | 
| 
       2505 
2481 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       2506 
2482 
     | 
    
         
             
                    """Initialise GUI elements that depend on specific settings."""
         
     | 
| 
       2507 
     | 
    
         
            -
                     
     | 
| 
      
 2483 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocToolBar")
         
     | 
| 
       2508 
2484 
     | 
    
         | 
| 
      
 2485 
     | 
    
         
            +
                    syntax = SHARED.theme.syntaxTheme
         
     | 
| 
       2509 
2486 
     | 
    
         
             
                    palette = self.palette()
         
     | 
| 
       2510 
2487 
     | 
    
         
             
                    palette.setColor(QPalette.ColorRole.Window, syntax.back)
         
     | 
| 
       2511 
2488 
     | 
    
         
             
                    palette.setColor(QPalette.ColorRole.WindowText, syntax.text)
         
     | 
| 
       2512 
2489 
     | 
    
         
             
                    palette.setColor(QPalette.ColorRole.Text, syntax.text)
         
     | 
| 
       2513 
2490 
     | 
    
         
             
                    self.setPalette(palette)
         
     | 
| 
       2514 
2491 
     | 
    
         | 
| 
       2515 
     | 
    
         
            -
                    self.tbBoldMD.setThemeIcon("fmt_bold", " 
     | 
| 
       2516 
     | 
    
         
            -
                    self.tbItalicMD.setThemeIcon("fmt_italic", " 
     | 
| 
       2517 
     | 
    
         
            -
                    self.tbStrikeMD.setThemeIcon("fmt_strike", " 
     | 
| 
       2518 
     | 
    
         
            -
                    self. 
     | 
| 
       2519 
     | 
    
         
            -
                    self. 
     | 
| 
       2520 
     | 
    
         
            -
                    self. 
     | 
| 
       2521 
     | 
    
         
            -
                    self. 
     | 
| 
       2522 
     | 
    
         
            -
                    self. 
     | 
| 
       2523 
     | 
    
         
            -
                    self. 
     | 
| 
       2524 
     | 
    
         
            -
                    self. 
     | 
| 
       2525 
     | 
    
         
            -
             
     | 
| 
       2526 
     | 
    
         
            -
                    return
         
     | 
| 
      
 2492 
     | 
    
         
            +
                    self.tbBoldMD.setThemeIcon("fmt_bold", "markdown")
         
     | 
| 
      
 2493 
     | 
    
         
            +
                    self.tbItalicMD.setThemeIcon("fmt_italic", "markdown")
         
     | 
| 
      
 2494 
     | 
    
         
            +
                    self.tbStrikeMD.setThemeIcon("fmt_strike", "markdown")
         
     | 
| 
      
 2495 
     | 
    
         
            +
                    self.tbMarkMD.setThemeIcon("fmt_mark", "markdown")
         
     | 
| 
      
 2496 
     | 
    
         
            +
                    self.tbBold.setThemeIcon("fmt_bold", "shortcode")
         
     | 
| 
      
 2497 
     | 
    
         
            +
                    self.tbItalic.setThemeIcon("fmt_italic", "shortcode")
         
     | 
| 
      
 2498 
     | 
    
         
            +
                    self.tbStrike.setThemeIcon("fmt_strike", "shortcode")
         
     | 
| 
      
 2499 
     | 
    
         
            +
                    self.tbUnderline.setThemeIcon("fmt_underline", "shortcode")
         
     | 
| 
      
 2500 
     | 
    
         
            +
                    self.tbMark.setThemeIcon("fmt_mark", "shortcode")
         
     | 
| 
      
 2501 
     | 
    
         
            +
                    self.tbSuperscript.setThemeIcon("fmt_superscript", "shortcode")
         
     | 
| 
      
 2502 
     | 
    
         
            +
                    self.tbSubscript.setThemeIcon("fmt_subscript", "shortcode")
         
     | 
| 
       2527 
2503 
     | 
    
         | 
| 
       2528 
2504 
     | 
    
         | 
| 
       2529 
2505 
     | 
    
         
             
            class GuiDocEditSearch(QFrame):
         
     | 
| 
       2530 
     | 
    
         
            -
                """The Embedded Document Search/Replace Feature
         
     | 
| 
      
 2506 
     | 
    
         
            +
                """The Embedded Document Search/Replace Feature.
         
     | 
| 
       2531 
2507 
     | 
    
         | 
| 
       2532 
2508 
     | 
    
         
             
                Only used by DocEditor, and is at a fixed position in the
         
     | 
| 
       2533 
2509 
     | 
    
         
             
                QTextEdit's viewport.
         
     | 
| 
         @@ -2617,7 +2593,7 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2617 
2593 
     | 
    
         
             
                    # Buttons
         
     | 
| 
       2618 
2594 
     | 
    
         
             
                    # =======
         
     | 
| 
       2619 
2595 
     | 
    
         | 
| 
       2620 
     | 
    
         
            -
                    self.showReplace = NIconToggleButton(self, iSz 
     | 
| 
      
 2596 
     | 
    
         
            +
                    self.showReplace = NIconToggleButton(self, iSz)
         
     | 
| 
       2621 
2597 
     | 
    
         
             
                    self.showReplace.toggled.connect(self._doToggleReplace)
         
     | 
| 
       2622 
2598 
     | 
    
         | 
| 
       2623 
2599 
     | 
    
         
             
                    self.searchButton = NIconToolButton(self, iSz)
         
     | 
| 
         @@ -2657,8 +2633,6 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2657 
2633 
     | 
    
         | 
| 
       2658 
2634 
     | 
    
         
             
                    logger.debug("Ready: GuiDocEditSearch")
         
     | 
| 
       2659 
2635 
     | 
    
         | 
| 
       2660 
     | 
    
         
            -
                    return
         
     | 
| 
       2661 
     | 
    
         
            -
             
     | 
| 
       2662 
2636 
     | 
    
         
             
                ##
         
     | 
| 
       2663 
2637 
     | 
    
         
             
                #  Properties
         
     | 
| 
       2664 
2638 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -2707,14 +2681,12 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2707 
2681 
     | 
    
         
             
                    self.searchBox.selectAll()
         
     | 
| 
       2708 
2682 
     | 
    
         
             
                    if CONFIG.searchRegEx:
         
     | 
| 
       2709 
2683 
     | 
    
         
             
                        self._alertSearchValid(True)
         
     | 
| 
       2710 
     | 
    
         
            -
                    return
         
     | 
| 
       2711 
2684 
     | 
    
         | 
| 
       2712 
2685 
     | 
    
         
             
                def setReplaceText(self, text: str) -> None:
         
     | 
| 
       2713 
2686 
     | 
    
         
             
                    """Set the replace text."""
         
     | 
| 
       2714 
2687 
     | 
    
         
             
                    self.showReplace.setChecked(True)
         
     | 
| 
       2715 
2688 
     | 
    
         
             
                    self.replaceBox.setFocus()
         
     | 
| 
       2716 
2689 
     | 
    
         
             
                    self.replaceBox.setText(text)
         
     | 
| 
       2717 
     | 
    
         
            -
                    return
         
     | 
| 
       2718 
2690 
     | 
    
         | 
| 
       2719 
2691 
     | 
    
         
             
                def setResultCount(self, currRes: int | None, resCount: int | None) -> None:
         
     | 
| 
       2720 
2692 
     | 
    
         
             
                    """Set the count values for the current search."""
         
     | 
| 
         @@ -2729,7 +2701,6 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2729 
2701 
     | 
    
         
             
                    self.resultLabel.setMinimumWidth(minWidth)
         
     | 
| 
       2730 
2702 
     | 
    
         
             
                    self.adjustSize()
         
     | 
| 
       2731 
2703 
     | 
    
         
             
                    self.docEditor.updateDocMargins()
         
     | 
| 
       2732 
     | 
    
         
            -
                    return
         
     | 
| 
       2733 
2704 
     | 
    
         | 
| 
       2734 
2705 
     | 
    
         
             
                ##
         
     | 
| 
       2735 
2706 
     | 
    
         
             
                #  Methods
         
     | 
| 
         @@ -2745,36 +2716,35 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2745 
2716 
     | 
    
         
             
                    self.resultLabel.setMinimumWidth(
         
     | 
| 
       2746 
2717 
     | 
    
         
             
                        SHARED.theme.getTextWidth("?/?", SHARED.theme.guiFontSmall)
         
     | 
| 
       2747 
2718 
     | 
    
         
             
                    )
         
     | 
| 
       2748 
     | 
    
         
            -
                    return
         
     | 
| 
       2749 
2719 
     | 
    
         | 
| 
       2750 
2720 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       2751 
2721 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
       2752 
     | 
    
         
            -
                     
     | 
| 
      
 2722 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocEditSearch")
         
     | 
| 
       2753 
2723 
     | 
    
         | 
| 
      
 2724 
     | 
    
         
            +
                    palette = QApplication.palette()
         
     | 
| 
       2754 
2725 
     | 
    
         
             
                    self.setPalette(palette)
         
     | 
| 
       2755 
2726 
     | 
    
         
             
                    self.searchBox.setPalette(palette)
         
     | 
| 
       2756 
2727 
     | 
    
         
             
                    self.replaceBox.setPalette(palette)
         
     | 
| 
       2757 
2728 
     | 
    
         | 
| 
       2758 
2729 
     | 
    
         
             
                    # Set icons
         
     | 
| 
       2759 
     | 
    
         
            -
                    self.toggleCase.setIcon(SHARED.theme.getIcon("search_case"))
         
     | 
| 
       2760 
     | 
    
         
            -
                    self.toggleWord.setIcon(SHARED.theme.getIcon("search_word"))
         
     | 
| 
       2761 
     | 
    
         
            -
                    self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex"))
         
     | 
| 
       2762 
     | 
    
         
            -
                    self.toggleLoop.setIcon(SHARED.theme.getIcon("search_loop"))
         
     | 
| 
       2763 
     | 
    
         
            -
                    self.toggleProject.setIcon(SHARED.theme.getIcon("search_project"))
         
     | 
| 
       2764 
     | 
    
         
            -
                    self.toggleMatchCap.setIcon(SHARED.theme.getIcon("search_preserve"))
         
     | 
| 
       2765 
     | 
    
         
            -
                    self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel"))
         
     | 
| 
       2766 
     | 
    
         
            -
                    self.searchButton.setThemeIcon("search", " 
     | 
| 
       2767 
     | 
    
         
            -
                    self.replaceButton.setThemeIcon("search_replace", " 
     | 
| 
      
 2730 
     | 
    
         
            +
                    self.toggleCase.setIcon(SHARED.theme.getIcon("search_case", "tool"))
         
     | 
| 
      
 2731 
     | 
    
         
            +
                    self.toggleWord.setIcon(SHARED.theme.getIcon("search_word", "tool"))
         
     | 
| 
      
 2732 
     | 
    
         
            +
                    self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex", "tool"))
         
     | 
| 
      
 2733 
     | 
    
         
            +
                    self.toggleLoop.setIcon(SHARED.theme.getIcon("search_loop", "tool"))
         
     | 
| 
      
 2734 
     | 
    
         
            +
                    self.toggleProject.setIcon(SHARED.theme.getIcon("search_project", "tool"))
         
     | 
| 
      
 2735 
     | 
    
         
            +
                    self.toggleMatchCap.setIcon(SHARED.theme.getIcon("search_preserve", "tool"))
         
     | 
| 
      
 2736 
     | 
    
         
            +
                    self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel", "tool"))
         
     | 
| 
      
 2737 
     | 
    
         
            +
                    self.searchButton.setThemeIcon("search", "action")
         
     | 
| 
      
 2738 
     | 
    
         
            +
                    self.replaceButton.setThemeIcon("search_replace", "apply")
         
     | 
| 
      
 2739 
     | 
    
         
            +
                    self.showReplace.setThemeIcon("unfold", "default")
         
     | 
| 
       2768 
2740 
     | 
    
         | 
| 
       2769 
2741 
     | 
    
         
             
                    # Set stylesheets
         
     | 
| 
       2770 
2742 
     | 
    
         
             
                    self.searchOpt.setStyleSheet("QToolBar {padding: 0;}")
         
     | 
| 
       2771 
2743 
     | 
    
         
             
                    self.showReplace.setStyleSheet("QToolButton {border: none; background: transparent;}")
         
     | 
| 
       2772 
2744 
     | 
    
         | 
| 
       2773 
     | 
    
         
            -
                    return
         
     | 
| 
       2774 
     | 
    
         
            -
             
     | 
| 
       2775 
2745 
     | 
    
         
             
                def cycleFocus(self) -> bool:
         
     | 
| 
       2776 
     | 
    
         
            -
                    """ 
     | 
| 
       2777 
     | 
    
         
            -
                    boxes, if the replace box is visible.
         
     | 
| 
      
 2746 
     | 
    
         
            +
                    """Cycle focus on tab key press. This just alternates focus
         
     | 
| 
      
 2747 
     | 
    
         
            +
                    between the two input boxes, if the replace box is visible.
         
     | 
| 
       2778 
2748 
     | 
    
         
             
                    """
         
     | 
| 
       2779 
2749 
     | 
    
         
             
                    if self.searchBox.hasFocus():
         
     | 
| 
       2780 
2750 
     | 
    
         
             
                        self.replaceBox.setFocus()
         
     | 
| 
         @@ -2799,7 +2769,6 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2799 
2769 
     | 
    
         
             
                    self.setVisible(False)
         
     | 
| 
       2800 
2770 
     | 
    
         
             
                    self.docEditor.updateDocMargins()
         
     | 
| 
       2801 
2771 
     | 
    
         
             
                    self.docEditor.setFocus()
         
     | 
| 
       2802 
     | 
    
         
            -
                    return
         
     | 
| 
       2803 
2772 
     | 
    
         | 
| 
       2804 
2773 
     | 
    
         
             
                ##
         
     | 
| 
       2805 
2774 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -2809,13 +2778,11 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2809 
2778 
     | 
    
         
             
                def _doSearch(self) -> None:
         
     | 
| 
       2810 
2779 
     | 
    
         
             
                    """Call the search action function for the document editor."""
         
     | 
| 
       2811 
2780 
     | 
    
         
             
                    self.docEditor.findNext(goBack=(QApplication.keyboardModifiers() == QtModShift))
         
     | 
| 
       2812 
     | 
    
         
            -
                    return
         
     | 
| 
       2813 
2781 
     | 
    
         | 
| 
       2814 
2782 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       2815 
2783 
     | 
    
         
             
                def _doReplace(self) -> None:
         
     | 
| 
       2816 
2784 
     | 
    
         
             
                    """Call the replace action function for the document editor."""
         
     | 
| 
       2817 
2785 
     | 
    
         
             
                    self.docEditor.replaceNext()
         
     | 
| 
       2818 
     | 
    
         
            -
                    return
         
     | 
| 
       2819 
2786 
     | 
    
         | 
| 
       2820 
2787 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2821 
2788 
     | 
    
         
             
                def _doToggleReplace(self, state: bool) -> None:
         
     | 
| 
         @@ -2824,43 +2791,36 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2824 
2791 
     | 
    
         
             
                    self.replaceButton.setVisible(state)
         
     | 
| 
       2825 
2792 
     | 
    
         
             
                    self.adjustSize()
         
     | 
| 
       2826 
2793 
     | 
    
         
             
                    self.docEditor.updateDocMargins()
         
     | 
| 
       2827 
     | 
    
         
            -
                    return
         
     | 
| 
       2828 
2794 
     | 
    
         | 
| 
       2829 
2795 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2830 
2796 
     | 
    
         
             
                def _doToggleCase(self, state: bool) -> None:
         
     | 
| 
       2831 
2797 
     | 
    
         
             
                    """Enable/disable case sensitive mode."""
         
     | 
| 
       2832 
2798 
     | 
    
         
             
                    CONFIG.searchCase = state
         
     | 
| 
       2833 
     | 
    
         
            -
                    return
         
     | 
| 
       2834 
2799 
     | 
    
         | 
| 
       2835 
2800 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2836 
2801 
     | 
    
         
             
                def _doToggleWord(self, state: bool) -> None:
         
     | 
| 
       2837 
2802 
     | 
    
         
             
                    """Enable/disable whole word search mode."""
         
     | 
| 
       2838 
2803 
     | 
    
         
             
                    CONFIG.searchWord = state
         
     | 
| 
       2839 
     | 
    
         
            -
                    return
         
     | 
| 
       2840 
2804 
     | 
    
         | 
| 
       2841 
2805 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2842 
2806 
     | 
    
         
             
                def _doToggleRegEx(self, state: bool) -> None:
         
     | 
| 
       2843 
2807 
     | 
    
         
             
                    """Enable/disable regular expression search mode."""
         
     | 
| 
       2844 
2808 
     | 
    
         
             
                    CONFIG.searchRegEx = state
         
     | 
| 
       2845 
     | 
    
         
            -
                    return
         
     | 
| 
       2846 
2809 
     | 
    
         | 
| 
       2847 
2810 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2848 
2811 
     | 
    
         
             
                def _doToggleLoop(self, state: bool) -> None:
         
     | 
| 
       2849 
2812 
     | 
    
         
             
                    """Enable/disable looping the search."""
         
     | 
| 
       2850 
2813 
     | 
    
         
             
                    CONFIG.searchLoop = state
         
     | 
| 
       2851 
     | 
    
         
            -
                    return
         
     | 
| 
       2852 
2814 
     | 
    
         | 
| 
       2853 
2815 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2854 
2816 
     | 
    
         
             
                def _doToggleProject(self, state: bool) -> None:
         
     | 
| 
       2855 
2817 
     | 
    
         
             
                    """Enable/disable continuing search in next project file."""
         
     | 
| 
       2856 
2818 
     | 
    
         
             
                    CONFIG.searchNextFile = state
         
     | 
| 
       2857 
     | 
    
         
            -
                    return
         
     | 
| 
       2858 
2819 
     | 
    
         | 
| 
       2859 
2820 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       2860 
2821 
     | 
    
         
             
                def _doToggleMatchCap(self, state: bool) -> None:
         
     | 
| 
       2861 
2822 
     | 
    
         
             
                    """Enable/disable preserving capitalisation when replacing."""
         
     | 
| 
       2862 
2823 
     | 
    
         
             
                    CONFIG.searchMatchCap = state
         
     | 
| 
       2863 
     | 
    
         
            -
                    return
         
     | 
| 
       2864 
2824 
     | 
    
         | 
| 
       2865 
2825 
     | 
    
         
             
                ##
         
     | 
| 
       2866 
2826 
     | 
    
         
             
                #  Internal Functions
         
     | 
| 
         @@ -2876,11 +2836,10 @@ class GuiDocEditSearch(QFrame): 
     | 
|
| 
       2876 
2836 
     | 
    
         
             
                        palette.text().color() if isValid else SHARED.theme.errorText
         
     | 
| 
       2877 
2837 
     | 
    
         
             
                    )
         
     | 
| 
       2878 
2838 
     | 
    
         
             
                    self.searchBox.setPalette(palette)
         
     | 
| 
       2879 
     | 
    
         
            -
                    return
         
     | 
| 
       2880 
2839 
     | 
    
         | 
| 
       2881 
2840 
     | 
    
         | 
| 
       2882 
2841 
     | 
    
         
             
            class GuiDocEditHeader(QWidget):
         
     | 
| 
       2883 
     | 
    
         
            -
                """The Embedded Document Header
         
     | 
| 
      
 2842 
     | 
    
         
            +
                """The Embedded Document Header.
         
     | 
| 
       2884 
2843 
     | 
    
         | 
| 
       2885 
2844 
     | 
    
         
             
                Only used by DocEditor, and is at a fixed position in the
         
     | 
| 
       2886 
2845 
     | 
    
         
             
                QTextEdit's viewport.
         
     | 
| 
         @@ -2971,8 +2930,6 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       2971 
2930 
     | 
    
         | 
| 
       2972 
2931 
     | 
    
         
             
                    logger.debug("Ready: GuiDocEditHeader")
         
     | 
| 
       2973 
2932 
     | 
    
         | 
| 
       2974 
     | 
    
         
            -
                    return
         
     | 
| 
       2975 
     | 
    
         
            -
             
     | 
| 
       2976 
2933 
     | 
    
         
             
                ##
         
     | 
| 
       2977 
2934 
     | 
    
         
             
                #  Methods
         
     | 
| 
       2978 
2935 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -2989,7 +2946,6 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       2989 
2946 
     | 
    
         
             
                    self.searchButton.setVisible(False)
         
     | 
| 
       2990 
2947 
     | 
    
         
             
                    self.closeButton.setVisible(False)
         
     | 
| 
       2991 
2948 
     | 
    
         
             
                    self.minmaxButton.setVisible(False)
         
     | 
| 
       2992 
     | 
    
         
            -
                    return
         
     | 
| 
       2993 
2949 
     | 
    
         | 
| 
       2994 
2950 
     | 
    
         
             
                def setOutline(self, data: dict[int, str]) -> None:
         
     | 
| 
       2995 
2951 
     | 
    
         
             
                    """Set the document outline dataset."""
         
     | 
| 
         @@ -3001,21 +2957,21 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3001 
2957 
     | 
    
         
             
                            action.triggered.connect(qtLambda(self._gotoBlock, number))
         
     | 
| 
       3002 
2958 
     | 
    
         
             
                        self._docOutline = data
         
     | 
| 
       3003 
2959 
     | 
    
         
             
                        logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart))
         
     | 
| 
       3004 
     | 
    
         
            -
                    return
         
     | 
| 
       3005 
2960 
     | 
    
         | 
| 
       3006 
2961 
     | 
    
         
             
                def updateFont(self) -> None:
         
     | 
| 
       3007 
2962 
     | 
    
         
             
                    """Update the font settings."""
         
     | 
| 
       3008 
2963 
     | 
    
         
             
                    self.setFont(SHARED.theme.guiFont)
         
     | 
| 
       3009 
2964 
     | 
    
         
             
                    self.itemTitle.setFont(SHARED.theme.guiFontSmall)
         
     | 
| 
       3010 
     | 
    
         
            -
                    return
         
     | 
| 
       3011 
2965 
     | 
    
         | 
| 
       3012 
2966 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       3013 
2967 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
       3014 
     | 
    
         
            -
                     
     | 
| 
       3015 
     | 
    
         
            -
             
     | 
| 
       3016 
     | 
    
         
            -
                    self. 
     | 
| 
       3017 
     | 
    
         
            -
                    self. 
     | 
| 
       3018 
     | 
    
         
            -
                    self. 
     | 
| 
      
 2968 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocEditHeader")
         
     | 
| 
      
 2969 
     | 
    
         
            +
             
     | 
| 
      
 2970 
     | 
    
         
            +
                    self.tbButton.setThemeIcon("fmt_toolbar", "action")
         
     | 
| 
      
 2971 
     | 
    
         
            +
                    self.outlineButton.setThemeIcon("list", "action")
         
     | 
| 
      
 2972 
     | 
    
         
            +
                    self.searchButton.setThemeIcon("search", "action")
         
     | 
| 
      
 2973 
     | 
    
         
            +
                    self.minmaxButton.setThemeIcon("maximise", "action")
         
     | 
| 
      
 2974 
     | 
    
         
            +
                    self.closeButton.setThemeIcon("close", "reject")
         
     | 
| 
       3019 
2975 
     | 
    
         | 
| 
       3020 
2976 
     | 
    
         
             
                    buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
         
     | 
| 
       3021 
2977 
     | 
    
         
             
                    self.tbButton.setStyleSheet(buttonStyle)
         
     | 
| 
         @@ -3026,8 +2982,6 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3026 
2982 
     | 
    
         | 
| 
       3027 
2983 
     | 
    
         
             
                    self.matchColors()
         
     | 
| 
       3028 
2984 
     | 
    
         | 
| 
       3029 
     | 
    
         
            -
                    return
         
     | 
| 
       3030 
     | 
    
         
            -
             
     | 
| 
       3031 
2985 
     | 
    
         
             
                def matchColors(self) -> None:
         
     | 
| 
       3032 
2986 
     | 
    
         
             
                    """Update the colours of the widget to match those of the syntax
         
     | 
| 
       3033 
2987 
     | 
    
         
             
                    theme rather than the main GUI.
         
     | 
| 
         @@ -3041,12 +2995,10 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3041 
2995 
     | 
    
         
             
                    self.itemTitle.setTextColors(
         
     | 
| 
       3042 
2996 
     | 
    
         
             
                        color=palette.windowText().color(), faded=SHARED.theme.fadedText
         
     | 
| 
       3043 
2997 
     | 
    
         
             
                    )
         
     | 
| 
       3044 
     | 
    
         
            -
                    return
         
     | 
| 
       3045 
2998 
     | 
    
         | 
| 
       3046 
2999 
     | 
    
         
             
                def changeFocusState(self, state: bool) -> None:
         
     | 
| 
       3047 
3000 
     | 
    
         
             
                    """Toggle focus state."""
         
     | 
| 
       3048 
3001 
     | 
    
         
             
                    self.itemTitle.setColorState(state)
         
     | 
| 
       3049 
     | 
    
         
            -
                    return
         
     | 
| 
       3050 
3002 
     | 
    
         | 
| 
       3051 
3003 
     | 
    
         
             
                def setHandle(self, tHandle: str) -> None:
         
     | 
| 
       3052 
3004 
     | 
    
         
             
                    """Set the document title from the handle, or alternatively, set
         
     | 
| 
         @@ -3067,8 +3019,6 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3067 
3019 
     | 
    
         
             
                    self.closeButton.setVisible(True)
         
     | 
| 
       3068 
3020 
     | 
    
         
             
                    self.minmaxButton.setVisible(True)
         
     | 
| 
       3069 
3021 
     | 
    
         | 
| 
       3070 
     | 
    
         
            -
                    return
         
     | 
| 
       3071 
     | 
    
         
            -
             
     | 
| 
       3072 
3022 
     | 
    
         
             
                ##
         
     | 
| 
       3073 
3023 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
       3074 
3024 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -3078,19 +3028,16 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3078 
3028 
     | 
    
         
             
                    """Trigger the close editor on the main window."""
         
     | 
| 
       3079 
3029 
     | 
    
         
             
                    self.clearHeader()
         
     | 
| 
       3080 
3030 
     | 
    
         
             
                    self.closeDocumentRequest.emit()
         
     | 
| 
       3081 
     | 
    
         
            -
                    return
         
     | 
| 
       3082 
3031 
     | 
    
         | 
| 
       3083 
3032 
     | 
    
         
             
                @pyqtSlot(int)
         
     | 
| 
       3084 
3033 
     | 
    
         
             
                def _gotoBlock(self, blockNumber: int) -> None:
         
     | 
| 
       3085 
3034 
     | 
    
         
             
                    """Move cursor to a specific heading."""
         
     | 
| 
       3086 
3035 
     | 
    
         
             
                    self.docEditor.setCursorLine(blockNumber + 1)
         
     | 
| 
       3087 
     | 
    
         
            -
                    return
         
     | 
| 
       3088 
3036 
     | 
    
         | 
| 
       3089 
3037 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       3090 
3038 
     | 
    
         
             
                def _focusModeChanged(self, focusMode: bool) -> None:
         
     | 
| 
       3091 
3039 
     | 
    
         
             
                    """Update minimise/maximise icon of the Focus Mode button."""
         
     | 
| 
       3092 
     | 
    
         
            -
                    self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise", " 
     | 
| 
       3093 
     | 
    
         
            -
                    return
         
     | 
| 
      
 3040 
     | 
    
         
            +
                    self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise", "action")
         
     | 
| 
       3094 
3041 
     | 
    
         | 
| 
       3095 
3042 
     | 
    
         
             
                ##
         
     | 
| 
       3096 
3043 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -3102,11 +3049,10 @@ class GuiDocEditHeader(QWidget): 
     | 
|
| 
       3102 
3049 
     | 
    
         
             
                    """
         
     | 
| 
       3103 
3050 
     | 
    
         
             
                    if event.button() == QtMouseLeft:
         
     | 
| 
       3104 
3051 
     | 
    
         
             
                        self.docEditor.requestProjectItemSelected.emit(self._docHandle or "", True)
         
     | 
| 
       3105 
     | 
    
         
            -
                    return
         
     | 
| 
       3106 
3052 
     | 
    
         | 
| 
       3107 
3053 
     | 
    
         | 
| 
       3108 
3054 
     | 
    
         
             
            class GuiDocEditFooter(QWidget):
         
     | 
| 
       3109 
     | 
    
         
            -
                """The Embedded Document Footer
         
     | 
| 
      
 3055 
     | 
    
         
            +
                """The Embedded Document Footer.
         
     | 
| 
       3110 
3056 
     | 
    
         | 
| 
       3111 
3057 
     | 
    
         
             
                Only used by DocEditor, and is at a fixed position in the
         
     | 
| 
       3112 
3058 
     | 
    
         
             
                QTextEdit's viewport.
         
     | 
| 
         @@ -3191,8 +3137,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3191 
3137 
     | 
    
         | 
| 
       3192 
3138 
     | 
    
         
             
                    logger.debug("Ready: GuiDocEditFooter")
         
     | 
| 
       3193 
3139 
     | 
    
         | 
| 
       3194 
     | 
    
         
            -
                    return
         
     | 
| 
       3195 
     | 
    
         
            -
             
     | 
| 
       3196 
3140 
     | 
    
         
             
                ##
         
     | 
| 
       3197 
3141 
     | 
    
         
             
                #  Methods
         
     | 
| 
       3198 
3142 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -3202,7 +3146,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3202 
3146 
     | 
    
         
             
                    self._trMainCount = trStats(nwLabels.STATS_DISPLAY[
         
     | 
| 
       3203 
3147 
     | 
    
         
             
                        nwStats.CHARS if CONFIG.useCharCount else nwStats.WORDS
         
     | 
| 
       3204 
3148 
     | 
    
         
             
                    ])
         
     | 
| 
       3205 
     | 
    
         
            -
                    return
         
     | 
| 
       3206 
3149 
     | 
    
         | 
| 
       3207 
3150 
     | 
    
         
             
                def updateFont(self) -> None:
         
     | 
| 
       3208 
3151 
     | 
    
         
             
                    """Update the font settings."""
         
     | 
| 
         @@ -3210,15 +3153,15 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3210 
3153 
     | 
    
         
             
                    self.statusText.setFont(SHARED.theme.guiFontSmall)
         
     | 
| 
       3211 
3154 
     | 
    
         
             
                    self.linesText.setFont(SHARED.theme.guiFontSmall)
         
     | 
| 
       3212 
3155 
     | 
    
         
             
                    self.wordsText.setFont(SHARED.theme.guiFontSmall)
         
     | 
| 
       3213 
     | 
    
         
            -
                    return
         
     | 
| 
       3214 
3156 
     | 
    
         | 
| 
       3215 
3157 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       3216 
3158 
     | 
    
         
             
                    """Update theme elements."""
         
     | 
| 
      
 3159 
     | 
    
         
            +
                    logger.debug("Theme Update: GuiDocEditFooter")
         
     | 
| 
      
 3160 
     | 
    
         
            +
             
     | 
| 
       3217 
3161 
     | 
    
         
             
                    iPx = round(0.9*SHARED.theme.baseIconHeight)
         
     | 
| 
       3218 
3162 
     | 
    
         
             
                    self.linesIcon.setPixmap(SHARED.theme.getPixmap("lines", (iPx, iPx)))
         
     | 
| 
       3219 
3163 
     | 
    
         
             
                    self.wordsIcon.setPixmap(SHARED.theme.getPixmap("stats", (iPx, iPx)))
         
     | 
| 
       3220 
3164 
     | 
    
         
             
                    self.matchColors()
         
     | 
| 
       3221 
     | 
    
         
            -
                    return
         
     | 
| 
       3222 
3165 
     | 
    
         | 
| 
       3223 
3166 
     | 
    
         
             
                def matchColors(self) -> None:
         
     | 
| 
       3224 
3167 
     | 
    
         
             
                    """Update the colours of the widget to match those of the syntax
         
     | 
| 
         @@ -3236,8 +3179,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3236 
3179 
     | 
    
         
             
                    self.linesText.setPalette(palette)
         
     | 
| 
       3237 
3180 
     | 
    
         
             
                    self.wordsText.setPalette(palette)
         
     | 
| 
       3238 
3181 
     | 
    
         | 
| 
       3239 
     | 
    
         
            -
                    return
         
     | 
| 
       3240 
     | 
    
         
            -
             
     | 
| 
       3241 
3182 
     | 
    
         
             
                def setHandle(self, tHandle: str | None) -> None:
         
     | 
| 
       3242 
3183 
     | 
    
         
             
                    """Set the handle that will populate the footer's data."""
         
     | 
| 
       3243 
3184 
     | 
    
         
             
                    self._docHandle = tHandle
         
     | 
| 
         @@ -3250,8 +3191,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3250 
3191 
     | 
    
         
             
                    self.updateInfo()
         
     | 
| 
       3251 
3192 
     | 
    
         
             
                    self.updateMainCount(0, False)
         
     | 
| 
       3252 
3193 
     | 
    
         | 
| 
       3253 
     | 
    
         
            -
                    return
         
     | 
| 
       3254 
     | 
    
         
            -
             
     | 
| 
       3255 
3194 
     | 
    
         
             
                def updateInfo(self) -> None:
         
     | 
| 
       3256 
3195 
     | 
    
         
             
                    """Update the content of text labels."""
         
     | 
| 
       3257 
3196 
     | 
    
         
             
                    if self._tItem is None:
         
     | 
| 
         @@ -3266,8 +3205,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3266 
3205 
     | 
    
         
             
                    self.statusIcon.setPixmap(sIcon)
         
     | 
| 
       3267 
3206 
     | 
    
         
             
                    self.statusText.setText(sText)
         
     | 
| 
       3268 
3207 
     | 
    
         | 
| 
       3269 
     | 
    
         
            -
                    return
         
     | 
| 
       3270 
     | 
    
         
            -
             
     | 
| 
       3271 
3208 
     | 
    
         
             
                def updateLineCount(self, cursor: QTextCursor) -> None:
         
     | 
| 
       3272 
3209 
     | 
    
         
             
                    """Update the line and document position counter."""
         
     | 
| 
       3273 
3210 
     | 
    
         
             
                    if document := cursor.document():
         
     | 
| 
         @@ -3277,7 +3214,6 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3277 
3214 
     | 
    
         
             
                        self.linesText.setText(
         
     | 
| 
       3278 
3215 
     | 
    
         
             
                            self._trLineCount.format(f"{cLine:n}", f"{100*cPos//cCount:d} %")
         
     | 
| 
       3279 
3216 
     | 
    
         
             
                        )
         
     | 
| 
       3280 
     | 
    
         
            -
                    return
         
     | 
| 
       3281 
3217 
     | 
    
         | 
| 
       3282 
3218 
     | 
    
         
             
                def updateMainCount(self, count: int, selection: bool) -> None:
         
     | 
| 
       3283 
3219 
     | 
    
         
             
                    """Update main counter information."""
         
     | 
| 
         @@ -3290,4 +3226,3 @@ class GuiDocEditFooter(QWidget): 
     | 
|
| 
       3290 
3226 
     | 
    
         
             
                    else:
         
     | 
| 
       3291 
3227 
     | 
    
         
             
                        text = self._trMainCount.format("0", "+0")
         
     | 
| 
       3292 
3228 
     | 
    
         
             
                    self.wordsText.setText(text)
         
     | 
| 
       3293 
     | 
    
         
            -
                    return
         
     |