novelWriter 2.4.4__py3-none-any.whl → 2.5__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.4.4.dist-info → novelWriter-2.5.dist-info}/METADATA +4 -5
- {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/RECORD +121 -111
- {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +33 -39
- 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_pl_PL.qm +0 -0
- novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_en_GB.json +1 -0
- novelwriter/assets/i18n/project_pl_PL.json +116 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +2 -0
- novelwriter/assets/icons/typicons_dark/nw_font.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_quote.svg +4 -0
- novelwriter/assets/icons/typicons_light/icons.conf +2 -0
- novelwriter/assets/icons/typicons_light/nw_font.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_quote.svg +4 -0
- novelwriter/assets/manual.pdf +0 -0
- novelwriter/assets/sample.zip +0 -0
- novelwriter/assets/syntax/cyberpunk_night.conf +5 -3
- novelwriter/assets/syntax/default_dark.conf +32 -18
- novelwriter/assets/syntax/default_light.conf +24 -10
- novelwriter/assets/syntax/dracula.conf +44 -0
- novelwriter/assets/syntax/grey_dark.conf +5 -4
- novelwriter/assets/syntax/grey_light.conf +5 -4
- novelwriter/assets/syntax/light_owl.conf +7 -6
- novelwriter/assets/syntax/night_owl.conf +7 -6
- novelwriter/assets/syntax/snazzy.conf +42 -0
- novelwriter/assets/syntax/solarized_dark.conf +4 -3
- novelwriter/assets/syntax/solarized_light.conf +4 -3
- novelwriter/assets/syntax/tango.conf +27 -11
- novelwriter/assets/syntax/tomorrow.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night.conf +7 -6
- novelwriter/assets/syntax/tomorrow_night_blue.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night_bright.conf +6 -5
- novelwriter/assets/syntax/tomorrow_night_eighties.conf +6 -5
- novelwriter/assets/text/credits_en.htm +52 -41
- novelwriter/assets/themes/cyberpunk_night.conf +3 -0
- novelwriter/assets/themes/default_dark.conf +2 -0
- novelwriter/assets/themes/default_light.conf +2 -0
- novelwriter/assets/themes/dracula.conf +48 -0
- novelwriter/assets/themes/solarized_dark.conf +2 -0
- novelwriter/assets/themes/solarized_light.conf +2 -0
- novelwriter/common.py +33 -12
- novelwriter/config.py +184 -98
- novelwriter/constants.py +47 -35
- novelwriter/core/buildsettings.py +68 -69
- novelwriter/core/coretools.py +5 -23
- novelwriter/core/docbuild.py +52 -40
- novelwriter/core/document.py +3 -5
- novelwriter/core/index.py +115 -45
- novelwriter/core/item.py +8 -19
- novelwriter/core/options.py +2 -4
- novelwriter/core/project.py +37 -61
- novelwriter/core/projectdata.py +1 -3
- novelwriter/core/projectxml.py +12 -15
- novelwriter/core/sessions.py +3 -5
- novelwriter/core/spellcheck.py +4 -9
- novelwriter/core/status.py +211 -164
- novelwriter/core/storage.py +0 -8
- novelwriter/core/tohtml.py +139 -105
- novelwriter/core/tokenizer.py +278 -122
- novelwriter/core/{tomd.py → tomarkdown.py} +97 -78
- novelwriter/core/toodt.py +257 -166
- novelwriter/core/toqdoc.py +419 -0
- novelwriter/core/tree.py +5 -7
- novelwriter/dialogs/about.py +11 -18
- novelwriter/dialogs/docmerge.py +17 -19
- novelwriter/dialogs/docsplit.py +17 -19
- novelwriter/dialogs/editlabel.py +6 -10
- novelwriter/dialogs/preferences.py +200 -164
- novelwriter/dialogs/projectsettings.py +225 -189
- novelwriter/dialogs/quotes.py +12 -9
- novelwriter/dialogs/wordlist.py +9 -15
- novelwriter/enum.py +35 -30
- novelwriter/error.py +8 -15
- novelwriter/extensions/configlayout.py +55 -21
- novelwriter/extensions/eventfilters.py +1 -5
- novelwriter/extensions/modified.py +58 -14
- novelwriter/extensions/novelselector.py +1 -3
- novelwriter/extensions/pagedsidebar.py +9 -12
- novelwriter/extensions/{circularprogress.py → progressbars.py} +30 -8
- novelwriter/extensions/statusled.py +40 -26
- novelwriter/extensions/switch.py +4 -6
- novelwriter/extensions/switchbox.py +7 -6
- novelwriter/extensions/versioninfo.py +3 -9
- novelwriter/gui/doceditor.py +120 -139
- novelwriter/gui/dochighlight.py +231 -186
- novelwriter/gui/docviewer.py +69 -108
- novelwriter/gui/docviewerpanel.py +3 -10
- novelwriter/gui/editordocument.py +1 -3
- novelwriter/gui/itemdetails.py +7 -11
- novelwriter/gui/mainmenu.py +22 -18
- novelwriter/gui/noveltree.py +11 -24
- novelwriter/gui/outline.py +15 -26
- novelwriter/gui/projtree.py +35 -60
- novelwriter/gui/search.py +10 -3
- novelwriter/gui/sidebar.py +2 -6
- novelwriter/gui/statusbar.py +29 -37
- novelwriter/gui/theme.py +26 -48
- novelwriter/guimain.py +162 -160
- novelwriter/shared.py +36 -32
- novelwriter/text/patterns.py +113 -0
- novelwriter/tools/dictionaries.py +10 -20
- novelwriter/tools/lipsum.py +10 -16
- novelwriter/tools/manusbuild.py +9 -11
- novelwriter/tools/manuscript.py +71 -145
- novelwriter/tools/manussettings.py +71 -75
- novelwriter/tools/noveldetails.py +16 -21
- novelwriter/tools/welcome.py +21 -26
- novelwriter/tools/writingstats.py +9 -12
- novelwriter/types.py +49 -4
- novelwriter/extensions/simpleprogress.py +0 -55
- {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.4.4.dist-info → novelWriter-2.5.dist-info}/top_level.txt +0 -0
@@ -27,23 +27,24 @@ import logging
|
|
27
27
|
|
28
28
|
from typing import TYPE_CHECKING
|
29
29
|
|
30
|
-
from PyQt5.QtCore import QEvent,
|
30
|
+
from PyQt5.QtCore import QEvent, pyqtSignal, pyqtSlot
|
31
31
|
from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
|
32
32
|
from PyQt5.QtWidgets import (
|
33
|
-
QAbstractButton, QAbstractItemView, QDialogButtonBox,
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
QAbstractButton, QAbstractItemView, QDialogButtonBox, QFrame, QGridLayout,
|
34
|
+
QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit,
|
35
|
+
QPushButton, QSplitter, QStackedWidget, QTreeWidget, QTreeWidgetItem,
|
36
|
+
QVBoxLayout, QWidget
|
37
37
|
)
|
38
38
|
|
39
39
|
from novelwriter import CONFIG, SHARED
|
40
|
+
from novelwriter.common import describeFont
|
40
41
|
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst
|
41
42
|
from novelwriter.core.buildsettings import BuildSettings, FilterMode
|
42
43
|
from novelwriter.extensions.configlayout import (
|
43
44
|
NColourLabel, NFixedPage, NScrollableForm, NScrollablePage
|
44
45
|
)
|
45
46
|
from novelwriter.extensions.modified import (
|
46
|
-
NComboBox,
|
47
|
+
NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox, NToolDialog
|
47
48
|
)
|
48
49
|
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
49
50
|
from novelwriter.extensions.switch import NSwitch
|
@@ -59,7 +60,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
59
60
|
logger = logging.getLogger(__name__)
|
60
61
|
|
61
62
|
|
62
|
-
class GuiBuildSettings(
|
63
|
+
class GuiBuildSettings(NToolDialog):
|
63
64
|
"""GUI Tools: Manuscript Build Settings Dialog
|
64
65
|
|
65
66
|
The main tool for configuring manuscript builds. It's a GUI tool for
|
@@ -74,13 +75,11 @@ class GuiBuildSettings(NDialog):
|
|
74
75
|
|
75
76
|
newSettingsReady = pyqtSignal(BuildSettings)
|
76
77
|
|
77
|
-
def __init__(self,
|
78
|
-
super().__init__(parent=
|
78
|
+
def __init__(self, parent: GuiMain, build: BuildSettings) -> None:
|
79
|
+
super().__init__(parent=parent)
|
79
80
|
|
80
81
|
logger.debug("Create: GuiBuildSettings")
|
81
82
|
self.setObjectName("GuiBuildSettings")
|
82
|
-
if CONFIG.osDarwin:
|
83
|
-
self.setWindowFlag(Qt.WindowType.Tool)
|
84
83
|
|
85
84
|
self._build = build
|
86
85
|
|
@@ -99,8 +98,8 @@ class GuiBuildSettings(NDialog):
|
|
99
98
|
|
100
99
|
# Title
|
101
100
|
self.titleLabel = NColourLabel(
|
102
|
-
self.tr("Manuscript Build Settings"), SHARED.theme.helpText,
|
103
|
-
|
101
|
+
self.tr("Manuscript Build Settings"), self, color=SHARED.theme.helpText,
|
102
|
+
scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
|
104
103
|
)
|
105
104
|
|
106
105
|
# Settings Name
|
@@ -280,8 +279,6 @@ class GuiBuildSettings(NDialog):
|
|
280
279
|
self._build.resetChangedState()
|
281
280
|
return
|
282
281
|
|
283
|
-
# END Class GuiBuildSettings
|
284
|
-
|
285
282
|
|
286
283
|
class _FilterTab(NFixedPage):
|
287
284
|
|
@@ -298,8 +295,8 @@ class _FilterTab(NFixedPage):
|
|
298
295
|
F_INCLUDED = 2
|
299
296
|
F_EXCLUDED = 3
|
300
297
|
|
301
|
-
def __init__(self,
|
302
|
-
super().__init__(parent=
|
298
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
299
|
+
super().__init__(parent=parent)
|
303
300
|
|
304
301
|
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
305
302
|
self._build = build
|
@@ -576,8 +573,6 @@ class _FilterTab(NFixedPage):
|
|
576
573
|
self._scanChildren(item.child(i), items)
|
577
574
|
return items
|
578
575
|
|
579
|
-
# END Class _FilterTab
|
580
|
-
|
581
576
|
|
582
577
|
class _HeadingsTab(NScrollablePage):
|
583
578
|
|
@@ -588,8 +583,8 @@ class _HeadingsTab(NScrollablePage):
|
|
588
583
|
EDIT_HSCENE = 5
|
589
584
|
EDIT_SECTION = 6
|
590
585
|
|
591
|
-
def __init__(self,
|
592
|
-
super().__init__(parent=
|
586
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
587
|
+
super().__init__(parent=parent)
|
593
588
|
|
594
589
|
self._build = build
|
595
590
|
self._editing = 0
|
@@ -943,8 +938,6 @@ class _HeadingsTab(NScrollablePage):
|
|
943
938
|
|
944
939
|
return
|
945
940
|
|
946
|
-
# END Class _HeadingsTab
|
947
|
-
|
948
941
|
|
949
942
|
class _HeadingSyntaxHighlighter(QSyntaxHighlighter):
|
950
943
|
|
@@ -969,13 +962,11 @@ class _HeadingSyntaxHighlighter(QSyntaxHighlighter):
|
|
969
962
|
self.setFormat(pos + ddots, 1, self._fmtSymbol)
|
970
963
|
return
|
971
964
|
|
972
|
-
# END Class _HeadingSyntaxHighlighter
|
973
|
-
|
974
965
|
|
975
966
|
class _ContentTab(NScrollableForm):
|
976
967
|
|
977
|
-
def __init__(self,
|
978
|
-
super().__init__(parent=
|
968
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
969
|
+
super().__init__(parent=parent)
|
979
970
|
|
980
971
|
self._build = build
|
981
972
|
|
@@ -1054,16 +1045,15 @@ class _ContentTab(NScrollableForm):
|
|
1054
1045
|
self.ignoredKeywords.setText(", ".join(verified))
|
1055
1046
|
return
|
1056
1047
|
|
1057
|
-
# END Class _ContentTab
|
1058
|
-
|
1059
1048
|
|
1060
1049
|
class _FormatTab(NScrollableForm):
|
1061
1050
|
|
1062
|
-
def __init__(self,
|
1063
|
-
super().__init__(parent=
|
1051
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
1052
|
+
super().__init__(parent=parent)
|
1064
1053
|
|
1065
1054
|
self._build = build
|
1066
1055
|
self._unitScale = 1.0
|
1056
|
+
self._textFont = QFont(CONFIG.textFont)
|
1067
1057
|
|
1068
1058
|
iPx = SHARED.theme.baseIconHeight
|
1069
1059
|
iSz = SHARED.theme.baseIconSize
|
@@ -1075,24 +1065,16 @@ class _FormatTab(NScrollableForm):
|
|
1075
1065
|
|
1076
1066
|
self.addGroupLabel(self._build.getLabel("format.grpFormat"))
|
1077
1067
|
|
1078
|
-
# Font
|
1068
|
+
# Text Font
|
1079
1069
|
self.textFont = QLineEdit(self)
|
1080
1070
|
self.textFont.setReadOnly(True)
|
1081
|
-
self.btnTextFont = NIconToolButton(self, iSz, "
|
1071
|
+
self.btnTextFont = NIconToolButton(self, iSz, "font")
|
1082
1072
|
self.btnTextFont.clicked.connect(self._selectFont)
|
1083
1073
|
self.addRow(
|
1084
1074
|
self._build.getLabel("format.textFont"), self.textFont,
|
1085
|
-
button=self.btnTextFont, stretch=(
|
1075
|
+
button=self.btnTextFont, stretch=(1, 1)
|
1086
1076
|
)
|
1087
1077
|
|
1088
|
-
# Font Size
|
1089
|
-
self.textSize = NSpinBox(self)
|
1090
|
-
self.textSize.setMinimum(8)
|
1091
|
-
self.textSize.setMaximum(60)
|
1092
|
-
self.textSize.setSingleStep(1)
|
1093
|
-
self.textSize.setMinimumWidth(spW)
|
1094
|
-
self.addRow(self._build.getLabel("format.textSize"), self.textSize, unit="pt")
|
1095
|
-
|
1096
1078
|
# Line Height
|
1097
1079
|
self.lineHeight = NDoubleSpinBox(self)
|
1098
1080
|
self.lineHeight.setFixedWidth(spW)
|
@@ -1110,10 +1092,33 @@ class _FormatTab(NScrollableForm):
|
|
1110
1092
|
self.justifyText = NSwitch(self, height=iPx)
|
1111
1093
|
self.stripUnicode = NSwitch(self, height=iPx)
|
1112
1094
|
self.replaceTabs = NSwitch(self, height=iPx)
|
1095
|
+
self.keepBreaks = NSwitch(self, height=iPx)
|
1096
|
+
self.showDialogue = NSwitch(self, height=iPx)
|
1113
1097
|
|
1114
1098
|
self.addRow(self._build.getLabel("format.justifyText"), self.justifyText)
|
1115
1099
|
self.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode)
|
1116
1100
|
self.addRow(self._build.getLabel("format.replaceTabs"), self.replaceTabs)
|
1101
|
+
self.addRow(self._build.getLabel("format.keepBreaks"), self.keepBreaks)
|
1102
|
+
self.addRow(self._build.getLabel("format.showDialogue"), self.showDialogue)
|
1103
|
+
|
1104
|
+
# First Line Indent
|
1105
|
+
# =================
|
1106
|
+
|
1107
|
+
self.addGroupLabel(self._build.getLabel("format.grpParIndent"))
|
1108
|
+
|
1109
|
+
self.firstIndent = NSwitch(self, height=iPx)
|
1110
|
+
self.indentFirstPar = NSwitch(self, height=iPx)
|
1111
|
+
|
1112
|
+
self.indentWidth = NDoubleSpinBox(self)
|
1113
|
+
self.indentWidth.setFixedWidth(spW)
|
1114
|
+
self.indentWidth.setMinimum(0.1)
|
1115
|
+
self.indentWidth.setMaximum(9.9)
|
1116
|
+
self.indentWidth.setSingleStep(0.1)
|
1117
|
+
self.indentWidth.setDecimals(1)
|
1118
|
+
|
1119
|
+
self.addRow(self._build.getLabel("format.firstLineIndent"), self.firstIndent)
|
1120
|
+
self.addRow(self._build.getLabel("format.firstIndentWidth"), self.indentWidth, unit="em")
|
1121
|
+
self.addRow(self._build.getLabel("format.indentFirstPar"), self.indentFirstPar)
|
1117
1122
|
|
1118
1123
|
# Page Layout
|
1119
1124
|
# ===========
|
@@ -1166,17 +1171,22 @@ class _FormatTab(NScrollableForm):
|
|
1166
1171
|
|
1167
1172
|
def loadContent(self) -> None:
|
1168
1173
|
"""Populate the widgets."""
|
1169
|
-
|
1170
|
-
|
1171
|
-
textFont = str(CONFIG.textFont)
|
1174
|
+
self._textFont = QFont()
|
1175
|
+
self._textFont.fromString(self._build.getStr("format.textFont"))
|
1172
1176
|
|
1173
|
-
self.textFont.setText(
|
1174
|
-
self.
|
1175
|
-
self.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
|
1177
|
+
self.textFont.setText(describeFont(self._textFont))
|
1178
|
+
self.textFont.setCursorPosition(0)
|
1176
1179
|
|
1180
|
+
self.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
|
1177
1181
|
self.justifyText.setChecked(self._build.getBool("format.justifyText"))
|
1178
1182
|
self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode"))
|
1179
1183
|
self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs"))
|
1184
|
+
self.keepBreaks.setChecked(self._build.getBool("format.keepBreaks"))
|
1185
|
+
self.showDialogue.setChecked(self._build.getBool("format.showDialogue"))
|
1186
|
+
|
1187
|
+
self.firstIndent.setChecked(self._build.getBool("format.firstLineIndent"))
|
1188
|
+
self.indentWidth.setValue(self._build.getFloat("format.firstIndentWidth"))
|
1189
|
+
self.indentFirstPar.setChecked(self._build.getBool("format.indentFirstPar"))
|
1180
1190
|
|
1181
1191
|
pageUnit = self._build.getStr("format.pageUnit")
|
1182
1192
|
index = self.pageUnit.findData(pageUnit)
|
@@ -1205,13 +1215,18 @@ class _FormatTab(NScrollableForm):
|
|
1205
1215
|
|
1206
1216
|
def saveContent(self) -> None:
|
1207
1217
|
"""Save choices back into build object."""
|
1208
|
-
self._build.setValue("format.textFont", self.
|
1209
|
-
self._build.setValue("format.textSize", self.textSize.value())
|
1218
|
+
self._build.setValue("format.textFont", self._textFont.toString())
|
1210
1219
|
self._build.setValue("format.lineHeight", self.lineHeight.value())
|
1211
1220
|
|
1212
1221
|
self._build.setValue("format.justifyText", self.justifyText.isChecked())
|
1213
1222
|
self._build.setValue("format.stripUnicode", self.stripUnicode.isChecked())
|
1214
1223
|
self._build.setValue("format.replaceTabs", self.replaceTabs.isChecked())
|
1224
|
+
self._build.setValue("format.keepBreaks", self.keepBreaks.isChecked())
|
1225
|
+
self._build.setValue("format.showDialogue", self.showDialogue.isChecked())
|
1226
|
+
|
1227
|
+
self._build.setValue("format.firstLineIndent", self.firstIndent.isChecked())
|
1228
|
+
self._build.setValue("format.firstIndentWidth", self.indentWidth.value())
|
1229
|
+
self._build.setValue("format.indentFirstPar", self.indentFirstPar.isChecked())
|
1215
1230
|
|
1216
1231
|
self._build.setValue("format.pageUnit", str(self.pageUnit.currentData()))
|
1217
1232
|
self._build.setValue("format.pageSize", str(self.pageSize.currentData()))
|
@@ -1230,13 +1245,11 @@ class _FormatTab(NScrollableForm):
|
|
1230
1245
|
@pyqtSlot()
|
1231
1246
|
def _selectFont(self) -> None:
|
1232
1247
|
"""Open the QFontDialog and set a font for the font style."""
|
1233
|
-
|
1234
|
-
currFont.setFamily(self.textFont.text())
|
1235
|
-
currFont.setPointSize(self.textSize.value())
|
1236
|
-
newFont, status = QFontDialog.getFont(currFont, self)
|
1248
|
+
font, status = SHARED.getFont(self._textFont, CONFIG.nativeFont)
|
1237
1249
|
if status:
|
1238
|
-
self.textFont.setText(
|
1239
|
-
self.
|
1250
|
+
self.textFont.setText(describeFont(font))
|
1251
|
+
self.textFont.setCursorPosition(0)
|
1252
|
+
self._textFont = font
|
1240
1253
|
return
|
1241
1254
|
|
1242
1255
|
@pyqtSlot(int)
|
@@ -1321,13 +1334,11 @@ class _FormatTab(NScrollableForm):
|
|
1321
1334
|
self.pageSize.setCurrentIndex(index)
|
1322
1335
|
return
|
1323
1336
|
|
1324
|
-
# END Class _FormatTab
|
1325
|
-
|
1326
1337
|
|
1327
1338
|
class _OutputTab(NScrollableForm):
|
1328
1339
|
|
1329
|
-
def __init__(self,
|
1330
|
-
super().__init__(parent=
|
1340
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
1341
|
+
super().__init__(parent=parent)
|
1331
1342
|
|
1332
1343
|
self._build = build
|
1333
1344
|
|
@@ -1357,9 +1368,6 @@ class _OutputTab(NScrollableForm):
|
|
1357
1368
|
self.odtPageCountOffset.setMinimumWidth(spW)
|
1358
1369
|
self.addRow(self._build.getLabel("odt.pageCountOffset"), self.odtPageCountOffset)
|
1359
1370
|
|
1360
|
-
self.odtFirstLineIndent = NSwitch(self, height=iPx)
|
1361
|
-
self.addRow(self._build.getLabel("odt.firstLineIndent"), self.odtFirstLineIndent)
|
1362
|
-
|
1363
1371
|
# HTML Document
|
1364
1372
|
self.addGroupLabel(self._build.getLabel("html"))
|
1365
1373
|
|
@@ -1369,12 +1377,6 @@ class _OutputTab(NScrollableForm):
|
|
1369
1377
|
self.htmlPreserveTabs = NSwitch(self, height=iPx)
|
1370
1378
|
self.addRow(self._build.getLabel("html.preserveTabs"), self.htmlPreserveTabs)
|
1371
1379
|
|
1372
|
-
# Markdown Document
|
1373
|
-
self.addGroupLabel(self._build.getLabel("md"))
|
1374
|
-
|
1375
|
-
self.mdPreserveBreaks = NSwitch(self, height=iPx)
|
1376
|
-
self.addRow(self._build.getLabel("md.preserveBreaks"), self.mdPreserveBreaks)
|
1377
|
-
|
1378
1380
|
# Finalise
|
1379
1381
|
self.finalise()
|
1380
1382
|
|
@@ -1385,10 +1387,8 @@ class _OutputTab(NScrollableForm):
|
|
1385
1387
|
self.odtAddColours.setChecked(self._build.getBool("odt.addColours"))
|
1386
1388
|
self.odtPageHeader.setText(self._build.getStr("odt.pageHeader"))
|
1387
1389
|
self.odtPageCountOffset.setValue(self._build.getInt("odt.pageCountOffset"))
|
1388
|
-
self.odtFirstLineIndent.setChecked(self._build.getBool("odt.firstLineIndent"))
|
1389
1390
|
self.htmlAddStyles.setChecked(self._build.getBool("html.addStyles"))
|
1390
1391
|
self.htmlPreserveTabs.setChecked(self._build.getBool("html.preserveTabs"))
|
1391
|
-
self.mdPreserveBreaks.setChecked(self._build.getBool("md.preserveBreaks"))
|
1392
1392
|
self.odtPageHeader.setCursorPosition(0)
|
1393
1393
|
return
|
1394
1394
|
|
@@ -1397,10 +1397,8 @@ class _OutputTab(NScrollableForm):
|
|
1397
1397
|
self._build.setValue("odt.addColours", self.odtAddColours.isChecked())
|
1398
1398
|
self._build.setValue("odt.pageHeader", self.odtPageHeader.text())
|
1399
1399
|
self._build.setValue("odt.pageCountOffset", self.odtPageCountOffset.value())
|
1400
|
-
self._build.setValue("odt.firstLineIndent", self.odtFirstLineIndent.isChecked())
|
1401
1400
|
self._build.setValue("html.addStyles", self.htmlAddStyles.isChecked())
|
1402
1401
|
self._build.setValue("html.preserveTabs", self.htmlPreserveTabs.isChecked())
|
1403
|
-
self._build.setValue("md.preserveBreaks", self.mdPreserveBreaks.isChecked())
|
1404
1402
|
return
|
1405
1403
|
|
1406
1404
|
##
|
@@ -1412,5 +1410,3 @@ class _OutputTab(NScrollableForm):
|
|
1412
1410
|
self.odtPageHeader.setText(nwHeadFmt.ODT_AUTO)
|
1413
1411
|
self.odtPageHeader.setCursorPosition(0)
|
1414
1412
|
return
|
1415
|
-
|
1416
|
-
# END Class _OutputTab
|
@@ -23,21 +23,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
23
23
|
"""
|
24
24
|
from __future__ import annotations
|
25
25
|
|
26
|
-
import math
|
27
26
|
import logging
|
27
|
+
import math
|
28
28
|
|
29
29
|
from PyQt5.QtCore import pyqtSlot
|
30
30
|
from PyQt5.QtGui import QCloseEvent
|
31
31
|
from PyQt5.QtWidgets import (
|
32
|
-
QAbstractItemView,
|
33
|
-
|
34
|
-
|
32
|
+
QAbstractItemView, QDialogButtonBox, QFormLayout, QGridLayout, QHBoxLayout,
|
33
|
+
QLabel, QSpinBox, QStackedWidget, QTreeWidget, QTreeWidgetItem,
|
34
|
+
QVBoxLayout, QWidget
|
35
35
|
)
|
36
36
|
|
37
37
|
from novelwriter import CONFIG, SHARED
|
38
38
|
from novelwriter.common import formatTime, numberToRoman
|
39
39
|
from novelwriter.constants import nwUnicode
|
40
40
|
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
|
41
|
+
from novelwriter.extensions.modified import NNonBlockingDialog
|
41
42
|
from novelwriter.extensions.novelselector import NovelSelector
|
42
43
|
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
43
44
|
from novelwriter.extensions.switch import NSwitch
|
@@ -46,7 +47,7 @@ from novelwriter.types import QtAlignRight, QtDecoration, QtDialogClose
|
|
46
47
|
logger = logging.getLogger(__name__)
|
47
48
|
|
48
49
|
|
49
|
-
class GuiNovelDetails(
|
50
|
+
class GuiNovelDetails(NNonBlockingDialog):
|
50
51
|
|
51
52
|
PAGE_OVERVIEW = 1
|
52
53
|
PAGE_CONTENTS = 2
|
@@ -67,8 +68,8 @@ class GuiNovelDetails(QDialog):
|
|
67
68
|
|
68
69
|
# Title
|
69
70
|
self.titleLabel = NColourLabel(
|
70
|
-
self.tr("Novel Details"), SHARED.theme.helpText,
|
71
|
-
|
71
|
+
self.tr("Novel Details"), self, color=SHARED.theme.helpText,
|
72
|
+
scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
|
72
73
|
)
|
73
74
|
|
74
75
|
# Novel Selector
|
@@ -96,7 +97,7 @@ class GuiNovelDetails(QDialog):
|
|
96
97
|
|
97
98
|
# Buttons
|
98
99
|
self.buttonBox = QDialogButtonBox(QtDialogClose, self)
|
99
|
-
self.buttonBox.rejected.connect(self.
|
100
|
+
self.buttonBox.rejected.connect(self.reject)
|
100
101
|
|
101
102
|
# Assemble
|
102
103
|
self.topBox = QHBoxLayout()
|
@@ -149,7 +150,7 @@ class GuiNovelDetails(QDialog):
|
|
149
150
|
"""Capture the user closing the window and save settings."""
|
150
151
|
self._saveSettings()
|
151
152
|
event.accept()
|
152
|
-
self.
|
153
|
+
self.softDelete()
|
153
154
|
return
|
154
155
|
|
155
156
|
##
|
@@ -185,8 +186,6 @@ class GuiNovelDetails(QDialog):
|
|
185
186
|
|
186
187
|
return
|
187
188
|
|
188
|
-
# END Class GuiNovelDetails
|
189
|
-
|
190
189
|
|
191
190
|
class _OverviewPage(NScrollablePage):
|
192
191
|
|
@@ -200,8 +199,8 @@ class _OverviewPage(NScrollablePage):
|
|
200
199
|
|
201
200
|
# Project Info
|
202
201
|
self.projLabel = NColourLabel(
|
203
|
-
self.tr("Project"), SHARED.theme.helpText,
|
204
|
-
|
202
|
+
self.tr("Project"), self, color=SHARED.theme.helpText,
|
203
|
+
scale=NColourLabel.HEADER_SCALE
|
205
204
|
)
|
206
205
|
|
207
206
|
self.projName = QLabel("", self)
|
@@ -224,8 +223,8 @@ class _OverviewPage(NScrollablePage):
|
|
224
223
|
|
225
224
|
# Novel Info
|
226
225
|
self.novelLabel = NColourLabel(
|
227
|
-
self.tr("Selected Novel"), SHARED.theme.helpText,
|
228
|
-
|
226
|
+
self.tr("Selected Novel"), self, color=SHARED.theme.helpText,
|
227
|
+
scale=NColourLabel.HEADER_SCALE
|
229
228
|
)
|
230
229
|
|
231
230
|
self.novelName = QLabel("", self)
|
@@ -293,8 +292,6 @@ class _OverviewPage(NScrollablePage):
|
|
293
292
|
|
294
293
|
return
|
295
294
|
|
296
|
-
# END Class _OverviewPage
|
297
|
-
|
298
295
|
|
299
296
|
class _ContentsPage(NFixedPage):
|
300
297
|
|
@@ -318,8 +315,8 @@ class _ContentsPage(NFixedPage):
|
|
318
315
|
|
319
316
|
# Title
|
320
317
|
self.contentLabel = NColourLabel(
|
321
|
-
self.tr("Table of Contents"), SHARED.theme.helpText,
|
322
|
-
|
318
|
+
self.tr("Table of Contents"), self, color=SHARED.theme.helpText,
|
319
|
+
scale=NColourLabel.HEADER_SCALE
|
323
320
|
)
|
324
321
|
|
325
322
|
# Contents Tree
|
@@ -523,5 +520,3 @@ class _ContentsPage(NFixedPage):
|
|
523
520
|
self._data = SHARED.project.index.getTableOfContents(rootHandle, 2)
|
524
521
|
self._data.append(("", 0, self.tr("END"), 0))
|
525
522
|
return
|
526
|
-
|
527
|
-
# END Class _ContentsPage
|
novelwriter/tools/welcome.py
CHANGED
@@ -32,11 +32,11 @@ from PyQt5.QtCore import (
|
|
32
32
|
QAbstractListModel, QEvent, QModelIndex, QObject, QPoint, QSize, Qt,
|
33
33
|
pyqtSignal, pyqtSlot
|
34
34
|
)
|
35
|
-
from PyQt5.QtGui import QCloseEvent, QColor, QFont,
|
35
|
+
from PyQt5.QtGui import QCloseEvent, QColor, QFont, QPainter, QPaintEvent, QPen
|
36
36
|
from PyQt5.QtWidgets import (
|
37
|
-
QAction, QApplication,
|
38
|
-
|
39
|
-
QStackedWidget,
|
37
|
+
QAction, QApplication, QFileDialog, QFormLayout, QHBoxLayout, QLabel,
|
38
|
+
QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut,
|
39
|
+
QStackedWidget, QStyledItemDelegate, QStyleOptionViewItem, QVBoxLayout,
|
40
40
|
QWidget
|
41
41
|
)
|
42
42
|
|
@@ -46,7 +46,7 @@ from novelwriter.constants import nwFiles
|
|
46
46
|
from novelwriter.core.coretools import ProjectBuilder
|
47
47
|
from novelwriter.enum import nwItemClass
|
48
48
|
from novelwriter.extensions.configlayout import NWrappedWidgetBox
|
49
|
-
from novelwriter.extensions.modified import NIconToolButton, NSpinBox
|
49
|
+
from novelwriter.extensions.modified import NDialog, NIconToolButton, NSpinBox
|
50
50
|
from novelwriter.extensions.switch import NSwitch
|
51
51
|
from novelwriter.extensions.versioninfo import VersionInfoWidget
|
52
52
|
from novelwriter.types import QtAlignLeft, QtAlignRightTop, QtSelected
|
@@ -56,7 +56,7 @@ logger = logging.getLogger(__name__)
|
|
56
56
|
PANEL_ALPHA = 178
|
57
57
|
|
58
58
|
|
59
|
-
class GuiWelcome(
|
59
|
+
class GuiWelcome(NDialog):
|
60
60
|
|
61
61
|
openProjectRequest = pyqtSignal(Path)
|
62
62
|
|
@@ -196,7 +196,7 @@ class GuiWelcome(QDialog):
|
|
196
196
|
"""Capture the user closing the window and save settings."""
|
197
197
|
self._saveSettings()
|
198
198
|
event.accept()
|
199
|
-
self.
|
199
|
+
self.softDelete()
|
200
200
|
return
|
201
201
|
|
202
202
|
##
|
@@ -208,6 +208,7 @@ class GuiWelcome(QDialog):
|
|
208
208
|
"""Show the create new project page."""
|
209
209
|
self.mainStack.setCurrentWidget(self.tabNew)
|
210
210
|
self._setButtonVisibility()
|
211
|
+
self.tabNew.enterForm()
|
211
212
|
return
|
212
213
|
|
213
214
|
@pyqtSlot()
|
@@ -220,8 +221,7 @@ class GuiWelcome(QDialog):
|
|
220
221
|
@pyqtSlot()
|
221
222
|
def _browseForProject(self) -> None:
|
222
223
|
"""Browse for a project to open."""
|
223
|
-
if path := SHARED.getProjectPath(self, path=CONFIG.
|
224
|
-
CONFIG.setLastPath(path)
|
224
|
+
if path := SHARED.getProjectPath(self, path=CONFIG.homePath(), allowZip=False):
|
225
225
|
self._openProjectPath(path)
|
226
226
|
return
|
227
227
|
|
@@ -267,8 +267,6 @@ class GuiWelcome(QDialog):
|
|
267
267
|
self.btnCreate.setFocus()
|
268
268
|
return
|
269
269
|
|
270
|
-
# END Class GuiWelcome
|
271
|
-
|
272
270
|
|
273
271
|
class _OpenProjectPage(QWidget):
|
274
272
|
|
@@ -392,8 +390,6 @@ class _OpenProjectPage(QWidget):
|
|
392
390
|
self._projectClicked(index)
|
393
391
|
return
|
394
392
|
|
395
|
-
# END Class _OpenProjectPage
|
396
|
-
|
397
393
|
|
398
394
|
class _ProjectListItem(QStyledItemDelegate):
|
399
395
|
|
@@ -450,8 +446,6 @@ class _ProjectListItem(QStyledItemDelegate):
|
|
450
446
|
"""Set the size hint to fixed height."""
|
451
447
|
return QSize(opt.rect.width(), self._hPx)
|
452
448
|
|
453
|
-
# END Class _ProjectListItem
|
454
|
-
|
455
449
|
|
456
450
|
class _ProjectListModel(QAbstractListModel):
|
457
451
|
|
@@ -491,8 +485,6 @@ class _ProjectListModel(QAbstractListModel):
|
|
491
485
|
return True
|
492
486
|
return False
|
493
487
|
|
494
|
-
# END Class _ProjectListModel
|
495
|
-
|
496
488
|
|
497
489
|
class _NewProjectPage(QWidget):
|
498
490
|
|
@@ -512,6 +504,8 @@ class _NewProjectPage(QWidget):
|
|
512
504
|
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
513
505
|
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
514
506
|
|
507
|
+
self.enterForm = self.projectForm.enterForm
|
508
|
+
|
515
509
|
# Assemble
|
516
510
|
# ========
|
517
511
|
|
@@ -548,8 +542,6 @@ class _NewProjectPage(QWidget):
|
|
548
542
|
self.openProjectRequest.emit(path)
|
549
543
|
return
|
550
544
|
|
551
|
-
# END Class _NewProjectPage
|
552
|
-
|
553
545
|
|
554
546
|
class _NewProjectForm(QWidget):
|
555
547
|
|
@@ -560,7 +552,7 @@ class _NewProjectForm(QWidget):
|
|
560
552
|
def __init__(self, parent: QWidget) -> None:
|
561
553
|
super().__init__(parent=parent)
|
562
554
|
|
563
|
-
self._basePath = CONFIG.
|
555
|
+
self._basePath = CONFIG.lastPath("project")
|
564
556
|
self._fillMode = self.FILL_BLANK
|
565
557
|
self._copyPath = None
|
566
558
|
|
@@ -707,6 +699,12 @@ class _NewProjectForm(QWidget):
|
|
707
699
|
|
708
700
|
return
|
709
701
|
|
702
|
+
def enterForm(self) -> None:
|
703
|
+
"""Focus the project name field when entering the form."""
|
704
|
+
self.projName.setFocus()
|
705
|
+
self.projName.selectAll()
|
706
|
+
return
|
707
|
+
|
710
708
|
def getProjectData(self) -> dict:
|
711
709
|
"""Collect form data and return it as a dictionary."""
|
712
710
|
roots = []
|
@@ -736,12 +734,13 @@ class _NewProjectForm(QWidget):
|
|
736
734
|
@pyqtSlot()
|
737
735
|
def _doBrowse(self) -> None:
|
738
736
|
"""Select a project folder."""
|
739
|
-
if
|
737
|
+
if path := QFileDialog.getExistingDirectory(
|
740
738
|
self, self.tr("Select Project Folder"),
|
741
739
|
str(self._basePath), options=QFileDialog.Option.ShowDirsOnly
|
742
740
|
):
|
743
|
-
self._basePath = Path(
|
741
|
+
self._basePath = Path(path)
|
744
742
|
self._updateProjPath()
|
743
|
+
CONFIG.setLastPath("project", path)
|
745
744
|
return
|
746
745
|
|
747
746
|
@pyqtSlot()
|
@@ -805,8 +804,6 @@ class _NewProjectForm(QWidget):
|
|
805
804
|
|
806
805
|
return
|
807
806
|
|
808
|
-
# END Class _NewProjectForm
|
809
|
-
|
810
807
|
|
811
808
|
class _PopLeftDirectionMenu(QMenu):
|
812
809
|
|
@@ -817,5 +814,3 @@ class _PopLeftDirectionMenu(QMenu):
|
|
817
814
|
offset = QPoint(parent.width() - self.width(), parent.height())
|
818
815
|
self.move(parent.mapToGlobal(offset))
|
819
816
|
return super(_PopLeftDirectionMenu, self).event(event)
|
820
|
-
|
821
|
-
# END Class _PopLeftDirectionMenu
|