novelWriter 2.4rc1__py3-none-any.whl → 2.4.1__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-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/METADATA +1 -1
 - {novelWriter-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/RECORD +48 -48
 - novelwriter/__init__.py +13 -6
 - novelwriter/assets/i18n/nw_de_DE.qm +0 -0
 - novelwriter/assets/i18n/nw_en_US.qm +0 -0
 - novelwriter/assets/i18n/nw_es_419.qm +0 -0
 - novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
 - novelwriter/assets/i18n/nw_it_IT.qm +0 -0
 - novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
 - novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
 - novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
 - novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
 - novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
 - novelwriter/assets/manual.pdf +0 -0
 - novelwriter/assets/sample.zip +0 -0
 - novelwriter/common.py +5 -2
 - novelwriter/config.py +4 -0
 - novelwriter/core/buildsettings.py +7 -7
 - novelwriter/core/docbuild.py +2 -2
 - novelwriter/core/projectxml.py +1 -1
 - novelwriter/core/spellcheck.py +3 -3
 - novelwriter/core/tokenizer.py +3 -3
 - novelwriter/core/toodt.py +1 -1
 - novelwriter/dialogs/preferences.py +1 -1
 - novelwriter/dialogs/projectsettings.py +2 -2
 - novelwriter/dialogs/wordlist.py +2 -2
 - novelwriter/error.py +1 -1
 - novelwriter/gui/doceditor.py +27 -25
 - novelwriter/gui/dochighlight.py +22 -5
 - novelwriter/gui/docviewer.py +3 -3
 - novelwriter/gui/mainmenu.py +2 -2
 - novelwriter/gui/noveltree.py +1 -1
 - novelwriter/gui/outline.py +9 -9
 - novelwriter/gui/projtree.py +1 -1
 - novelwriter/gui/search.py +2 -2
 - novelwriter/gui/theme.py +15 -5
 - novelwriter/guimain.py +2 -2
 - novelwriter/shared.py +16 -4
 - novelwriter/text/counting.py +1 -0
 - novelwriter/tools/dictionaries.py +2 -2
 - novelwriter/tools/manusbuild.py +12 -11
 - novelwriter/tools/manuscript.py +48 -43
 - novelwriter/tools/manussettings.py +27 -29
 - novelwriter/tools/welcome.py +4 -5
 - {novelWriter-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/LICENSE.md +0 -0
 - {novelWriter-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/WHEEL +0 -0
 - {novelWriter-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/entry_points.txt +0 -0
 - {novelWriter-2.4rc1.dist-info → novelWriter-2.4.1.dist-info}/top_level.txt +0 -0
 
    
        novelwriter/tools/manuscript.py
    CHANGED
    
    | 
         @@ -30,9 +30,9 @@ from datetime import datetime 
     | 
|
| 
       30 
30 
     | 
    
         
             
            from time import time
         
     | 
| 
       31 
31 
     | 
    
         
             
            from typing import TYPE_CHECKING
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
            from PyQt5.QtCore import QTimer, QUrl,  
     | 
| 
      
 33 
     | 
    
         
            +
            from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
         
     | 
| 
       34 
34 
     | 
    
         
             
            from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
         
     | 
| 
       35 
     | 
    
         
            -
            from PyQt5.QtPrintSupport import  
     | 
| 
      
 35 
     | 
    
         
            +
            from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
         
     | 
| 
       36 
36 
     | 
    
         
             
            from PyQt5.QtWidgets import (
         
     | 
| 
       37 
37 
     | 
    
         
             
                QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
         
     | 
| 
       38 
38 
     | 
    
         
             
                QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton,
         
     | 
| 
         @@ -155,7 +155,7 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       155 
155 
     | 
    
         
             
                    self.buildOutline = _OutlineWidget(self)
         
     | 
| 
       156 
156 
     | 
    
         | 
| 
       157 
157 
     | 
    
         
             
                    self.detailsTabs = QTabWidget(self)
         
     | 
| 
       158 
     | 
    
         
            -
                    self.detailsTabs.addTab(self.buildDetails, self.tr(" 
     | 
| 
      
 158 
     | 
    
         
            +
                    self.detailsTabs.addTab(self.buildDetails, self.tr("Details"))
         
     | 
| 
       159 
159 
     | 
    
         
             
                    self.detailsTabs.addTab(self.buildOutline, self.tr("Outline"))
         
     | 
| 
       160 
160 
     | 
    
         
             
                    self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
         
     | 
| 
       161 
161 
     | 
    
         | 
| 
         @@ -303,26 +303,24 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       303 
303 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       304 
304 
     | 
    
         
             
                def _editSelectedBuild(self) -> None:
         
     | 
| 
       305 
305 
     | 
    
         
             
                    """Edit the currently selected build settings entry."""
         
     | 
| 
       306 
     | 
    
         
            -
                    build  
     | 
| 
       307 
     | 
    
         
            -
                    if build is not None:
         
     | 
| 
      
 306 
     | 
    
         
            +
                    if build := self._getSelectedBuild():
         
     | 
| 
       308 
307 
     | 
    
         
             
                        self._openSettingsDialog(build)
         
     | 
| 
       309 
308 
     | 
    
         
             
                    return
         
     | 
| 
       310 
309 
     | 
    
         | 
| 
       311 
310 
     | 
    
         
             
                @pyqtSlot("QListWidgetItem*", "QListWidgetItem*")
         
     | 
| 
       312 
311 
     | 
    
         
             
                def _updateBuildDetails(self, current: QListWidgetItem, previous: QListWidgetItem) -> None:
         
     | 
| 
       313 
312 
     | 
    
         
             
                    """Process change of build selection to update the details."""
         
     | 
| 
       314 
     | 
    
         
            -
                    if  
     | 
| 
       315 
     | 
    
         
            -
                         
     | 
| 
       316 
     | 
    
         
            -
                        if build is not None:
         
     | 
| 
       317 
     | 
    
         
            -
                            self.buildDetails.updateInfo(build)
         
     | 
| 
      
 313 
     | 
    
         
            +
                    if current and (build := self._builds.getBuild(current.data(self.D_KEY))):
         
     | 
| 
      
 314 
     | 
    
         
            +
                        self.buildDetails.updateInfo(build)
         
     | 
| 
       318 
315 
     | 
    
         
             
                    return
         
     | 
| 
       319 
316 
     | 
    
         | 
| 
       320 
317 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       321 
318 
     | 
    
         
             
                def _deleteSelectedBuild(self) -> None:
         
     | 
| 
       322 
319 
     | 
    
         
             
                    """Delete the currently selected build settings entry."""
         
     | 
| 
       323 
     | 
    
         
            -
                    build  
     | 
| 
       324 
     | 
    
         
            -
                    if build is not None:
         
     | 
| 
      
 320 
     | 
    
         
            +
                    if build := self._getSelectedBuild():
         
     | 
| 
       325 
321 
     | 
    
         
             
                        if SHARED.question(self.tr("Delete build '{0}'?".format(build.name))):
         
     | 
| 
      
 322 
     | 
    
         
            +
                            if dialog := self._findSettingsDialog(build.buildID):
         
     | 
| 
      
 323 
     | 
    
         
            +
                                dialog.close()
         
     | 
| 
       326 
324 
     | 
    
         
             
                            self._builds.removeBuild(build.buildID)
         
     | 
| 
       327 
325 
     | 
    
         
             
                            self._updateBuildsList()
         
     | 
| 
       328 
326 
     | 
    
         
             
                    return
         
     | 
| 
         @@ -332,8 +330,7 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       332 
330 
     | 
    
         
             
                    """Process new build settings from the settings dialog."""
         
     | 
| 
       333 
331 
     | 
    
         
             
                    self._builds.setBuild(build)
         
     | 
| 
       334 
332 
     | 
    
         
             
                    self._updateBuildItem(build)
         
     | 
| 
       335 
     | 
    
         
            -
                    current  
     | 
| 
       336 
     | 
    
         
            -
                    if isinstance(current, QListWidgetItem) and current.data(self.D_KEY) == build.buildID:
         
     | 
| 
      
 333 
     | 
    
         
            +
                    if (current := self.buildList.currentItem()) and current.data(self.D_KEY) == build.buildID:
         
     | 
| 
       337 
334 
     | 
    
         
             
                        self._updateBuildDetails(current, current)
         
     | 
| 
       338 
335 
     | 
    
         
             
                    return
         
     | 
| 
       339 
336 
     | 
    
         | 
| 
         @@ -342,10 +339,12 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       342 
339 
     | 
    
         
             
                    """Run the document builder on the current build settings for
         
     | 
| 
       343 
340 
     | 
    
         
             
                    the preview widget.
         
     | 
| 
       344 
341 
     | 
    
         
             
                    """
         
     | 
| 
       345 
     | 
    
         
            -
                    build  
     | 
| 
       346 
     | 
    
         
            -
                    if build is None:
         
     | 
| 
      
 342 
     | 
    
         
            +
                    if not (build := self._getSelectedBuild()):
         
     | 
| 
       347 
343 
     | 
    
         
             
                        return
         
     | 
| 
       348 
344 
     | 
    
         | 
| 
      
 345 
     | 
    
         
            +
                    # Make sure editor content is saved before we start
         
     | 
| 
      
 346 
     | 
    
         
            +
                    SHARED.mainGui.saveDocument()
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
       349 
348 
     | 
    
         
             
                    docBuild = NWBuildDocument(SHARED.project, build)
         
     | 
| 
       350 
349 
     | 
    
         
             
                    docBuild.setPreviewMode(True)
         
     | 
| 
       351 
350 
     | 
    
         
             
                    docBuild.queueAll()
         
     | 
| 
         @@ -383,8 +382,7 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       383 
382 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       384 
383 
     | 
    
         
             
                def _buildManuscript(self) -> None:
         
     | 
| 
       385 
384 
     | 
    
         
             
                    """Open the build dialog and build the manuscript."""
         
     | 
| 
       386 
     | 
    
         
            -
                    build  
     | 
| 
       387 
     | 
    
         
            -
                    if isinstance(build, BuildSettings):
         
     | 
| 
      
 385 
     | 
    
         
            +
                    if build := self._getSelectedBuild():
         
     | 
| 
       388 
386 
     | 
    
         
             
                        dlgBuild = GuiManuscriptBuild(self, build)
         
     | 
| 
       389 
387 
     | 
    
         
             
                        dlgBuild.exec()
         
     | 
| 
       390 
388 
     | 
    
         | 
| 
         @@ -474,14 +472,10 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       474 
472 
     | 
    
         | 
| 
       475 
473 
     | 
    
         
             
                def _openSettingsDialog(self, build: BuildSettings) -> None:
         
     | 
| 
       476 
474 
     | 
    
         
             
                    """Open the build settings dialog."""
         
     | 
| 
       477 
     | 
    
         
            -
                     
     | 
| 
       478 
     | 
    
         
            -
                         
     | 
| 
       479 
     | 
    
         
            -
                         
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
                                logger.debug("Found instance of GuiBuildSettings")
         
     | 
| 
       482 
     | 
    
         
            -
                                obj.show()
         
     | 
| 
       483 
     | 
    
         
            -
                                obj.raise_()
         
     | 
| 
       484 
     | 
    
         
            -
                                return
         
     | 
| 
      
 475 
     | 
    
         
            +
                    if dialog := self._findSettingsDialog(build.buildID):
         
     | 
| 
      
 476 
     | 
    
         
            +
                        dialog.show()
         
     | 
| 
      
 477 
     | 
    
         
            +
                        dialog.raise_()
         
     | 
| 
      
 478 
     | 
    
         
            +
                        return
         
     | 
| 
       485 
479 
     | 
    
         | 
| 
       486 
480 
     | 
    
         
             
                    dlgSettings = GuiBuildSettings(self.mainGui, build)
         
     | 
| 
       487 
481 
     | 
    
         
             
                    dlgSettings.setModal(False)
         
     | 
| 
         @@ -496,6 +490,7 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       496 
490 
     | 
    
         
             
                def _updateBuildsList(self) -> None:
         
     | 
| 
       497 
491 
     | 
    
         
             
                    """Update the list of available builds."""
         
     | 
| 
       498 
492 
     | 
    
         
             
                    self.buildList.clear()
         
     | 
| 
      
 493 
     | 
    
         
            +
                    self._buildMap.clear()
         
     | 
| 
       499 
494 
     | 
    
         
             
                    for key, name in self._builds.builds():
         
     | 
| 
       500 
495 
     | 
    
         
             
                        bItem = QListWidgetItem()
         
     | 
| 
       501 
496 
     | 
    
         
             
                        bItem.setText(name)
         
     | 
| 
         @@ -514,6 +509,15 @@ class GuiManuscript(QDialog): 
     | 
|
| 
       514 
509 
     | 
    
         
             
                        self._updateBuildsList()
         
     | 
| 
       515 
510 
     | 
    
         
             
                    return
         
     | 
| 
       516 
511 
     | 
    
         | 
| 
      
 512 
     | 
    
         
            +
                def _findSettingsDialog(self, buildID: str) -> GuiBuildSettings | None:
         
     | 
| 
      
 513 
     | 
    
         
            +
                    """Return an open build settings dialog for a given build, if
         
     | 
| 
      
 514 
     | 
    
         
            +
                    one exists.
         
     | 
| 
      
 515 
     | 
    
         
            +
                    """
         
     | 
| 
      
 516 
     | 
    
         
            +
                    for obj in SHARED.mainGui.children():
         
     | 
| 
      
 517 
     | 
    
         
            +
                        if isinstance(obj, GuiBuildSettings) and obj.buildID == buildID:
         
     | 
| 
      
 518 
     | 
    
         
            +
                            return obj
         
     | 
| 
      
 519 
     | 
    
         
            +
                    return None
         
     | 
| 
      
 520 
     | 
    
         
            +
             
     | 
| 
       517 
521 
     | 
    
         
             
            # END Class GuiManuscript
         
     | 
| 
       518 
522 
     | 
    
         | 
| 
       519 
523 
     | 
    
         | 
| 
         @@ -627,7 +631,7 @@ class _DetailsWidget(QWidget): 
     | 
|
| 
       627 
631 
     | 
    
         
             
                        ("headings.fmtChapter", "headings.hideChapter"),
         
     | 
| 
       628 
632 
     | 
    
         
             
                        ("headings.fmtUnnumbered", "headings.hideUnnumbered"),
         
     | 
| 
       629 
633 
     | 
    
         
             
                        ("headings.fmtScene", "headings.hideScene"),
         
     | 
| 
       630 
     | 
    
         
            -
                        ("headings. 
     | 
| 
      
 634 
     | 
    
         
            +
                        ("headings.fmtAltScene", "headings.hideAltScene"),
         
     | 
| 
       631 
635 
     | 
    
         
             
                        ("headings.fmtSection", "headings.hideSection"),
         
     | 
| 
       632 
636 
     | 
    
         
             
                    ]:
         
     | 
| 
       633 
637 
     | 
    
         
             
                        sub = QTreeWidgetItem()
         
     | 
| 
         @@ -748,6 +752,7 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       748 
752 
     | 
    
         | 
| 
       749 
753 
     | 
    
         
             
                    self._docTime = 0
         
     | 
| 
       750 
754 
     | 
    
         
             
                    self._buildName = ""
         
     | 
| 
      
 755 
     | 
    
         
            +
                    self._scrollPos = 0
         
     | 
| 
       751 
756 
     | 
    
         | 
| 
       752 
757 
     | 
    
         
             
                    # Document Setup
         
     | 
| 
       753 
758 
     | 
    
         
             
                    dPalette = self.palette()
         
     | 
| 
         @@ -844,6 +849,7 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       844 
849 
     | 
    
         
             
                    self.buildProgress.setValue(0)
         
     | 
| 
       845 
850 
     | 
    
         
             
                    self.buildProgress.setCentreText(None)
         
     | 
| 
       846 
851 
     | 
    
         
             
                    self.buildProgress.setVisible(True)
         
     | 
| 
      
 852 
     | 
    
         
            +
                    self._scrollPos = self.verticalScrollBar().value()
         
     | 
| 
       847 
853 
     | 
    
         
             
                    self.setPlaceholderText("")
         
     | 
| 
       848 
854 
     | 
    
         
             
                    self.clear()
         
     | 
| 
       849 
855 
     | 
    
         
             
                    return
         
     | 
| 
         @@ -856,7 +862,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       856 
862 
     | 
    
         | 
| 
       857 
863 
     | 
    
         
             
                def setContent(self, data: dict) -> None:
         
     | 
| 
       858 
864 
     | 
    
         
             
                    """Set the content of the preview widget."""
         
     | 
| 
       859 
     | 
    
         
            -
                    sPos = self.verticalScrollBar().value()
         
     | 
| 
       860 
865 
     | 
    
         
             
                    QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
         
     | 
| 
       861 
866 
     | 
    
         | 
| 
       862 
867 
     | 
    
         
             
                    self.buildProgress.setCentreText(self.tr("Processing ..."))
         
     | 
| 
         @@ -873,7 +878,6 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       873 
878 
     | 
    
         
             
                        cursor = self.textCursor()
         
     | 
| 
       874 
879 
     | 
    
         
             
                        cursor.insertText("\t")
         
     | 
| 
       875 
880 
     | 
    
         | 
| 
       876 
     | 
    
         
            -
                    self.verticalScrollBar().setValue(sPos)
         
     | 
| 
       877 
881 
     | 
    
         
             
                    self._docTime = checkInt(data.get("time"), 0)
         
     | 
| 
       878 
882 
     | 
    
         
             
                    self._updateBuildAge()
         
     | 
| 
       879 
883 
     | 
    
         | 
| 
         @@ -884,7 +888,7 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       884 
888 
     | 
    
         
             
                    self.buildProgress.setCentreText(self.tr("Done"))
         
     | 
| 
       885 
889 
     | 
    
         
             
                    QApplication.restoreOverrideCursor()
         
     | 
| 
       886 
890 
     | 
    
         
             
                    QApplication.processEvents()
         
     | 
| 
       887 
     | 
    
         
            -
                    QTimer.singleShot(300, self. 
     | 
| 
      
 891 
     | 
    
         
            +
                    QTimer.singleShot(300, self._postUpdate)
         
     | 
| 
       888 
892 
     | 
    
         | 
| 
       889 
893 
     | 
    
         
             
                    return
         
     | 
| 
       890 
894 
     | 
    
         | 
| 
         @@ -939,9 +943,10 @@ class _PreviewWidget(QTextBrowser): 
     | 
|
| 
       939 
943 
     | 
    
         
             
                    return
         
     | 
| 
       940 
944 
     | 
    
         | 
| 
       941 
945 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       942 
     | 
    
         
            -
                def  
     | 
| 
       943 
     | 
    
         
            -
                    """ 
     | 
| 
      
 946 
     | 
    
         
            +
                def _postUpdate(self) -> None:
         
     | 
| 
      
 947 
     | 
    
         
            +
                    """Run tasks after content update."""
         
     | 
| 
       944 
948 
     | 
    
         
             
                    self.buildProgress.setVisible(False)
         
     | 
| 
      
 949 
     | 
    
         
            +
                    self.verticalScrollBar().setValue(self._scrollPos)
         
     | 
| 
       945 
950 
     | 
    
         
             
                    return
         
     | 
| 
       946 
951 
     | 
    
         | 
| 
       947 
952 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -1008,7 +1013,7 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1008 
1013 
     | 
    
         | 
| 
       1009 
1014 
     | 
    
         
             
                    # Maximal
         
     | 
| 
       1010 
1015 
     | 
    
         
             
                    self.maxTotalWords.setText("{0:n}".format(data.get("allWords", 0)))
         
     | 
| 
       1011 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1016 
     | 
    
         
            +
                    self.maxHeadWords.setText("{0:n}".format(data.get("titleWords", 0)))
         
     | 
| 
       1012 
1017 
     | 
    
         
             
                    self.maxTextWords.setText("{0:n}".format(data.get("textWords", 0)))
         
     | 
| 
       1013 
1018 
     | 
    
         
             
                    self.maxTitleCount.setText("{0:n}".format(data.get("titleCount", 0)))
         
     | 
| 
       1014 
1019 
     | 
    
         
             
                    self.maxParCount.setText("{0:n}".format(data.get("paragraphCount", 0)))
         
     | 
| 
         @@ -1018,7 +1023,7 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1018 
1023 
     | 
    
         
             
                    self.maxTextChars.setText("{0:n}".format(data.get("textChars", 0)))
         
     | 
| 
       1019 
1024 
     | 
    
         | 
| 
       1020 
1025 
     | 
    
         
             
                    self.maxTotalWordChars.setText("{0:n}".format(data.get("allWordChars", 0)))
         
     | 
| 
       1021 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1026 
     | 
    
         
            +
                    self.maxHeadWordChars.setText("{0:n}".format(data.get("titleWordChars", 0)))
         
     | 
| 
       1022 
1027 
     | 
    
         
             
                    self.maxTextWordChars.setText("{0:n}".format(data.get("textWordChars", 0)))
         
     | 
| 
       1023 
1028 
     | 
    
         | 
| 
       1024 
1029 
     | 
    
         
             
                    return
         
     | 
| 
         @@ -1082,21 +1087,21 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1082 
1087 
     | 
    
         | 
| 
       1083 
1088 
     | 
    
         
             
                    # Left Column
         
     | 
| 
       1084 
1089 
     | 
    
         
             
                    self.maxTotalWords = QLabel(self)
         
     | 
| 
       1085 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1090 
     | 
    
         
            +
                    self.maxHeadWords = QLabel(self)
         
     | 
| 
       1086 
1091 
     | 
    
         
             
                    self.maxTextWords = QLabel(self)
         
     | 
| 
       1087 
1092 
     | 
    
         
             
                    self.maxTitleCount = QLabel(self)
         
     | 
| 
       1088 
1093 
     | 
    
         
             
                    self.maxParCount = QLabel(self)
         
     | 
| 
       1089 
1094 
     | 
    
         | 
| 
       1090 
1095 
     | 
    
         
             
                    self.maxTotalWords.setAlignment(QtAlignRight)
         
     | 
| 
       1091 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1096 
     | 
    
         
            +
                    self.maxHeadWords.setAlignment(QtAlignRight)
         
     | 
| 
       1092 
1097 
     | 
    
         
             
                    self.maxTextWords.setAlignment(QtAlignRight)
         
     | 
| 
       1093 
1098 
     | 
    
         
             
                    self.maxTitleCount.setAlignment(QtAlignRight)
         
     | 
| 
       1094 
1099 
     | 
    
         
             
                    self.maxParCount.setAlignment(QtAlignRight)
         
     | 
| 
       1095 
1100 
     | 
    
         | 
| 
       1096 
1101 
     | 
    
         
             
                    self.leftForm = QFormLayout()
         
     | 
| 
       1097 
1102 
     | 
    
         
             
                    self.leftForm.addRow(self.tr("Words"), self.maxTotalWords)
         
     | 
| 
       1098 
     | 
    
         
            -
                    self.leftForm.addRow(self.tr(" 
     | 
| 
       1099 
     | 
    
         
            -
                    self.leftForm.addRow(self.tr(" 
     | 
| 
      
 1103 
     | 
    
         
            +
                    self.leftForm.addRow(self.tr("Words in Headings"), self.maxHeadWords)
         
     | 
| 
      
 1104 
     | 
    
         
            +
                    self.leftForm.addRow(self.tr("Words in Text"), self.maxTextWords)
         
     | 
| 
       1100 
1105 
     | 
    
         
             
                    self.leftForm.addRow("", QLabel(self))
         
     | 
| 
       1101 
1106 
     | 
    
         
             
                    self.leftForm.addRow(self.tr("Headings"), self.maxTitleCount)
         
     | 
| 
       1102 
1107 
     | 
    
         
             
                    self.leftForm.addRow(self.tr("Paragraphs"), self.maxParCount)
         
     | 
| 
         @@ -1109,7 +1114,7 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1109 
1114 
     | 
    
         
             
                    self.maxTextChars = QLabel(self)
         
     | 
| 
       1110 
1115 
     | 
    
         | 
| 
       1111 
1116 
     | 
    
         
             
                    self.maxTotalWordChars = QLabel(self)
         
     | 
| 
       1112 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1117 
     | 
    
         
            +
                    self.maxHeadWordChars = QLabel(self)
         
     | 
| 
       1113 
1118 
     | 
    
         
             
                    self.maxTextWordChars = QLabel(self)
         
     | 
| 
       1114 
1119 
     | 
    
         | 
| 
       1115 
1120 
     | 
    
         
             
                    self.maxTotalChars.setAlignment(QtAlignRight)
         
     | 
| 
         @@ -1117,16 +1122,16 @@ class _StatsWidget(QWidget): 
     | 
|
| 
       1117 
1122 
     | 
    
         
             
                    self.maxTextChars.setAlignment(QtAlignRight)
         
     | 
| 
       1118 
1123 
     | 
    
         | 
| 
       1119 
1124 
     | 
    
         
             
                    self.maxTotalWordChars.setAlignment(QtAlignRight)
         
     | 
| 
       1120 
     | 
    
         
            -
                    self. 
     | 
| 
      
 1125 
     | 
    
         
            +
                    self.maxHeadWordChars.setAlignment(QtAlignRight)
         
     | 
| 
       1121 
1126 
     | 
    
         
             
                    self.maxTextWordChars.setAlignment(QtAlignRight)
         
     | 
| 
       1122 
1127 
     | 
    
         | 
| 
       1123 
1128 
     | 
    
         
             
                    self.rightForm = QFormLayout()
         
     | 
| 
       1124 
1129 
     | 
    
         
             
                    self.rightForm.addRow(self.tr("Characters"), self.maxTotalChars)
         
     | 
| 
       1125 
     | 
    
         
            -
                    self.rightForm.addRow(self.tr(" 
     | 
| 
       1126 
     | 
    
         
            -
                    self.rightForm.addRow(self.tr(" 
     | 
| 
      
 1130 
     | 
    
         
            +
                    self.rightForm.addRow(self.tr("Characters in Headings"), self.maxHeaderChars)
         
     | 
| 
      
 1131 
     | 
    
         
            +
                    self.rightForm.addRow(self.tr("Characters in Text"), self.maxTextChars)
         
     | 
| 
       1127 
1132 
     | 
    
         
             
                    self.rightForm.addRow(self.tr("Characters, No Spaces"), self.maxTotalWordChars)
         
     | 
| 
       1128 
     | 
    
         
            -
                    self.rightForm.addRow(self.tr(" 
     | 
| 
       1129 
     | 
    
         
            -
                    self.rightForm.addRow(self.tr(" 
     | 
| 
      
 1133 
     | 
    
         
            +
                    self.rightForm.addRow(self.tr("Characters in Headings, No Spaces"), self.maxHeadWordChars)
         
     | 
| 
      
 1134 
     | 
    
         
            +
                    self.rightForm.addRow(self.tr("Characters in Text, No Spaces"), self.maxTextWordChars)
         
     | 
| 
       1130 
1135 
     | 
    
         
             
                    self.rightForm.setHorizontalSpacing(hPx)
         
     | 
| 
       1131 
1136 
     | 
    
         
             
                    self.rightForm.setVerticalSpacing(vPx)
         
     | 
| 
       1132 
1137 
     | 
    
         | 
| 
         @@ -27,13 +27,13 @@ import logging 
     | 
|
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            from typing import TYPE_CHECKING
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
            from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
         
     | 
| 
       31 
30 
     | 
    
         
             
            from PyQt5.QtCore import QEvent, Qt, pyqtSignal, pyqtSlot
         
     | 
| 
      
 31 
     | 
    
         
            +
            from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
         
     | 
| 
       32 
32 
     | 
    
         
             
            from PyQt5.QtWidgets import (
         
     | 
| 
       33 
     | 
    
         
            -
                QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox,
         
     | 
| 
       34 
     | 
    
         
            -
                 
     | 
| 
       35 
     | 
    
         
            -
                 
     | 
| 
       36 
     | 
    
         
            -
                 
     | 
| 
      
 33 
     | 
    
         
            +
                QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFontDialog,
         
     | 
| 
      
 34 
     | 
    
         
            +
                QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu,
         
     | 
| 
      
 35 
     | 
    
         
            +
                QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, QTreeWidget,
         
     | 
| 
      
 36 
     | 
    
         
            +
                QTreeWidgetItem, QVBoxLayout, QWidget
         
     | 
| 
       37 
37 
     | 
    
         
             
            )
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
            from novelwriter import CONFIG, SHARED
         
     | 
| 
         @@ -669,20 +669,20 @@ class _HeadingsTab(NScrollablePage): 
     | 
|
| 
       669 
669 
     | 
    
         
             
                    self.formatBox.addWidget(self.swtScene, 3, 4)
         
     | 
| 
       670 
670 
     | 
    
         | 
| 
       671 
671 
     | 
    
         
             
                    # Alt Scene Heading
         
     | 
| 
       672 
     | 
    
         
            -
                    self. 
     | 
| 
       673 
     | 
    
         
            -
                    self. 
     | 
| 
       674 
     | 
    
         
            -
                    self. 
     | 
| 
       675 
     | 
    
         
            -
                    self. 
     | 
| 
       676 
     | 
    
         
            -
                    self. 
     | 
| 
       677 
     | 
    
         
            -
                    self. 
     | 
| 
       678 
     | 
    
         
            -
                    self. 
     | 
| 
       679 
     | 
    
         
            -
                    self. 
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
                    self.formatBox.addWidget(self. 
     | 
| 
       682 
     | 
    
         
            -
                    self.formatBox.addWidget(self. 
     | 
| 
       683 
     | 
    
         
            -
                    self.formatBox.addWidget(self. 
     | 
| 
       684 
     | 
    
         
            -
                    self.formatBox.addWidget(self. 
     | 
| 
       685 
     | 
    
         
            -
                    self.formatBox.addWidget(self. 
     | 
| 
      
 672 
     | 
    
         
            +
                    self.lblAScene = QLabel(self._build.getLabel("headings.fmtAltScene"), self)
         
     | 
| 
      
 673 
     | 
    
         
            +
                    self.fmtAScene = QLineEdit("", self)
         
     | 
| 
      
 674 
     | 
    
         
            +
                    self.fmtAScene.setReadOnly(True)
         
     | 
| 
      
 675 
     | 
    
         
            +
                    self.btnAScene = NIconToolButton(self, iSz, "edit")
         
     | 
| 
      
 676 
     | 
    
         
            +
                    self.btnAScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE))
         
     | 
| 
      
 677 
     | 
    
         
            +
                    self.hdeAScene = QLabel(trHide, self)
         
     | 
| 
      
 678 
     | 
    
         
            +
                    self.hdeAScene.setIndent(bSp)
         
     | 
| 
      
 679 
     | 
    
         
            +
                    self.swtAScene = NSwitch(self, height=iPx)
         
     | 
| 
      
 680 
     | 
    
         
            +
             
     | 
| 
      
 681 
     | 
    
         
            +
                    self.formatBox.addWidget(self.lblAScene, 4, 0)
         
     | 
| 
      
 682 
     | 
    
         
            +
                    self.formatBox.addWidget(self.fmtAScene, 4, 1)
         
     | 
| 
      
 683 
     | 
    
         
            +
                    self.formatBox.addWidget(self.btnAScene, 4, 2)
         
     | 
| 
      
 684 
     | 
    
         
            +
                    self.formatBox.addWidget(self.hdeAScene, 4, 3)
         
     | 
| 
      
 685 
     | 
    
         
            +
                    self.formatBox.addWidget(self.swtAScene, 4, 4)
         
     | 
| 
       686 
686 
     | 
    
         | 
| 
       687 
687 
     | 
    
         
             
                    # Section Heading
         
     | 
| 
       688 
688 
     | 
    
         
             
                    self.lblSection = QLabel(self._build.getLabel("headings.fmtSection"), self)
         
     | 
| 
         @@ -826,14 +826,14 @@ class _HeadingsTab(NScrollablePage): 
     | 
|
| 
       826 
826 
     | 
    
         
             
                    self.fmtChapter.setText(self._build.getStr("headings.fmtChapter"))
         
     | 
| 
       827 
827 
     | 
    
         
             
                    self.fmtUnnumbered.setText(self._build.getStr("headings.fmtUnnumbered"))
         
     | 
| 
       828 
828 
     | 
    
         
             
                    self.fmtScene.setText(self._build.getStr("headings.fmtScene"))
         
     | 
| 
       829 
     | 
    
         
            -
                    self. 
     | 
| 
      
 829 
     | 
    
         
            +
                    self.fmtAScene.setText(self._build.getStr("headings.fmtAltScene"))
         
     | 
| 
       830 
830 
     | 
    
         
             
                    self.fmtSection.setText(self._build.getStr("headings.fmtSection"))
         
     | 
| 
       831 
831 
     | 
    
         | 
| 
       832 
832 
     | 
    
         
             
                    self.swtTitle.setChecked(self._build.getBool("headings.hideTitle"))
         
     | 
| 
       833 
833 
     | 
    
         
             
                    self.swtChapter.setChecked(self._build.getBool("headings.hideChapter"))
         
     | 
| 
       834 
834 
     | 
    
         
             
                    self.swtUnnumbered.setChecked(self._build.getBool("headings.hideUnnumbered"))
         
     | 
| 
       835 
835 
     | 
    
         
             
                    self.swtScene.setChecked(self._build.getBool("headings.hideScene"))
         
     | 
| 
       836 
     | 
    
         
            -
                    self. 
     | 
| 
      
 836 
     | 
    
         
            +
                    self.swtAScene.setChecked(self._build.getBool("headings.hideAltScene"))
         
     | 
| 
       837 
837 
     | 
    
         
             
                    self.swtSection.setChecked(self._build.getBool("headings.hideSection"))
         
     | 
| 
       838 
838 
     | 
    
         | 
| 
       839 
839 
     | 
    
         
             
                    self.centerTitle.setChecked(self._build.getBool("headings.centerTitle"))
         
     | 
| 
         @@ -850,7 +850,7 @@ class _HeadingsTab(NScrollablePage): 
     | 
|
| 
       850 
850 
     | 
    
         
             
                    self._build.setValue("headings.hideChapter", self.swtChapter.isChecked())
         
     | 
| 
       851 
851 
     | 
    
         
             
                    self._build.setValue("headings.hideUnnumbered", self.swtUnnumbered.isChecked())
         
     | 
| 
       852 
852 
     | 
    
         
             
                    self._build.setValue("headings.hideScene", self.swtScene.isChecked())
         
     | 
| 
       853 
     | 
    
         
            -
                    self._build.setValue("headings. 
     | 
| 
      
 853 
     | 
    
         
            +
                    self._build.setValue("headings.hideAltScene", self.swtAScene.isChecked())
         
     | 
| 
       854 
854 
     | 
    
         
             
                    self._build.setValue("headings.hideSection", self.swtSection.isChecked())
         
     | 
| 
       855 
855 
     | 
    
         | 
| 
       856 
856 
     | 
    
         
             
                    self._build.setValue("headings.centerTitle", self.centerTitle.isChecked())
         
     | 
| 
         @@ -890,8 +890,8 @@ class _HeadingsTab(NScrollablePage): 
     | 
|
| 
       890 
890 
     | 
    
         
             
                        text = self.fmtScene.text()
         
     | 
| 
       891 
891 
     | 
    
         
             
                        label = self._build.getLabel("headings.fmtScene")
         
     | 
| 
       892 
892 
     | 
    
         
             
                    elif heading == self.EDIT_HSCENE:
         
     | 
| 
       893 
     | 
    
         
            -
                        text = self. 
     | 
| 
       894 
     | 
    
         
            -
                        label = self._build.getLabel("headings. 
     | 
| 
      
 893 
     | 
    
         
            +
                        text = self.fmtAScene.text()
         
     | 
| 
      
 894 
     | 
    
         
            +
                        label = self._build.getLabel("headings.fmtAltScene")
         
     | 
| 
       895 
895 
     | 
    
         
             
                    elif heading == self.EDIT_SECTION:
         
     | 
| 
       896 
896 
     | 
    
         
             
                        text = self.fmtSection.text()
         
     | 
| 
       897 
897 
     | 
    
         
             
                        label = self._build.getLabel("headings.fmtSection")
         
     | 
| 
         @@ -928,8 +928,8 @@ class _HeadingsTab(NScrollablePage): 
     | 
|
| 
       928 
928 
     | 
    
         
             
                        self.fmtScene.setText(text)
         
     | 
| 
       929 
929 
     | 
    
         
             
                        self._build.setValue("headings.fmtScene", text)
         
     | 
| 
       930 
930 
     | 
    
         
             
                    elif heading == self.EDIT_HSCENE:
         
     | 
| 
       931 
     | 
    
         
            -
                        self. 
     | 
| 
       932 
     | 
    
         
            -
                        self._build.setValue("headings. 
     | 
| 
      
 931 
     | 
    
         
            +
                        self.fmtAScene.setText(text)
         
     | 
| 
      
 932 
     | 
    
         
            +
                        self._build.setValue("headings.fmtAltScene", text)
         
     | 
| 
       933 
933 
     | 
    
         
             
                    elif heading == self.EDIT_SECTION:
         
     | 
| 
       934 
934 
     | 
    
         
             
                        self.fmtSection.setText(text)
         
     | 
| 
       935 
935 
     | 
    
         
             
                        self._build.setValue("headings.fmtSection", text)
         
     | 
| 
         @@ -1060,8 +1060,6 @@ class _FormatTab(NScrollableForm): 
     | 
|
| 
       1060 
1060 
     | 
    
         
             
                def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None:
         
     | 
| 
       1061 
1061 
     | 
    
         
             
                    super().__init__(parent=buildMain)
         
     | 
| 
       1062 
1062 
     | 
    
         | 
| 
       1063 
     | 
    
         
            -
                    self.buildMain = buildMain
         
     | 
| 
       1064 
     | 
    
         
            -
             
     | 
| 
       1065 
1063 
     | 
    
         
             
                    self._build = build
         
     | 
| 
       1066 
1064 
     | 
    
         
             
                    self._unitScale = 1.0
         
     | 
| 
       1067 
1065 
     | 
    
         | 
| 
         @@ -1312,7 +1310,7 @@ class _FormatTab(NScrollableForm): 
     | 
|
| 
       1312 
1310 
     | 
    
         
             
                    return
         
     | 
| 
       1313 
1311 
     | 
    
         | 
| 
       1314 
1312 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       1315 
     | 
    
         
            -
                def _pageSizeValueChanged(self):
         
     | 
| 
      
 1313 
     | 
    
         
            +
                def _pageSizeValueChanged(self) -> None:
         
     | 
| 
       1316 
1314 
     | 
    
         
             
                    """The user has changed the page size spin boxes, so we flip
         
     | 
| 
       1317 
1315 
     | 
    
         
             
                    the page size box to Custom.
         
     | 
| 
       1318 
1316 
     | 
    
         
             
                    """
         
     | 
    
        novelwriter/tools/welcome.py
    CHANGED
    
    | 
         @@ -560,7 +560,7 @@ class _NewProjectForm(QWidget): 
     | 
|
| 
       560 
560 
     | 
    
         
             
                def __init__(self, parent: QWidget) -> None:
         
     | 
| 
       561 
561 
     | 
    
         
             
                    super().__init__(parent=parent)
         
     | 
| 
       562 
562 
     | 
    
         | 
| 
       563 
     | 
    
         
            -
                    self._basePath = CONFIG. 
     | 
| 
      
 563 
     | 
    
         
            +
                    self._basePath = CONFIG.homePath()
         
     | 
| 
       564 
564 
     | 
    
         
             
                    self._fillMode = self.FILL_BLANK
         
     | 
| 
       565 
565 
     | 
    
         
             
                    self._copyPath = None
         
     | 
| 
       566 
566 
     | 
    
         | 
| 
         @@ -632,7 +632,7 @@ class _NewProjectForm(QWidget): 
     | 
|
| 
       632 
632 
     | 
    
         | 
| 
       633 
633 
     | 
    
         
             
                    self.numChapters = NSpinBox(self)
         
     | 
| 
       634 
634 
     | 
    
         
             
                    self.numChapters.setRange(0, 200)
         
     | 
| 
       635 
     | 
    
         
            -
                    self.numChapters.setValue( 
     | 
| 
      
 635 
     | 
    
         
            +
                    self.numChapters.setValue(0)
         
     | 
| 
       636 
636 
     | 
    
         
             
                    self.numChapters.setToolTip(self.tr("Set to 0 to only add scenes"))
         
     | 
| 
       637 
637 
     | 
    
         | 
| 
       638 
638 
     | 
    
         
             
                    self.chapterBox = NWrappedWidgetBox(
         
     | 
| 
         @@ -642,7 +642,7 @@ class _NewProjectForm(QWidget): 
     | 
|
| 
       642 
642 
     | 
    
         | 
| 
       643 
643 
     | 
    
         
             
                    self.numScenes = NSpinBox(self)
         
     | 
| 
       644 
644 
     | 
    
         
             
                    self.numScenes.setRange(0, 200)
         
     | 
| 
       645 
     | 
    
         
            -
                    self.numScenes.setValue( 
     | 
| 
      
 645 
     | 
    
         
            +
                    self.numScenes.setValue(0)
         
     | 
| 
       646 
646 
     | 
    
         | 
| 
       647 
647 
     | 
    
         
             
                    self.sceneBox = NWrappedWidgetBox(
         
     | 
| 
       648 
648 
     | 
    
         
             
                        self.tr("Add {0} scene documents (to each chapter)"), self.numScenes
         
     | 
| 
         @@ -742,7 +742,6 @@ class _NewProjectForm(QWidget): 
     | 
|
| 
       742 
742 
     | 
    
         
             
                    ):
         
     | 
| 
       743 
743 
     | 
    
         
             
                        self._basePath = Path(projDir)
         
     | 
| 
       744 
744 
     | 
    
         
             
                        self._updateProjPath()
         
     | 
| 
       745 
     | 
    
         
            -
                        CONFIG.setLastPath(self._basePath)
         
     | 
| 
       746 
745 
     | 
    
         
             
                    return
         
     | 
| 
       747 
746 
     | 
    
         | 
| 
       748 
747 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
         @@ -753,7 +752,7 @@ class _NewProjectForm(QWidget): 
     | 
|
| 
       753 
752 
     | 
    
         
             
                    return
         
     | 
| 
       754 
753 
     | 
    
         | 
| 
       755 
754 
     | 
    
         
             
                @pyqtSlot()
         
     | 
| 
       756 
     | 
    
         
            -
                def _syncSwitches(self):
         
     | 
| 
      
 755 
     | 
    
         
            +
                def _syncSwitches(self) -> None:
         
     | 
| 
       757 
756 
     | 
    
         
             
                    """Check if the add notes option should also be switched off."""
         
     | 
| 
       758 
757 
     | 
    
         
             
                    addPlot = self.addPlot.isChecked()
         
     | 
| 
       759 
758 
     | 
    
         
             
                    addChar = self.addChar.isChecked()
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |