novelWriter 2.4.3__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.3.dist-info → novelWriter-2.5.dist-info}/METADATA +4 -5
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/RECORD +122 -112
- {novelWriter-2.4.3.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/i18n/project_pt_BR.json +74 -74
- 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 +70 -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 +39 -65
- 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 -19
- 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 +75 -149
- novelwriter/tools/manussettings.py +74 -76
- 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.3.dist-info → novelWriter-2.5.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.4.3.dist-info → novelWriter-2.5.dist-info}/top_level.txt +0 -0
@@ -27,22 +27,25 @@ 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,
|
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
|
-
from novelwriter.extensions.modified import
|
46
|
+
from novelwriter.extensions.modified import (
|
47
|
+
NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox, NToolDialog
|
48
|
+
)
|
46
49
|
from novelwriter.extensions.pagedsidebar import NPagedSideBar
|
47
50
|
from novelwriter.extensions.switch import NSwitch
|
48
51
|
from novelwriter.extensions.switchbox import NSwitchBox
|
@@ -57,7 +60,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
57
60
|
logger = logging.getLogger(__name__)
|
58
61
|
|
59
62
|
|
60
|
-
class GuiBuildSettings(
|
63
|
+
class GuiBuildSettings(NToolDialog):
|
61
64
|
"""GUI Tools: Manuscript Build Settings Dialog
|
62
65
|
|
63
66
|
The main tool for configuring manuscript builds. It's a GUI tool for
|
@@ -72,13 +75,11 @@ class GuiBuildSettings(QDialog):
|
|
72
75
|
|
73
76
|
newSettingsReady = pyqtSignal(BuildSettings)
|
74
77
|
|
75
|
-
def __init__(self,
|
76
|
-
super().__init__(parent=
|
78
|
+
def __init__(self, parent: GuiMain, build: BuildSettings) -> None:
|
79
|
+
super().__init__(parent=parent)
|
77
80
|
|
78
81
|
logger.debug("Create: GuiBuildSettings")
|
79
82
|
self.setObjectName("GuiBuildSettings")
|
80
|
-
if CONFIG.osDarwin:
|
81
|
-
self.setWindowFlag(Qt.WindowType.Tool)
|
82
83
|
|
83
84
|
self._build = build
|
84
85
|
|
@@ -97,8 +98,8 @@ class GuiBuildSettings(QDialog):
|
|
97
98
|
|
98
99
|
# Title
|
99
100
|
self.titleLabel = NColourLabel(
|
100
|
-
self.tr("Manuscript Build Settings"), SHARED.theme.helpText,
|
101
|
-
|
101
|
+
self.tr("Manuscript Build Settings"), self, color=SHARED.theme.helpText,
|
102
|
+
scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
|
102
103
|
)
|
103
104
|
|
104
105
|
# Settings Name
|
@@ -199,7 +200,7 @@ class GuiBuildSettings(QDialog):
|
|
199
200
|
self._askToSaveBuild()
|
200
201
|
self._saveSettings()
|
201
202
|
event.accept()
|
202
|
-
self.
|
203
|
+
self.softDelete()
|
203
204
|
return
|
204
205
|
|
205
206
|
##
|
@@ -278,8 +279,6 @@ class GuiBuildSettings(QDialog):
|
|
278
279
|
self._build.resetChangedState()
|
279
280
|
return
|
280
281
|
|
281
|
-
# END Class GuiBuildSettings
|
282
|
-
|
283
282
|
|
284
283
|
class _FilterTab(NFixedPage):
|
285
284
|
|
@@ -296,8 +295,8 @@ class _FilterTab(NFixedPage):
|
|
296
295
|
F_INCLUDED = 2
|
297
296
|
F_EXCLUDED = 3
|
298
297
|
|
299
|
-
def __init__(self,
|
300
|
-
super().__init__(parent=
|
298
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
299
|
+
super().__init__(parent=parent)
|
301
300
|
|
302
301
|
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
303
302
|
self._build = build
|
@@ -574,8 +573,6 @@ class _FilterTab(NFixedPage):
|
|
574
573
|
self._scanChildren(item.child(i), items)
|
575
574
|
return items
|
576
575
|
|
577
|
-
# END Class _FilterTab
|
578
|
-
|
579
576
|
|
580
577
|
class _HeadingsTab(NScrollablePage):
|
581
578
|
|
@@ -586,8 +583,8 @@ class _HeadingsTab(NScrollablePage):
|
|
586
583
|
EDIT_HSCENE = 5
|
587
584
|
EDIT_SECTION = 6
|
588
585
|
|
589
|
-
def __init__(self,
|
590
|
-
super().__init__(parent=
|
586
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
587
|
+
super().__init__(parent=parent)
|
591
588
|
|
592
589
|
self._build = build
|
593
590
|
self._editing = 0
|
@@ -941,8 +938,6 @@ class _HeadingsTab(NScrollablePage):
|
|
941
938
|
|
942
939
|
return
|
943
940
|
|
944
|
-
# END Class _HeadingsTab
|
945
|
-
|
946
941
|
|
947
942
|
class _HeadingSyntaxHighlighter(QSyntaxHighlighter):
|
948
943
|
|
@@ -967,13 +962,11 @@ class _HeadingSyntaxHighlighter(QSyntaxHighlighter):
|
|
967
962
|
self.setFormat(pos + ddots, 1, self._fmtSymbol)
|
968
963
|
return
|
969
964
|
|
970
|
-
# END Class _HeadingSyntaxHighlighter
|
971
|
-
|
972
965
|
|
973
966
|
class _ContentTab(NScrollableForm):
|
974
967
|
|
975
|
-
def __init__(self,
|
976
|
-
super().__init__(parent=
|
968
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
969
|
+
super().__init__(parent=parent)
|
977
970
|
|
978
971
|
self._build = build
|
979
972
|
|
@@ -1052,16 +1045,15 @@ class _ContentTab(NScrollableForm):
|
|
1052
1045
|
self.ignoredKeywords.setText(", ".join(verified))
|
1053
1046
|
return
|
1054
1047
|
|
1055
|
-
# END Class _ContentTab
|
1056
|
-
|
1057
1048
|
|
1058
1049
|
class _FormatTab(NScrollableForm):
|
1059
1050
|
|
1060
|
-
def __init__(self,
|
1061
|
-
super().__init__(parent=
|
1051
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
1052
|
+
super().__init__(parent=parent)
|
1062
1053
|
|
1063
1054
|
self._build = build
|
1064
1055
|
self._unitScale = 1.0
|
1056
|
+
self._textFont = QFont(CONFIG.textFont)
|
1065
1057
|
|
1066
1058
|
iPx = SHARED.theme.baseIconHeight
|
1067
1059
|
iSz = SHARED.theme.baseIconSize
|
@@ -1073,24 +1065,16 @@ class _FormatTab(NScrollableForm):
|
|
1073
1065
|
|
1074
1066
|
self.addGroupLabel(self._build.getLabel("format.grpFormat"))
|
1075
1067
|
|
1076
|
-
# Font
|
1068
|
+
# Text Font
|
1077
1069
|
self.textFont = QLineEdit(self)
|
1078
1070
|
self.textFont.setReadOnly(True)
|
1079
|
-
self.btnTextFont = NIconToolButton(self, iSz, "
|
1071
|
+
self.btnTextFont = NIconToolButton(self, iSz, "font")
|
1080
1072
|
self.btnTextFont.clicked.connect(self._selectFont)
|
1081
1073
|
self.addRow(
|
1082
1074
|
self._build.getLabel("format.textFont"), self.textFont,
|
1083
|
-
button=self.btnTextFont, stretch=(
|
1075
|
+
button=self.btnTextFont, stretch=(1, 1)
|
1084
1076
|
)
|
1085
1077
|
|
1086
|
-
# Font Size
|
1087
|
-
self.textSize = NSpinBox(self)
|
1088
|
-
self.textSize.setMinimum(8)
|
1089
|
-
self.textSize.setMaximum(60)
|
1090
|
-
self.textSize.setSingleStep(1)
|
1091
|
-
self.textSize.setMinimumWidth(spW)
|
1092
|
-
self.addRow(self._build.getLabel("format.textSize"), self.textSize, unit="pt")
|
1093
|
-
|
1094
1078
|
# Line Height
|
1095
1079
|
self.lineHeight = NDoubleSpinBox(self)
|
1096
1080
|
self.lineHeight.setFixedWidth(spW)
|
@@ -1108,10 +1092,33 @@ class _FormatTab(NScrollableForm):
|
|
1108
1092
|
self.justifyText = NSwitch(self, height=iPx)
|
1109
1093
|
self.stripUnicode = NSwitch(self, height=iPx)
|
1110
1094
|
self.replaceTabs = NSwitch(self, height=iPx)
|
1095
|
+
self.keepBreaks = NSwitch(self, height=iPx)
|
1096
|
+
self.showDialogue = NSwitch(self, height=iPx)
|
1111
1097
|
|
1112
1098
|
self.addRow(self._build.getLabel("format.justifyText"), self.justifyText)
|
1113
1099
|
self.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode)
|
1114
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)
|
1115
1122
|
|
1116
1123
|
# Page Layout
|
1117
1124
|
# ===========
|
@@ -1164,17 +1171,22 @@ class _FormatTab(NScrollableForm):
|
|
1164
1171
|
|
1165
1172
|
def loadContent(self) -> None:
|
1166
1173
|
"""Populate the widgets."""
|
1167
|
-
|
1168
|
-
|
1169
|
-
textFont = str(CONFIG.textFont)
|
1174
|
+
self._textFont = QFont()
|
1175
|
+
self._textFont.fromString(self._build.getStr("format.textFont"))
|
1170
1176
|
|
1171
|
-
self.textFont.setText(
|
1172
|
-
self.
|
1173
|
-
self.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
|
1177
|
+
self.textFont.setText(describeFont(self._textFont))
|
1178
|
+
self.textFont.setCursorPosition(0)
|
1174
1179
|
|
1180
|
+
self.lineHeight.setValue(self._build.getFloat("format.lineHeight"))
|
1175
1181
|
self.justifyText.setChecked(self._build.getBool("format.justifyText"))
|
1176
1182
|
self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode"))
|
1177
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"))
|
1178
1190
|
|
1179
1191
|
pageUnit = self._build.getStr("format.pageUnit")
|
1180
1192
|
index = self.pageUnit.findData(pageUnit)
|
@@ -1203,13 +1215,18 @@ class _FormatTab(NScrollableForm):
|
|
1203
1215
|
|
1204
1216
|
def saveContent(self) -> None:
|
1205
1217
|
"""Save choices back into build object."""
|
1206
|
-
self._build.setValue("format.textFont", self.
|
1207
|
-
self._build.setValue("format.textSize", self.textSize.value())
|
1218
|
+
self._build.setValue("format.textFont", self._textFont.toString())
|
1208
1219
|
self._build.setValue("format.lineHeight", self.lineHeight.value())
|
1209
1220
|
|
1210
1221
|
self._build.setValue("format.justifyText", self.justifyText.isChecked())
|
1211
1222
|
self._build.setValue("format.stripUnicode", self.stripUnicode.isChecked())
|
1212
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())
|
1213
1230
|
|
1214
1231
|
self._build.setValue("format.pageUnit", str(self.pageUnit.currentData()))
|
1215
1232
|
self._build.setValue("format.pageSize", str(self.pageSize.currentData()))
|
@@ -1228,13 +1245,11 @@ class _FormatTab(NScrollableForm):
|
|
1228
1245
|
@pyqtSlot()
|
1229
1246
|
def _selectFont(self) -> None:
|
1230
1247
|
"""Open the QFontDialog and set a font for the font style."""
|
1231
|
-
|
1232
|
-
currFont.setFamily(self.textFont.text())
|
1233
|
-
currFont.setPointSize(self.textSize.value())
|
1234
|
-
newFont, status = QFontDialog.getFont(currFont, self)
|
1248
|
+
font, status = SHARED.getFont(self._textFont, CONFIG.nativeFont)
|
1235
1249
|
if status:
|
1236
|
-
self.textFont.setText(
|
1237
|
-
self.
|
1250
|
+
self.textFont.setText(describeFont(font))
|
1251
|
+
self.textFont.setCursorPosition(0)
|
1252
|
+
self._textFont = font
|
1238
1253
|
return
|
1239
1254
|
|
1240
1255
|
@pyqtSlot(int)
|
@@ -1319,13 +1334,11 @@ class _FormatTab(NScrollableForm):
|
|
1319
1334
|
self.pageSize.setCurrentIndex(index)
|
1320
1335
|
return
|
1321
1336
|
|
1322
|
-
# END Class _FormatTab
|
1323
|
-
|
1324
1337
|
|
1325
1338
|
class _OutputTab(NScrollableForm):
|
1326
1339
|
|
1327
|
-
def __init__(self,
|
1328
|
-
super().__init__(parent=
|
1340
|
+
def __init__(self, parent: QWidget, build: BuildSettings) -> None:
|
1341
|
+
super().__init__(parent=parent)
|
1329
1342
|
|
1330
1343
|
self._build = build
|
1331
1344
|
|
@@ -1355,9 +1368,6 @@ class _OutputTab(NScrollableForm):
|
|
1355
1368
|
self.odtPageCountOffset.setMinimumWidth(spW)
|
1356
1369
|
self.addRow(self._build.getLabel("odt.pageCountOffset"), self.odtPageCountOffset)
|
1357
1370
|
|
1358
|
-
self.odtFirstLineIndent = NSwitch(self, height=iPx)
|
1359
|
-
self.addRow(self._build.getLabel("odt.firstLineIndent"), self.odtFirstLineIndent)
|
1360
|
-
|
1361
1371
|
# HTML Document
|
1362
1372
|
self.addGroupLabel(self._build.getLabel("html"))
|
1363
1373
|
|
@@ -1367,12 +1377,6 @@ class _OutputTab(NScrollableForm):
|
|
1367
1377
|
self.htmlPreserveTabs = NSwitch(self, height=iPx)
|
1368
1378
|
self.addRow(self._build.getLabel("html.preserveTabs"), self.htmlPreserveTabs)
|
1369
1379
|
|
1370
|
-
# Markdown Document
|
1371
|
-
self.addGroupLabel(self._build.getLabel("md"))
|
1372
|
-
|
1373
|
-
self.mdPreserveBreaks = NSwitch(self, height=iPx)
|
1374
|
-
self.addRow(self._build.getLabel("md.preserveBreaks"), self.mdPreserveBreaks)
|
1375
|
-
|
1376
1380
|
# Finalise
|
1377
1381
|
self.finalise()
|
1378
1382
|
|
@@ -1383,10 +1387,8 @@ class _OutputTab(NScrollableForm):
|
|
1383
1387
|
self.odtAddColours.setChecked(self._build.getBool("odt.addColours"))
|
1384
1388
|
self.odtPageHeader.setText(self._build.getStr("odt.pageHeader"))
|
1385
1389
|
self.odtPageCountOffset.setValue(self._build.getInt("odt.pageCountOffset"))
|
1386
|
-
self.odtFirstLineIndent.setChecked(self._build.getBool("odt.firstLineIndent"))
|
1387
1390
|
self.htmlAddStyles.setChecked(self._build.getBool("html.addStyles"))
|
1388
1391
|
self.htmlPreserveTabs.setChecked(self._build.getBool("html.preserveTabs"))
|
1389
|
-
self.mdPreserveBreaks.setChecked(self._build.getBool("md.preserveBreaks"))
|
1390
1392
|
self.odtPageHeader.setCursorPosition(0)
|
1391
1393
|
return
|
1392
1394
|
|
@@ -1395,10 +1397,8 @@ class _OutputTab(NScrollableForm):
|
|
1395
1397
|
self._build.setValue("odt.addColours", self.odtAddColours.isChecked())
|
1396
1398
|
self._build.setValue("odt.pageHeader", self.odtPageHeader.text())
|
1397
1399
|
self._build.setValue("odt.pageCountOffset", self.odtPageCountOffset.value())
|
1398
|
-
self._build.setValue("odt.firstLineIndent", self.odtFirstLineIndent.isChecked())
|
1399
1400
|
self._build.setValue("html.addStyles", self.htmlAddStyles.isChecked())
|
1400
1401
|
self._build.setValue("html.preserveTabs", self.htmlPreserveTabs.isChecked())
|
1401
|
-
self._build.setValue("md.preserveBreaks", self.mdPreserveBreaks.isChecked())
|
1402
1402
|
return
|
1403
1403
|
|
1404
1404
|
##
|
@@ -1410,5 +1410,3 @@ class _OutputTab(NScrollableForm):
|
|
1410
1410
|
self.odtPageHeader.setText(nwHeadFmt.ODT_AUTO)
|
1411
1411
|
self.odtPageHeader.setCursorPosition(0)
|
1412
1412
|
return
|
1413
|
-
|
1414
|
-
# 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
|