novelWriter 2.7.4__py3-none-any.whl → 2.8b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- novelwriter/__init__.py +8 -7
 - novelwriter/assets/icons/font_awesome.icons +22 -4
 - novelwriter/assets/icons/material_filled_normal.icons +20 -2
 - novelwriter/assets/icons/material_filled_thin.icons +20 -2
 - novelwriter/assets/icons/material_rounded_normal.icons +20 -2
 - novelwriter/assets/icons/material_rounded_thin.icons +20 -2
 - novelwriter/assets/icons/material_sharp_normal.icons +20 -2
 - novelwriter/assets/icons/material_sharp_thin.icons +20 -2
 - novelwriter/assets/icons/remix_filled.icons +20 -2
 - novelwriter/assets/icons/remix_outline.icons +20 -2
 - novelwriter/assets/images/welcome.webp +0 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/manual_fr.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/assets/text/credits_en.htm +61 -11
 - novelwriter/assets/themes/aura.conf +97 -0
 - novelwriter/assets/themes/aura_bright.conf +95 -0
 - novelwriter/assets/themes/aura_soft.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_garden_light.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_dark.conf +97 -0
 - novelwriter/assets/themes/b2t_suburb_light.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_classic_o_light.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_dark.conf +97 -0
 - novelwriter/assets/themes/b4t_modern_c_light.conf +97 -0
 - novelwriter/assets/themes/blue_streak_dark.conf +97 -0
 - novelwriter/assets/themes/blue_streak_light.conf +97 -0
 - novelwriter/assets/themes/castle_day.conf +95 -0
 - novelwriter/assets/themes/castle_night.conf +95 -0
 - novelwriter/assets/themes/catppuccin_latte.conf +97 -0
 - novelwriter/assets/themes/catppuccin_mocha.conf +97 -0
 - novelwriter/assets/themes/chalky_soil.conf +95 -0
 - novelwriter/assets/themes/chernozem.conf +95 -0
 - novelwriter/assets/themes/cyberpunk_night.conf +88 -40
 - novelwriter/assets/themes/default_dark.conf +89 -41
 - novelwriter/assets/themes/default_light.conf +89 -41
 - novelwriter/assets/themes/dracula.conf +91 -42
 - novelwriter/assets/themes/espresso.conf +97 -0
 - novelwriter/assets/themes/everforest_dark.conf +97 -0
 - novelwriter/assets/themes/everforest_light.conf +97 -0
 - novelwriter/assets/themes/floral_daydream.conf +95 -0
 - novelwriter/assets/themes/floral_midnight.conf +95 -0
 - novelwriter/assets/themes/full_moon.conf +95 -0
 - novelwriter/assets/themes/grey_dark.conf +97 -0
 - novelwriter/assets/themes/grey_light.conf +97 -0
 - novelwriter/assets/themes/horizon_dark.conf +97 -0
 - novelwriter/assets/themes/horizon_light.conf +97 -0
 - novelwriter/assets/themes/jewel_case_dark.conf +95 -0
 - novelwriter/assets/themes/jewel_case_light.conf +95 -0
 - novelwriter/assets/themes/lcars.conf +97 -0
 - novelwriter/assets/themes/light_owl.conf +117 -0
 - novelwriter/assets/themes/new_moon.conf +97 -0
 - novelwriter/assets/themes/night_owl.conf +117 -0
 - novelwriter/assets/themes/noctis.conf +129 -0
 - novelwriter/assets/themes/noctis_lux.conf +129 -0
 - novelwriter/assets/themes/nord.conf +97 -0
 - novelwriter/assets/themes/nordlicht.conf +95 -0
 - novelwriter/assets/themes/otium_dark.conf +95 -0
 - novelwriter/assets/themes/otium_light.conf +95 -0
 - novelwriter/assets/themes/paragon.conf +96 -0
 - novelwriter/assets/themes/primer_light.conf +97 -0
 - novelwriter/assets/themes/primer_night.conf +97 -0
 - novelwriter/assets/themes/rose_pine.conf +97 -0
 - novelwriter/assets/themes/rose_pine_dawn.conf +97 -0
 - novelwriter/assets/themes/ruby_day.conf +95 -0
 - novelwriter/assets/themes/ruby_night.conf +95 -0
 - novelwriter/assets/themes/selenium_dark.conf +95 -0
 - novelwriter/assets/themes/selenium_light.conf +95 -0
 - novelwriter/assets/themes/sepia_dark.conf +95 -0
 - novelwriter/assets/themes/sepia_light.conf +95 -0
 - novelwriter/assets/themes/snazzy.conf +102 -40
 - novelwriter/assets/themes/solarized_dark.conf +108 -40
 - novelwriter/assets/themes/solarized_light.conf +108 -40
 - novelwriter/assets/themes/sultana_light.conf +95 -0
 - novelwriter/assets/themes/sultana_night.conf +95 -0
 - novelwriter/assets/themes/tango_dark.conf +111 -0
 - novelwriter/assets/themes/tango_light.conf +111 -0
 - novelwriter/assets/themes/tomorrow.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_blue.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_bright.conf +117 -0
 - novelwriter/assets/themes/tomorrow_night_eighties.conf +117 -0
 - novelwriter/assets/themes/vivid_black_green.conf +97 -0
 - novelwriter/assets/themes/vivid_black_red.conf +97 -0
 - novelwriter/assets/themes/vivid_white_green.conf +97 -0
 - novelwriter/assets/themes/vivid_white_red.conf +97 -0
 - novelwriter/assets/themes/warpgate.conf +96 -0
 - novelwriter/assets/themes/waterlily_dark.conf +95 -0
 - novelwriter/assets/themes/waterlily_light.conf +95 -0
 - novelwriter/common.py +47 -17
 - novelwriter/config.py +57 -62
 - novelwriter/constants.py +32 -6
 - novelwriter/core/buildsettings.py +3 -23
 - novelwriter/core/coretools.py +21 -25
 - novelwriter/core/docbuild.py +4 -9
 - novelwriter/core/document.py +2 -6
 - novelwriter/core/index.py +33 -53
 - novelwriter/core/indexdata.py +17 -22
 - novelwriter/core/item.py +11 -35
 - novelwriter/core/itemmodel.py +5 -21
 - novelwriter/core/novelmodel.py +3 -7
 - novelwriter/core/options.py +3 -4
 - novelwriter/core/project.py +31 -21
 - novelwriter/core/projectdata.py +2 -21
 - novelwriter/core/projectxml.py +13 -21
 - novelwriter/core/sessions.py +2 -4
 - novelwriter/core/spellcheck.py +12 -13
 - novelwriter/core/status.py +27 -20
 - novelwriter/core/storage.py +5 -10
 - novelwriter/core/tree.py +6 -15
 - novelwriter/dialogs/about.py +9 -10
 - novelwriter/dialogs/docmerge.py +17 -14
 - novelwriter/dialogs/docsplit.py +18 -14
 - novelwriter/dialogs/editlabel.py +15 -9
 - novelwriter/dialogs/preferences.py +69 -68
 - novelwriter/dialogs/projectsettings.py +88 -67
 - novelwriter/dialogs/quotes.py +15 -10
 - novelwriter/dialogs/wordlist.py +18 -21
 - novelwriter/enum.py +75 -30
 - novelwriter/error.py +6 -11
 - novelwriter/extensions/configlayout.py +8 -34
 - novelwriter/extensions/eventfilters.py +3 -3
 - novelwriter/extensions/modified.py +87 -32
 - novelwriter/extensions/novelselector.py +13 -12
 - novelwriter/extensions/pagedsidebar.py +10 -18
 - novelwriter/extensions/progressbars.py +5 -11
 - novelwriter/extensions/statusled.py +3 -6
 - novelwriter/extensions/switch.py +8 -11
 - novelwriter/extensions/switchbox.py +2 -11
 - novelwriter/extensions/versioninfo.py +6 -7
 - novelwriter/formats/shared.py +10 -2
 - novelwriter/formats/todocx.py +15 -37
 - novelwriter/formats/tohtml.py +52 -61
 - novelwriter/formats/tokenizer.py +33 -64
 - novelwriter/formats/tomarkdown.py +4 -11
 - novelwriter/formats/toodt.py +12 -71
 - novelwriter/formats/toqdoc.py +11 -21
 - novelwriter/formats/toraw.py +2 -6
 - novelwriter/gui/doceditor.py +207 -245
 - novelwriter/gui/dochighlight.py +142 -101
 - novelwriter/gui/docviewer.py +53 -84
 - novelwriter/gui/docviewerpanel.py +18 -41
 - novelwriter/gui/editordocument.py +12 -17
 - novelwriter/gui/itemdetails.py +5 -14
 - novelwriter/gui/mainmenu.py +24 -32
 - novelwriter/gui/noveltree.py +13 -51
 - novelwriter/gui/outline.py +20 -61
 - novelwriter/gui/projtree.py +40 -96
 - novelwriter/gui/search.py +9 -24
 - novelwriter/gui/sidebar.py +54 -22
 - novelwriter/gui/statusbar.py +7 -22
 - novelwriter/gui/theme.py +482 -368
 - novelwriter/guimain.py +87 -101
 - novelwriter/shared.py +79 -48
 - novelwriter/splash.py +9 -5
 - novelwriter/text/comments.py +1 -1
 - novelwriter/text/counting.py +9 -5
 - novelwriter/text/patterns.py +20 -15
 - novelwriter/tools/dictionaries.py +18 -16
 - novelwriter/tools/lipsum.py +15 -17
 - novelwriter/tools/manusbuild.py +25 -45
 - novelwriter/tools/manuscript.py +94 -95
 - novelwriter/tools/manussettings.py +149 -104
 - novelwriter/tools/noveldetails.py +10 -24
 - novelwriter/tools/welcome.py +24 -72
 - novelwriter/tools/writingstats.py +17 -26
 - novelwriter/types.py +25 -13
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/METADATA +7 -7
 - novelwriter-2.8b1.dist-info/RECORD +212 -0
 - novelwriter/assets/images/welcome-dark.jpg +0 -0
 - novelwriter/assets/images/welcome-light.jpg +0 -0
 - novelwriter/assets/syntax/cyberpunk_night.conf +0 -28
 - novelwriter/assets/syntax/default_dark.conf +0 -42
 - novelwriter/assets/syntax/default_light.conf +0 -42
 - novelwriter/assets/syntax/dracula.conf +0 -44
 - novelwriter/assets/syntax/grey_dark.conf +0 -29
 - novelwriter/assets/syntax/grey_light.conf +0 -29
 - novelwriter/assets/syntax/light_owl.conf +0 -49
 - novelwriter/assets/syntax/night_owl.conf +0 -49
 - novelwriter/assets/syntax/snazzy.conf +0 -42
 - novelwriter/assets/syntax/solarized_dark.conf +0 -29
 - novelwriter/assets/syntax/solarized_light.conf +0 -29
 - novelwriter/assets/syntax/tango.conf +0 -39
 - novelwriter/assets/syntax/tomorrow.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_blue.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_bright.conf +0 -49
 - novelwriter/assets/syntax/tomorrow_night_eighties.conf +0 -49
 - novelwriter/assets/themes/default.conf +0 -3
 - novelwriter-2.7.4.dist-info/RECORD +0 -163
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/WHEEL +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/entry_points.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/LICENSE.md +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/licenses/setup/LICENSE-Apache-2.0.txt +0 -0
 - {novelwriter-2.7.4.dist-info → novelwriter-2.8b1.dist-info}/top_level.txt +0 -0
 
| 
         @@ -24,15 +24,15 @@ General Public License for more details. 
     | 
|
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       26 
26 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       27 
     | 
    
         
            -
            """
         
     | 
| 
      
 27 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       28 
28 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
            from typing import TYPE_CHECKING
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            from PyQt6.QtCore import QModelIndex, QSize, Qt, pyqtSignal, pyqtSlot
         
     | 
| 
       33 
33 
     | 
    
         
             
            from PyQt6.QtWidgets import (
         
     | 
| 
       34 
     | 
    
         
            -
                QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel,  
     | 
| 
       35 
     | 
    
         
            -
                QToolButton, QTreeView, QWidget
         
     | 
| 
      
 34 
     | 
    
         
            +
                QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel, QPushButton,
         
     | 
| 
      
 35 
     | 
    
         
            +
                QSpinBox, QToolButton, QTreeView, QWidget
         
     | 
| 
       36 
36 
     | 
    
         
             
            )
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
         @@ -47,6 +47,7 @@ if TYPE_CHECKING: 
     | 
|
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
            class NDialog(QDialog):
         
     | 
| 
      
 50 
     | 
    
         
            +
                """Custom: Modified QDialog."""
         
     | 
| 
       50 
51 
     | 
    
         | 
| 
       51 
52 
     | 
    
         
             
                def softDelete(self) -> None:
         
     | 
| 
       52 
53 
     | 
    
         
             
                    """Since calling deleteLater is sometimes not safe from Python,
         
     | 
| 
         @@ -55,53 +56,54 @@ class NDialog(QDialog): 
     | 
|
| 
       55 
56 
     | 
    
         
             
                    so that it gets garbage collected when it runs out of scope.
         
     | 
| 
       56 
57 
     | 
    
         
             
                    """
         
     | 
| 
       57 
58 
     | 
    
         
             
                    self.setParent(None)  # type: ignore
         
     | 
| 
       58 
     | 
    
         
            -
                    return
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       61 
61 
     | 
    
         
             
                def reject(self) -> None:
         
     | 
| 
       62 
62 
     | 
    
         
             
                    """Overload the reject slot and also call close."""
         
     | 
| 
       63 
63 
     | 
    
         
             
                    super().reject()
         
     | 
| 
       64 
64 
     | 
    
         
             
                    self.close()
         
     | 
| 
       65 
     | 
    
         
            -
                    return
         
     | 
| 
       66 
65 
     | 
    
         | 
| 
       67 
66 
     | 
    
         | 
| 
       68 
67 
     | 
    
         
             
            class NToolDialog(NDialog):
         
     | 
| 
      
 68 
     | 
    
         
            +
                """Custom: Modified QDialog for Tools."""
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
                def __init__(self, parent: GuiMain) -> None:
         
     | 
| 
       71 
71 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       72 
72 
     | 
    
         
             
                    self.setModal(False)
         
     | 
| 
       73 
73 
     | 
    
         
             
                    if CONFIG.osDarwin:
         
     | 
| 
       74 
74 
     | 
    
         
             
                        self.setWindowFlag(Qt.WindowType.Tool)
         
     | 
| 
       75 
     | 
    
         
            -
                    return
         
     | 
| 
       76 
75 
     | 
    
         | 
| 
       77 
76 
     | 
    
         
             
                def activateDialog(self) -> None:
         
     | 
| 
       78 
     | 
    
         
            -
                    """ 
     | 
| 
      
 77 
     | 
    
         
            +
                    """Activate dialog on various operating systems."""
         
     | 
| 
       79 
78 
     | 
    
         
             
                    self.show()
         
     | 
| 
       80 
79 
     | 
    
         
             
                    if CONFIG.osWindows:
         
     | 
| 
       81 
80 
     | 
    
         
             
                        self.activateWindow()
         
     | 
| 
       82 
81 
     | 
    
         
             
                    self.raise_()
         
     | 
| 
       83 
82 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       84 
     | 
    
         
            -
                    return
         
     | 
| 
       85 
83 
     | 
    
         | 
| 
       86 
84 
     | 
    
         | 
| 
       87 
85 
     | 
    
         
             
            class NNonBlockingDialog(NDialog):
         
     | 
| 
      
 86 
     | 
    
         
            +
                """Custom: Modified Non-Blocking QDialog."""
         
     | 
| 
       88 
87 
     | 
    
         | 
| 
       89 
88 
     | 
    
         
             
                def __init__(self, parent: QWidget | None = None) -> None:
         
     | 
| 
       90 
89 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       91 
90 
     | 
    
         
             
                    self.setModal(True)
         
     | 
| 
       92 
     | 
    
         
            -
                    return
         
     | 
| 
       93 
91 
     | 
    
         | 
| 
       94 
92 
     | 
    
         
             
                def activateDialog(self) -> None:
         
     | 
| 
       95 
     | 
    
         
            -
                    """ 
     | 
| 
      
 93 
     | 
    
         
            +
                    """Activate dialog on various operating systems."""
         
     | 
| 
       96 
94 
     | 
    
         
             
                    self.show()
         
     | 
| 
       97 
95 
     | 
    
         
             
                    if CONFIG.osWindows:
         
     | 
| 
       98 
96 
     | 
    
         
             
                        self.activateWindow()
         
     | 
| 
       99 
97 
     | 
    
         
             
                    self.raise_()
         
     | 
| 
       100 
98 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       101 
     | 
    
         
            -
                    return
         
     | 
| 
       102 
99 
     | 
    
         | 
| 
       103 
100 
     | 
    
         | 
| 
       104 
101 
     | 
    
         
             
            class NTreeView(QTreeView):
         
     | 
| 
      
 102 
     | 
    
         
            +
                """Custom: Modified QTreeView.
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                The main purpose is to provide the middleClicked signal that matches
         
     | 
| 
      
 105 
     | 
    
         
            +
                clicked and doubleCLicked.
         
     | 
| 
      
 106 
     | 
    
         
            +
                """
         
     | 
| 
       105 
107 
     | 
    
         | 
| 
       106 
108 
     | 
    
         
             
                middleClicked = pyqtSignal(QModelIndex)
         
     | 
| 
       107 
109 
     | 
    
         | 
| 
         @@ -116,42 +118,65 @@ class NTreeView(QTreeView): 
     | 
|
| 
       116 
118 
     | 
    
         | 
| 
       117 
119 
     | 
    
         | 
| 
       118 
120 
     | 
    
         
             
            class NComboBox(QComboBox):
         
     | 
| 
      
 121 
     | 
    
         
            +
                """Custom: Modified QComboBox.
         
     | 
| 
       119 
122 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                 
     | 
| 
      
 123 
     | 
    
         
            +
                The main purpose is to provide a combo box that doesn't scroll when
         
     | 
| 
      
 124 
     | 
    
         
            +
                the mousewheel is active on it while scrolling through a scrollable
         
     | 
| 
      
 125 
     | 
    
         
            +
                window of many widgets.
         
     | 
| 
      
 126 
     | 
    
         
            +
                """
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                def __init__(self, parent: QWidget | None = None, maxItems: int = 15) -> None:
         
     | 
| 
       121 
129 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       122 
130 
     | 
    
         
             
                    self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
         
     | 
| 
       123 
     | 
    
         
            -
                     
     | 
| 
      
 131 
     | 
    
         
            +
                    self.setMaxVisibleItems(maxItems)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    self.updateStyle()
         
     | 
| 
       124 
133 
     | 
    
         | 
| 
       125 
134 
     | 
    
         
             
                def wheelEvent(self, event: QWheelEvent) -> None:
         
     | 
| 
      
 135 
     | 
    
         
            +
                    """Only capture the mouse wheel if the widget has focus."""
         
     | 
| 
       126 
136 
     | 
    
         
             
                    if self.hasFocus():
         
     | 
| 
       127 
137 
     | 
    
         
             
                        super().wheelEvent(event)
         
     | 
| 
       128 
138 
     | 
    
         
             
                    else:
         
     | 
| 
       129 
139 
     | 
    
         
             
                        event.ignore()
         
     | 
| 
       130 
     | 
    
         
            -
                    return
         
     | 
| 
       131 
140 
     | 
    
         | 
| 
       132 
141 
     | 
    
         
             
                def setCurrentData(self, data: str | int | Enum, default: str | int | Enum) -> None:
         
     | 
| 
       133 
142 
     | 
    
         
             
                    """Set the current index from data, with a fallback."""
         
     | 
| 
       134 
143 
     | 
    
         
             
                    idx = self.findData(data)
         
     | 
| 
       135 
144 
     | 
    
         
             
                    self.setCurrentIndex(self.findData(default) if idx < 0 else idx)
         
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                def updateStyle(self) -> None:
         
     | 
| 
      
 147 
     | 
    
         
            +
                    """Update the style sheet."""
         
     | 
| 
      
 148 
     | 
    
         
            +
                    # The style sheet disables Fusion style pop-up mode on some
         
     | 
| 
      
 149 
     | 
    
         
            +
                    # platforms and allows for scrolling of long lists of items
         
     | 
| 
      
 150 
     | 
    
         
            +
                    self.setStyleSheet("QComboBox {combobox-popup: 0;}")
         
     | 
| 
       137 
151 
     | 
    
         | 
| 
       138 
152 
     | 
    
         | 
| 
       139 
153 
     | 
    
         
             
            class NSpinBox(QSpinBox):
         
     | 
| 
      
 154 
     | 
    
         
            +
                """Custom: Modified QSpinBox.
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                The main purpose is to provide a spin box that doesn't scroll when
         
     | 
| 
      
 157 
     | 
    
         
            +
                the mousewheel is active on it while scrolling through a scrollable
         
     | 
| 
      
 158 
     | 
    
         
            +
                window of many widgets.
         
     | 
| 
      
 159 
     | 
    
         
            +
                """
         
     | 
| 
       140 
160 
     | 
    
         | 
| 
       141 
161 
     | 
    
         
             
                def __init__(self, parent: QWidget | None = None) -> None:
         
     | 
| 
       142 
162 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       143 
163 
     | 
    
         
             
                    self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
         
     | 
| 
       144 
     | 
    
         
            -
                    return
         
     | 
| 
       145 
164 
     | 
    
         | 
| 
       146 
165 
     | 
    
         
             
                def wheelEvent(self, event: QWheelEvent) -> None:
         
     | 
| 
      
 166 
     | 
    
         
            +
                    """Only capture the mouse wheel if the widget has focus."""
         
     | 
| 
       147 
167 
     | 
    
         
             
                    if self.hasFocus():
         
     | 
| 
       148 
168 
     | 
    
         
             
                        super().wheelEvent(event)
         
     | 
| 
       149 
169 
     | 
    
         
             
                    else:
         
     | 
| 
       150 
170 
     | 
    
         
             
                        event.ignore()
         
     | 
| 
       151 
     | 
    
         
            -
                    return
         
     | 
| 
       152 
171 
     | 
    
         | 
| 
       153 
172 
     | 
    
         | 
| 
       154 
173 
     | 
    
         
             
            class NDoubleSpinBox(QDoubleSpinBox):
         
     | 
| 
      
 174 
     | 
    
         
            +
                """Custom: Modified QDoubleSpinBox.
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                The main purpose is to provide a float spin box that doesn't scroll
         
     | 
| 
      
 177 
     | 
    
         
            +
                when the mousewheel is active on it while scrolling through a
         
     | 
| 
      
 178 
     | 
    
         
            +
                scrollable window of many widgets.
         
     | 
| 
      
 179 
     | 
    
         
            +
                """
         
     | 
| 
       155 
180 
     | 
    
         | 
| 
       156 
181 
     | 
    
         
             
                def __init__(
         
     | 
| 
       157 
182 
     | 
    
         
             
                    self,
         
     | 
| 
         @@ -168,17 +193,43 @@ class NDoubleSpinBox(QDoubleSpinBox): 
     | 
|
| 
       168 
193 
     | 
    
         
             
                    self.setMaximum(maxVal)
         
     | 
| 
       169 
194 
     | 
    
         
             
                    self.setSingleStep(step)
         
     | 
| 
       170 
195 
     | 
    
         
             
                    self.setDecimals(prec)
         
     | 
| 
       171 
     | 
    
         
            -
                    return
         
     | 
| 
       172 
196 
     | 
    
         | 
| 
       173 
197 
     | 
    
         
             
                def wheelEvent(self, event: QWheelEvent) -> None:
         
     | 
| 
      
 198 
     | 
    
         
            +
                    """Only capture the mouse wheel if the widget has focus."""
         
     | 
| 
       174 
199 
     | 
    
         
             
                    if self.hasFocus():
         
     | 
| 
       175 
200 
     | 
    
         
             
                        super().wheelEvent(event)
         
     | 
| 
       176 
201 
     | 
    
         
             
                    else:
         
     | 
| 
       177 
202 
     | 
    
         
             
                        event.ignore()
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
            class NPushButton(QPushButton):
         
     | 
| 
      
 206 
     | 
    
         
            +
                """Custom: Modified QPushButton.
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                A quicker way to create a push button using the app theme.
         
     | 
| 
      
 209 
     | 
    
         
            +
                """
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                def __init__(
         
     | 
| 
      
 212 
     | 
    
         
            +
                    self, parent: QWidget, text: str, iconSize: QSize,
         
     | 
| 
      
 213 
     | 
    
         
            +
                    icon: str | None = None, color: str | None = None
         
     | 
| 
      
 214 
     | 
    
         
            +
                ) -> None:
         
     | 
| 
      
 215 
     | 
    
         
            +
                    super().__init__(parent=parent)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    self._icon = icon
         
     | 
| 
      
 217 
     | 
    
         
            +
                    self._color = color
         
     | 
| 
      
 218 
     | 
    
         
            +
                    self.setText(text)
         
     | 
| 
      
 219 
     | 
    
         
            +
                    self.setIconSize(iconSize)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    self.updateIcon()
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
                def updateIcon(self) -> None:
         
     | 
| 
      
 223 
     | 
    
         
            +
                    """Update the theme icon."""
         
     | 
| 
      
 224 
     | 
    
         
            +
                    if self._icon and self._color:
         
     | 
| 
      
 225 
     | 
    
         
            +
                        self.setIcon(SHARED.theme.getIcon(self._icon, self._color))
         
     | 
| 
       179 
226 
     | 
    
         | 
| 
       180 
227 
     | 
    
         | 
| 
       181 
228 
     | 
    
         
             
            class NIconToolButton(QToolButton):
         
     | 
| 
      
 229 
     | 
    
         
            +
                """Custom: Modified QToolButton.
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                A quicker way to create a tool button using the app theme.
         
     | 
| 
      
 232 
     | 
    
         
            +
                """
         
     | 
| 
       182 
233 
     | 
    
         | 
| 
       183 
234 
     | 
    
         
             
                def __init__(
         
     | 
| 
       184 
235 
     | 
    
         
             
                    self, parent: QWidget, iconSize: QSize,
         
     | 
| 
         @@ -188,37 +239,41 @@ class NIconToolButton(QToolButton): 
     | 
|
| 
       188 
239 
     | 
    
         
             
                    self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
         
     | 
| 
       189 
240 
     | 
    
         
             
                    self.setIconSize(iconSize)
         
     | 
| 
       190 
241 
     | 
    
         
             
                    self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
         
     | 
| 
       191 
     | 
    
         
            -
                    if icon:
         
     | 
| 
      
 242 
     | 
    
         
            +
                    if icon and color:
         
     | 
| 
       192 
243 
     | 
    
         
             
                        self.setThemeIcon(icon, color)
         
     | 
| 
       193 
     | 
    
         
            -
                    return
         
     | 
| 
       194 
244 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
                def setThemeIcon(self,  
     | 
| 
      
 245 
     | 
    
         
            +
                def setThemeIcon(self, icon: str, color: str) -> None:
         
     | 
| 
       196 
246 
     | 
    
         
             
                    """Set an icon from the current theme."""
         
     | 
| 
       197 
     | 
    
         
            -
                    self.setIcon(SHARED.theme.getIcon( 
     | 
| 
       198 
     | 
    
         
            -
                    return
         
     | 
| 
      
 247 
     | 
    
         
            +
                    self.setIcon(SHARED.theme.getIcon(icon, color))
         
     | 
| 
       199 
248 
     | 
    
         | 
| 
       200 
249 
     | 
    
         | 
| 
       201 
250 
     | 
    
         
             
            class NIconToggleButton(QToolButton):
         
     | 
| 
      
 251 
     | 
    
         
            +
                """Custom: Modified QToolButton.
         
     | 
| 
       202 
252 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
                 
     | 
| 
      
 253 
     | 
    
         
            +
                A quicker way to create a toggle button using the app theme.
         
     | 
| 
      
 254 
     | 
    
         
            +
                """
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                def __init__(
         
     | 
| 
      
 257 
     | 
    
         
            +
                    self, parent: QWidget, iconSize: QSize,
         
     | 
| 
      
 258 
     | 
    
         
            +
                    icon: str | None = None, color: str | None = None
         
     | 
| 
      
 259 
     | 
    
         
            +
                ) -> None:
         
     | 
| 
       204 
260 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       205 
261 
     | 
    
         
             
                    self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
         
     | 
| 
       206 
262 
     | 
    
         
             
                    self.setIconSize(iconSize)
         
     | 
| 
       207 
263 
     | 
    
         
             
                    self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
         
     | 
| 
       208 
264 
     | 
    
         
             
                    self.setCheckable(True)
         
     | 
| 
       209 
265 
     | 
    
         
             
                    self.setStyleSheet("border: none; background: transparent;")
         
     | 
| 
       210 
     | 
    
         
            -
                    if icon:
         
     | 
| 
       211 
     | 
    
         
            -
                        self.setThemeIcon(icon)
         
     | 
| 
       212 
     | 
    
         
            -
                    return
         
     | 
| 
      
 266 
     | 
    
         
            +
                    if icon and color:
         
     | 
| 
      
 267 
     | 
    
         
            +
                        self.setThemeIcon(icon, color)
         
     | 
| 
       213 
268 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
                def setThemeIcon(self,  
     | 
| 
      
 269 
     | 
    
         
            +
                def setThemeIcon(self, icon: str, color: str) -> None:
         
     | 
| 
       215 
270 
     | 
    
         
             
                    """Set an icon from the current theme."""
         
     | 
| 
       216 
     | 
    
         
            -
                     
     | 
| 
       217 
     | 
    
         
            -
                    self.setIcon(SHARED.theme.getToggleIcon( 
     | 
| 
       218 
     | 
    
         
            -
                    return
         
     | 
| 
      
 271 
     | 
    
         
            +
                    size = self.iconSize()
         
     | 
| 
      
 272 
     | 
    
         
            +
                    self.setIcon(SHARED.theme.getToggleIcon(icon, (size.width(), size.height()), color))
         
     | 
| 
       219 
273 
     | 
    
         | 
| 
       220 
274 
     | 
    
         | 
| 
       221 
275 
     | 
    
         
             
            class NClickableLabel(QLabel):
         
     | 
| 
      
 276 
     | 
    
         
            +
                """Custom: Clickable QLabel."""
         
     | 
| 
       222 
277 
     | 
    
         | 
| 
       223 
278 
     | 
    
         
             
                mouseClicked = pyqtSignal()
         
     | 
| 
       224 
279 
     | 
    
         | 
| 
         @@ -20,23 +20,30 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            import logging
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
            from typing import TYPE_CHECKING
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       28 
30 
     | 
    
         
             
            from PyQt6.QtCore import pyqtSignal, pyqtSlot
         
     | 
| 
       29 
31 
     | 
    
         
             
            from PyQt6.QtGui import QPalette
         
     | 
| 
       30 
     | 
    
         
            -
            from PyQt6.QtWidgets import QComboBox 
     | 
| 
      
 32 
     | 
    
         
            +
            from PyQt6.QtWidgets import QComboBox
         
     | 
| 
       31 
33 
     | 
    
         | 
| 
       32 
34 
     | 
    
         
             
            from novelwriter import SHARED
         
     | 
| 
       33 
35 
     | 
    
         
             
            from novelwriter.constants import nwLabels
         
     | 
| 
       34 
36 
     | 
    
         
             
            from novelwriter.enum import nwItemClass
         
     | 
| 
      
 37 
     | 
    
         
            +
            from novelwriter.types import QtColDisabled
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            if TYPE_CHECKING:
         
     | 
| 
      
 40 
     | 
    
         
            +
                from PyQt6.QtWidgets import QWidget
         
     | 
| 
       35 
41 
     | 
    
         | 
| 
       36 
42 
     | 
    
         
             
            logger = logging.getLogger(__name__)
         
     | 
| 
       37 
43 
     | 
    
         | 
| 
       38 
44 
     | 
    
         | 
| 
       39 
45 
     | 
    
         
             
            class NovelSelector(QComboBox):
         
     | 
| 
      
 46 
     | 
    
         
            +
                """Custom: Novel Root Folder Selector."""
         
     | 
| 
       40 
47 
     | 
    
         | 
| 
       41 
48 
     | 
    
         
             
                novelSelectionChanged = pyqtSignal(str)
         
     | 
| 
       42 
49 
     | 
    
         | 
| 
         @@ -48,7 +55,6 @@ class NovelSelector(QComboBox): 
     | 
|
| 
       48 
55 
     | 
    
         
             
                    self._listFormat = None
         
     | 
| 
       49 
56 
     | 
    
         
             
                    self.currentIndexChanged.connect(self._indexChanged)
         
     | 
| 
       50 
57 
     | 
    
         
             
                    self.updateTheme()
         
     | 
| 
       51 
     | 
    
         
            -
                    return
         
     | 
| 
       52 
58 
     | 
    
         | 
| 
       53 
59 
     | 
    
         
             
                ##
         
     | 
| 
       54 
60 
     | 
    
         
             
                #  Properties
         
     | 
| 
         @@ -75,26 +81,24 @@ class NovelSelector(QComboBox): 
     | 
|
| 
       75 
81 
     | 
    
         
             
                        self._blockSignal = blockSignal
         
     | 
| 
       76 
82 
     | 
    
         
             
                        self.setCurrentIndex(index)
         
     | 
| 
       77 
83 
     | 
    
         
             
                        self._blockSignal = False
         
     | 
| 
       78 
     | 
    
         
            -
                    return
         
     | 
| 
       79 
84 
     | 
    
         | 
| 
       80 
85 
     | 
    
         
             
                def setIncludeAll(self, value: bool) -> None:
         
     | 
| 
       81 
86 
     | 
    
         
             
                    """Set flag to add an "All Novel Folders" option."""
         
     | 
| 
       82 
87 
     | 
    
         
             
                    self._includeAll = value
         
     | 
| 
       83 
     | 
    
         
            -
                    return
         
     | 
| 
       84 
88 
     | 
    
         | 
| 
       85 
89 
     | 
    
         
             
                def setListFormat(self, value: str | None) -> None:
         
     | 
| 
       86 
90 
     | 
    
         
             
                    """Set a format string for the list entries."""
         
     | 
| 
       87 
91 
     | 
    
         
             
                    if value is None or "{0}" in value:
         
     | 
| 
       88 
92 
     | 
    
         
             
                        self._listFormat = value
         
     | 
| 
       89 
     | 
    
         
            -
                    return
         
     | 
| 
       90 
93 
     | 
    
         | 
| 
       91 
94 
     | 
    
         
             
                def updateTheme(self) -> None:
         
     | 
| 
       92 
95 
     | 
    
         
             
                    """Update theme colours."""
         
     | 
| 
       93 
96 
     | 
    
         
             
                    palette = self.palette()
         
     | 
| 
       94 
     | 
    
         
            -
                    palette.setBrush( 
     | 
| 
      
 97 
     | 
    
         
            +
                    palette.setBrush(QtColDisabled, QPalette.ColorRole.Text, palette.text())
         
     | 
| 
      
 98 
     | 
    
         
            +
                    palette.setBrush(QtColDisabled, QPalette.ColorRole.WindowText, palette.windowText())
         
     | 
| 
      
 99 
     | 
    
         
            +
                    palette.setBrush(QtColDisabled, QPalette.ColorRole.ButtonText, palette.buttonText())
         
     | 
| 
       95 
100 
     | 
    
         
             
                    self.setPalette(palette)
         
     | 
| 
       96 
101 
     | 
    
         
             
                    self.refreshNovelList()
         
     | 
| 
       97 
     | 
    
         
            -
                    return
         
     | 
| 
       98 
102 
     | 
    
         | 
| 
       99 
103 
     | 
    
         
             
                ##
         
     | 
| 
       100 
104 
     | 
    
         
             
                #  Public Slots
         
     | 
| 
         @@ -109,7 +113,7 @@ class NovelSelector(QComboBox): 
     | 
|
| 
       109 
113 
     | 
    
         
             
                    self._firstHandle = None
         
     | 
| 
       110 
114 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       111 
115 
     | 
    
         | 
| 
       112 
     | 
    
         
            -
                    icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL], " 
     | 
| 
      
 116 
     | 
    
         
            +
                    icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL], "root")
         
     | 
| 
       113 
117 
     | 
    
         
             
                    for tHandle, nwItem in SHARED.project.tree.iterRoots(nwItemClass.NOVEL):
         
     | 
| 
       114 
118 
     | 
    
         
             
                        if self._listFormat:
         
     | 
| 
       115 
119 
     | 
    
         
             
                            name = self._listFormat.format(nwItem.itemName)
         
     | 
| 
         @@ -128,8 +132,6 @@ class NovelSelector(QComboBox): 
     | 
|
| 
       128 
132 
     | 
    
         
             
                    self.setEnabled(self.count() > 1)
         
     | 
| 
       129 
133 
     | 
    
         
             
                    self._blockSignal = False
         
     | 
| 
       130 
134 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                    return
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
135 
     | 
    
         
             
                ##
         
     | 
| 
       134 
136 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
       135 
137 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -139,4 +141,3 @@ class NovelSelector(QComboBox): 
     | 
|
| 
       139 
141 
     | 
    
         
             
                    """Re-emit the change of selection signal, unless blocked."""
         
     | 
| 
       140 
142 
     | 
    
         
             
                    if not self._blockSignal:
         
     | 
| 
       141 
143 
     | 
    
         
             
                        self.novelSelectionChanged.emit(self.currentData())
         
     | 
| 
       142 
     | 
    
         
            -
                    return
         
     | 
| 
         @@ -22,7 +22,7 @@ General Public License for more details. 
     | 
|
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       24 
24 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       25 
     | 
    
         
            -
            """
         
     | 
| 
      
 25 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       26 
26 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            from PyQt6.QtCore import QPoint, QRectF, QSize, Qt, pyqtSignal, pyqtSlot
         
     | 
| 
         @@ -39,7 +39,7 @@ from novelwriter.types import ( 
     | 
|
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
            class NPagedSideBar(QToolBar):
         
     | 
| 
       42 
     | 
    
         
            -
                """Extensions: Paged Side Bar
         
     | 
| 
      
 42 
     | 
    
         
            +
                """Extensions: Paged Side Bar.
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
                A side bar widget that holds buttons that mimic tabs. It is designed
         
     | 
| 
       45 
45 
     | 
    
         
             
                to be used in combination with a QStackedWidget for options panels.
         
     | 
| 
         @@ -65,8 +65,6 @@ class NPagedSideBar(QToolBar): 
     | 
|
| 
       65 
65 
     | 
    
         
             
                    stretch.setSizePolicy(QtSizeExpanding, QtSizeExpanding)
         
     | 
| 
       66 
66 
     | 
    
         
             
                    self._stretchAction = self.addWidget(stretch)
         
     | 
| 
       67 
67 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                    return
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
68 
     | 
    
         
             
                def button(self, buttonId: int) -> _PagedToolButton:
         
     | 
| 
       71 
69 
     | 
    
         
             
                    """Return a specific button."""
         
     | 
| 
       72 
70 
     | 
    
         
             
                    return self._buttons[buttonId]
         
     | 
| 
         @@ -74,14 +72,15 @@ class NPagedSideBar(QToolBar): 
     | 
|
| 
       74 
72 
     | 
    
         
             
                def setLabelColor(self, color: QColor) -> None:
         
     | 
| 
       75 
73 
     | 
    
         
             
                    """Set the text color for the labels."""
         
     | 
| 
       76 
74 
     | 
    
         
             
                    self._labelCol = color
         
     | 
| 
       77 
     | 
    
         
            -
                     
     | 
| 
      
 75 
     | 
    
         
            +
                    for widget in self.children():
         
     | 
| 
      
 76 
     | 
    
         
            +
                        if isinstance(widget, _NPagedToolLabel):
         
     | 
| 
      
 77 
     | 
    
         
            +
                            widget.setTextColor(color)
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         
             
                def addLabel(self, text: str) -> None:
         
     | 
| 
       80 
80 
     | 
    
         
             
                    """Add a new label to the toolbar."""
         
     | 
| 
       81 
81 
     | 
    
         
             
                    label = _NPagedToolLabel(self, self._labelCol)
         
     | 
| 
       82 
82 
     | 
    
         
             
                    label.setText(text)
         
     | 
| 
       83 
83 
     | 
    
         
             
                    self.insertWidget(self._stretchAction, label)
         
     | 
| 
       84 
     | 
    
         
            -
                    return
         
     | 
| 
       85 
84 
     | 
    
         | 
| 
       86 
85 
     | 
    
         
             
                def addButton(self, text: str, buttonId: int = -1) -> None:
         
     | 
| 
       87 
86 
     | 
    
         
             
                    """Add a new button to the toolbar."""
         
     | 
| 
         @@ -90,13 +89,11 @@ class NPagedSideBar(QToolBar): 
     | 
|
| 
       90 
89 
     | 
    
         
             
                    self.insertWidget(self._stretchAction, button)
         
     | 
| 
       91 
90 
     | 
    
         
             
                    self._group.addButton(button, id=buttonId)
         
     | 
| 
       92 
91 
     | 
    
         
             
                    self._buttons[buttonId] = button
         
     | 
| 
       93 
     | 
    
         
            -
                    return
         
     | 
| 
       94 
92 
     | 
    
         | 
| 
       95 
93 
     | 
    
         
             
                def setSelected(self, buttonId: int) -> None:
         
     | 
| 
       96 
94 
     | 
    
         
             
                    """Set the selected button."""
         
     | 
| 
       97 
95 
     | 
    
         
             
                    if button := self._group.button(buttonId):
         
     | 
| 
       98 
96 
     | 
    
         
             
                        button.setChecked(True)
         
     | 
| 
       99 
     | 
    
         
            -
                    return
         
     | 
| 
       100 
97 
     | 
    
         | 
| 
       101 
98 
     | 
    
         
             
                ##
         
     | 
| 
       102 
99 
     | 
    
         
             
                #  Private Slots
         
     | 
| 
         @@ -104,11 +101,10 @@ class NPagedSideBar(QToolBar): 
     | 
|
| 
       104 
101 
     | 
    
         | 
| 
       105 
102 
     | 
    
         
             
                @pyqtSlot("QAbstractButton*")
         
     | 
| 
       106 
103 
     | 
    
         
             
                def _buttonClicked(self, button: QAbstractButton) -> None:
         
     | 
| 
       107 
     | 
    
         
            -
                    """ 
     | 
| 
      
 104 
     | 
    
         
            +
                    """Handle a button click in the group and emit its id."""
         
     | 
| 
       108 
105 
     | 
    
         
             
                    buttonId = self._group.id(button)
         
     | 
| 
       109 
106 
     | 
    
         
             
                    if buttonId != -1:
         
     | 
| 
       110 
107 
     | 
    
         
             
                        self.buttonClicked.emit(buttonId)
         
     | 
| 
       111 
     | 
    
         
            -
                    return
         
     | 
| 
       112 
108 
     | 
    
         | 
| 
       113 
109 
     | 
    
         | 
| 
       114 
110 
     | 
    
         
             
            class _PagedToolButton(QToolButton):
         
     | 
| 
         @@ -127,8 +123,6 @@ class _PagedToolButton(QToolButton): 
     | 
|
| 
       127 
123 
     | 
    
         
             
                    self._aH = 2*fH//7
         
     | 
| 
       128 
124 
     | 
    
         
             
                    self.setFixedHeight(self._bH)
         
     | 
| 
       129 
125 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                    return
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
126 
     | 
    
         
             
                def sizeHint(self) -> QSize:
         
     | 
| 
       133 
127 
     | 
    
         
             
                    """Return a size hint that includes the arrow."""
         
     | 
| 
       134 
128 
     | 
    
         
             
                    return super().sizeHint() + QSize(4*self._aH, 0)
         
     | 
| 
         @@ -156,7 +150,7 @@ class _PagedToolButton(QToolButton): 
     | 
|
| 
       156 
150 
     | 
    
         | 
| 
       157 
151 
     | 
    
         
             
                    if self.isChecked():
         
     | 
| 
       158 
152 
     | 
    
         
             
                        painter.setBrush(palette.highlight())
         
     | 
| 
       159 
     | 
    
         
            -
                        painter.setOpacity(0. 
     | 
| 
      
 153 
     | 
    
         
            +
                        painter.setOpacity(0.8)
         
     | 
| 
       160 
154 
     | 
    
         
             
                        painter.drawRoundedRect(0, 0, width, height, 4, 4)
         
     | 
| 
       161 
155 
     | 
    
         
             
                        textCol = palette.highlightedText().color()
         
     | 
| 
       162 
156 
     | 
    
         
             
                    else:
         
     | 
| 
         @@ -180,8 +174,6 @@ class _PagedToolButton(QToolButton): 
     | 
|
| 
       180 
174 
     | 
    
         
             
                    ]))
         
     | 
| 
       181 
175 
     | 
    
         
             
                    painter.end()
         
     | 
| 
       182 
176 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
                    return
         
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
177 
     | 
    
         | 
| 
       186 
178 
     | 
    
         
             
            class _NPagedToolLabel(QLabel):
         
     | 
| 
       187 
179 
     | 
    
         | 
| 
         @@ -199,7 +191,9 @@ class _NPagedToolLabel(QLabel): 
     | 
|
| 
       199 
191 
     | 
    
         | 
| 
       200 
192 
     | 
    
         
             
                    self._textCol = textColor or self.palette().text().color()
         
     | 
| 
       201 
193 
     | 
    
         | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
      
 194 
     | 
    
         
            +
                def setTextColor(self, textColor: QColor | None = None) -> None:
         
     | 
| 
      
 195 
     | 
    
         
            +
                    """Set a new text colour."""
         
     | 
| 
      
 196 
     | 
    
         
            +
                    self._textCol = textColor or self.palette().text().color()
         
     | 
| 
       203 
197 
     | 
    
         | 
| 
       204 
198 
     | 
    
         
             
                def paintEvent(self, event: QPaintEvent) -> None:
         
     | 
| 
       205 
199 
     | 
    
         
             
                    """Overload the paint event to draw a simple, left aligned text
         
     | 
| 
         @@ -215,5 +209,3 @@ class _NPagedToolLabel(QLabel): 
     | 
|
| 
       215 
209 
     | 
    
         
             
                    painter.setOpacity(1.0)
         
     | 
| 
       216 
210 
     | 
    
         
             
                    painter.drawText(QRectF(4, self._tM, tW, tH), QtAlignLeft, self.text())
         
     | 
| 
       217 
211 
     | 
    
         
             
                    painter.end()
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                    return
         
     | 
| 
         @@ -21,7 +21,7 @@ General Public License for more details. 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       23 
23 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       24 
     | 
    
         
            -
            """
         
     | 
| 
      
 24 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       25 
25 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
            from math import ceil
         
     | 
| 
         @@ -37,7 +37,7 @@ from novelwriter.types import ( 
     | 
|
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
            class NProgressCircle(QProgressBar):
         
     | 
| 
       40 
     | 
    
         
            -
                """Extension: Circular Progress Widget
         
     | 
| 
      
 40 
     | 
    
         
            +
                """Extension: Circular Progress Widget.
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                A custom widget that paints a circular progress indicator instead of
         
     | 
| 
       43 
43 
     | 
    
         
             
                a straight bar. It is also possible to set custom text for iṫ.
         
     | 
| 
         @@ -64,7 +64,6 @@ class NProgressCircle(QProgressBar): 
     | 
|
| 
       64 
64 
     | 
    
         
             
                    self.setSizePolicy(QtSizeFixed, QtSizeFixed)
         
     | 
| 
       65 
65 
     | 
    
         
             
                    self.setFixedWidth(size)
         
     | 
| 
       66 
66 
     | 
    
         
             
                    self.setFixedHeight(size)
         
     | 
| 
       67 
     | 
    
         
            -
                    return
         
     | 
| 
       68 
67 
     | 
    
         | 
| 
       69 
68 
     | 
    
         
             
                def setColors(
         
     | 
| 
       70 
69 
     | 
    
         
             
                    self, back: QColor | None = None, track: QColor | None = None,
         
     | 
| 
         @@ -80,16 +79,14 @@ class NProgressCircle(QProgressBar): 
     | 
|
| 
       80 
79 
     | 
    
         
             
                        self._bPen = QPen(QBrush(track), self._point, QtSolidLine, QtRoundCap)
         
     | 
| 
       81 
80 
     | 
    
         
             
                    if isinstance(text, QColor):
         
     | 
| 
       82 
81 
     | 
    
         
             
                        self._tColor = text
         
     | 
| 
       83 
     | 
    
         
            -
                    return
         
     | 
| 
       84 
82 
     | 
    
         | 
| 
       85 
83 
     | 
    
         
             
                def setCentreText(self, text: str | None) -> None:
         
     | 
| 
       86 
84 
     | 
    
         
             
                    """Replace the progress text with a custom string."""
         
     | 
| 
       87 
85 
     | 
    
         
             
                    self._text = text
         
     | 
| 
       88 
86 
     | 
    
         
             
                    self.setValue(self.value())  # Triggers a redraw
         
     | 
| 
       89 
     | 
    
         
            -
                    return
         
     | 
| 
       90 
87 
     | 
    
         | 
| 
       91 
88 
     | 
    
         
             
                def paintEvent(self, event: QPaintEvent) -> None:
         
     | 
| 
       92 
     | 
    
         
            -
                    """ 
     | 
| 
      
 89 
     | 
    
         
            +
                    """Paint the progress bar."""
         
     | 
| 
       93 
90 
     | 
    
         
             
                    progress = 100.0*self.value()/self.maximum()
         
     | 
| 
       94 
91 
     | 
    
         
             
                    angle = ceil(16*3.6*progress)
         
     | 
| 
       95 
92 
     | 
    
         
             
                    painter = QPainter(self)
         
     | 
| 
         @@ -103,21 +100,19 @@ class NProgressCircle(QProgressBar): 
     | 
|
| 
       103 
100 
     | 
    
         
             
                    painter.drawArc(self._cRect, 90*16, -angle)
         
     | 
| 
       104 
101 
     | 
    
         
             
                    painter.setPen(self._tColor)
         
     | 
| 
       105 
102 
     | 
    
         
             
                    painter.drawText(self._cRect, QtAlignCenter, self._text or f"{progress:.1f} %")
         
     | 
| 
       106 
     | 
    
         
            -
                    return
         
     | 
| 
       107 
103 
     | 
    
         | 
| 
       108 
104 
     | 
    
         | 
| 
       109 
105 
     | 
    
         
             
            class NProgressSimple(QProgressBar):
         
     | 
| 
       110 
     | 
    
         
            -
                """Extension: Simple Progress Widget
         
     | 
| 
      
 106 
     | 
    
         
            +
                """Extension: Simple Progress Widget.
         
     | 
| 
       111 
107 
     | 
    
         | 
| 
       112 
108 
     | 
    
         
             
                A custom widget that paints a plain bar with no other styling.
         
     | 
| 
       113 
109 
     | 
    
         
             
                """
         
     | 
| 
       114 
110 
     | 
    
         | 
| 
       115 
111 
     | 
    
         
             
                def __init__(self, parent: QWidget) -> None:
         
     | 
| 
       116 
112 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       117 
     | 
    
         
            -
                    return
         
     | 
| 
       118 
113 
     | 
    
         | 
| 
       119 
114 
     | 
    
         
             
                def paintEvent(self, event: QPaintEvent) -> None:
         
     | 
| 
       120 
     | 
    
         
            -
                    """ 
     | 
| 
      
 115 
     | 
    
         
            +
                    """Paint the progress bar."""
         
     | 
| 
       121 
116 
     | 
    
         
             
                    if (value := self.value()) > 0:
         
     | 
| 
       122 
117 
     | 
    
         
             
                        progress = ceil(self.width()*float(value)/self.maximum())
         
     | 
| 
       123 
118 
     | 
    
         
             
                        painter = QPainter(self)
         
     | 
| 
         @@ -125,4 +120,3 @@ class NProgressSimple(QProgressBar): 
     | 
|
| 
       125 
120 
     | 
    
         
             
                        painter.setPen(self.palette().highlight().color())
         
     | 
| 
       126 
121 
     | 
    
         
             
                        painter.setBrush(self.palette().highlight())
         
     | 
| 
       127 
122 
     | 
    
         
             
                        painter.drawRect(0, 0, progress, self.height())
         
     | 
| 
       128 
     | 
    
         
            -
                    return
         
     | 
| 
         @@ -20,7 +20,7 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            import logging
         
     | 
| 
         @@ -34,6 +34,7 @@ logger = logging.getLogger(__name__) 
     | 
|
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
            class StatusLED(QAbstractButton):
         
     | 
| 
      
 37 
     | 
    
         
            +
                """Custom: LED Style Indicator."""
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
39 
     | 
    
         
             
                __slots__ = ("_color", "_negative", "_neutral", "_postitve", "_state")
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
         @@ -46,7 +47,6 @@ class StatusLED(QAbstractButton): 
     | 
|
| 
       46 
47 
     | 
    
         
             
                    self._state = None
         
     | 
| 
       47 
48 
     | 
    
         
             
                    self.setFixedWidth(sW)
         
     | 
| 
       48 
49 
     | 
    
         
             
                    self.setFixedHeight(sH)
         
     | 
| 
       49 
     | 
    
         
            -
                    return
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
51 
     | 
    
         
             
                @property
         
     | 
| 
       52 
52 
     | 
    
         
             
                def state(self) -> bool | None:
         
     | 
| 
         @@ -59,7 +59,6 @@ class StatusLED(QAbstractButton): 
     | 
|
| 
       59 
59 
     | 
    
         
             
                    self._postitve = positive
         
     | 
| 
       60 
60 
     | 
    
         
             
                    self._negative = negative
         
     | 
| 
       61 
61 
     | 
    
         
             
                    self.setState(self._state)
         
     | 
| 
       62 
     | 
    
         
            -
                    return
         
     | 
| 
       63 
62 
     | 
    
         | 
| 
       64 
63 
     | 
    
         
             
                def setState(self, state: bool | None) -> None:
         
     | 
| 
       65 
64 
     | 
    
         
             
                    """Set the colour state."""
         
     | 
| 
         @@ -71,15 +70,13 @@ class StatusLED(QAbstractButton): 
     | 
|
| 
       71 
70 
     | 
    
         
             
                        self._color = self._neutral
         
     | 
| 
       72 
71 
     | 
    
         
             
                    self._state = state
         
     | 
| 
       73 
72 
     | 
    
         
             
                    self.update()
         
     | 
| 
       74 
     | 
    
         
            -
                    return
         
     | 
| 
       75 
73 
     | 
    
         | 
| 
       76 
74 
     | 
    
         
             
                def paintEvent(self, event: QPaintEvent) -> None:
         
     | 
| 
       77 
75 
     | 
    
         
             
                    """Draw the LED."""
         
     | 
| 
       78 
76 
     | 
    
         
             
                    painter = QPainter(self)
         
     | 
| 
       79 
77 
     | 
    
         
             
                    painter.setRenderHint(QtPaintAntiAlias, True)
         
     | 
| 
       80 
     | 
    
         
            -
                    painter.setPen(self.palette(). 
     | 
| 
      
 78 
     | 
    
         
            +
                    painter.setPen(self.palette().light().color())
         
     | 
| 
       81 
79 
     | 
    
         
             
                    painter.setBrush(self._color)
         
     | 
| 
       82 
80 
     | 
    
         
             
                    painter.setOpacity(1.0)
         
     | 
| 
       83 
81 
     | 
    
         
             
                    painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
         
     | 
| 
       84 
82 
     | 
    
         
             
                    painter.end()
         
     | 
| 
       85 
     | 
    
         
            -
                    return
         
     | 
    
        novelwriter/extensions/switch.py
    CHANGED
    
    | 
         @@ -20,7 +20,7 @@ General Public License for more details. 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            You should have received a copy of the GNU General Public License
         
     | 
| 
       22 
22 
     | 
    
         
             
            along with this program. If not, see <https://www.gnu.org/licenses/>.
         
     | 
| 
       23 
     | 
    
         
            -
            """
         
     | 
| 
      
 23 
     | 
    
         
            +
            """  # noqa
         
     | 
| 
       24 
24 
     | 
    
         
             
            from __future__ import annotations
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            from PyQt6.QtCore import QPropertyAnimation, Qt, pyqtProperty, pyqtSlot  # pyright: ignore
         
     | 
| 
         @@ -32,6 +32,7 @@ from novelwriter.types import QtNoPen, QtPaintAntiAlias, QtSizeFixed 
     | 
|
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            class NSwitch(QAbstractButton):
         
     | 
| 
      
 35 
     | 
    
         
            +
                """Custom: Toggle Switch."""
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
       36 
37 
     | 
    
         
             
                __slots__ = ("_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
         @@ -48,12 +49,11 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       48 
49 
     | 
    
         
             
                    self.setSizePolicy(QtSizeFixed, QtSizeFixed)
         
     | 
| 
       49 
50 
     | 
    
         
             
                    self.setFixedWidth(self._xW)
         
     | 
| 
       50 
51 
     | 
    
         
             
                    self.setFixedHeight(self._xH)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    self.setUpdatesEnabled(True)
         
     | 
| 
       51 
53 
     | 
    
         
             
                    self._offset = self._xR
         
     | 
| 
       52 
54 
     | 
    
         | 
| 
       53 
55 
     | 
    
         
             
                    self.clicked.connect(self._onClick)
         
     | 
| 
       54 
56 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                    return
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
57 
     | 
    
         
             
                ##
         
     | 
| 
       58 
58 
     | 
    
         
             
                #  Properties
         
     | 
| 
       59 
59 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -66,7 +66,6 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       66 
66 
     | 
    
         
             
                def offset(self, offset: int) -> None:
         
     | 
| 
       67 
67 
     | 
    
         
             
                    self._offset = offset
         
     | 
| 
       68 
68 
     | 
    
         
             
                    self.update()
         
     | 
| 
       69 
     | 
    
         
            -
                    return
         
     | 
| 
       70 
69 
     | 
    
         | 
| 
       71 
70 
     | 
    
         
             
                ##
         
     | 
| 
       72 
71 
     | 
    
         
             
                #  Getters and Setters
         
     | 
| 
         @@ -76,7 +75,6 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       76 
75 
     | 
    
         
             
                    """Overload setChecked to also alter the offset."""
         
     | 
| 
       77 
76 
     | 
    
         
             
                    super().setChecked(checked)
         
     | 
| 
       78 
77 
     | 
    
         
             
                    self._offset = (self._xW - self._xR) if checked else self._xR
         
     | 
| 
       79 
     | 
    
         
            -
                    return
         
     | 
| 
       80 
78 
     | 
    
         | 
| 
       81 
79 
     | 
    
         
             
                ##
         
     | 
| 
       82 
80 
     | 
    
         
             
                #  Events
         
     | 
| 
         @@ -86,7 +84,6 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       86 
84 
     | 
    
         
             
                    """Overload resize to ensure correct offset."""
         
     | 
| 
       87 
85 
     | 
    
         
             
                    super().resizeEvent(event)
         
     | 
| 
       88 
86 
     | 
    
         
             
                    self._offset = (self._xW - self._xR) if self.isChecked() else self._xR
         
     | 
| 
       89 
     | 
    
         
            -
                    return
         
     | 
| 
       90 
87 
     | 
    
         | 
| 
       91 
88 
     | 
    
         
             
                def paintEvent(self, event: QPaintEvent) -> None:
         
     | 
| 
       92 
89 
     | 
    
         
             
                    """Drawing the switch itself."""
         
     | 
| 
         @@ -97,7 +94,7 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       97 
94 
     | 
    
         
             
                    painter.setOpacity(1.0 if self.isEnabled() else 0.5)
         
     | 
| 
       98 
95 
     | 
    
         | 
| 
       99 
96 
     | 
    
         
             
                    painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color())
         
     | 
| 
       100 
     | 
    
         
            -
                    painter.setBrush( 
     | 
| 
      
 97 
     | 
    
         
            +
                    painter.setBrush(SHARED.theme.accentCol if self.isChecked() else palette.alternateBase())
         
     | 
| 
       101 
98 
     | 
    
         
             
                    painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
         
     | 
| 
       102 
99 
     | 
    
         | 
| 
       103 
100 
     | 
    
         
             
                    painter.setPen(QtNoPen)
         
     | 
| 
         @@ -106,13 +103,14 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       106 
103 
     | 
    
         | 
| 
       107 
104 
     | 
    
         
             
                    painter.end()
         
     | 
| 
       108 
105 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                    return
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
106 
     | 
    
         
             
                def enterEvent(self, event: QEnterEvent) -> None:
         
     | 
| 
       112 
107 
     | 
    
         
             
                    """Change the cursor when hovering the button."""
         
     | 
| 
       113 
108 
     | 
    
         
             
                    self.setCursor(Qt.CursorShape.PointingHandCursor)
         
     | 
| 
       114 
109 
     | 
    
         
             
                    super().enterEvent(event)
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                ##
         
     | 
| 
      
 112 
     | 
    
         
            +
                #  Internal Functions
         
     | 
| 
      
 113 
     | 
    
         
            +
                ##
         
     | 
| 
       116 
114 
     | 
    
         | 
| 
       117 
115 
     | 
    
         
             
                @pyqtSlot(bool)
         
     | 
| 
       118 
116 
     | 
    
         
             
                def _onClick(self, checked: bool) -> None:
         
     | 
| 
         @@ -122,4 +120,3 @@ class NSwitch(QAbstractButton): 
     | 
|
| 
       122 
120 
     | 
    
         
             
                    anim.setStartValue(self._offset)
         
     | 
| 
       123 
121 
     | 
    
         
             
                    anim.setEndValue((self._xW - self._xR) if checked else self._xR)
         
     | 
| 
       124 
122 
     | 
    
         
             
                    anim.start()
         
     | 
| 
       125 
     | 
    
         
            -
                    return
         
     |