novelWriter 2.6.3__py3-none-any.whl → 2.7b1__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 +84 -74
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/icons/font_awesome.icons +109 -0
- novelwriter/assets/icons/material_filled_bold.icons +109 -0
- novelwriter/assets/icons/material_filled_normal.icons +109 -0
- novelwriter/assets/icons/material_filled_thin.icons +109 -0
- novelwriter/assets/icons/material_rounded_bold.icons +109 -0
- novelwriter/assets/icons/material_rounded_normal.icons +109 -0
- novelwriter/assets/icons/material_rounded_thin.icons +109 -0
- novelwriter/assets/icons/remix_filled.icons +108 -0
- novelwriter/assets/icons/remix_outline.icons +108 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/{manual_fr_FR.pdf → manual_fr.pdf} +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/cyberpunk_night.conf +1 -1
- novelwriter/assets/text/credits_en.htm +6 -6
- novelwriter/assets/themes/cyberpunk_night.conf +23 -7
- novelwriter/assets/themes/default_dark.conf +20 -4
- novelwriter/assets/themes/default_light.conf +21 -5
- novelwriter/assets/themes/dracula.conf +20 -4
- novelwriter/assets/themes/solarized_dark.conf +24 -8
- novelwriter/assets/themes/solarized_light.conf +22 -6
- novelwriter/common.py +33 -26
- novelwriter/config.py +118 -127
- novelwriter/constants.py +50 -36
- novelwriter/core/buildsettings.py +23 -16
- novelwriter/core/coretools.py +11 -7
- novelwriter/core/docbuild.py +19 -13
- novelwriter/core/document.py +2 -2
- novelwriter/core/index.py +142 -432
- novelwriter/core/indexdata.py +403 -0
- novelwriter/core/item.py +35 -28
- novelwriter/core/itemmodel.py +27 -26
- novelwriter/core/novelmodel.py +223 -0
- novelwriter/core/options.py +1 -1
- novelwriter/core/project.py +10 -11
- novelwriter/core/projectdata.py +5 -5
- novelwriter/core/projectxml.py +1 -1
- novelwriter/core/sessions.py +3 -2
- novelwriter/core/spellcheck.py +4 -3
- novelwriter/core/status.py +12 -15
- novelwriter/core/storage.py +1 -1
- novelwriter/core/tree.py +46 -8
- novelwriter/dialogs/about.py +19 -22
- novelwriter/dialogs/docmerge.py +21 -23
- novelwriter/dialogs/docsplit.py +20 -23
- novelwriter/dialogs/editlabel.py +9 -13
- novelwriter/dialogs/preferences.py +111 -48
- novelwriter/dialogs/projectsettings.py +48 -54
- novelwriter/dialogs/quotes.py +14 -19
- novelwriter/dialogs/wordlist.py +25 -30
- novelwriter/enum.py +8 -0
- novelwriter/error.py +16 -16
- novelwriter/extensions/configlayout.py +18 -18
- novelwriter/extensions/eventfilters.py +9 -5
- novelwriter/extensions/modified.py +34 -15
- novelwriter/extensions/novelselector.py +18 -5
- novelwriter/extensions/pagedsidebar.py +39 -49
- novelwriter/extensions/progressbars.py +10 -8
- novelwriter/extensions/statusled.py +6 -13
- novelwriter/extensions/switch.py +19 -30
- novelwriter/extensions/switchbox.py +7 -3
- novelwriter/extensions/versioninfo.py +4 -4
- novelwriter/formats/shared.py +1 -1
- novelwriter/formats/todocx.py +14 -10
- novelwriter/formats/tohtml.py +7 -5
- novelwriter/formats/tokenizer.py +36 -33
- novelwriter/formats/tomarkdown.py +6 -2
- novelwriter/formats/toodt.py +27 -22
- novelwriter/formats/toqdoc.py +19 -14
- novelwriter/formats/toraw.py +6 -2
- novelwriter/gui/doceditor.py +216 -265
- novelwriter/gui/dochighlight.py +46 -45
- novelwriter/gui/docviewer.py +102 -104
- novelwriter/gui/docviewerpanel.py +47 -51
- novelwriter/gui/editordocument.py +8 -5
- novelwriter/gui/itemdetails.py +11 -14
- novelwriter/gui/mainmenu.py +146 -145
- novelwriter/gui/noveltree.py +239 -405
- novelwriter/gui/outline.py +133 -72
- novelwriter/gui/projtree.py +138 -132
- novelwriter/gui/search.py +33 -31
- novelwriter/gui/sidebar.py +13 -18
- novelwriter/gui/statusbar.py +13 -15
- novelwriter/gui/theme.py +533 -430
- novelwriter/guimain.py +27 -29
- novelwriter/shared.py +32 -23
- novelwriter/text/comments.py +70 -0
- novelwriter/text/patterns.py +4 -4
- novelwriter/tools/dictionaries.py +20 -29
- novelwriter/tools/lipsum.py +16 -17
- novelwriter/tools/manusbuild.py +39 -42
- novelwriter/tools/manuscript.py +101 -114
- novelwriter/tools/manussettings.py +78 -83
- novelwriter/tools/noveldetails.py +51 -64
- novelwriter/tools/welcome.py +56 -75
- novelwriter/tools/writingstats.py +44 -57
- novelwriter/types.py +5 -7
- {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/METADATA +6 -6
- novelwriter-2.7b1.dist-info/RECORD +159 -0
- {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/WHEEL +1 -1
- novelWriter-2.6.3.dist-info/RECORD +0 -363
- novelwriter/assets/icons/typicons_dark/README.md +0 -29
- novelwriter/assets/icons/typicons_dark/icons.conf +0 -134
- novelwriter/assets/icons/typicons_dark/mixed_copy.svg +0 -4
- novelwriter/assets/icons/typicons_dark/mixed_document-chapter.svg +0 -12
- novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_document-note.svg +0 -12
- novelwriter/assets/icons/typicons_dark/mixed_document-scene.svg +0 -12
- novelwriter/assets/icons/typicons_dark/mixed_document-section.svg +0 -12
- novelwriter/assets/icons/typicons_dark/mixed_document-title.svg +0 -12
- novelwriter/assets/icons/typicons_dark/mixed_edit.svg +0 -4
- novelwriter/assets/icons/typicons_dark/mixed_import.svg +0 -5
- novelwriter/assets/icons/typicons_dark/mixed_input-checked.svg +0 -5
- novelwriter/assets/icons/typicons_dark/mixed_input-none.svg +0 -5
- novelwriter/assets/icons/typicons_dark/mixed_input-unchecked.svg +0 -5
- novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_search-replace.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +0 -6
- novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +0 -6
- novelwriter/assets/icons/typicons_dark/nw_deco-h0.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h1.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h2.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h3.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-h4.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_font.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_panel.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_quote.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_search-case.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_search-preserve.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_search-regex.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_search-word.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +0 -6
- novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +0 -6
- novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +0 -7
- novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +0 -4
- novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +0 -6
- novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +0 -7
- novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +0 -7
- novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +0 -7
- novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +0 -5
- novelwriter/assets/icons/typicons_dark/typ_arrow-down-thick-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-forward.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-maximise.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-minimise.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_arrow-repeat-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_book-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_book.svg +0 -6
- novelwriter/assets/icons/typicons_dark/typ_bookmark.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_calendar.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_cancel-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_cancel.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_chart-bar-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_chevron-down.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_chevron-left.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_chevron-right.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_chevron-up.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_cog.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_delete-full.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_delete.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_directions-full.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_document-add.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_document-text.svg +0 -8
- novelwriter/assets/icons/typicons_dark/typ_document.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_export-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_export.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_eye.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_flag.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_folder-open.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_folder.svg +0 -5
- novelwriter/assets/icons/typicons_dark/typ_globe-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_key.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_lightbulb-full.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_location.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_media-pause-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_media-record-outline.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_media-record.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_minus.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_pencil.svg +0 -5
- novelwriter/assets/icons/typicons_dark/typ_pin-outline.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_pin.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_plus.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_puzzle-outline.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_puzzle.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_refresh.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_search.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_star.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_stopwatch-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_th-dot-menu.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_th-list-grey.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_th-list.svg +0 -9
- novelwriter/assets/icons/typicons_dark/typ_times.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_trash.svg +0 -5
- novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +0 -4
- novelwriter/assets/icons/typicons_dark/typ_user.svg +0 -5
- novelwriter/assets/icons/typicons_dark/typ_warning-full.svg +0 -4
- novelwriter/assets/icons/typicons_light/README.md +0 -29
- novelwriter/assets/icons/typicons_light/icons.conf +0 -134
- novelwriter/assets/icons/typicons_light/mixed_copy.svg +0 -4
- novelwriter/assets/icons/typicons_light/mixed_document-chapter.svg +0 -12
- novelwriter/assets/icons/typicons_light/mixed_document-new.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_document-note.svg +0 -12
- novelwriter/assets/icons/typicons_light/mixed_document-scene.svg +0 -12
- novelwriter/assets/icons/typicons_light/mixed_document-section.svg +0 -12
- novelwriter/assets/icons/typicons_light/mixed_document-title.svg +0 -12
- novelwriter/assets/icons/typicons_light/mixed_edit.svg +0 -4
- novelwriter/assets/icons/typicons_light/mixed_import.svg +0 -5
- novelwriter/assets/icons/typicons_light/mixed_input-checked.svg +0 -5
- novelwriter/assets/icons/typicons_light/mixed_input-none.svg +0 -5
- novelwriter/assets/icons/typicons_light/mixed_input-unchecked.svg +0 -5
- novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_search-replace.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_size-height.svg +0 -6
- novelwriter/assets/icons/typicons_light/mixed_size-width.svg +0 -6
- novelwriter/assets/icons/typicons_light/nw_deco-h0.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h1.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h2.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h3.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-h4.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-note.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_font.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_panel.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_quote.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_search-case.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_search-preserve.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_search-regex.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_search-word.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +0 -6
- novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +0 -6
- novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +0 -7
- novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +0 -4
- novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +0 -6
- novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +0 -7
- novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +0 -7
- novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +0 -7
- novelwriter/assets/icons/typicons_light/nw_toolbar.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_arrow-down-thick-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-forward.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-maximise.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-minimise.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_arrow-repeat-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_book-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_book.svg +0 -6
- novelwriter/assets/icons/typicons_light/typ_bookmark.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_calendar.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_cancel-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_cancel.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_chart-bar-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_chevron-down.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_chevron-left.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_chevron-right.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_chevron-up.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_cog.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_delete-full.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_delete.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_directions-full.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_document-add.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_document-text.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_document.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_export-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_export.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_eye.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_flag.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_folder-open.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_folder.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_globe-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_key.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_lightbulb-full.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_location.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_media-pause-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_media-record-outline.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_media-record.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_minus.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_pencil.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_pin-outline.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_pin.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_plus.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_puzzle-outline.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_puzzle.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_refresh.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_search-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_search.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_star.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_stopwatch-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_th-dot-menu.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_th-list-grey.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_th-list.svg +0 -9
- novelwriter/assets/icons/typicons_light/typ_times.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_trash.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +0 -4
- novelwriter/assets/icons/typicons_light/typ_user.svg +0 -5
- novelwriter/assets/icons/typicons_light/typ_warning-full.svg +0 -4
- {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info/licenses}/LICENSE.md +0 -0
- {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/top_level.txt +0 -0
@@ -31,9 +31,9 @@ from time import sleep
|
|
31
31
|
from urllib.error import HTTPError
|
32
32
|
from urllib.request import Request, urlopen
|
33
33
|
|
34
|
-
from
|
35
|
-
from
|
36
|
-
from
|
34
|
+
from PyQt6.QtCore import QObject, QRunnable, QUrl, pyqtSignal, pyqtSlot
|
35
|
+
from PyQt6.QtGui import QDesktopServices
|
36
|
+
from PyQt6.QtWidgets import QLabel, QVBoxLayout, QWidget
|
37
37
|
|
38
38
|
from novelwriter import CONFIG, SHARED, __date__, __domain__, __version__
|
39
39
|
from novelwriter.common import formatVersion
|
@@ -70,7 +70,7 @@ class VersionInfoWidget(QWidget):
|
|
70
70
|
self._layout = QVBoxLayout()
|
71
71
|
self._layout.addWidget(self._lblInfo)
|
72
72
|
self._layout.addWidget(self._lblRelease)
|
73
|
-
self._layout.setSpacing(
|
73
|
+
self._layout.setSpacing(2)
|
74
74
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
75
75
|
|
76
76
|
self.setLayout(self._layout)
|
novelwriter/formats/shared.py
CHANGED
@@ -27,7 +27,7 @@ import re
|
|
27
27
|
|
28
28
|
from enum import Flag, IntEnum
|
29
29
|
|
30
|
-
from
|
30
|
+
from PyQt6.QtGui import QColor
|
31
31
|
|
32
32
|
ESCAPES = {r"\*": "*", r"\~": "~", r"\_": "_", r"\[": "[", r"\]": "]", r"\ ": ""}
|
33
33
|
RX_ESC = re.compile("|".join([re.escape(k) for k in ESCAPES.keys()]), flags=re.DOTALL)
|
novelwriter/formats/todocx.py
CHANGED
@@ -29,21 +29,25 @@ import re
|
|
29
29
|
import xml.etree.ElementTree as ET
|
30
30
|
|
31
31
|
from datetime import datetime
|
32
|
-
from
|
33
|
-
from typing import NamedTuple
|
32
|
+
from typing import TYPE_CHECKING, NamedTuple
|
34
33
|
from zipfile import ZIP_DEFLATED, ZipFile
|
35
34
|
|
36
|
-
from
|
37
|
-
from PyQt5.QtGui import QColor
|
35
|
+
from PyQt6.QtCore import QMargins, QSize
|
38
36
|
|
39
37
|
from novelwriter import __version__
|
40
38
|
from novelwriter.common import firstFloat, xmlElement, xmlSubElem
|
41
39
|
from novelwriter.constants import nwHeadFmt, nwStyles
|
42
|
-
from novelwriter.core.project import NWProject
|
43
40
|
from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt
|
44
41
|
from novelwriter.formats.tokenizer import Tokenizer
|
45
42
|
from novelwriter.types import QtHexRgb
|
46
43
|
|
44
|
+
if TYPE_CHECKING:
|
45
|
+
from pathlib import Path
|
46
|
+
|
47
|
+
from PyQt6.QtGui import QColor
|
48
|
+
|
49
|
+
from novelwriter.core.project import NWProject
|
50
|
+
|
47
51
|
logger = logging.getLogger(__name__)
|
48
52
|
|
49
53
|
# RegEx
|
@@ -212,9 +216,9 @@ class ToDocX(Tokenizer):
|
|
212
216
|
self._pageMargins = QMargins(_mmToSz(left), _mmToSz(top), _mmToSz(right), _mmToSz(bottom))
|
213
217
|
return
|
214
218
|
|
215
|
-
def setHeaderFormat(self,
|
219
|
+
def setHeaderFormat(self, value: str, offset: int) -> None:
|
216
220
|
"""Set the document header format."""
|
217
|
-
self._headerFormat =
|
221
|
+
self._headerFormat = value.strip()
|
218
222
|
self._pageOffset = offset
|
219
223
|
return
|
220
224
|
|
@@ -1052,9 +1056,9 @@ class ToDocX(Tokenizer):
|
|
1052
1056
|
class DocXParagraph:
|
1053
1057
|
|
1054
1058
|
__slots__ = (
|
1055
|
-
"
|
1056
|
-
"
|
1057
|
-
"
|
1059
|
+
"_bottomMargin", "_breakAfter", "_breakBefore", "_content",
|
1060
|
+
"_footnoteRef", "_indentFirst", "_leftMargin", "_rightMargin",
|
1061
|
+
"_style", "_textAlign", "_topMargin",
|
1058
1062
|
)
|
1059
1063
|
|
1060
1064
|
def __init__(self) -> None:
|
novelwriter/formats/tohtml.py
CHANGED
@@ -26,16 +26,20 @@ from __future__ import annotations
|
|
26
26
|
import json
|
27
27
|
import logging
|
28
28
|
|
29
|
-
from pathlib import Path
|
30
29
|
from time import time
|
30
|
+
from typing import TYPE_CHECKING
|
31
31
|
|
32
32
|
from novelwriter.common import formatTimeStamp
|
33
33
|
from novelwriter.constants import nwHtmlUnicode, nwStyles
|
34
|
-
from novelwriter.core.project import NWProject
|
35
34
|
from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt, stripEscape
|
36
35
|
from novelwriter.formats.tokenizer import Tokenizer
|
37
36
|
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS, QtHexRgb
|
38
37
|
|
38
|
+
if TYPE_CHECKING:
|
39
|
+
from pathlib import Path
|
40
|
+
|
41
|
+
from novelwriter.core.project import NWProject
|
42
|
+
|
39
43
|
logger = logging.getLogger(__name__)
|
40
44
|
|
41
45
|
# Each opener tag, with the id of its corresponding closer and tag format
|
@@ -311,10 +315,8 @@ class ToHtml(Tokenizer):
|
|
311
315
|
|
312
316
|
def replaceTabs(self, nSpaces: int = 8, spaceChar: str = " ") -> None:
|
313
317
|
"""Replace tabs with spaces in the html."""
|
314
|
-
pages = []
|
315
318
|
tabSpace = spaceChar*nSpaces
|
316
|
-
for aLine in self._pages
|
317
|
-
pages.append(aLine.replace("\t", tabSpace))
|
319
|
+
pages = [aLine.replace("\t", tabSpace) for aLine in self._pages]
|
318
320
|
self._pages = pages
|
319
321
|
return
|
320
322
|
|
novelwriter/formats/tokenizer.py
CHANGED
@@ -28,11 +28,10 @@ import logging
|
|
28
28
|
import re
|
29
29
|
|
30
30
|
from abc import ABC, abstractmethod
|
31
|
-
from
|
32
|
-
from typing import NamedTuple
|
31
|
+
from typing import TYPE_CHECKING, NamedTuple
|
33
32
|
|
34
|
-
from
|
35
|
-
from
|
33
|
+
from PyQt6.QtCore import QLocale
|
34
|
+
from PyQt6.QtGui import QColor, QFont
|
36
35
|
|
37
36
|
from novelwriter import CONFIG
|
38
37
|
from novelwriter.common import checkInt, fontMatcher, numberToRoman
|
@@ -40,14 +39,18 @@ from novelwriter.constants import (
|
|
40
39
|
nwHeadFmt, nwKeyWords, nwLabels, nwShortcode, nwStats, nwStyles, nwUnicode,
|
41
40
|
trConst
|
42
41
|
)
|
43
|
-
from novelwriter.core.index import processComment
|
44
|
-
from novelwriter.core.project import NWProject
|
45
42
|
from novelwriter.enum import nwComment, nwItemLayout
|
46
43
|
from novelwriter.formats.shared import (
|
47
44
|
BlockFmt, BlockTyp, T_Block, T_Formats, T_Note, TextDocumentTheme, TextFmt
|
48
45
|
)
|
46
|
+
from novelwriter.text.comments import processComment
|
49
47
|
from novelwriter.text.patterns import REGEX_PATTERNS, DialogParser
|
50
48
|
|
49
|
+
if TYPE_CHECKING:
|
50
|
+
from pathlib import Path
|
51
|
+
|
52
|
+
from novelwriter.core.project import NWProject
|
53
|
+
|
51
54
|
logger = logging.getLogger(__name__)
|
52
55
|
|
53
56
|
|
@@ -61,18 +64,18 @@ class ComStyle(NamedTuple):
|
|
61
64
|
COMMENT_STYLE = {
|
62
65
|
nwComment.PLAIN: ComStyle("Comment", "comment", "comment"),
|
63
66
|
nwComment.IGNORE: ComStyle(),
|
64
|
-
nwComment.SYNOPSIS: ComStyle("Synopsis", "modifier", "
|
65
|
-
nwComment.SHORT: ComStyle("Short Description", "modifier", "
|
67
|
+
nwComment.SYNOPSIS: ComStyle("Synopsis", "modifier", "note"),
|
68
|
+
nwComment.SHORT: ComStyle("Short Description", "modifier", "note"),
|
66
69
|
nwComment.NOTE: ComStyle("Note", "modifier", "note"),
|
67
70
|
nwComment.FOOTNOTE: ComStyle("", "modifier", "note"),
|
68
71
|
nwComment.COMMENT: ComStyle(),
|
69
|
-
nwComment.STORY: ComStyle("", "modifier", "note"),
|
72
|
+
nwComment.STORY: ComStyle("Story Structure", "modifier", "note"),
|
70
73
|
}
|
71
74
|
HEADINGS = [
|
72
75
|
BlockTyp.TITLE, BlockTyp.PART, BlockTyp.HEAD1,
|
73
76
|
BlockTyp.HEAD2, BlockTyp.HEAD3, BlockTyp.HEAD4,
|
74
77
|
]
|
75
|
-
SKIP_INDENT = HEADINGS
|
78
|
+
SKIP_INDENT = [*HEADINGS, BlockTyp.SEP, BlockTyp.SKIP]
|
76
79
|
B_EMPTY: T_Block = (BlockTyp.EMPTY, "", "", [], BlockFmt.NONE)
|
77
80
|
|
78
81
|
|
@@ -118,14 +121,16 @@ class Tokenizer(ABC):
|
|
118
121
|
self._indentFirst = False # Indent first paragraph
|
119
122
|
self._doJustify = False # Justify text
|
120
123
|
self._doBodyText = True # Include body text
|
121
|
-
self.
|
122
|
-
self._doComments = False # Also process comments
|
124
|
+
self._doComments = set() # Comment styles to allow
|
123
125
|
self._doKeywords = False # Also process keywords like tags and references
|
124
126
|
self._keepBreaks = True # Keep line breaks in paragraphs
|
125
127
|
self._defaultAlign = "left" # The default text alignment
|
126
128
|
|
127
129
|
self._skipKeywords: set[str] = set() # Keywords to ignore
|
128
130
|
|
131
|
+
# Defaults
|
132
|
+
self._doComments.add(nwComment.FOOTNOTE)
|
133
|
+
|
129
134
|
# Other Setting
|
130
135
|
self._theme = TextDocumentTheme()
|
131
136
|
self._classes: dict[str, QColor] = {}
|
@@ -393,14 +398,12 @@ class Tokenizer(ABC):
|
|
393
398
|
self._doBodyText = state
|
394
399
|
return
|
395
400
|
|
396
|
-
def
|
397
|
-
"""
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
"""Include comments in build."""
|
403
|
-
self._doComments = state
|
401
|
+
def setCommentType(self, comment: nwComment, state: bool) -> None:
|
402
|
+
"""Toggle the inclusion og certain comment types."""
|
403
|
+
if state:
|
404
|
+
self._doComments.add(comment)
|
405
|
+
else:
|
406
|
+
self._doComments.discard(comment)
|
404
407
|
return
|
405
408
|
|
406
409
|
def setKeywords(self, state: bool) -> None:
|
@@ -437,7 +440,7 @@ class Tokenizer(ABC):
|
|
437
440
|
def initDocument(self) -> None:
|
438
441
|
"""Initialise data after settings."""
|
439
442
|
self._classes["modifier"] = self._theme.modifier
|
440
|
-
self._classes["
|
443
|
+
self._classes["note"] = self._theme.note
|
441
444
|
self._classes["comment"] = self._theme.comment
|
442
445
|
self._classes["dialog"] = self._theme.dialog
|
443
446
|
self._classes["altdialog"] = self._theme.altdialog
|
@@ -604,15 +607,15 @@ class Tokenizer(ABC):
|
|
604
607
|
continue
|
605
608
|
|
606
609
|
cStyle, cKey, cText, _, _ = processComment(aLine)
|
607
|
-
if cStyle in
|
608
|
-
continue
|
609
|
-
if cStyle == nwComment.PLAIN and not self._doComments:
|
610
|
+
if cStyle not in self._doComments:
|
610
611
|
continue
|
611
612
|
|
612
613
|
if doJustify and not tStyle & BlockFmt.ALIGNED:
|
613
614
|
tStyle |= BlockFmt.JUSTIFY
|
614
615
|
|
615
|
-
if cStyle in (
|
616
|
+
if cStyle in (
|
617
|
+
nwComment.SYNOPSIS, nwComment.SHORT, nwComment.PLAIN, nwComment.STORY
|
618
|
+
):
|
616
619
|
bStyle = COMMENT_STYLE[cStyle]
|
617
620
|
tLine, tFmt = self._formatComment(bStyle, cKey, cText)
|
618
621
|
tBlocks.append((
|
@@ -651,7 +654,7 @@ class Tokenizer(ABC):
|
|
651
654
|
tText = aLine[2:].strip()
|
652
655
|
tType = BlockTyp.HEAD1 if isPlain else BlockTyp.TITLE
|
653
656
|
sHide = self._hidePart if isPlain else False
|
654
|
-
if not (isPlain or isNovel and sHide):
|
657
|
+
if not (isPlain or (isNovel and sHide)):
|
655
658
|
tStyle |= self._titleStyle
|
656
659
|
if isNovel:
|
657
660
|
tType = BlockTyp.PART if isPlain else BlockTyp.TITLE
|
@@ -1034,10 +1037,12 @@ class Tokenizer(ABC):
|
|
1034
1037
|
|
1035
1038
|
def _formatComment(self, style: ComStyle, key: str, text: str) -> tuple[str, T_Formats]:
|
1036
1039
|
"""Apply formatting to comments and notes."""
|
1040
|
+
rFmt = []
|
1037
1041
|
tTxt, tFmt = self._extractFormats(text)
|
1038
1042
|
tFmt.insert(0, (0, TextFmt.COL_B, style.textClass))
|
1039
1043
|
tFmt.append((len(tTxt), TextFmt.COL_E, ""))
|
1040
|
-
|
1044
|
+
term = f" ({key.title()})" if key else ""
|
1045
|
+
if label := f"{self._localLookup(style.label)}{term}".strip():
|
1041
1046
|
shift = len(label) + 2
|
1042
1047
|
tTxt = f"{label}: {tTxt}"
|
1043
1048
|
rFmt = [(0, TextFmt.B_B, ""), (shift - 1, TextFmt.B_E, "")]
|
@@ -1123,12 +1128,10 @@ class Tokenizer(ABC):
|
|
1123
1128
|
temp.append((res.end(0), 0, TextFmt.HRF_E, ""))
|
1124
1129
|
|
1125
1130
|
# Match Shortcodes
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
"",
|
1131
|
-
))
|
1131
|
+
temp.extend(
|
1132
|
+
(res.start(1), res.end(1), self._shortCodeFmt.get(res.group(1).lower(), 0), "")
|
1133
|
+
for res in REGEX_PATTERNS.shortcodePlain.finditer(text)
|
1134
|
+
)
|
1132
1135
|
|
1133
1136
|
# Match Shortcode w/Values
|
1134
1137
|
tHandle = self._handle or ""
|
@@ -25,13 +25,17 @@ from __future__ import annotations
|
|
25
25
|
|
26
26
|
import logging
|
27
27
|
|
28
|
-
from
|
28
|
+
from typing import TYPE_CHECKING
|
29
29
|
|
30
30
|
from novelwriter.constants import nwUnicode
|
31
|
-
from novelwriter.core.project import NWProject
|
32
31
|
from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt
|
33
32
|
from novelwriter.formats.tokenizer import Tokenizer
|
34
33
|
|
34
|
+
if TYPE_CHECKING:
|
35
|
+
from pathlib import Path
|
36
|
+
|
37
|
+
from novelwriter.core.project import NWProject
|
38
|
+
|
35
39
|
logger = logging.getLogger(__name__)
|
36
40
|
|
37
41
|
|
novelwriter/formats/toodt.py
CHANGED
@@ -29,22 +29,26 @@ from __future__ import annotations
|
|
29
29
|
import logging
|
30
30
|
import xml.etree.ElementTree as ET
|
31
31
|
|
32
|
-
from collections.abc import Sequence
|
33
32
|
from datetime import datetime
|
34
33
|
from hashlib import sha256
|
35
|
-
from
|
34
|
+
from typing import TYPE_CHECKING, Final
|
36
35
|
from zipfile import ZIP_DEFLATED, ZipFile
|
37
36
|
|
38
|
-
from
|
37
|
+
from PyQt6.QtGui import QColor, QFont
|
39
38
|
|
40
39
|
from novelwriter import __version__
|
41
40
|
from novelwriter.common import xmlElement, xmlIndent, xmlSubElem
|
42
41
|
from novelwriter.constants import nwHeadFmt, nwStyles
|
43
|
-
from novelwriter.core.project import NWProject
|
44
42
|
from novelwriter.formats.shared import BlockFmt, BlockTyp, TextFmt, stripEscape
|
45
43
|
from novelwriter.formats.tokenizer import Tokenizer
|
46
44
|
from novelwriter.types import FONT_STYLE, QtHexRgb
|
47
45
|
|
46
|
+
if TYPE_CHECKING:
|
47
|
+
from collections.abc import Sequence
|
48
|
+
from pathlib import Path
|
49
|
+
|
50
|
+
from novelwriter.core.project import NWProject
|
51
|
+
|
48
52
|
logger = logging.getLogger(__name__)
|
49
53
|
|
50
54
|
# Main XML NameSpaces
|
@@ -203,9 +207,9 @@ class ToOdt(Tokenizer):
|
|
203
207
|
self._mDocRight = f"{right/10.0:.3f}cm"
|
204
208
|
return
|
205
209
|
|
206
|
-
def setHeaderFormat(self,
|
210
|
+
def setHeaderFormat(self, value: str, offset: int) -> None:
|
207
211
|
"""Set the document header format."""
|
208
|
-
self._headerFormat =
|
212
|
+
self._headerFormat = value.strip()
|
209
213
|
self._pageOffset = offset
|
210
214
|
return
|
211
215
|
|
@@ -598,6 +602,7 @@ class ToOdt(Tokenizer):
|
|
598
602
|
def _textStyle(self, hFmt: int, fClass: str = "") -> str:
|
599
603
|
"""Return a text style for a given style code."""
|
600
604
|
tKey = str(hFmt)
|
605
|
+
color = None
|
601
606
|
if fClass and (color := self._classes.get(fClass)):
|
602
607
|
tKey = f"{tKey}:{fClass}"
|
603
608
|
if tKey in self._autoText:
|
@@ -999,11 +1004,11 @@ class ODTParagraphStyle:
|
|
999
1004
|
exporter. Only the used settings are exposed here to keep the class
|
1000
1005
|
minimal and fast.
|
1001
1006
|
"""
|
1002
|
-
VALID_ALIGN = ["start", "center", "end", "justify", "
|
1003
|
-
VALID_BREAK = ["auto", "
|
1004
|
-
VALID_LEVEL = ["1", "2", "3", "4"]
|
1005
|
-
VALID_CLASS = ["text", "chapter", "extra"]
|
1006
|
-
VALID_WEIGHT = ["normal", "bold"
|
1007
|
+
VALID_ALIGN: Final[list[str]] = ["start", "center", "end", "justify", "left", "right"]
|
1008
|
+
VALID_BREAK: Final[list[str]] = ["auto", "page", "even-page", "odd-page", "inherit"]
|
1009
|
+
VALID_LEVEL: Final[list[str]] = ["1", "2", "3", "4"]
|
1010
|
+
VALID_CLASS: Final[list[str]] = ["text", "chapter", "extra"]
|
1011
|
+
VALID_WEIGHT: Final[list[str]] = ["normal", "bold", *FONT_WEIGHT_NUM]
|
1007
1012
|
|
1008
1013
|
def __init__(self, name: str) -> None:
|
1009
1014
|
|
@@ -1206,9 +1211,9 @@ class ODTParagraphStyle:
|
|
1206
1211
|
def getID(self) -> str:
|
1207
1212
|
"""Generate a unique ID from the settings."""
|
1208
1213
|
return sha256((
|
1209
|
-
f"Paragraph:Main:{
|
1210
|
-
f"Paragraph:Para:{
|
1211
|
-
f"Paragraph:Text:{
|
1214
|
+
f"Paragraph:Main:{self._mAttr!s}:"
|
1215
|
+
f"Paragraph:Para:{self._pAttr!s}:"
|
1216
|
+
f"Paragraph:Text:{self._tAttr!s}:"
|
1212
1217
|
).encode()).hexdigest()
|
1213
1218
|
|
1214
1219
|
def packXML(self, xParent: ET.Element) -> None:
|
@@ -1236,13 +1241,13 @@ class ODTTextStyle:
|
|
1236
1241
|
Only the used settings are exposed here to keep the class minimal
|
1237
1242
|
and fast.
|
1238
1243
|
"""
|
1239
|
-
VALID_WEIGHT = ["normal", "bold"
|
1240
|
-
VALID_STYLE = ["normal", "italic", "oblique"]
|
1241
|
-
VALID_POS = ["super", "sub"]
|
1242
|
-
VALID_LSTYLE = ["none", "solid"]
|
1243
|
-
VALID_LTYPE = ["single", "double"]
|
1244
|
-
VALID_LWIDTH = ["auto"]
|
1245
|
-
VALID_LCOL = ["font-color"]
|
1244
|
+
VALID_WEIGHT: Final[list[str]] = ["normal", "bold", *FONT_WEIGHT_NUM]
|
1245
|
+
VALID_STYLE: Final[list[str]] = ["normal", "italic", "oblique"]
|
1246
|
+
VALID_POS: Final[list[str]] = ["super", "sub"]
|
1247
|
+
VALID_LSTYLE: Final[list[str]] = ["none", "solid"]
|
1248
|
+
VALID_LTYPE: Final[list[str]] = ["single", "double"]
|
1249
|
+
VALID_LWIDTH: Final[list[str]] = ["auto"]
|
1250
|
+
VALID_LCOL: Final[list[str]] = ["font-color"]
|
1246
1251
|
|
1247
1252
|
def __init__(self, name: str) -> None:
|
1248
1253
|
self._name = name
|
@@ -1508,7 +1513,7 @@ class XMLParagraph:
|
|
1508
1513
|
errMsg = ""
|
1509
1514
|
nMissed = len(self._rawTxt) - self._chrPos
|
1510
1515
|
if nMissed != 0:
|
1511
|
-
errMsg = "
|
1516
|
+
errMsg = f"{nMissed} char(s) were not written: '{self._rawTxt}'"
|
1512
1517
|
return nMissed, errMsg
|
1513
1518
|
|
1514
1519
|
##
|
novelwriter/formats/toqdoc.py
CHANGED
@@ -25,18 +25,17 @@ from __future__ import annotations
|
|
25
25
|
|
26
26
|
import logging
|
27
27
|
|
28
|
-
from
|
28
|
+
from typing import TYPE_CHECKING
|
29
29
|
|
30
|
-
from
|
31
|
-
from
|
32
|
-
QColor, QFont, QFontDatabase, QPageSize, QTextBlockFormat,
|
33
|
-
QTextCursor, QTextDocument, QTextFrameFormat
|
30
|
+
from PyQt6.QtCore import QMarginsF, QSizeF
|
31
|
+
from PyQt6.QtGui import (
|
32
|
+
QColor, QFont, QFontDatabase, QPageLayout, QPageSize, QTextBlockFormat,
|
33
|
+
QTextCharFormat, QTextCursor, QTextDocument, QTextFrameFormat
|
34
34
|
)
|
35
|
-
from
|
35
|
+
from PyQt6.QtPrintSupport import QPrinter
|
36
36
|
|
37
37
|
from novelwriter import __version__
|
38
38
|
from novelwriter.constants import nwStyles, nwUnicode
|
39
|
-
from novelwriter.core.project import NWProject
|
40
39
|
from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt
|
41
40
|
from novelwriter.formats.tokenizer import HEADINGS, Tokenizer
|
42
41
|
from novelwriter.types import (
|
@@ -45,6 +44,11 @@ from novelwriter.types import (
|
|
45
44
|
QtPropLineHeight, QtTransparent, QtVAlignNormal, QtVAlignSub, QtVAlignSuper
|
46
45
|
)
|
47
46
|
|
47
|
+
if TYPE_CHECKING:
|
48
|
+
from pathlib import Path
|
49
|
+
|
50
|
+
from novelwriter.core.project import NWProject
|
51
|
+
|
48
52
|
logger = logging.getLogger(__name__)
|
49
53
|
|
50
54
|
T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat]
|
@@ -129,10 +133,9 @@ class ToQTextDocument(Tokenizer):
|
|
129
133
|
super().initDocument()
|
130
134
|
|
131
135
|
if pdf:
|
132
|
-
fontDB = QFontDatabase()
|
133
136
|
family = self._textFont.family()
|
134
137
|
style = self._textFont.styleName()
|
135
|
-
self._dpi = 1200 if
|
138
|
+
self._dpi = 1200 if QFontDatabase.isScalable(family, style) else 72
|
136
139
|
|
137
140
|
self._document.setUndoRedoEnabled(False)
|
138
141
|
self._document.blockSignals(True)
|
@@ -270,7 +273,6 @@ class ToQTextDocument(Tokenizer):
|
|
270
273
|
|
271
274
|
def saveDocument(self, path: Path) -> None:
|
272
275
|
"""Save the document as a PDF file."""
|
273
|
-
m = self._pageMargins
|
274
276
|
logger.info("Writing PDF at %d DPI", self._dpi)
|
275
277
|
|
276
278
|
printer = QPrinter(QPrinter.PrinterMode.HighResolution)
|
@@ -279,11 +281,13 @@ class ToQTextDocument(Tokenizer):
|
|
279
281
|
printer.setResolution(self._dpi)
|
280
282
|
printer.setOutputFormat(QPrinter.OutputFormat.PdfFormat)
|
281
283
|
printer.setPageSize(self._pageSize)
|
282
|
-
printer.setPageMargins(
|
284
|
+
printer.setPageMargins(self._pageMargins, QPageLayout.Unit.Millimeter)
|
283
285
|
printer.setOutputFileName(str(path))
|
284
286
|
|
285
|
-
self._document.documentLayout()
|
286
|
-
|
287
|
+
if layout := self._document.documentLayout():
|
288
|
+
layout.setPaintDevice(printer)
|
289
|
+
|
290
|
+
self._document.setPageSize(printer.pageRect(QPrinter.Unit.DevicePixel).size())
|
287
291
|
self._document.print(printer)
|
288
292
|
|
289
293
|
return
|
@@ -462,7 +466,8 @@ class ToQTextDocument(Tokenizer):
|
|
462
466
|
cursor.insertFrame(fFmt)
|
463
467
|
cursor.setBlockFormat(bFmt)
|
464
468
|
cursor.insertText(self._project.localLookup("New Page"), cFmt)
|
465
|
-
|
469
|
+
if root := self._document.rootFrame():
|
470
|
+
cursor.swap(root.lastCursorPosition())
|
466
471
|
|
467
472
|
return
|
468
473
|
|
novelwriter/formats/toraw.py
CHANGED
@@ -26,13 +26,17 @@ from __future__ import annotations
|
|
26
26
|
import json
|
27
27
|
import logging
|
28
28
|
|
29
|
-
from pathlib import Path
|
30
29
|
from time import time
|
30
|
+
from typing import TYPE_CHECKING
|
31
31
|
|
32
32
|
from novelwriter.common import formatTimeStamp
|
33
|
-
from novelwriter.core.project import NWProject
|
34
33
|
from novelwriter.formats.tokenizer import Tokenizer
|
35
34
|
|
35
|
+
if TYPE_CHECKING:
|
36
|
+
from pathlib import Path
|
37
|
+
|
38
|
+
from novelwriter.core.project import NWProject
|
39
|
+
|
36
40
|
logger = logging.getLogger(__name__)
|
37
41
|
|
38
42
|
|