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
novelwriter/core/spellcheck.py
CHANGED
@@ -27,14 +27,14 @@ from __future__ import annotations
|
|
27
27
|
import json
|
28
28
|
import logging
|
29
29
|
|
30
|
-
from typing import TYPE_CHECKING
|
31
|
-
from pathlib import Path
|
32
30
|
from collections.abc import Iterator
|
31
|
+
from pathlib import Path
|
32
|
+
from typing import TYPE_CHECKING
|
33
33
|
|
34
34
|
from PyQt5.QtCore import QLocale
|
35
35
|
|
36
|
-
from novelwriter.error import logException
|
37
36
|
from novelwriter.constants import nwFiles
|
37
|
+
from novelwriter.error import logException
|
38
38
|
|
39
39
|
if TYPE_CHECKING: # pragma: no cover
|
40
40
|
from novelwriter.core.project import NWProject
|
@@ -164,11 +164,10 @@ class NWSpellEnchant:
|
|
164
164
|
name = ""
|
165
165
|
return tag, name
|
166
166
|
|
167
|
-
# END Class NWSpellEnchant
|
168
|
-
|
169
167
|
|
170
168
|
class FakeEnchant:
|
171
169
|
"""Fallback for when Enchant is selected, but not installed."""
|
170
|
+
|
172
171
|
def __init__(self) -> None:
|
173
172
|
|
174
173
|
class FakeProvider:
|
@@ -188,8 +187,6 @@ class FakeEnchant:
|
|
188
187
|
def add_to_session(self, word: str) -> None:
|
189
188
|
return
|
190
189
|
|
191
|
-
# END Class FakeEnchant
|
192
|
-
|
193
190
|
|
194
191
|
class UserDictionary:
|
195
192
|
|
@@ -240,5 +237,3 @@ class UserDictionary:
|
|
240
237
|
logger.error("Failed to save user dictionary")
|
241
238
|
logException()
|
242
239
|
return
|
243
|
-
|
244
|
-
# END Class UserDictionary
|
novelwriter/core/status.py
CHANGED
@@ -24,17 +24,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
24
24
|
"""
|
25
25
|
from __future__ import annotations
|
26
26
|
|
27
|
-
import
|
27
|
+
import dataclasses
|
28
28
|
import logging
|
29
|
+
import random
|
29
30
|
|
31
|
+
from collections.abc import Iterable
|
30
32
|
from typing import TYPE_CHECKING, Literal
|
31
|
-
from collections.abc import ItemsView, Iterable, Iterator, KeysView, ValuesView
|
32
33
|
|
33
|
-
from PyQt5.
|
34
|
-
from PyQt5.
|
34
|
+
from PyQt5.QtCore import QPointF, Qt
|
35
|
+
from PyQt5.QtGui import QColor, QIcon, QPainter, QPainterPath, QPixmap, QPolygonF
|
35
36
|
|
36
|
-
from novelwriter import
|
37
|
-
from novelwriter.common import
|
37
|
+
from novelwriter import SHARED
|
38
|
+
from novelwriter.common import simplified
|
39
|
+
from novelwriter.enum import nwStatusShape
|
38
40
|
from novelwriter.types import QtPaintAnitAlias, QtTransparent
|
39
41
|
|
40
42
|
if TYPE_CHECKING: # pragma: no cover
|
@@ -43,83 +45,92 @@ if TYPE_CHECKING: # pragma: no cover
|
|
43
45
|
logger = logging.getLogger(__name__)
|
44
46
|
|
45
47
|
|
46
|
-
|
48
|
+
@dataclasses.dataclass
|
49
|
+
class StatusEntry:
|
47
50
|
|
48
|
-
|
49
|
-
|
51
|
+
name: str
|
52
|
+
color: QColor
|
53
|
+
shape: nwStatusShape
|
54
|
+
icon: QIcon
|
55
|
+
count: int = 0
|
50
56
|
|
51
|
-
|
57
|
+
@classmethod
|
58
|
+
def duplicate(cls, source: StatusEntry) -> StatusEntry:
|
59
|
+
"""Create a deep copy of the source object."""
|
60
|
+
cls = dataclasses.replace(source)
|
61
|
+
cls.color = QColor(source.color)
|
62
|
+
cls.icon = QIcon(source.icon)
|
63
|
+
return cls
|
52
64
|
|
53
|
-
self._type = kind
|
54
|
-
self._store = {}
|
55
|
-
self._default = None
|
56
65
|
|
57
|
-
|
66
|
+
NO_ENTRY = StatusEntry("", QColor(0, 0, 0), nwStatusShape.SQUARE, QIcon(), 0)
|
67
|
+
|
58
68
|
|
59
|
-
|
60
|
-
pB = CONFIG.pxInt(20)
|
61
|
-
pR = float(CONFIG.pxInt(4))
|
62
|
-
self._iconPath = QPainterPath()
|
63
|
-
self._iconPath.addRoundedRect(QRectF(pA, pA, pB, pB), pR, pR)
|
69
|
+
class NWStatus:
|
64
70
|
|
65
|
-
|
71
|
+
STATUS = "s"
|
72
|
+
IMPORT = "i"
|
66
73
|
|
67
|
-
|
68
|
-
self._prefix = "s"
|
69
|
-
elif self._type == self.IMPORT:
|
70
|
-
self._prefix = "i"
|
71
|
-
else:
|
72
|
-
raise Exception("This is a bug!")
|
74
|
+
__slots__ = ("_store", "_default", "_prefix", "_height")
|
73
75
|
|
76
|
+
def __init__(self, prefix: Literal["s", "i"]) -> None:
|
77
|
+
self._store: dict[str, StatusEntry] = {}
|
78
|
+
self._default = None
|
79
|
+
self._prefix = prefix[:1]
|
80
|
+
self._height = SHARED.theme.baseIconHeight
|
74
81
|
return
|
75
82
|
|
76
|
-
def
|
83
|
+
def __len__(self) -> int:
|
84
|
+
return len(self._store)
|
85
|
+
|
86
|
+
def __getitem__(self, key: str | None) -> StatusEntry:
|
87
|
+
"""Return the entry associated with a given key."""
|
88
|
+
if key and key in self._store:
|
89
|
+
return self._store[key]
|
90
|
+
elif self._default is not None:
|
91
|
+
return self._store[self._default]
|
92
|
+
return NO_ENTRY
|
93
|
+
|
94
|
+
##
|
95
|
+
# Methods
|
96
|
+
##
|
97
|
+
|
98
|
+
def add(self, key: str | None, name: str, color: tuple[int, int, int],
|
99
|
+
shape: str, count: int) -> str:
|
77
100
|
"""Add or update a status entry. If the key is invalid, a new
|
78
101
|
key is generated.
|
79
102
|
"""
|
80
|
-
if
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
cB = minmax(col[2], 0, 255)
|
90
|
-
name = simplified(name)
|
91
|
-
if count is None:
|
92
|
-
count = self._store.get(key, {}).get("count", 0)
|
103
|
+
if isinstance(color, tuple) and len(color) == 3:
|
104
|
+
qColor = QColor(*color)
|
105
|
+
else:
|
106
|
+
qColor = QColor(100, 100, 100)
|
107
|
+
|
108
|
+
try:
|
109
|
+
iShape = nwStatusShape[shape]
|
110
|
+
except KeyError:
|
111
|
+
iShape = nwStatusShape.SQUARE
|
93
112
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
"count": count,
|
99
|
-
}
|
113
|
+
key = self._checkKey(key)
|
114
|
+
name = simplified(name)
|
115
|
+
icon = self.createIcon(self._height, qColor, iShape)
|
116
|
+
self._store[key] = StatusEntry(name, qColor, iShape, icon, count)
|
100
117
|
|
101
118
|
if self._default is None:
|
102
119
|
self._default = key
|
103
120
|
|
104
121
|
return key
|
105
122
|
|
106
|
-
def
|
107
|
-
"""
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
return False
|
112
|
-
|
113
|
-
del self._store[key]
|
123
|
+
def update(self, update: list[tuple[str | None, StatusEntry]]) -> None:
|
124
|
+
"""Update the list of statuses, and from removed list."""
|
125
|
+
self._store.clear()
|
126
|
+
for key, entry in update:
|
127
|
+
self._store[self._checkKey(key)] = entry
|
114
128
|
|
115
|
-
|
116
|
-
if
|
117
|
-
|
118
|
-
self._default = keys[0]
|
119
|
-
else:
|
120
|
-
self._default = None
|
129
|
+
# Check if we need a new default
|
130
|
+
if self._default not in self._store:
|
131
|
+
self._default = next(iter(self._store)) if self._store else None
|
121
132
|
|
122
|
-
return
|
133
|
+
return
|
123
134
|
|
124
135
|
def check(self, value: str) -> str:
|
125
136
|
"""Check the key against the stored status names."""
|
@@ -129,93 +140,51 @@ class NWStatus:
|
|
129
140
|
return self._default
|
130
141
|
return ""
|
131
142
|
|
132
|
-
def name(self, key: str | None) -> str:
|
133
|
-
"""Return the name associated with a given key."""
|
134
|
-
if key and key in self._store:
|
135
|
-
return self._store[key]["name"]
|
136
|
-
elif self._default is not None:
|
137
|
-
return self._store[self._default]["name"]
|
138
|
-
return ""
|
139
|
-
|
140
|
-
def cols(self, key: str | None) -> tuple[int, int, int]:
|
141
|
-
"""Return the colours associated with a given key."""
|
142
|
-
if key and key in self._store:
|
143
|
-
return self._store[key]["cols"]
|
144
|
-
elif self._default is not None:
|
145
|
-
return self._store[self._default]["cols"]
|
146
|
-
return 100, 100, 100
|
147
|
-
|
148
|
-
def count(self, key: str | None) -> int:
|
149
|
-
"""Return the count associated with a given key."""
|
150
|
-
if key and key in self._store:
|
151
|
-
return self._store[key]["count"]
|
152
|
-
elif self._default is not None:
|
153
|
-
return self._store[self._default]["count"]
|
154
|
-
return 0
|
155
|
-
|
156
|
-
def icon(self, key: str | None) -> QIcon:
|
157
|
-
"""Return the icon associated with a given key."""
|
158
|
-
if key and key in self._store:
|
159
|
-
return self._store[key]["icon"]
|
160
|
-
elif self._default is not None:
|
161
|
-
return self._store[self._default]["icon"]
|
162
|
-
return self._defaultIcon
|
163
|
-
|
164
|
-
def reorder(self, order: list[str]) -> bool:
|
165
|
-
"""Reorder the items according to list."""
|
166
|
-
if len(order) != len(self._store):
|
167
|
-
logger.error("Length mismatch between new and old order")
|
168
|
-
return False
|
169
|
-
|
170
|
-
if order == list(self._store.keys()):
|
171
|
-
return False
|
172
|
-
|
173
|
-
store = {}
|
174
|
-
for key in order:
|
175
|
-
if key in self._store:
|
176
|
-
store[key] = self._store[key]
|
177
|
-
else:
|
178
|
-
logger.error("Unknown key '%s' in order", key)
|
179
|
-
return False
|
180
|
-
|
181
|
-
self._store = store
|
182
|
-
|
183
|
-
return True
|
184
|
-
|
185
143
|
def resetCounts(self) -> None:
|
186
144
|
"""Clear the counts of references to the status entries."""
|
187
|
-
for
|
188
|
-
|
145
|
+
for entry in self._store.values():
|
146
|
+
entry.count = 0
|
189
147
|
return
|
190
148
|
|
191
149
|
def increment(self, key: str | None) -> None:
|
192
150
|
"""Increment the counter for a given entry."""
|
193
151
|
if key and key in self._store:
|
194
|
-
self._store[key]
|
152
|
+
self._store[key].count += 1
|
195
153
|
return
|
196
154
|
|
197
155
|
def pack(self) -> Iterable[tuple[str, dict]]:
|
198
156
|
"""Pack the status entries into a dictionary."""
|
199
|
-
for key,
|
200
|
-
yield (
|
157
|
+
for key, entry in self._store.items():
|
158
|
+
yield (entry.name, {
|
201
159
|
"key": key,
|
202
|
-
"count": str(
|
203
|
-
"red": str(
|
204
|
-
"green": str(
|
205
|
-
"blue": str(
|
160
|
+
"count": str(entry.count),
|
161
|
+
"red": str(entry.color.red()),
|
162
|
+
"green": str(entry.color.green()),
|
163
|
+
"blue": str(entry.color.blue()),
|
164
|
+
"shape": entry.shape.name,
|
206
165
|
})
|
207
166
|
return
|
208
167
|
|
209
|
-
def
|
210
|
-
"""
|
211
|
-
self._store
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
168
|
+
def iterItems(self) -> Iterable[tuple[str, StatusEntry]]:
|
169
|
+
"""Yield entries from the status icons."""
|
170
|
+
yield from self._store.items()
|
171
|
+
|
172
|
+
@staticmethod
|
173
|
+
def createIcon(height: int, color: QColor, shape: nwStatusShape) -> QIcon:
|
174
|
+
"""Generate an icon for a status label."""
|
175
|
+
pixmap = QPixmap(48, 48)
|
176
|
+
pixmap.fill(QtTransparent)
|
177
|
+
|
178
|
+
painter = QPainter(pixmap)
|
179
|
+
painter.setRenderHint(QtPaintAnitAlias)
|
180
|
+
painter.fillPath(_SHAPES.getShape(shape), color)
|
181
|
+
painter.end()
|
182
|
+
|
183
|
+
return QIcon(pixmap.scaled(
|
184
|
+
height, height,
|
185
|
+
Qt.AspectRatioMode.IgnoreAspectRatio,
|
186
|
+
Qt.TransformationMode.SmoothTransformation
|
187
|
+
))
|
219
188
|
|
220
189
|
##
|
221
190
|
# Internal Functions
|
@@ -246,38 +215,116 @@ class NWStatus:
|
|
246
215
|
return False
|
247
216
|
return True
|
248
217
|
|
249
|
-
def
|
250
|
-
"""
|
251
|
-
|
252
|
-
pixmap.fill(QtTransparent)
|
253
|
-
|
254
|
-
painter = QPainter(pixmap)
|
255
|
-
painter.setRenderHint(QtPaintAnitAlias)
|
256
|
-
painter.fillPath(self._iconPath, QColor(red, green, blue))
|
257
|
-
painter.end()
|
258
|
-
|
259
|
-
return QIcon(pixmap)
|
218
|
+
def _checkKey(self, key: str | None) -> str:
|
219
|
+
"""Check key is valid, and if not, generate one."""
|
220
|
+
return key if self._isKey(key) else self._newKey()
|
260
221
|
|
261
|
-
##
|
262
|
-
# Iterator Bits
|
263
|
-
##
|
264
|
-
|
265
|
-
def __len__(self) -> int:
|
266
|
-
return len(self._store)
|
267
222
|
|
268
|
-
|
269
|
-
return self._store[key]
|
223
|
+
class _ShapeCache:
|
270
224
|
|
271
|
-
def
|
272
|
-
|
273
|
-
|
274
|
-
def keys(self) -> KeysView[str]:
|
275
|
-
return self._store.keys()
|
276
|
-
|
277
|
-
def items(self) -> ItemsView[str, dict]:
|
278
|
-
return self._store.items()
|
279
|
-
|
280
|
-
def values(self) -> ValuesView[dict]:
|
281
|
-
return self._store.values()
|
225
|
+
def __init__(self) -> None:
|
226
|
+
self._cache: dict[nwStatusShape, QPainterPath] = {}
|
227
|
+
return
|
282
228
|
|
283
|
-
|
229
|
+
def getShape(self, shape: nwStatusShape) -> QPainterPath:
|
230
|
+
"""Return a painter shape for an icon."""
|
231
|
+
if shape in self._cache:
|
232
|
+
return self._cache[shape]
|
233
|
+
|
234
|
+
path = QPainterPath()
|
235
|
+
if shape == nwStatusShape.SQUARE:
|
236
|
+
path.addRoundedRect(2.0, 2.0, 44.0, 44.0, 4.0, 4.0)
|
237
|
+
elif shape == nwStatusShape.TRIANGLE:
|
238
|
+
path.addPolygon(QPolygonF([
|
239
|
+
QPointF(24.00, 3.00),
|
240
|
+
QPointF(43.92, 37.50),
|
241
|
+
QPointF(4.08, 37.50),
|
242
|
+
]))
|
243
|
+
elif shape == nwStatusShape.NABLA:
|
244
|
+
path.addPolygon(QPolygonF([
|
245
|
+
QPointF(24.00, 48.00),
|
246
|
+
QPointF(4.08, 14.50),
|
247
|
+
QPointF(43.92, 14.50),
|
248
|
+
]))
|
249
|
+
elif shape == nwStatusShape.DIAMOND:
|
250
|
+
path.addPolygon(QPolygonF([
|
251
|
+
QPointF(24.00, 2.00),
|
252
|
+
QPointF(44.00, 24.00),
|
253
|
+
QPointF(24.00, 46.00),
|
254
|
+
QPointF(4.00, 24.00),
|
255
|
+
]))
|
256
|
+
elif shape == nwStatusShape.PENTAGON:
|
257
|
+
path.addPolygon(QPolygonF([
|
258
|
+
QPointF(24.00, 1.50),
|
259
|
+
QPointF(45.87, 17.39),
|
260
|
+
QPointF(37.52, 43.11),
|
261
|
+
QPointF(10.48, 43.11),
|
262
|
+
QPointF(2.13, 17.39),
|
263
|
+
]))
|
264
|
+
elif shape == nwStatusShape.HEXAGON:
|
265
|
+
path.addPolygon(QPolygonF([
|
266
|
+
QPointF(24.00, 1.50),
|
267
|
+
QPointF(43.92, 13.00),
|
268
|
+
QPointF(43.92, 36.00),
|
269
|
+
QPointF(24.00, 47.50),
|
270
|
+
QPointF(4.08, 36.00),
|
271
|
+
QPointF(4.08, 13.00),
|
272
|
+
]))
|
273
|
+
elif shape == nwStatusShape.STAR:
|
274
|
+
path.addPolygon(QPolygonF([
|
275
|
+
QPointF(24.00, 0.50), QPointF(31.05, 14.79),
|
276
|
+
QPointF(46.83, 17.08), QPointF(35.41, 28.21),
|
277
|
+
QPointF(38.11, 43.92), QPointF(24.00, 36.50),
|
278
|
+
QPointF(9.89, 43.92), QPointF(12.59, 28.21),
|
279
|
+
QPointF(1.17, 17.08), QPointF(15.37, 16.16),
|
280
|
+
]))
|
281
|
+
elif shape == nwStatusShape.PACMAN:
|
282
|
+
path.moveTo(24.0, 24.0)
|
283
|
+
path.arcTo(2.0, 2.0, 44.0, 44.0, 40.0, 280.0)
|
284
|
+
elif shape == nwStatusShape.CIRCLE_Q:
|
285
|
+
path.moveTo(24.0, 24.0)
|
286
|
+
path.arcTo(2.0, 2.0, 44.0, 44.0, 0.0, 90.0)
|
287
|
+
elif shape == nwStatusShape.CIRCLE_H:
|
288
|
+
path.moveTo(24.0, 24.0)
|
289
|
+
path.arcTo(2.0, 2.0, 44.0, 44.0, -90.0, 180.0)
|
290
|
+
elif shape == nwStatusShape.CIRCLE_T:
|
291
|
+
path.moveTo(24.0, 24.0)
|
292
|
+
path.arcTo(2.0, 2.0, 44.0, 44.0, -180.0, 270.0)
|
293
|
+
elif shape == nwStatusShape.CIRCLE:
|
294
|
+
path.addEllipse(2.0, 2.0, 44.0, 44.0)
|
295
|
+
elif shape == nwStatusShape.BARS_1:
|
296
|
+
path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
297
|
+
elif shape == nwStatusShape.BARS_2:
|
298
|
+
path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
299
|
+
path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
300
|
+
elif shape == nwStatusShape.BARS_3:
|
301
|
+
path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
302
|
+
path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
303
|
+
path.addRoundedRect(26.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
304
|
+
elif shape == nwStatusShape.BARS_4:
|
305
|
+
path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
306
|
+
path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
307
|
+
path.addRoundedRect(26.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
308
|
+
path.addRoundedRect(38.0, 2.0, 8.0, 44.0, 4.0, 4.0)
|
309
|
+
elif shape == nwStatusShape.BLOCK_1:
|
310
|
+
path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
311
|
+
elif shape == nwStatusShape.BLOCK_2:
|
312
|
+
path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
313
|
+
path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
314
|
+
elif shape == nwStatusShape.BLOCK_3:
|
315
|
+
path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
316
|
+
path.addRoundedRect(2.0, 24.0, 20.0, 20.0, 4.0, 4.0)
|
317
|
+
path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
318
|
+
elif shape == nwStatusShape.BLOCK_4:
|
319
|
+
path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
320
|
+
path.addRoundedRect(2.0, 24.0, 20.0, 20.0, 4.0, 4.0)
|
321
|
+
path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0)
|
322
|
+
path.addRoundedRect(24.0, 24.0, 20.0, 20.0, 4.0, 4.0)
|
323
|
+
|
324
|
+
self._cache[shape] = path
|
325
|
+
|
326
|
+
return path
|
327
|
+
|
328
|
+
|
329
|
+
# Create Singleton
|
330
|
+
_SHAPES = _ShapeCache()
|
novelwriter/core/storage.py
CHANGED
@@ -54,8 +54,6 @@ class NWStorageOpen(Enum):
|
|
54
54
|
FAILED = 3
|
55
55
|
READY = 4
|
56
56
|
|
57
|
-
# END Enum NWStorageOpen
|
58
|
-
|
59
57
|
|
60
58
|
class NWStorageCreate(Enum):
|
61
59
|
|
@@ -63,8 +61,6 @@ class NWStorageCreate(Enum):
|
|
63
61
|
OS_ERROR = 1
|
64
62
|
READY = 2
|
65
63
|
|
66
|
-
# END Enum NWStorageCreate
|
67
|
-
|
68
64
|
|
69
65
|
class NWStorage:
|
70
66
|
"""Core: Project Storage Class
|
@@ -391,8 +387,6 @@ class NWStorage:
|
|
391
387
|
self._lockedBy = None
|
392
388
|
return True
|
393
389
|
|
394
|
-
# END Class NWStorage
|
395
|
-
|
396
390
|
|
397
391
|
class _LegacyStorage:
|
398
392
|
"""Core: Legacy Storage Converter Utils
|
@@ -590,5 +584,3 @@ class _LegacyStorage:
|
|
590
584
|
logException()
|
591
585
|
|
592
586
|
return
|
593
|
-
|
594
|
-
# END Class _LegacyStorage
|