novelWriter 2.2.1__py3-none-any.whl → 2.3b1__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.2.1.dist-info → novelWriter-2.3b1.dist-info}/METADATA +1 -1
- {novelWriter-2.2.1.dist-info → novelWriter-2.3b1.dist-info}/RECORD +102 -92
- novelwriter/__init__.py +4 -4
- novelwriter/assets/icons/typicons_dark/icons.conf +6 -0
- novelwriter/assets/icons/typicons_dark/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_dark/typ_document-add-col.svg +8 -0
- novelwriter/assets/icons/typicons_dark/typ_document-add.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_document.svg +4 -0
- novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +6 -0
- novelwriter/assets/icons/typicons_light/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_light/typ_document-add-col.svg +8 -0
- novelwriter/assets/icons/typicons_light/typ_document-add.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_document.svg +4 -0
- novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +4 -0
- novelwriter/assets/images/novelwriter-text-dark.svg +4 -0
- novelwriter/assets/images/novelwriter-text-light.svg +4 -0
- novelwriter/assets/images/welcome-dark.jpg +0 -0
- novelwriter/assets/images/welcome-light.jpg +0 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/default_dark.conf +1 -0
- novelwriter/assets/syntax/default_light.conf +1 -0
- novelwriter/assets/syntax/grey_dark.conf +1 -0
- novelwriter/assets/syntax/grey_light.conf +1 -0
- novelwriter/assets/syntax/light_owl.conf +1 -0
- novelwriter/assets/syntax/night_owl.conf +1 -0
- novelwriter/assets/syntax/solarized_dark.conf +1 -0
- novelwriter/assets/syntax/solarized_light.conf +1 -0
- novelwriter/assets/syntax/tomorrow.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_blue.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_bright.conf +1 -0
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +1 -0
- novelwriter/assets/text/credits_en.htm +4 -2
- novelwriter/assets/themes/default_dark.conf +2 -2
- novelwriter/assets/themes/default_light.conf +2 -2
- novelwriter/common.py +48 -37
- novelwriter/config.py +36 -41
- novelwriter/constants.py +38 -16
- novelwriter/core/buildsettings.py +7 -7
- novelwriter/core/coretools.py +192 -154
- novelwriter/core/docbuild.py +6 -3
- novelwriter/core/document.py +6 -6
- novelwriter/core/index.py +89 -56
- novelwriter/core/item.py +21 -3
- novelwriter/core/options.py +8 -7
- novelwriter/core/project.py +69 -44
- novelwriter/core/projectdata.py +1 -14
- novelwriter/core/projectxml.py +13 -41
- novelwriter/core/sessions.py +2 -1
- novelwriter/core/spellcheck.py +2 -1
- novelwriter/core/status.py +2 -1
- novelwriter/core/storage.py +178 -140
- novelwriter/core/tohtml.py +4 -2
- novelwriter/core/tokenizer.py +73 -45
- novelwriter/core/toodt.py +40 -30
- novelwriter/core/tree.py +3 -2
- novelwriter/dialogs/about.py +70 -160
- novelwriter/dialogs/docmerge.py +6 -5
- novelwriter/dialogs/docsplit.py +6 -6
- novelwriter/dialogs/editlabel.py +1 -1
- novelwriter/dialogs/preferences.py +553 -703
- novelwriter/dialogs/{projsettings.py → projectsettings.py} +288 -262
- novelwriter/dialogs/quotes.py +27 -23
- novelwriter/dialogs/wordlist.py +96 -40
- novelwriter/enum.py +20 -18
- novelwriter/error.py +1 -1
- novelwriter/extensions/circularprogress.py +11 -11
- novelwriter/extensions/configlayout.py +185 -134
- novelwriter/extensions/modified.py +81 -0
- novelwriter/extensions/novelselector.py +26 -12
- novelwriter/extensions/pagedsidebar.py +14 -16
- novelwriter/extensions/simpleprogress.py +5 -5
- novelwriter/extensions/statusled.py +8 -8
- novelwriter/extensions/switch.py +31 -63
- novelwriter/extensions/switchbox.py +1 -1
- novelwriter/extensions/versioninfo.py +153 -0
- novelwriter/gui/doceditor.py +178 -150
- novelwriter/gui/dochighlight.py +63 -92
- novelwriter/gui/docviewer.py +49 -51
- novelwriter/gui/docviewerpanel.py +72 -24
- novelwriter/gui/itemdetails.py +7 -7
- novelwriter/gui/mainmenu.py +14 -18
- novelwriter/gui/noveltree.py +9 -8
- novelwriter/gui/outline.py +98 -75
- novelwriter/gui/projtree.py +188 -61
- novelwriter/gui/sidebar.py +3 -4
- novelwriter/gui/statusbar.py +3 -4
- novelwriter/gui/theme.py +60 -68
- novelwriter/guimain.py +49 -156
- novelwriter/shared.py +15 -1
- novelwriter/tools/dictionaries.py +5 -6
- novelwriter/tools/manuscript.py +6 -6
- novelwriter/tools/manussettings.py +192 -221
- novelwriter/tools/noveldetails.py +525 -0
- novelwriter/tools/welcome.py +802 -0
- novelwriter/tools/writingstats.py +9 -9
- novelwriter/assets/images/wizard-back.jpg +0 -0
- novelwriter/assets/text/gplv3_en.htm +0 -641
- novelwriter/assets/text/release_notes.htm +0 -60
- novelwriter/dialogs/projdetails.py +0 -518
- novelwriter/dialogs/projload.py +0 -294
- novelwriter/dialogs/updates.py +0 -172
- novelwriter/extensions/pageddialog.py +0 -130
- novelwriter/tools/projwizard.py +0 -478
- {novelWriter-2.2.1.dist-info → novelWriter-2.3b1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2.1.dist-info → novelWriter-2.3b1.dist-info}/WHEEL +0 -0
- {novelWriter-2.2.1.dist-info → novelWriter-2.3b1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2.1.dist-info → novelWriter-2.3b1.dist-info}/top_level.txt +0 -0
novelwriter/dialogs/about.py
CHANGED
@@ -24,20 +24,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
24
24
|
from __future__ import annotations
|
25
25
|
|
26
26
|
import logging
|
27
|
-
import novelwriter
|
28
27
|
|
29
|
-
from
|
30
|
-
|
31
|
-
from PyQt5.QtGui import QCloseEvent, QCursor
|
28
|
+
from PyQt5.QtGui import QCloseEvent, QColor
|
32
29
|
from PyQt5.QtCore import Qt
|
33
30
|
from PyQt5.QtWidgets import (
|
34
|
-
|
35
|
-
|
31
|
+
QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QTextBrowser, QVBoxLayout,
|
32
|
+
QWidget
|
36
33
|
)
|
37
34
|
|
38
35
|
from novelwriter import CONFIG, SHARED
|
39
36
|
from novelwriter.common import readTextFile
|
40
|
-
from novelwriter.
|
37
|
+
from novelwriter.extensions.configlayout import NColourLabel
|
38
|
+
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
41
39
|
|
42
40
|
logger = logging.getLogger(__name__)
|
43
41
|
|
@@ -50,62 +48,67 @@ class GuiAbout(QDialog):
|
|
50
48
|
logger.debug("Create: GuiAbout")
|
51
49
|
self.setObjectName("GuiAbout")
|
52
50
|
|
53
|
-
self.outerBox = QVBoxLayout()
|
54
|
-
self.innerBox = QHBoxLayout()
|
55
|
-
self.innerBox.setSpacing(CONFIG.pxInt(16))
|
56
|
-
|
57
51
|
self.setWindowTitle(self.tr("About novelWriter"))
|
58
|
-
self.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
self.
|
67
|
-
|
68
|
-
|
69
|
-
self.
|
70
|
-
self.
|
71
|
-
|
72
|
-
self.
|
73
|
-
self.
|
74
|
-
|
75
|
-
self.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
self.
|
81
|
-
|
82
|
-
|
83
|
-
self.
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
self.
|
88
|
-
self.
|
89
|
-
|
90
|
-
self.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
self.
|
98
|
-
self.
|
99
|
-
self.
|
100
|
-
self.innerBox.addWidget(self.
|
101
|
-
|
102
|
-
|
103
|
-
self.
|
104
|
-
self.
|
105
|
-
|
106
|
-
self.
|
107
|
-
self.
|
52
|
+
self.resize(CONFIG.pxInt(700), CONFIG.pxInt(500))
|
53
|
+
|
54
|
+
hA = CONFIG.pxInt(8)
|
55
|
+
hB = CONFIG.pxInt(16)
|
56
|
+
nwH = CONFIG.pxInt(36)
|
57
|
+
nwPx = CONFIG.pxInt(128)
|
58
|
+
|
59
|
+
# Logo and Banner
|
60
|
+
self.nwImage = SHARED.theme.loadDecoration("nw-text", h=nwH)
|
61
|
+
self.bgColor = QColor(255, 255, 255) if SHARED.theme.isLightTheme else QColor(54, 54, 54)
|
62
|
+
|
63
|
+
self.nwLogo = QLabel(self)
|
64
|
+
self.nwLogo.setPixmap(SHARED.theme.getPixmap("novelwriter", (nwPx, nwPx)))
|
65
|
+
|
66
|
+
self.nwLabel = QLabel(self)
|
67
|
+
self.nwLabel.setPixmap(self.nwImage)
|
68
|
+
|
69
|
+
self.nwInfo = VersionInfoWidget(self)
|
70
|
+
|
71
|
+
self.nwLicence = QLabel(self.tr("This application is licenced under {0}".format(
|
72
|
+
"<a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a>"
|
73
|
+
)))
|
74
|
+
self.nwLicence.setOpenExternalLinks(True)
|
75
|
+
|
76
|
+
# Credits
|
77
|
+
self.lblCredits = NColourLabel(
|
78
|
+
self.tr("Credits"), scale=1.6, parent=self, bold=True
|
79
|
+
)
|
80
|
+
|
81
|
+
self.txtCredits = QTextBrowser(self)
|
82
|
+
self.txtCredits.setOpenExternalLinks(True)
|
83
|
+
self.txtCredits.document().setDocumentMargin(0)
|
84
|
+
self.txtCredits.setViewportMargins(0, hA, hA, 0)
|
85
|
+
|
86
|
+
# Buttons
|
87
|
+
self.btnBox = QDialogButtonBox(QDialogButtonBox.Close, self)
|
88
|
+
self.btnBox.rejected.connect(self.close)
|
89
|
+
|
90
|
+
# Assemble
|
91
|
+
self.innerBox = QVBoxLayout()
|
92
|
+
self.innerBox.addSpacing(hB)
|
93
|
+
self.innerBox.addWidget(self.nwLabel)
|
94
|
+
self.innerBox.addWidget(self.nwInfo)
|
95
|
+
self.innerBox.addSpacing(hA)
|
96
|
+
self.innerBox.addWidget(self.nwLicence)
|
97
|
+
self.innerBox.addSpacing(hA)
|
98
|
+
self.innerBox.addWidget(self.lblCredits)
|
99
|
+
self.innerBox.addWidget(self.txtCredits)
|
100
|
+
self.innerBox.addSpacing(hB)
|
101
|
+
self.innerBox.addWidget(self.btnBox)
|
102
|
+
|
103
|
+
topRight = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight
|
104
|
+
|
105
|
+
self.outerBox = QHBoxLayout()
|
106
|
+
self.outerBox.addWidget(self.nwLogo, 0, topRight)
|
107
|
+
self.outerBox.addLayout(self.innerBox, 1)
|
108
|
+
|
108
109
|
self.setLayout(self.outerBox)
|
110
|
+
self.setSizeGripEnabled(True)
|
111
|
+
self._setStyleSheet()
|
109
112
|
|
110
113
|
logger.debug("Ready: GuiAbout")
|
111
114
|
|
@@ -117,18 +120,7 @@ class GuiAbout(QDialog):
|
|
117
120
|
|
118
121
|
def populateGUI(self) -> None:
|
119
122
|
"""Populate tabs with text."""
|
120
|
-
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
121
|
-
self._setStyleSheet()
|
122
|
-
self._fillAboutPage()
|
123
|
-
self._fillNotesPage()
|
124
123
|
self._fillCreditsPage()
|
125
|
-
self._fillLicensePage()
|
126
|
-
qApp.restoreOverrideCursor()
|
127
|
-
return
|
128
|
-
|
129
|
-
def showReleaseNotes(self) -> None:
|
130
|
-
"""Show the release notes."""
|
131
|
-
self.tabBox.setCurrentWidget(self.pageNotes)
|
132
124
|
return
|
133
125
|
|
134
126
|
##
|
@@ -145,104 +137,22 @@ class GuiAbout(QDialog):
|
|
145
137
|
# Internal Functions
|
146
138
|
##
|
147
139
|
|
148
|
-
def _fillAboutPage(self) -> None:
|
149
|
-
"""Generate the content for the About page."""
|
150
|
-
aboutMsg = (
|
151
|
-
"<h2>{title1}</h2>"
|
152
|
-
"<p>{copy}</p>"
|
153
|
-
"<p>{link}</p>"
|
154
|
-
"<p>{intro}</p>"
|
155
|
-
"<p>{license1}</p>"
|
156
|
-
"<p>{license2}</p>"
|
157
|
-
"<p>{license3}</p>"
|
158
|
-
).format(
|
159
|
-
title1=self.tr("About novelWriter"),
|
160
|
-
copy=novelwriter.__copyright__,
|
161
|
-
link=self.tr("Website: {0}").format(
|
162
|
-
f"<a href='{nwConst.URL_WEB}'>{novelwriter.__domain__}</a>"
|
163
|
-
),
|
164
|
-
intro=self.tr(
|
165
|
-
"novelWriter is a markdown-like text editor designed for organising and "
|
166
|
-
"writing novels. It is written in Python 3 with a Qt5 GUI, using PyQt5."
|
167
|
-
),
|
168
|
-
license1=self.tr(
|
169
|
-
"novelWriter is free software: you can redistribute it and/or modify it "
|
170
|
-
"under the terms of the GNU General Public License as published by the "
|
171
|
-
"Free Software Foundation, either version 3 of the License, or (at your "
|
172
|
-
"option) any later version."
|
173
|
-
),
|
174
|
-
license2=self.tr(
|
175
|
-
"novelWriter is distributed in the hope that it will be useful, but "
|
176
|
-
"WITHOUT ANY WARRANTY; without even the implied warranty of "
|
177
|
-
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
178
|
-
),
|
179
|
-
license3=self.tr(
|
180
|
-
"See the Licence tab for the full licence text, or visit the "
|
181
|
-
"GNU website at {0} for more details."
|
182
|
-
).format(
|
183
|
-
"<a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a>"
|
184
|
-
),
|
185
|
-
)
|
186
|
-
|
187
|
-
self.pageAbout.setHtml(aboutMsg)
|
188
|
-
|
189
|
-
return
|
190
|
-
|
191
|
-
def _fillNotesPage(self) -> None:
|
192
|
-
"""Load the content for the Release Notes page."""
|
193
|
-
docPath = CONFIG.assetPath("text") / "release_notes.htm"
|
194
|
-
docText = readTextFile(docPath)
|
195
|
-
if docText:
|
196
|
-
self.pageNotes.setHtml(docText)
|
197
|
-
else:
|
198
|
-
self.pageNotes.setHtml("Error loading release notes text ...")
|
199
|
-
return
|
200
|
-
|
201
140
|
def _fillCreditsPage(self) -> None:
|
202
141
|
"""Load the content for the Credits page."""
|
203
142
|
docPath = CONFIG.assetPath("text") / "credits_en.htm"
|
204
143
|
docText = readTextFile(docPath)
|
205
144
|
if docText:
|
206
|
-
self.
|
207
|
-
else:
|
208
|
-
self.pageCredits.setHtml("Error loading credits text ...")
|
209
|
-
return
|
210
|
-
|
211
|
-
def _fillLicensePage(self) -> None:
|
212
|
-
"""Load the content for the Licence page."""
|
213
|
-
docPath = CONFIG.assetPath("text") / "gplv3_en.htm"
|
214
|
-
docText = readTextFile(docPath)
|
215
|
-
if docText:
|
216
|
-
self.pageLicense.setHtml(docText)
|
145
|
+
self.txtCredits.setHtml(docText)
|
217
146
|
else:
|
218
|
-
self.
|
147
|
+
self.txtCredits.setHtml("Error loading credits text ...")
|
219
148
|
return
|
220
149
|
|
221
150
|
def _setStyleSheet(self) -> None:
|
222
151
|
"""Set stylesheet for all browser tabs."""
|
223
|
-
|
224
|
-
|
225
|
-
"
|
226
|
-
|
227
|
-
"a {{"
|
228
|
-
" color: rgb({hColR},{hColG},{hColB});"
|
229
|
-
"}}\n"
|
230
|
-
".alt {{"
|
231
|
-
" color: rgb({kColR},{kColG},{kColB});"
|
232
|
-
"}}\n"
|
233
|
-
).format(
|
234
|
-
hColR=SHARED.theme.colHead[0],
|
235
|
-
hColG=SHARED.theme.colHead[1],
|
236
|
-
hColB=SHARED.theme.colHead[2],
|
237
|
-
kColR=SHARED.theme.colKey[0],
|
238
|
-
kColG=SHARED.theme.colKey[1],
|
239
|
-
kColB=SHARED.theme.colKey[2],
|
240
|
-
)
|
241
|
-
self.pageAbout.document().setDefaultStyleSheet(styleSheet)
|
242
|
-
self.pageNotes.document().setDefaultStyleSheet(styleSheet)
|
243
|
-
self.pageCredits.document().setDefaultStyleSheet(styleSheet)
|
244
|
-
self.pageLicense.document().setDefaultStyleSheet(styleSheet)
|
245
|
-
|
152
|
+
baseCol = self.palette().window().color()
|
153
|
+
self.txtCredits.setStyleSheet((
|
154
|
+
"QTextBrowser {{border: none; background: rgb({r},{g},{b});}} "
|
155
|
+
).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue()))
|
246
156
|
return
|
247
157
|
|
248
158
|
# END Class GuiAbout
|
novelwriter/dialogs/docmerge.py
CHANGED
@@ -35,7 +35,7 @@ from PyQt5.QtWidgets import (
|
|
35
35
|
|
36
36
|
from novelwriter import CONFIG, SHARED
|
37
37
|
from novelwriter.extensions.switch import NSwitch
|
38
|
-
from novelwriter.extensions.configlayout import
|
38
|
+
from novelwriter.extensions.configlayout import NColourLabel
|
39
39
|
|
40
40
|
logger = logging.getLogger(__name__)
|
41
41
|
|
@@ -54,9 +54,10 @@ class GuiDocMerge(QDialog):
|
|
54
54
|
self._data = {}
|
55
55
|
|
56
56
|
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Documents to Merge")))
|
57
|
-
self.helpLabel =
|
58
|
-
"Drag and drop items to change the order, or uncheck to exclude."
|
59
|
-
|
57
|
+
self.helpLabel = NColourLabel(
|
58
|
+
self.tr("Drag and drop items to change the order, or uncheck to exclude."),
|
59
|
+
SHARED.theme.helpText, parent=self, wrap=True
|
60
|
+
)
|
60
61
|
|
61
62
|
iPx = SHARED.theme.baseIconSize
|
62
63
|
hSp = CONFIG.pxInt(12)
|
@@ -73,7 +74,7 @@ class GuiDocMerge(QDialog):
|
|
73
74
|
|
74
75
|
# Merge Options
|
75
76
|
self.trashLabel = QLabel(self.tr("Move merged items to Trash"))
|
76
|
-
self.trashSwitch = NSwitch(
|
77
|
+
self.trashSwitch = NSwitch(self, height=iPx)
|
77
78
|
|
78
79
|
self.optBox = QGridLayout()
|
79
80
|
self.optBox.addWidget(self.trashLabel, 0, 0)
|
novelwriter/dialogs/docsplit.py
CHANGED
@@ -35,7 +35,7 @@ from PyQt5.QtWidgets import (
|
|
35
35
|
|
36
36
|
from novelwriter import CONFIG, SHARED
|
37
37
|
from novelwriter.extensions.switch import NSwitch
|
38
|
-
from novelwriter.extensions.configlayout import
|
38
|
+
from novelwriter.extensions.configlayout import NColourLabel
|
39
39
|
|
40
40
|
logger = logging.getLogger(__name__)
|
41
41
|
|
@@ -58,9 +58,9 @@ class GuiDocSplit(QDialog):
|
|
58
58
|
self.setWindowTitle(self.tr("Split Document"))
|
59
59
|
|
60
60
|
self.headLabel = QLabel("<b>{0}</b>".format(self.tr("Document Headers")))
|
61
|
-
self.helpLabel =
|
61
|
+
self.helpLabel = NColourLabel(
|
62
62
|
self.tr("Select the maximum level to split into files."),
|
63
|
-
SHARED.theme.helpText
|
63
|
+
SHARED.theme.helpText, parent=self, wrap=True
|
64
64
|
)
|
65
65
|
|
66
66
|
# Values
|
@@ -92,15 +92,15 @@ class GuiDocSplit(QDialog):
|
|
92
92
|
|
93
93
|
# Split Options
|
94
94
|
self.folderLabel = QLabel(self.tr("Split into a new folder"))
|
95
|
-
self.folderSwitch = NSwitch(
|
95
|
+
self.folderSwitch = NSwitch(self, height=iPx)
|
96
96
|
self.folderSwitch.setChecked(intoFolder)
|
97
97
|
|
98
98
|
self.hierarchyLabel = QLabel(self.tr("Create document hierarchy"))
|
99
|
-
self.hierarchySwitch = NSwitch(
|
99
|
+
self.hierarchySwitch = NSwitch(self, height=iPx)
|
100
100
|
self.hierarchySwitch.setChecked(docHierarchy)
|
101
101
|
|
102
102
|
self.trashLabel = QLabel(self.tr("Move split document to Trash"))
|
103
|
-
self.trashSwitch = NSwitch(
|
103
|
+
self.trashSwitch = NSwitch(self, height=iPx)
|
104
104
|
|
105
105
|
self.optBox = QGridLayout()
|
106
106
|
self.optBox.addWidget(self.folderLabel, 0, 0)
|
novelwriter/dialogs/editlabel.py
CHANGED