novelWriter 2.2rc1__py3-none-any.whl → 2.3__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.3.dist-info}/METADATA +1 -1
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3.dist-info}/RECORD +149 -132
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3.dist-info}/WHEEL +1 -1
- novelWriter-2.3.dist-info/entry_points.txt +2 -0
- 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_nl_NL.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_nl_NL.json +11 -0
- novelwriter/assets/i18n/project_pt_BR.json +11 -0
- novelwriter/assets/i18n/project_zh_CN.json +11 -0
- novelwriter/assets/icons/typicons_dark/icons.conf +11 -2
- novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +6 -0
- 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.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_dark/typ_th-list.svg +9 -0
- novelwriter/assets/icons/typicons_light/icons.conf +11 -2
- novelwriter/assets/icons/typicons_light/mixed_document-new.svg +6 -0
- 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.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/icons/typicons_light/typ_th-list.svg +9 -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/cyberpunk_night.conf +26 -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/tango.conf +23 -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/cyberpunk_night.conf +29 -0
- 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 +198 -157
- 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 +73 -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 +183 -141
- novelwriter/core/tohtml.py +6 -4
- novelwriter/core/tokenizer.py +110 -83
- 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 -47
- novelwriter/gui/noveltree.py +53 -61
- novelwriter/gui/outline.py +100 -76
- novelwriter/gui/projtree.py +246 -112
- novelwriter/gui/sidebar.py +9 -8
- novelwriter/gui/statusbar.py +49 -7
- novelwriter/gui/theme.py +74 -76
- novelwriter/guimain.py +175 -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 +819 -0
- novelwriter/tools/writingstats.py +26 -13
- novelWriter-2.2rc1.dist-info/entry_points.txt +0 -5
- 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.3.dist-info}/LICENSE.md +0 -0
- {novelWriter-2.2rc1.dist-info → novelWriter-2.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
[Main]
|
2
|
+
name = Cyberpunk Night
|
3
|
+
author = Anders Lemvigh
|
4
|
+
url = https://github.com/alemvigh
|
5
|
+
license = CC BY-SA 4.0
|
6
|
+
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
|
7
|
+
|
8
|
+
[Syntax]
|
9
|
+
background = 0, 0, 0
|
10
|
+
text = 150, 150, 150
|
11
|
+
link = 77, 077, 255
|
12
|
+
headertext = 255, 255, 255
|
13
|
+
headertag = 50, 0, 180
|
14
|
+
emphasis = 0, 255, 255
|
15
|
+
straightquotes = 7, 27, 219
|
16
|
+
doublequotes = 0, 255, 0
|
17
|
+
singlequotes = 0, 140, 255
|
18
|
+
hidden = 77, 77, 100
|
19
|
+
shortcode = 255, 255, 0
|
20
|
+
keyword = 255, 100, 255
|
21
|
+
value = 255, 150, 10
|
22
|
+
spellcheckline = 242, 72, 23
|
23
|
+
errorline = 186, 218, 4
|
24
|
+
replacetag = 0, 0, 180
|
25
|
+
modifier = 144, 142, 176
|
26
|
+
optional = 180, 180, 180
|
@@ -0,0 +1,23 @@
|
|
1
|
+
[Main]
|
2
|
+
name = Tango
|
3
|
+
author = Veronica Berglyd Olsen (adaptation)
|
4
|
+
|
5
|
+
[Syntax]
|
6
|
+
background = 48, 48, 47
|
7
|
+
text = 238, 238, 236
|
8
|
+
link = 115, 159, 207
|
9
|
+
headertext = 115, 159, 207
|
10
|
+
headertag = 52, 101, 164
|
11
|
+
emphasis = 196, 160, 0
|
12
|
+
straightquotes = 239, 41, 41
|
13
|
+
doublequotes = 138, 226, 52
|
14
|
+
singlequotes = 252, 233, 79
|
15
|
+
hidden = 143, 143, 141
|
16
|
+
shortcode = 115, 159, 207
|
17
|
+
keyword = 239, 41, 41
|
18
|
+
value = 173, 127, 168
|
19
|
+
optional = 115, 159, 207
|
20
|
+
spellcheckline = 239, 41, 41
|
21
|
+
errorline = 138, 226, 52
|
22
|
+
replacetag = 51, 226, 226
|
23
|
+
modifier = 196, 160, 0
|
@@ -2,8 +2,6 @@
|
|
2
2
|
<html>
|
3
3
|
<body>
|
4
4
|
|
5
|
-
<h2>Credits</h2>
|
6
|
-
|
7
5
|
<h3>Main Developer</h3>
|
8
6
|
<p>Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)</p>
|
9
7
|
|
@@ -17,6 +15,10 @@
|
|
17
15
|
<p>For other contributions, see the project's
|
18
16
|
<a href="https://github.com/vkbo/novelWriter/graphs/contributors">Contributors</a> page.</p>
|
19
17
|
|
18
|
+
<h3>Artwork</h3>
|
19
|
+
|
20
|
+
<p>The artwork on the Welcome dialog was created by <a href="https://louisdurrant.art">Louis Durrant</a>.</p>
|
21
|
+
|
20
22
|
<h3>Translations</h3>
|
21
23
|
|
22
24
|
<p>The default language is English (UK) with English (US) as an option. These are the original
|
@@ -0,0 +1,29 @@
|
|
1
|
+
[Main]
|
2
|
+
name = Cyberpunk Night
|
3
|
+
description = A taste of the future 80s
|
4
|
+
author = Anders Lemvigh
|
5
|
+
url = https://github.com/alemvigh
|
6
|
+
license = CC BY-SA 4.0
|
7
|
+
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
|
8
|
+
icontheme = typicons_dark
|
9
|
+
|
10
|
+
[Palette]
|
11
|
+
window = 0, 0, 0
|
12
|
+
windowtext = 150, 150, 150
|
13
|
+
base = 0, 0, 0
|
14
|
+
alternatebase = 30, 20, 45
|
15
|
+
text = 150, 150, 150
|
16
|
+
tooltipbase = 40, 20, 70
|
17
|
+
tooltiptext = 255, 255, 255
|
18
|
+
button = 5, 0, 10
|
19
|
+
buttontext = 150, 150, 150
|
20
|
+
brighttext = 255, 255, 255
|
21
|
+
highlight = 50, 30, 80
|
22
|
+
highlightedtext = 255, 255, 255
|
23
|
+
link = 77, 77, 255
|
24
|
+
linkvisited = 50, 0, 80
|
25
|
+
|
26
|
+
[GUI]
|
27
|
+
statusnone = 50, 50, 50
|
28
|
+
statussaved = 77, 255, 77
|
29
|
+
statusunsaved = 255, 77, 77
|
@@ -21,8 +21,8 @@ buttontext = 204, 204, 204
|
|
21
21
|
brighttext = 62, 62, 62
|
22
22
|
highlight = 44, 152, 247
|
23
23
|
highlightedtext = 255, 255, 255
|
24
|
-
link =
|
25
|
-
linkvisited =
|
24
|
+
link = 102, 153, 204
|
25
|
+
linkvisited = 102, 153, 204
|
26
26
|
|
27
27
|
[GUI]
|
28
28
|
helptext = 164, 164, 164
|
novelwriter/common.py
CHANGED
@@ -3,10 +3,10 @@ novelWriter – Common Functions
|
|
3
3
|
==============================
|
4
4
|
|
5
5
|
File History:
|
6
|
-
Created: 2019-05-12 [0.1]
|
6
|
+
Created: 2019-05-12 [0.1.0]
|
7
7
|
|
8
8
|
This file is a part of novelWriter
|
9
|
-
Copyright 2018–
|
9
|
+
Copyright 2018–2024, Veronica Berglyd Olsen
|
10
10
|
|
11
11
|
This program is free software: you can redistribute it and/or modify
|
12
12
|
it under the terms of the GNU General Public License as published by
|
@@ -29,7 +29,7 @@ import logging
|
|
29
29
|
import unicodedata
|
30
30
|
import xml.etree.ElementTree as ET
|
31
31
|
|
32
|
-
from typing import Any, Literal
|
32
|
+
from typing import TYPE_CHECKING, Any, Literal
|
33
33
|
from pathlib import Path
|
34
34
|
from datetime import datetime
|
35
35
|
from configparser import ConfigParser
|
@@ -38,18 +38,20 @@ from urllib.request import pathname2url
|
|
38
38
|
|
39
39
|
from PyQt5.QtGui import QDesktopServices
|
40
40
|
from PyQt5.QtCore import QCoreApplication, QUrl
|
41
|
-
from PyQt5.QtWidgets import QWidget, qApp
|
42
41
|
|
43
42
|
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
|
44
43
|
from novelwriter.error import logException
|
45
|
-
from novelwriter.constants import nwConst, nwUnicode
|
44
|
+
from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst
|
45
|
+
|
46
|
+
if TYPE_CHECKING: # pragma: no cover
|
47
|
+
from typing import TypeGuard # Requires Python 3.10
|
46
48
|
|
47
49
|
logger = logging.getLogger(__name__)
|
48
50
|
|
49
51
|
|
50
|
-
|
52
|
+
##
|
51
53
|
# Checker Functions
|
52
|
-
|
54
|
+
##
|
53
55
|
|
54
56
|
def checkStringNone(value: Any, default: str | None) -> str | None:
|
55
57
|
"""Check if a variable is a string or a None."""
|
@@ -105,15 +107,6 @@ def checkBool(value: Any, default: bool) -> bool:
|
|
105
107
|
return default
|
106
108
|
|
107
109
|
|
108
|
-
def checkHandle(value, default, allowNone=False):
|
109
|
-
"""Check if a value is a handle."""
|
110
|
-
if allowNone and (value is None or value == "None"):
|
111
|
-
return None
|
112
|
-
if isHandle(value):
|
113
|
-
return str(value)
|
114
|
-
return default
|
115
|
-
|
116
|
-
|
117
110
|
def checkUuid(value: Any, default: str) -> str:
|
118
111
|
"""Try to process a value as an UUID, or return a default."""
|
119
112
|
try:
|
@@ -132,11 +125,11 @@ def checkPath(value: Any, default: Path) -> Path:
|
|
132
125
|
return default
|
133
126
|
|
134
127
|
|
135
|
-
|
128
|
+
##
|
136
129
|
# Validator Functions
|
137
|
-
|
130
|
+
##
|
138
131
|
|
139
|
-
def isHandle(value: Any) ->
|
132
|
+
def isHandle(value: Any) -> TypeGuard[str]:
|
140
133
|
"""Check if a string is a valid novelWriter handle.
|
141
134
|
Note: This is case sensitive. Must be lower case!
|
142
135
|
"""
|
@@ -150,7 +143,7 @@ def isHandle(value: Any) -> bool:
|
|
150
143
|
return True
|
151
144
|
|
152
145
|
|
153
|
-
def isTitleTag(value: Any) ->
|
146
|
+
def isTitleTag(value: Any) -> TypeGuard[str]:
|
154
147
|
"""Check if a string is a valid title tag string."""
|
155
148
|
if not isinstance(value, str):
|
156
149
|
return False
|
@@ -164,19 +157,19 @@ def isTitleTag(value: Any) -> bool:
|
|
164
157
|
return True
|
165
158
|
|
166
159
|
|
167
|
-
def isItemClass(value:
|
160
|
+
def isItemClass(value: Any) -> TypeGuard[str]:
|
168
161
|
"""Check if a string is a valid nwItemClass identifier."""
|
169
|
-
return value in nwItemClass.__members__
|
162
|
+
return isinstance(value, str) and value in nwItemClass.__members__
|
170
163
|
|
171
164
|
|
172
|
-
def isItemType(value:
|
165
|
+
def isItemType(value: Any) -> TypeGuard[str]:
|
173
166
|
"""Check if a string is a valid nwItemType identifier."""
|
174
|
-
return value in nwItemType.__members__
|
167
|
+
return isinstance(value, str) and value in nwItemType.__members__
|
175
168
|
|
176
169
|
|
177
|
-
def isItemLayout(value:
|
170
|
+
def isItemLayout(value: Any) -> TypeGuard[str]:
|
178
171
|
"""Check if a string is a valid nwItemLayout identifier."""
|
179
|
-
return value in nwItemLayout.__members__
|
172
|
+
return isinstance(value, str) and value in nwItemLayout.__members__
|
180
173
|
|
181
174
|
|
182
175
|
def hexToInt(value: Any, default: int = 0) -> int:
|
@@ -190,8 +183,7 @@ def hexToInt(value: Any, default: int = 0) -> int:
|
|
190
183
|
|
191
184
|
|
192
185
|
def minmax(value: int, minVal: int, maxVal: int) -> int:
|
193
|
-
"""
|
194
|
-
"""
|
186
|
+
"""Check that an value is between min and max value (inclusive)."""
|
195
187
|
return min(maxVal, max(minVal, value))
|
196
188
|
|
197
189
|
|
@@ -205,26 +197,26 @@ def checkIntTuple(value: int, valid: tuple | list | set, default: int) -> int:
|
|
205
197
|
return default
|
206
198
|
|
207
199
|
|
208
|
-
|
200
|
+
##
|
209
201
|
# Formatting Functions
|
210
|
-
|
202
|
+
##
|
211
203
|
|
212
204
|
def formatInt(value: int) -> str:
|
213
205
|
"""Formats an integer with k, M, G etc."""
|
214
206
|
if not isinstance(value, int):
|
215
207
|
return "ERR"
|
216
208
|
|
217
|
-
|
218
|
-
if
|
209
|
+
fVal = float(value)
|
210
|
+
if fVal > 1000.0:
|
219
211
|
for pF in ["k", "M", "G", "T", "P", "E"]:
|
220
|
-
|
221
|
-
if
|
222
|
-
if
|
223
|
-
return f"{
|
224
|
-
elif
|
225
|
-
return f"{
|
212
|
+
fVal /= 1000.0
|
213
|
+
if fVal < 1000.0:
|
214
|
+
if fVal < 10.0:
|
215
|
+
return f"{fVal:4.2f}{nwUnicode.U_THSP}{pF}"
|
216
|
+
elif fVal < 100.0:
|
217
|
+
return f"{fVal:4.1f}{nwUnicode.U_THSP}{pF}"
|
226
218
|
else:
|
227
|
-
return f"{
|
219
|
+
return f"{fVal:3.0f}{nwUnicode.U_THSP}{pF}"
|
228
220
|
|
229
221
|
return str(value)
|
230
222
|
|
@@ -251,9 +243,27 @@ def formatTime(t: int) -> str:
|
|
251
243
|
return "ERROR"
|
252
244
|
|
253
245
|
|
254
|
-
|
246
|
+
def formatVersion(value: str) -> str:
|
247
|
+
"""Format a version number into a more human readable form."""
|
248
|
+
return value.lower().replace("a", " Alpha ").replace("b", " Beta ").replace("rc", " RC ")
|
249
|
+
|
250
|
+
|
251
|
+
def formatFileFilter(extensions: list[str | tuple[str, str]]) -> str:
|
252
|
+
"""Format a list of extensions, or extension + label pairs into a
|
253
|
+
QFileDialog extensions filter.
|
254
|
+
"""
|
255
|
+
result = []
|
256
|
+
for ext in extensions:
|
257
|
+
if isinstance(ext, str):
|
258
|
+
result.append(f"{trConst(nwLabels.FILE_FILTERS.get(ext))} ({ext})")
|
259
|
+
elif isinstance(ext, tuple) and len(ext) == 2:
|
260
|
+
result.append(f"{ext[0]} ({ext[1]})")
|
261
|
+
return ";;".join(result)
|
262
|
+
|
263
|
+
|
264
|
+
##
|
255
265
|
# String Functions
|
256
|
-
|
266
|
+
##
|
257
267
|
|
258
268
|
def simplified(text: str) -> str:
|
259
269
|
"""Take a string and strip leading and trailing whitespaces, and
|
@@ -271,22 +281,22 @@ def transferCase(source: str, target: str) -> str:
|
|
271
281
|
"""Transfers the case of the source word to the target word. This
|
272
282
|
will consider all upper or lower, and first char capitalisation.
|
273
283
|
"""
|
274
|
-
|
284
|
+
result = target
|
275
285
|
|
276
286
|
if not isinstance(source, str) or not isinstance(target, str):
|
277
|
-
return
|
287
|
+
return result
|
278
288
|
if len(target) < 1 or len(source) < 1:
|
279
|
-
return
|
289
|
+
return result
|
280
290
|
|
281
291
|
if source.istitle():
|
282
|
-
|
292
|
+
result = target.title()
|
283
293
|
|
284
294
|
if source.isupper():
|
285
|
-
|
295
|
+
result = target.upper()
|
286
296
|
elif source.islower():
|
287
|
-
|
297
|
+
result = target.lower()
|
288
298
|
|
289
|
-
return
|
299
|
+
return result
|
290
300
|
|
291
301
|
|
292
302
|
def fuzzyTime(seconds: int) -> str:
|
@@ -372,9 +382,9 @@ def numberToRoman(value: int, toLower: bool = False) -> str:
|
|
372
382
|
return roman.lower() if toLower else roman
|
373
383
|
|
374
384
|
|
375
|
-
|
385
|
+
##
|
376
386
|
# Encoder Functions
|
377
|
-
|
387
|
+
##
|
378
388
|
|
379
389
|
def jsonEncode(data: dict | list | tuple, n: int = 0, nmax: int = 0) -> str:
|
380
390
|
"""Encode a dictionary, list or tuple as a json object or array, and
|
@@ -464,9 +474,9 @@ def xmlIndent(tree: ET.Element | ET.ElementTree) -> None:
|
|
464
474
|
return
|
465
475
|
|
466
476
|
|
467
|
-
|
477
|
+
##
|
468
478
|
# File and File System Functions
|
469
|
-
|
479
|
+
##
|
470
480
|
|
471
481
|
def readTextFile(path: str | Path) -> str:
|
472
482
|
"""Read the content of a text file in a robust manner."""
|
@@ -508,21 +518,9 @@ def openExternalPath(path: Path) -> bool:
|
|
508
518
|
return False
|
509
519
|
|
510
520
|
|
511
|
-
|
512
|
-
# Other Functions
|
513
|
-
# =============================================================================================== #
|
514
|
-
|
515
|
-
def getGuiItem(objName: str) -> QWidget | None:
|
516
|
-
"""Returns a QtWidget based on its objectName."""
|
517
|
-
for qWidget in qApp.topLevelWidgets():
|
518
|
-
if qWidget.objectName() == objName:
|
519
|
-
return qWidget
|
520
|
-
return None
|
521
|
-
|
522
|
-
|
523
|
-
# =============================================================================================== #
|
521
|
+
##
|
524
522
|
# Classes
|
525
|
-
|
523
|
+
##
|
526
524
|
|
527
525
|
class NWConfigParser(ConfigParser):
|
528
526
|
"""Common: Adapted Config Parser
|