novelWriter 2.2rc1__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.2rc1.dist-info → novelWriter-2.3b1.dist-info}/METADATA +1 -1
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/RECORD +141 -129
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/WHEEL +1 -1
- novelwriter/__init__.py +11 -6
- novelwriter/assets/i18n/nw_de_DE.qm +0 -0
- novelwriter/assets/i18n/nw_en_US.qm +0 -0
- novelwriter/assets/i18n/nw_es_419.qm +0 -0
- novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
- novelwriter/assets/i18n/nw_it_IT.qm +0 -0
- novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
- novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
- novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
- novelwriter/assets/i18n/project_de_DE.json +1 -0
- novelwriter/assets/i18n/project_en_US.json +1 -0
- novelwriter/assets/i18n/project_es_419.json +11 -0
- novelwriter/assets/i18n/project_fr_FR.json +11 -0
- novelwriter/assets/i18n/project_it_IT.json +11 -0
- novelwriter/assets/i18n/project_ja_JP.json +2 -1
- novelwriter/assets/i18n/project_nb_NO.json +1 -0
- novelwriter/assets/i18n/project_zh_CN.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +9 -2
- novelwriter/assets/icons/typicons_dark/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
- 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 +9 -2
- novelwriter/assets/icons/typicons_light/mixed_import.svg +5 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
- novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
- novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
- novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
- 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 +64 -66
- novelwriter/config.py +39 -44
- novelwriter/constants.py +39 -17
- novelwriter/core/buildsettings.py +8 -8
- novelwriter/core/coretools.py +194 -155
- novelwriter/core/docbuild.py +7 -4
- novelwriter/core/document.py +7 -7
- novelwriter/core/index.py +90 -57
- novelwriter/core/item.py +23 -5
- novelwriter/core/options.py +11 -10
- novelwriter/core/project.py +72 -47
- novelwriter/core/projectdata.py +3 -16
- novelwriter/core/projectxml.py +14 -42
- novelwriter/core/sessions.py +4 -3
- novelwriter/core/spellcheck.py +6 -4
- novelwriter/core/status.py +5 -4
- novelwriter/core/storage.py +179 -141
- novelwriter/core/tohtml.py +6 -4
- novelwriter/core/tokenizer.py +74 -46
- novelwriter/core/tomd.py +2 -2
- novelwriter/core/toodt.py +41 -31
- novelwriter/core/tree.py +5 -4
- novelwriter/dialogs/about.py +88 -179
- novelwriter/dialogs/docmerge.py +30 -20
- novelwriter/dialogs/docsplit.py +33 -22
- novelwriter/dialogs/editlabel.py +20 -8
- novelwriter/dialogs/preferences.py +562 -725
- novelwriter/dialogs/{projsettings.py → projectsettings.py} +301 -270
- novelwriter/dialogs/quotes.py +47 -36
- novelwriter/dialogs/wordlist.py +128 -59
- novelwriter/enum.py +25 -22
- novelwriter/error.py +2 -2
- novelwriter/extensions/circularprogress.py +12 -12
- novelwriter/extensions/configlayout.py +185 -146
- novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
- novelwriter/extensions/modified.py +81 -0
- novelwriter/extensions/novelselector.py +27 -13
- novelwriter/extensions/pagedsidebar.py +15 -20
- novelwriter/extensions/simpleprogress.py +8 -9
- novelwriter/extensions/statusled.py +9 -9
- novelwriter/extensions/switch.py +32 -64
- novelwriter/extensions/switchbox.py +2 -7
- novelwriter/extensions/versioninfo.py +153 -0
- novelwriter/gui/doceditor.py +250 -214
- novelwriter/gui/dochighlight.py +66 -94
- novelwriter/gui/docviewer.py +71 -98
- novelwriter/gui/docviewerpanel.py +140 -47
- novelwriter/gui/editordocument.py +3 -3
- novelwriter/gui/itemdetails.py +9 -9
- novelwriter/gui/mainmenu.py +47 -46
- novelwriter/gui/noveltree.py +53 -61
- novelwriter/gui/outline.py +100 -76
- novelwriter/gui/projtree.py +193 -67
- novelwriter/gui/sidebar.py +9 -8
- novelwriter/gui/statusbar.py +49 -7
- novelwriter/gui/theme.py +65 -74
- novelwriter/guimain.py +173 -330
- novelwriter/shared.py +68 -30
- novelwriter/tools/dictionaries.py +7 -8
- novelwriter/tools/lipsum.py +34 -28
- novelwriter/tools/manusbuild.py +3 -4
- novelwriter/tools/manuscript.py +25 -32
- novelwriter/tools/manussettings.py +194 -225
- novelwriter/tools/noveldetails.py +525 -0
- novelwriter/tools/welcome.py +802 -0
- novelwriter/tools/writingstats.py +26 -13
- novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
- novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
- novelwriter/assets/images/wizard-back.jpg +0 -0
- novelwriter/assets/text/gplv3_en.htm +0 -641
- novelwriter/assets/text/release_notes.htm +0 -17
- novelwriter/dialogs/projdetails.py +0 -525
- novelwriter/dialogs/projload.py +0 -298
- novelwriter/dialogs/updates.py +0 -182
- novelwriter/extensions/pageddialog.py +0 -130
- novelwriter/tools/projwizard.py +0 -478
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/entry_points.txt +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3b1.dist-info}/top_level.txt +0 -0
@@ -1,525 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
novelWriter – GUI Project Details
|
3
|
-
=================================
|
4
|
-
|
5
|
-
File History:
|
6
|
-
Created: 2021-01-03 [1.1rc1]
|
7
|
-
|
8
|
-
This file is a part of novelWriter
|
9
|
-
Copyright 2018–2023, Veronica Berglyd Olsen
|
10
|
-
|
11
|
-
This program is free software: you can redistribute it and/or modify
|
12
|
-
it under the terms of the GNU General Public License as published by
|
13
|
-
the Free Software Foundation, either version 3 of the License, or
|
14
|
-
(at your option) any later version.
|
15
|
-
|
16
|
-
This program is distributed in the hope that it will be useful, but
|
17
|
-
WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
19
|
-
General Public License for more details.
|
20
|
-
|
21
|
-
You should have received a copy of the GNU General Public License
|
22
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
23
|
-
"""
|
24
|
-
from __future__ import annotations
|
25
|
-
|
26
|
-
import math
|
27
|
-
import logging
|
28
|
-
|
29
|
-
from PyQt5.QtCore import Qt, QSize, pyqtSlot
|
30
|
-
from PyQt5.QtGui import QFont
|
31
|
-
from PyQt5.QtWidgets import (
|
32
|
-
QAbstractItemView, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel,
|
33
|
-
QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
34
|
-
)
|
35
|
-
|
36
|
-
from novelwriter import CONFIG, SHARED
|
37
|
-
from novelwriter.common import formatTime, numberToRoman
|
38
|
-
from novelwriter.constants import nwUnicode
|
39
|
-
from novelwriter.extensions.switch import NSwitch
|
40
|
-
from novelwriter.extensions.pageddialog import NPagedDialog
|
41
|
-
from novelwriter.extensions.novelselector import NovelSelector
|
42
|
-
|
43
|
-
logger = logging.getLogger(__name__)
|
44
|
-
|
45
|
-
|
46
|
-
class GuiProjectDetails(NPagedDialog):
|
47
|
-
|
48
|
-
def __init__(self, parent):
|
49
|
-
super().__init__(parent=parent)
|
50
|
-
|
51
|
-
logger.debug("Create: GuiProjectDetails")
|
52
|
-
self.setObjectName("GuiProjectDetails")
|
53
|
-
|
54
|
-
self.setWindowTitle(self.tr("Project Details"))
|
55
|
-
|
56
|
-
wW = CONFIG.pxInt(600)
|
57
|
-
wH = CONFIG.pxInt(400)
|
58
|
-
pOptions = SHARED.project.options
|
59
|
-
|
60
|
-
self.setMinimumWidth(wW)
|
61
|
-
self.setMinimumHeight(wH)
|
62
|
-
self.resize(
|
63
|
-
CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winWidth", wW)),
|
64
|
-
CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winHeight", wH))
|
65
|
-
)
|
66
|
-
|
67
|
-
self.tabMain = GuiProjectDetailsMain(self)
|
68
|
-
self.tabContents = GuiProjectDetailsContents(self)
|
69
|
-
|
70
|
-
self.addTab(self.tabMain, self.tr("Overview"))
|
71
|
-
self.addTab(self.tabContents, self.tr("Contents"))
|
72
|
-
|
73
|
-
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
74
|
-
self.buttonBox.button(QDialogButtonBox.Close)
|
75
|
-
self.buttonBox.rejected.connect(self._doClose)
|
76
|
-
self.addControls(self.buttonBox)
|
77
|
-
|
78
|
-
logger.debug("Ready: GuiProjectDetails")
|
79
|
-
|
80
|
-
return
|
81
|
-
|
82
|
-
def __del__(self): # pragma: no cover
|
83
|
-
logger.debug("Delete: GuiProjectDetails")
|
84
|
-
return
|
85
|
-
|
86
|
-
def updateValues(self):
|
87
|
-
"""Set all the values of the pages.
|
88
|
-
"""
|
89
|
-
self.tabMain.updateValues()
|
90
|
-
self.tabContents.updateValues()
|
91
|
-
return
|
92
|
-
|
93
|
-
##
|
94
|
-
# Slots
|
95
|
-
##
|
96
|
-
|
97
|
-
def _doClose(self):
|
98
|
-
"""Save settings and close the dialog.
|
99
|
-
"""
|
100
|
-
self._saveGuiSettings()
|
101
|
-
self.close()
|
102
|
-
return
|
103
|
-
|
104
|
-
##
|
105
|
-
# Internal Functions
|
106
|
-
##
|
107
|
-
|
108
|
-
def _saveGuiSettings(self):
|
109
|
-
"""Save GUI settings.
|
110
|
-
"""
|
111
|
-
winWidth = CONFIG.rpxInt(self.width())
|
112
|
-
winHeight = CONFIG.rpxInt(self.height())
|
113
|
-
|
114
|
-
cColWidth = self.tabContents.getColumnSizes()
|
115
|
-
widthCol0 = CONFIG.rpxInt(cColWidth[0])
|
116
|
-
widthCol1 = CONFIG.rpxInt(cColWidth[1])
|
117
|
-
widthCol2 = CONFIG.rpxInt(cColWidth[2])
|
118
|
-
widthCol3 = CONFIG.rpxInt(cColWidth[3])
|
119
|
-
widthCol4 = CONFIG.rpxInt(cColWidth[4])
|
120
|
-
|
121
|
-
wordsPerPage = self.tabContents.wpValue.value()
|
122
|
-
countFrom = self.tabContents.poValue.value()
|
123
|
-
clearDouble = self.tabContents.dblValue.isChecked()
|
124
|
-
|
125
|
-
pOptions = SHARED.project.options
|
126
|
-
pOptions.setValue("GuiProjectDetails", "winWidth", winWidth)
|
127
|
-
pOptions.setValue("GuiProjectDetails", "winHeight", winHeight)
|
128
|
-
pOptions.setValue("GuiProjectDetails", "widthCol0", widthCol0)
|
129
|
-
pOptions.setValue("GuiProjectDetails", "widthCol1", widthCol1)
|
130
|
-
pOptions.setValue("GuiProjectDetails", "widthCol2", widthCol2)
|
131
|
-
pOptions.setValue("GuiProjectDetails", "widthCol3", widthCol3)
|
132
|
-
pOptions.setValue("GuiProjectDetails", "widthCol4", widthCol4)
|
133
|
-
pOptions.setValue("GuiProjectDetails", "wordsPerPage", wordsPerPage)
|
134
|
-
pOptions.setValue("GuiProjectDetails", "countFrom", countFrom)
|
135
|
-
pOptions.setValue("GuiProjectDetails", "clearDouble", clearDouble)
|
136
|
-
|
137
|
-
return
|
138
|
-
|
139
|
-
# END Class GuiProjectDetails
|
140
|
-
|
141
|
-
|
142
|
-
class GuiProjectDetailsMain(QWidget):
|
143
|
-
|
144
|
-
def __init__(self, parent):
|
145
|
-
super().__init__(parent=parent)
|
146
|
-
|
147
|
-
fPx = SHARED.theme.fontPixelSize
|
148
|
-
fPt = SHARED.theme.fontPointSize
|
149
|
-
vPx = CONFIG.pxInt(4)
|
150
|
-
hPx = CONFIG.pxInt(12)
|
151
|
-
|
152
|
-
# Header
|
153
|
-
# ======
|
154
|
-
|
155
|
-
self.bookTitle = QLabel("")
|
156
|
-
bookFont = self.bookTitle.font()
|
157
|
-
bookFont.setPointSizeF(2.2*fPt)
|
158
|
-
bookFont.setWeight(QFont.Bold)
|
159
|
-
self.bookTitle.setFont(bookFont)
|
160
|
-
self.bookTitle.setAlignment(Qt.AlignHCenter)
|
161
|
-
self.bookTitle.setWordWrap(True)
|
162
|
-
|
163
|
-
self.projName = QLabel("")
|
164
|
-
workFont = self.projName.font()
|
165
|
-
workFont.setPointSizeF(0.8*fPt)
|
166
|
-
workFont.setItalic(True)
|
167
|
-
self.projName.setFont(workFont)
|
168
|
-
self.projName.setAlignment(Qt.AlignHCenter)
|
169
|
-
self.projName.setWordWrap(True)
|
170
|
-
|
171
|
-
self.bookAuthors = QLabel("")
|
172
|
-
authFont = self.bookAuthors.font()
|
173
|
-
authFont.setPointSizeF(1.2*fPt)
|
174
|
-
self.bookAuthors.setFont(authFont)
|
175
|
-
self.bookAuthors.setAlignment(Qt.AlignHCenter)
|
176
|
-
self.bookAuthors.setWordWrap(True)
|
177
|
-
|
178
|
-
# Stats
|
179
|
-
# =====
|
180
|
-
|
181
|
-
self.wordCountLbl = QLabel("<b>%s:</b>" % self.tr("Words"))
|
182
|
-
self.wordCountVal = QLabel("")
|
183
|
-
|
184
|
-
self.chapCountLbl = QLabel("<b>%s:</b>" % self.tr("Chapters"))
|
185
|
-
self.chapCountVal = QLabel("")
|
186
|
-
|
187
|
-
self.sceneCountLbl = QLabel("<b>%s:</b>" % self.tr("Scenes"))
|
188
|
-
self.sceneCountVal = QLabel("")
|
189
|
-
|
190
|
-
self.revCountLbl = QLabel("<b>%s:</b>" % self.tr("Revisions"))
|
191
|
-
self.revCountVal = QLabel("")
|
192
|
-
|
193
|
-
self.editTimeLbl = QLabel("<b>%s:</b>" % self.tr("Editing Time"))
|
194
|
-
self.editTimeVal = QLabel("")
|
195
|
-
|
196
|
-
self.statsGrid = QGridLayout()
|
197
|
-
self.statsGrid.addWidget(self.wordCountLbl, 0, 0, 1, 1, Qt.AlignRight)
|
198
|
-
self.statsGrid.addWidget(self.wordCountVal, 0, 1, 1, 1, Qt.AlignLeft)
|
199
|
-
self.statsGrid.addWidget(self.chapCountLbl, 1, 0, 1, 1, Qt.AlignRight)
|
200
|
-
self.statsGrid.addWidget(self.chapCountVal, 1, 1, 1, 1, Qt.AlignLeft)
|
201
|
-
self.statsGrid.addWidget(self.sceneCountLbl, 2, 0, 1, 1, Qt.AlignRight)
|
202
|
-
self.statsGrid.addWidget(self.sceneCountVal, 2, 1, 1, 1, Qt.AlignLeft)
|
203
|
-
self.statsGrid.addWidget(self.revCountLbl, 3, 0, 1, 1, Qt.AlignRight)
|
204
|
-
self.statsGrid.addWidget(self.revCountVal, 3, 1, 1, 1, Qt.AlignLeft)
|
205
|
-
self.statsGrid.addWidget(self.editTimeLbl, 4, 0, 1, 1, Qt.AlignRight)
|
206
|
-
self.statsGrid.addWidget(self.editTimeVal, 4, 1, 1, 1, Qt.AlignLeft)
|
207
|
-
self.statsGrid.setHorizontalSpacing(hPx)
|
208
|
-
self.statsGrid.setVerticalSpacing(vPx)
|
209
|
-
|
210
|
-
# Meta
|
211
|
-
# ====
|
212
|
-
|
213
|
-
self.projPathLbl = QLabel("<b>%s:</b>" % self.tr("Path"))
|
214
|
-
self.projPathVal = QLineEdit()
|
215
|
-
self.projPathVal.setReadOnly(True)
|
216
|
-
|
217
|
-
self.projPathBox = QHBoxLayout()
|
218
|
-
self.projPathBox.addWidget(self.projPathLbl)
|
219
|
-
self.projPathBox.addWidget(self.projPathVal)
|
220
|
-
self.projPathBox.setSpacing(hPx)
|
221
|
-
|
222
|
-
# Assemble
|
223
|
-
# ========
|
224
|
-
|
225
|
-
self.outerBox = QVBoxLayout()
|
226
|
-
self.outerBox.addSpacing(fPx)
|
227
|
-
self.outerBox.addWidget(self.bookTitle)
|
228
|
-
self.outerBox.addWidget(self.projName)
|
229
|
-
self.outerBox.addWidget(self.bookAuthors)
|
230
|
-
self.outerBox.addSpacing(2*fPx)
|
231
|
-
self.outerBox.addLayout(self.statsGrid)
|
232
|
-
self.outerBox.addSpacing(fPx)
|
233
|
-
self.outerBox.addStretch(1)
|
234
|
-
self.outerBox.addLayout(self.projPathBox)
|
235
|
-
|
236
|
-
self.setLayout(self.outerBox)
|
237
|
-
|
238
|
-
return
|
239
|
-
|
240
|
-
def updateValues(self) -> None:
|
241
|
-
"""Set all the values."""
|
242
|
-
project = SHARED.project
|
243
|
-
pIndex = project.index
|
244
|
-
hCounts = pIndex.getNovelTitleCounts()
|
245
|
-
nwCount = pIndex.getNovelWordCount()
|
246
|
-
edTime = project.currentEditTime
|
247
|
-
|
248
|
-
self.bookTitle.setText(project.data.title or project.data.name)
|
249
|
-
self.projName.setText(self.tr("Project: {0}").format(project.data.name))
|
250
|
-
self.bookAuthors.setText(self.tr("By {0}").format(project.data.author))
|
251
|
-
|
252
|
-
self.wordCountVal.setText(f"{nwCount:n}")
|
253
|
-
self.chapCountVal.setText(f"{hCounts[2]:n}")
|
254
|
-
self.sceneCountVal.setText(f"{hCounts[3]:n}")
|
255
|
-
self.revCountVal.setText(f"{project.data.saveCount:n}")
|
256
|
-
self.editTimeVal.setText(formatTime(edTime))
|
257
|
-
|
258
|
-
self.projPathVal.setText(str(project.storage.storagePath))
|
259
|
-
|
260
|
-
return
|
261
|
-
|
262
|
-
# END Class GuiProjectDetailsMain
|
263
|
-
|
264
|
-
|
265
|
-
class GuiProjectDetailsContents(QWidget):
|
266
|
-
|
267
|
-
C_TITLE = 0
|
268
|
-
C_WORDS = 1
|
269
|
-
C_PAGES = 2
|
270
|
-
C_PAGE = 3
|
271
|
-
C_PROG = 4
|
272
|
-
|
273
|
-
def __init__(self, parent):
|
274
|
-
super().__init__(parent=parent)
|
275
|
-
|
276
|
-
# Internal
|
277
|
-
self._theToC = []
|
278
|
-
self._currentRoot = None
|
279
|
-
|
280
|
-
iPx = SHARED.theme.baseIconSize
|
281
|
-
hPx = CONFIG.pxInt(12)
|
282
|
-
vPx = CONFIG.pxInt(4)
|
283
|
-
pOptions = SHARED.project.options
|
284
|
-
|
285
|
-
# Header
|
286
|
-
# ======
|
287
|
-
|
288
|
-
self.tocLabel = QLabel("<b>%s</b>" % self.tr("Table of Contents"))
|
289
|
-
|
290
|
-
self.novelValue = NovelSelector(self)
|
291
|
-
self.novelValue.setMinimumWidth(CONFIG.pxInt(200))
|
292
|
-
self.novelValue.novelSelectionChanged.connect(self._novelValueChanged)
|
293
|
-
|
294
|
-
self.headBox = QHBoxLayout()
|
295
|
-
self.headBox.addWidget(self.tocLabel)
|
296
|
-
self.headBox.addWidget(self.novelValue)
|
297
|
-
|
298
|
-
# Contents Tree
|
299
|
-
# =============
|
300
|
-
|
301
|
-
self.tocTree = QTreeWidget()
|
302
|
-
self.tocTree.setIconSize(QSize(iPx, iPx))
|
303
|
-
self.tocTree.setIndentation(0)
|
304
|
-
self.tocTree.setColumnCount(6)
|
305
|
-
self.tocTree.setSelectionMode(QAbstractItemView.NoSelection)
|
306
|
-
self.tocTree.setHeaderLabels([
|
307
|
-
self.tr("Title"),
|
308
|
-
self.tr("Words"),
|
309
|
-
self.tr("Pages"),
|
310
|
-
self.tr("Page"),
|
311
|
-
self.tr("Progress"),
|
312
|
-
""
|
313
|
-
])
|
314
|
-
|
315
|
-
treeHeadItem = self.tocTree.headerItem()
|
316
|
-
if treeHeadItem:
|
317
|
-
treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
|
318
|
-
treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
|
319
|
-
treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
|
320
|
-
treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignRight)
|
321
|
-
|
322
|
-
treeHeader = self.tocTree.header()
|
323
|
-
treeHeader.setStretchLastSection(True)
|
324
|
-
treeHeader.setMinimumSectionSize(hPx)
|
325
|
-
|
326
|
-
wCol0 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol0", 200))
|
327
|
-
wCol1 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol1", 60))
|
328
|
-
wCol2 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol2", 60))
|
329
|
-
wCol3 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol3", 60))
|
330
|
-
wCol4 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol4", 90))
|
331
|
-
|
332
|
-
self.tocTree.setColumnWidth(0, wCol0)
|
333
|
-
self.tocTree.setColumnWidth(1, wCol1)
|
334
|
-
self.tocTree.setColumnWidth(2, wCol2)
|
335
|
-
self.tocTree.setColumnWidth(3, wCol3)
|
336
|
-
self.tocTree.setColumnWidth(4, wCol4)
|
337
|
-
self.tocTree.setColumnWidth(5, hPx)
|
338
|
-
|
339
|
-
# Options
|
340
|
-
# =======
|
341
|
-
|
342
|
-
wordsPerPage = pOptions.getInt("GuiProjectDetails", "wordsPerPage", 350)
|
343
|
-
countFrom = pOptions.getInt("GuiProjectDetails", "countFrom", 1)
|
344
|
-
clearDouble = pOptions.getBool("GuiProjectDetails", "clearDouble", True)
|
345
|
-
|
346
|
-
wordsHelp = (
|
347
|
-
self.tr("Typical word count for a 5 by 8 inch book page with 11 pt font is 350.")
|
348
|
-
)
|
349
|
-
offsetHelp = (
|
350
|
-
self.tr("Start counting page numbers from this page.")
|
351
|
-
)
|
352
|
-
dblHelp = (
|
353
|
-
self.tr("Assume a new chapter or partition always start on an odd numbered page.")
|
354
|
-
)
|
355
|
-
|
356
|
-
self.wpLabel = QLabel(self.tr("Words per page"))
|
357
|
-
self.wpLabel.setToolTip(wordsHelp)
|
358
|
-
|
359
|
-
self.wpValue = QSpinBox()
|
360
|
-
self.wpValue.setMinimum(10)
|
361
|
-
self.wpValue.setMaximum(1000)
|
362
|
-
self.wpValue.setSingleStep(10)
|
363
|
-
self.wpValue.setValue(wordsPerPage)
|
364
|
-
self.wpValue.setToolTip(wordsHelp)
|
365
|
-
self.wpValue.valueChanged.connect(self._populateTree)
|
366
|
-
|
367
|
-
self.poLabel = QLabel(self.tr("Count pages from"))
|
368
|
-
self.poLabel.setToolTip(offsetHelp)
|
369
|
-
|
370
|
-
self.poValue = QSpinBox()
|
371
|
-
self.poValue.setMinimum(1)
|
372
|
-
self.poValue.setMaximum(9999)
|
373
|
-
self.poValue.setSingleStep(1)
|
374
|
-
self.poValue.setValue(countFrom)
|
375
|
-
self.poValue.setToolTip(offsetHelp)
|
376
|
-
self.poValue.valueChanged.connect(self._populateTree)
|
377
|
-
|
378
|
-
self.dblLabel = QLabel(self.tr("Clear double pages"))
|
379
|
-
self.dblLabel.setToolTip(dblHelp)
|
380
|
-
|
381
|
-
self.dblValue = NSwitch(self, 2*iPx, iPx)
|
382
|
-
self.dblValue.setChecked(clearDouble)
|
383
|
-
self.dblValue.setToolTip(dblHelp)
|
384
|
-
self.dblValue.clicked.connect(self._populateTree)
|
385
|
-
|
386
|
-
self.optionsBox = QGridLayout()
|
387
|
-
self.optionsBox.addWidget(self.wpLabel, 0, 0)
|
388
|
-
self.optionsBox.addWidget(self.wpValue, 0, 1)
|
389
|
-
self.optionsBox.addWidget(self.dblLabel, 0, 3)
|
390
|
-
self.optionsBox.addWidget(self.dblValue, 0, 4)
|
391
|
-
self.optionsBox.addWidget(self.poLabel, 1, 0)
|
392
|
-
self.optionsBox.addWidget(self.poValue, 1, 1)
|
393
|
-
self.optionsBox.setHorizontalSpacing(hPx)
|
394
|
-
self.optionsBox.setVerticalSpacing(vPx)
|
395
|
-
self.optionsBox.setColumnStretch(2, 1)
|
396
|
-
|
397
|
-
# Assemble
|
398
|
-
# ========
|
399
|
-
|
400
|
-
self.outerBox = QVBoxLayout()
|
401
|
-
self.outerBox.addLayout(self.headBox)
|
402
|
-
self.outerBox.addWidget(self.tocTree)
|
403
|
-
self.outerBox.addLayout(self.optionsBox)
|
404
|
-
|
405
|
-
self.setLayout(self.outerBox)
|
406
|
-
|
407
|
-
return
|
408
|
-
|
409
|
-
def getColumnSizes(self):
|
410
|
-
"""Return the column widths for the tree columns.
|
411
|
-
"""
|
412
|
-
retVals = [
|
413
|
-
self.tocTree.columnWidth(0),
|
414
|
-
self.tocTree.columnWidth(1),
|
415
|
-
self.tocTree.columnWidth(2),
|
416
|
-
self.tocTree.columnWidth(3),
|
417
|
-
self.tocTree.columnWidth(4),
|
418
|
-
]
|
419
|
-
return retVals
|
420
|
-
|
421
|
-
def updateValues(self):
|
422
|
-
"""Populate the tree.
|
423
|
-
"""
|
424
|
-
self._currentRoot = None
|
425
|
-
self.novelValue.updateList()
|
426
|
-
self.novelValue.setHandle(self.novelValue.firstHandle)
|
427
|
-
self._prepareData(self.novelValue.firstHandle)
|
428
|
-
self._populateTree()
|
429
|
-
|
430
|
-
return
|
431
|
-
|
432
|
-
##
|
433
|
-
# Internal Functions
|
434
|
-
##
|
435
|
-
|
436
|
-
def _prepareData(self, rootHandle):
|
437
|
-
"""Extract the information from the project index.
|
438
|
-
"""
|
439
|
-
logger.debug("Populating ToC from handle '%s'", rootHandle)
|
440
|
-
self._theToC = SHARED.project.index.getTableOfContents(rootHandle, 2)
|
441
|
-
self._theToC.append(("", 0, self.tr("END"), 0))
|
442
|
-
return
|
443
|
-
|
444
|
-
##
|
445
|
-
# Slots
|
446
|
-
##
|
447
|
-
|
448
|
-
@pyqtSlot(str)
|
449
|
-
def _novelValueChanged(self, tHandle):
|
450
|
-
"""Refresh the tree with another root item.
|
451
|
-
"""
|
452
|
-
if tHandle != self._currentRoot:
|
453
|
-
self._prepareData(tHandle)
|
454
|
-
self._populateTree()
|
455
|
-
self._currentRoot = self.novelValue.handle
|
456
|
-
return
|
457
|
-
|
458
|
-
@pyqtSlot()
|
459
|
-
def _populateTree(self):
|
460
|
-
"""Set the content of the chapter/page tree.
|
461
|
-
"""
|
462
|
-
dblPages = self.dblValue.isChecked()
|
463
|
-
wpPage = self.wpValue.value()
|
464
|
-
fstPage = self.poValue.value() - 1
|
465
|
-
|
466
|
-
pTotal = 0
|
467
|
-
tPages = 1
|
468
|
-
|
469
|
-
theList = []
|
470
|
-
for _, tLevel, tTitle, wCount in self._theToC:
|
471
|
-
pCount = math.ceil(wCount/wpPage)
|
472
|
-
if dblPages:
|
473
|
-
pCount += pCount%2
|
474
|
-
|
475
|
-
pTotal += pCount
|
476
|
-
theList.append((tLevel, tTitle, wCount, pCount))
|
477
|
-
|
478
|
-
pMax = pTotal - fstPage
|
479
|
-
|
480
|
-
self.tocTree.clear()
|
481
|
-
for tLevel, tTitle, wCount, pCount in theList:
|
482
|
-
newItem = QTreeWidgetItem()
|
483
|
-
|
484
|
-
if tPages <= fstPage:
|
485
|
-
progPage = numberToRoman(tPages, True)
|
486
|
-
progText = ""
|
487
|
-
else:
|
488
|
-
cPage = tPages - fstPage
|
489
|
-
pgProg = 100.0*(cPage - 1)/pMax if pMax > 0 else 0.0
|
490
|
-
progPage = f"{cPage:n}"
|
491
|
-
progText = f"{pgProg:.1f}{nwUnicode.U_THSP}%"
|
492
|
-
|
493
|
-
hDec = SHARED.theme.getHeaderDecoration(tLevel)
|
494
|
-
if tTitle.strip() == "":
|
495
|
-
tTitle = self.tr("Untitled")
|
496
|
-
|
497
|
-
newItem.setData(self.C_TITLE, Qt.DecorationRole, hDec)
|
498
|
-
newItem.setText(self.C_TITLE, tTitle)
|
499
|
-
newItem.setText(self.C_WORDS, f"{wCount:n}")
|
500
|
-
newItem.setText(self.C_PAGES, f"{pCount:n}")
|
501
|
-
newItem.setText(self.C_PAGE, progPage)
|
502
|
-
newItem.setText(self.C_PROG, progText)
|
503
|
-
|
504
|
-
newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
|
505
|
-
newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
|
506
|
-
newItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
|
507
|
-
newItem.setTextAlignment(self.C_PROG, Qt.AlignRight)
|
508
|
-
|
509
|
-
# Make pages and titles/partitions stand out
|
510
|
-
if tLevel < 2:
|
511
|
-
bFont = newItem.font(self.C_TITLE)
|
512
|
-
if tLevel == 0:
|
513
|
-
bFont.setItalic(True)
|
514
|
-
else:
|
515
|
-
bFont.setBold(True)
|
516
|
-
bFont.setUnderline(True)
|
517
|
-
newItem.setFont(self.C_TITLE, bFont)
|
518
|
-
|
519
|
-
tPages += pCount
|
520
|
-
|
521
|
-
self.tocTree.addTopLevelItem(newItem)
|
522
|
-
|
523
|
-
return
|
524
|
-
|
525
|
-
# END Class GuiProjectDetailsContents
|