novelWriter 2.2b1__py3-none-any.whl → 2.2.1__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.
Files changed (134) hide show
  1. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/METADATA +3 -3
  2. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/RECORD +128 -114
  3. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/WHEEL +1 -1
  4. novelwriter/__init__.py +10 -5
  5. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  6. novelwriter/assets/i18n/nw_en_US.qm +0 -0
  7. novelwriter/assets/i18n/nw_es_419.qm +0 -0
  8. novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
  9. novelwriter/assets/i18n/nw_it_IT.qm +0 -0
  10. novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
  11. novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
  12. novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
  13. novelwriter/assets/i18n/project_de_DE.json +1 -0
  14. novelwriter/assets/i18n/project_en_GB.json +1 -0
  15. novelwriter/assets/i18n/project_en_US.json +1 -0
  16. novelwriter/assets/i18n/project_es_419.json +11 -0
  17. novelwriter/assets/i18n/project_fr_FR.json +11 -0
  18. novelwriter/assets/i18n/project_it_IT.json +11 -0
  19. novelwriter/assets/i18n/project_ja_JP.json +2 -1
  20. novelwriter/assets/i18n/project_nb_NO.json +1 -0
  21. novelwriter/assets/i18n/project_zh_CN.json +11 -0
  22. novelwriter/assets/icons/novelwriter.ico +0 -0
  23. novelwriter/assets/icons/typicons_dark/icons.conf +11 -3
  24. novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +4 -0
  25. novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +4 -0
  26. novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +4 -0
  27. novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +4 -0
  28. novelwriter/assets/icons/typicons_dark/nw_panel.svg +4 -0
  29. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +4 -0
  30. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +3 -1
  31. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +4 -0
  32. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +3 -1
  33. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +4 -0
  34. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +3 -1
  35. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +4 -2
  36. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +4 -2
  37. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +4 -2
  38. novelwriter/assets/icons/typicons_dark/typ_eye.svg +4 -0
  39. novelwriter/assets/icons/typicons_light/icons.conf +11 -3
  40. novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +4 -0
  41. novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +4 -0
  42. novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +4 -0
  43. novelwriter/assets/icons/typicons_light/nw_deco-note.svg +4 -0
  44. novelwriter/assets/icons/typicons_light/nw_panel.svg +4 -0
  45. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +4 -0
  46. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +3 -1
  47. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +4 -0
  48. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +3 -1
  49. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +4 -0
  50. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +3 -1
  51. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +4 -2
  52. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +4 -2
  53. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +4 -2
  54. novelwriter/assets/icons/typicons_light/typ_eye.svg +4 -0
  55. novelwriter/assets/icons/x-novelwriter-project.ico +0 -0
  56. novelwriter/assets/manual.pdf +0 -0
  57. novelwriter/assets/sample.zip +0 -0
  58. novelwriter/assets/text/release_notes.htm +50 -7
  59. novelwriter/common.py +35 -27
  60. novelwriter/config.py +13 -28
  61. novelwriter/constants.py +21 -4
  62. novelwriter/core/buildsettings.py +2 -2
  63. novelwriter/core/coretools.py +8 -2
  64. novelwriter/core/docbuild.py +1 -1
  65. novelwriter/core/document.py +1 -1
  66. novelwriter/core/index.py +102 -36
  67. novelwriter/core/item.py +2 -2
  68. novelwriter/core/options.py +6 -3
  69. novelwriter/core/project.py +5 -5
  70. novelwriter/core/projectdata.py +3 -3
  71. novelwriter/core/projectxml.py +1 -1
  72. novelwriter/core/sessions.py +2 -2
  73. novelwriter/core/spellcheck.py +4 -3
  74. novelwriter/core/status.py +3 -3
  75. novelwriter/core/storage.py +1 -1
  76. novelwriter/core/tohtml.py +11 -5
  77. novelwriter/core/tokenizer.py +28 -21
  78. novelwriter/core/tomd.py +6 -2
  79. novelwriter/core/toodt.py +12 -5
  80. novelwriter/core/tree.py +2 -2
  81. novelwriter/dialogs/about.py +30 -31
  82. novelwriter/dialogs/docmerge.py +24 -15
  83. novelwriter/dialogs/docsplit.py +27 -16
  84. novelwriter/dialogs/editlabel.py +19 -7
  85. novelwriter/dialogs/preferences.py +116 -131
  86. novelwriter/dialogs/projdetails.py +29 -36
  87. novelwriter/dialogs/projload.py +32 -36
  88. novelwriter/dialogs/projsettings.py +20 -15
  89. novelwriter/dialogs/quotes.py +32 -25
  90. novelwriter/dialogs/updates.py +17 -16
  91. novelwriter/dialogs/wordlist.py +34 -21
  92. novelwriter/enum.py +19 -8
  93. novelwriter/error.py +1 -1
  94. novelwriter/extensions/circularprogress.py +1 -1
  95. novelwriter/extensions/configlayout.py +3 -15
  96. novelwriter/extensions/{wheeleventfilter.py → eventfilters.py} +15 -5
  97. novelwriter/extensions/novelselector.py +1 -1
  98. novelwriter/extensions/pageddialog.py +1 -1
  99. novelwriter/extensions/pagedsidebar.py +2 -5
  100. novelwriter/extensions/simpleprogress.py +8 -9
  101. novelwriter/extensions/statusled.py +1 -1
  102. novelwriter/extensions/switch.py +4 -4
  103. novelwriter/extensions/switchbox.py +1 -6
  104. novelwriter/gui/doceditor.py +349 -236
  105. novelwriter/gui/dochighlight.py +10 -11
  106. novelwriter/gui/docviewer.py +158 -360
  107. novelwriter/gui/docviewerpanel.py +502 -0
  108. novelwriter/gui/editordocument.py +4 -4
  109. novelwriter/gui/itemdetails.py +2 -2
  110. novelwriter/gui/mainmenu.py +50 -36
  111. novelwriter/gui/noveltree.py +44 -53
  112. novelwriter/gui/outline.py +12 -7
  113. novelwriter/gui/projtree.py +465 -381
  114. novelwriter/gui/sidebar.py +9 -7
  115. novelwriter/gui/statusbar.py +48 -5
  116. novelwriter/gui/theme.py +26 -8
  117. novelwriter/guimain.py +212 -208
  118. novelwriter/shared.py +76 -30
  119. novelwriter/tools/dictionaries.py +268 -0
  120. novelwriter/tools/lipsum.py +34 -28
  121. novelwriter/tools/manusbuild.py +20 -10
  122. novelwriter/tools/manuscript.py +20 -27
  123. novelwriter/tools/manussettings.py +2 -4
  124. novelwriter/tools/projwizard.py +3 -3
  125. novelwriter/tools/writingstats.py +18 -5
  126. novelwriter/assets/icons/typicons_dark/nw_tb-markdown.svg +0 -8
  127. novelwriter/assets/icons/typicons_dark/nw_tb-shortcode.svg +0 -8
  128. novelwriter/assets/icons/typicons_dark/typ_at.svg +0 -4
  129. novelwriter/assets/icons/typicons_light/nw_tb-markdown.svg +0 -8
  130. novelwriter/assets/icons/typicons_light/nw_tb-shortcode.svg +0 -8
  131. novelwriter/assets/icons/typicons_light/typ_at.svg +0 -4
  132. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/LICENSE.md +0 -0
  133. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/entry_points.txt +0 -0
  134. {novelWriter-2.2b1.dist-info → novelWriter-2.2.1.dist-info}/top_level.txt +0 -0
novelwriter/core/item.py CHANGED
@@ -3,10 +3,10 @@ novelWriter – Project Item Class
3
3
  ================================
4
4
 
5
5
  File History:
6
- Created: 2018-10-27 [0.0.1]
6
+ Created: 2018-10-27 [0.0.1] NWItem
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -3,11 +3,11 @@ novelWriter – Project Options Cache
3
3
  ===================================
4
4
 
5
5
  File History:
6
- Created: 2019-10-21 [0.3.1]
7
- Rewritten: 2020-02-19 [0.4.5]
6
+ Created: 2019-10-21 [0.3.1] OptionState
7
+ Rewritten: 2020-02-19 [0.4.5] OptionState
8
8
 
9
9
  This file is a part of novelWriter
10
- Copyright 2018–2023, Veronica Berglyd Olsen
10
+ Copyright 2018–2024, Veronica Berglyd Olsen
11
11
 
12
12
  This program is free software: you can redistribute it and/or modify
13
13
  it under the terms of the GNU General Public License as published by
@@ -69,6 +69,9 @@ VALID_MAP = {
69
69
  "GuiManuscriptBuild": {
70
70
  "winWidth", "winHeight", "fmtWidth", "sumWidth",
71
71
  },
72
+ "GuiDocViewerPanel": {
73
+ "colWidths",
74
+ }
72
75
  }
73
76
 
74
77
 
@@ -3,10 +3,10 @@ novelWriter – Project Wrapper
3
3
  =============================
4
4
 
5
5
  File History:
6
- Created: 2018-09-29 [0.0.1]
6
+ Created: 2018-09-29 [0.0.1] NWProject
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -45,7 +45,7 @@ from novelwriter.core.sessions import NWSessionLog
45
45
  from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
46
46
  from novelwriter.core.projectdata import NWProjectData
47
47
  from novelwriter.common import (
48
- checkStringNone, formatInt, formatTimeStamp, hexToInt, makeFileNameSafe, minmax
48
+ checkStringNone, formatInt, formatTimeStamp, getFileSize, hexToInt, makeFileNameSafe, minmax
49
49
  )
50
50
 
51
51
  if TYPE_CHECKING: # pragma: no cover
@@ -80,7 +80,7 @@ class NWProject:
80
80
 
81
81
  return
82
82
 
83
- def __del__(self): # pragma: no cover
83
+ def __del__(self) -> None: # pragma: no cover
84
84
  logger.debug("Delete: NWProject")
85
85
  return
86
86
 
@@ -420,7 +420,7 @@ class NWProject:
420
420
  timeStamp = formatTimeStamp(time(), fileSafe=True)
421
421
  archName = baseDir / f"{cleanName} {timeStamp}.zip"
422
422
  if self._storage.zipIt(archName, compression=2):
423
- size = formatInt(archName.stat().st_size)
423
+ size = formatInt(getFileSize(archName))
424
424
  if doNotify:
425
425
  SHARED.info(
426
426
  self.tr("Created a backup of your project of size {0}B.").format(size),
@@ -3,10 +3,10 @@ novelWriter – Project Data Class
3
3
  ================================
4
4
 
5
5
  File History:
6
- Created: 2022-10-30 [2.0rc2]
6
+ Created: 2022-10-30 [2.0rc2] NWProjectData
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -170,7 +170,7 @@ class NWProjectData:
170
170
 
171
171
  @property
172
172
  def autoReplace(self) -> dict[str, str]:
173
- """Return the autoreplace dictionary."""
173
+ """Return the auto-replace dictionary."""
174
174
  return self._autoReplace
175
175
 
176
176
  @property
@@ -8,7 +8,7 @@ Created: 2022-09-28 [2.0rc2] ProjectXMLReader
8
8
  Created: 2022-10-31 [2.0rc2] ProjectXMLWriter
9
9
 
10
10
  This file is a part of novelWriter
11
- Copyright 2018–2023, Veronica Berglyd Olsen
11
+ Copyright 2018–2024, Veronica Berglyd Olsen
12
12
 
13
13
  This program is free software: you can redistribute it and/or modify
14
14
  it under the terms of the GNU General Public License as published by
@@ -3,10 +3,10 @@ novelWriter – Project Session Log Class
3
3
  =======================================
4
4
 
5
5
  File History:
6
- Created: 2023-06-11 [2.1b1]
6
+ Created: 2023-06-11 [2.1b1] NWSessionLog
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -3,10 +3,11 @@ novelWriter – Spell Check Classes
3
3
  =================================
4
4
 
5
5
  File History:
6
- Created: 2019-06-11 [0.1.5]
6
+ Created: 2019-06-11 [0.1.5] NWSpellEnchant
7
+ Created: 2023-06-13 [2.1b1] UserDictionary
7
8
 
8
9
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
10
+ Copyright 2018–2024, Veronica Berglyd Olsen
10
11
 
11
12
  This program is free software: you can redistribute it and/or modify
12
13
  it under the terms of the GNU General Public License as published by
@@ -56,7 +57,7 @@ class NWSpellEnchant:
56
57
  logger.debug("Ready: NWSpellEnchant")
57
58
  return
58
59
 
59
- def __del__(self): # pragma: no cover
60
+ def __del__(self) -> None: # pragma: no cover
60
61
  logger.debug("Delete: NWSpellEnchant")
61
62
  return
62
63
 
@@ -3,11 +3,11 @@ novelWriter – Project Item Status Class
3
3
  =======================================
4
4
 
5
5
  File History:
6
- Created: 2019-05-19 [0.1.3]
7
- Rewritten: 2022-04-05 [2.0b1]
6
+ Created: 2019-05-19 [0.1.3] NWStatus
7
+ Rewritten: 2022-04-05 [2.0b1] NWStatus
8
8
 
9
9
  This file is a part of novelWriter
10
- Copyright 2018–2023, Veronica Berglyd Olsen
10
+ Copyright 2018–2024, Veronica Berglyd Olsen
11
11
 
12
12
  This program is free software: you can redistribute it and/or modify
13
13
  it under the terms of the GNU General Public License as published by
@@ -6,7 +6,7 @@ File History:
6
6
  Created: 2022-11-01 [2.0rc2] NWStorage
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -3,10 +3,10 @@ novelWriter – HTML Text Converter
3
3
  =================================
4
4
 
5
5
  File History:
6
- Created: 2019-05-07 [0.0.1]
6
+ Created: 2019-05-07 [0.0.1] ToHtml
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -287,7 +287,10 @@ class ToHtml(Tokenizer):
287
287
  para.append(stripEscape(tTemp.rstrip()))
288
288
 
289
289
  elif tType == self.T_SYNOPSIS and self._doSynopsis:
290
- lines.append(self._formatSynopsis(tText))
290
+ lines.append(self._formatSynopsis(tText, True))
291
+
292
+ elif tType == self.T_SHORT and self._doSynopsis:
293
+ lines.append(self._formatSynopsis(tText, False))
291
294
 
292
295
  elif tType == self.T_COMMENT and self._doComments:
293
296
  lines.append(self._formatComments(tText))
@@ -454,9 +457,12 @@ class ToHtml(Tokenizer):
454
457
  # Internal Functions
455
458
  ##
456
459
 
457
- def _formatSynopsis(self, text: str) -> str:
460
+ def _formatSynopsis(self, text: str, synopsis: bool) -> str:
458
461
  """Apply HTML formatting to synopsis."""
459
- sSynop = self._localLookup("Synopsis")
462
+ if synopsis:
463
+ sSynop = self._localLookup("Synopsis")
464
+ else:
465
+ sSynop = self._localLookup("Short Description")
460
466
  if self._genMode == self.M_PREVIEW:
461
467
  return f"<p class='comment'><span class='synopsis'>{sSynop}:</span> {text}</p>\n"
462
468
  else:
@@ -7,7 +7,7 @@ Created: 2019-05-05 [0.0.1] Tokenizer
7
7
  Created: 2023-05-23 [2.1b1] HeadingFormatter
8
8
 
9
9
  This file is a part of novelWriter
10
- Copyright 2018–2023, Veronica Berglyd Olsen
10
+ Copyright 2018–2024, Veronica Berglyd Olsen
11
11
 
12
12
  This program is free software: you can redistribute it and/or modify
13
13
  it under the terms of the GNU General Public License as published by
@@ -34,8 +34,9 @@ from pathlib import Path
34
34
  from functools import partial
35
35
 
36
36
  from PyQt5.QtCore import QCoreApplication, QRegularExpression
37
+ from novelwriter.core.index import processComment
37
38
 
38
- from novelwriter.enum import nwItemLayout
39
+ from novelwriter.enum import nwComment, nwItemLayout
39
40
  from novelwriter.common import formatTimeStamp, numberToRoman, checkInt
40
41
  from novelwriter.constants import nwHeadFmt, nwRegEx, nwShortcode, nwUnicode
41
42
  from novelwriter.core.project import NWProject
@@ -79,17 +80,18 @@ class Tokenizer(ABC):
79
80
  # Block Type
80
81
  T_EMPTY = 1 # Empty line (new paragraph)
81
82
  T_SYNOPSIS = 2 # Synopsis comment
82
- T_COMMENT = 3 # Comment line
83
- T_KEYWORD = 4 # Command line
84
- T_TITLE = 5 # Title
85
- T_UNNUM = 6 # Unnumbered
86
- T_HEAD1 = 7 # Header 1
87
- T_HEAD2 = 8 # Header 2
88
- T_HEAD3 = 9 # Header 3
89
- T_HEAD4 = 10 # Header 4
90
- T_TEXT = 11 # Text line
91
- T_SEP = 12 # Scene separator
92
- T_SKIP = 13 # Paragraph break
83
+ T_SHORT = 3 # Short description comment
84
+ T_COMMENT = 4 # Comment line
85
+ T_KEYWORD = 5 # Command line
86
+ T_TITLE = 6 # Title
87
+ T_UNNUM = 7 # Unnumbered
88
+ T_HEAD1 = 8 # Header 1
89
+ T_HEAD2 = 9 # Header 2
90
+ T_HEAD3 = 10 # Header 3
91
+ T_HEAD4 = 11 # Header 4
92
+ T_TEXT = 12 # Text line
93
+ T_SEP = 13 # Scene separator
94
+ T_SKIP = 14 # Paragraph break
93
95
 
94
96
  # Block Style
95
97
  A_NONE = 0x0000 # No special style
@@ -216,7 +218,7 @@ class Tokenizer(ABC):
216
218
  return
217
219
 
218
220
  def setChapterFormat(self, hFormat: str) -> None:
219
- """Set the chapert format pattern."""
221
+ """Set the chapter format pattern."""
220
222
  self._fmtChapter = hFormat.strip()
221
223
  return
222
224
 
@@ -435,8 +437,8 @@ class Tokenizer(ABC):
435
437
  if aLine[0] == "[":
436
438
  # Parse special formatting line
437
439
  # This must be a separate if statement, as it may not
438
- # reach a continue statement and must thefore proceed to
439
- # check other formats.
440
+ # reach a continue statement and must therefore proceed
441
+ # to check other formats.
440
442
 
441
443
  if sLine in ("[newpage]", "[new page]"):
442
444
  breakNext = True
@@ -461,17 +463,22 @@ class Tokenizer(ABC):
461
463
  continue
462
464
 
463
465
  if aLine[0] == "%":
464
- cLine = aLine[1:].lstrip()
465
- synTag = cLine[:9].lower()
466
- if synTag == "synopsis:":
466
+ cStyle, cText, _ = processComment(aLine)
467
+ if cStyle == nwComment.SYNOPSIS:
467
468
  self._tokens.append((
468
- self.T_SYNOPSIS, nHead, cLine[9:].strip(), None, sAlign
469
+ self.T_SYNOPSIS, nHead, cText, None, sAlign
470
+ ))
471
+ if self._doSynopsis and self._keepMarkdown:
472
+ tmpMarkdown.append("%s\n" % aLine)
473
+ elif cStyle == nwComment.SHORT:
474
+ self._tokens.append((
475
+ self.T_SHORT, nHead, cText, None, sAlign
469
476
  ))
470
477
  if self._doSynopsis and self._keepMarkdown:
471
478
  tmpMarkdown.append("%s\n" % aLine)
472
479
  else:
473
480
  self._tokens.append((
474
- self.T_COMMENT, nHead, aLine[1:].strip(), None, sAlign
481
+ self.T_COMMENT, nHead, cText, None, sAlign
475
482
  ))
476
483
  if self._doComments and self._keepMarkdown:
477
484
  tmpMarkdown.append("%s\n" % aLine)
novelwriter/core/tomd.py CHANGED
@@ -3,10 +3,10 @@ novelWriter – Markdown Text Converter
3
3
  =====================================
4
4
 
5
5
  File History:
6
- Created: 2021-02-06 [1.2b1]
6
+ Created: 2021-02-06 [1.2b1] ToMarkdown
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -170,6 +170,10 @@ class ToMarkdown(Tokenizer):
170
170
  label = self._localLookup("Synopsis")
171
171
  lines.append(f"**{label}:** {tText}\n\n")
172
172
 
173
+ elif tType == self.T_SHORT and self._doSynopsis:
174
+ label = self._localLookup("Short Description")
175
+ lines.append(f"**{label}:** {tText}\n\n")
176
+
173
177
  elif tType == self.T_COMMENT and self._doComments:
174
178
  label = self._localLookup("Comment")
175
179
  lines.append(f"**{label}:** {tText}\n\n")
novelwriter/core/toodt.py CHANGED
@@ -9,7 +9,7 @@ Created: 2021-01-27 [1.2b1] ODTTextStyle
9
9
  Created: 2021-08-14 [1.5b1] XMLParagraph
10
10
 
11
11
  This file is a part of novelWriter
12
- Copyright 2018–2023, Veronica Berglyd Olsen
12
+ Copyright 2018–2024, Veronica Berglyd Olsen
13
13
 
14
14
  This program is free software: you can redistribute it and/or modify
15
15
  it under the terms of the GNU General Public License as published by
@@ -195,7 +195,7 @@ class ToOdt(Tokenizer):
195
195
  # Setters
196
196
  ##
197
197
 
198
- def setLanguage(self, language: str) -> None:
198
+ def setLanguage(self, language: str | None) -> None:
199
199
  """Set language for the document."""
200
200
  if language:
201
201
  langBits = language.split("_")
@@ -481,7 +481,11 @@ class ToOdt(Tokenizer):
481
481
  pFmt.append(tFormat)
482
482
 
483
483
  elif tType == self.T_SYNOPSIS and self._doSynopsis:
484
- tTemp, fTemp = self._formatSynopsis(tText)
484
+ tTemp, fTemp = self._formatSynopsis(tText, True)
485
+ self._addTextPar("Text_20_Meta", oStyle, tTemp, tFmt=fTemp)
486
+
487
+ elif tType == self.T_SHORT and self._doSynopsis:
488
+ tTemp, fTemp = self._formatSynopsis(tText, False)
485
489
  self._addTextPar("Text_20_Meta", oStyle, tTemp, tFmt=fTemp)
486
490
 
487
491
  elif tType == self.T_COMMENT and self._doComments:
@@ -552,9 +556,12 @@ class ToOdt(Tokenizer):
552
556
  # Internal Functions
553
557
  ##
554
558
 
555
- def _formatSynopsis(self, text: str) -> tuple[str, list[tuple[int, int]]]:
559
+ def _formatSynopsis(self, text: str, synopsis: bool) -> tuple[str, list[tuple[int, int]]]:
556
560
  """Apply formatting to synopsis lines."""
557
- name = self._localLookup("Synopsis")
561
+ if synopsis:
562
+ name = self._localLookup("Synopsis")
563
+ else:
564
+ name = self._localLookup("Short Description")
558
565
  rTxt = f"{name}: {text}"
559
566
  rFmt = [(0, self.FMT_B_B), (len(name) + 1, self.FMT_B_E)]
560
567
  return rTxt, rFmt
novelwriter/core/tree.py CHANGED
@@ -3,10 +3,10 @@ novelWriter – Project Tree Class
3
3
  ================================
4
4
 
5
5
  File History:
6
- Created: 2020-05-07 [0.4.5]
6
+ Created: 2020-05-07 [0.4.5] NWTree
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -3,10 +3,10 @@ novelWriter – GUI About Box
3
3
  ===========================
4
4
 
5
5
  File History:
6
- Created: 2020-05-21 [0.5.2]
6
+ Created: 2020-05-21 [0.5.2] GuiAbout
7
7
 
8
8
  This file is a part of novelWriter
9
- Copyright 2018–2023, Veronica Berglyd Olsen
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
@@ -28,7 +28,7 @@ import novelwriter
28
28
 
29
29
  from datetime import datetime
30
30
 
31
- from PyQt5.QtGui import QCursor
31
+ from PyQt5.QtGui import QCloseEvent, QCursor
32
32
  from PyQt5.QtCore import Qt
33
33
  from PyQt5.QtWidgets import (
34
34
  qApp, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QTabWidget,
@@ -44,7 +44,7 @@ logger = logging.getLogger(__name__)
44
44
 
45
45
  class GuiAbout(QDialog):
46
46
 
47
- def __init__(self, parent: QWidget):
47
+ def __init__(self, parent: QWidget) -> None:
48
48
  super().__init__(parent=parent)
49
49
 
50
50
  logger.debug("Create: GuiAbout")
@@ -101,7 +101,7 @@ class GuiAbout(QDialog):
101
101
 
102
102
  # OK Button
103
103
  self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
104
- self.buttonBox.accepted.connect(self._doClose)
104
+ self.buttonBox.accepted.connect(self.close)
105
105
 
106
106
  self.outerBox.addLayout(self.innerBox)
107
107
  self.outerBox.addWidget(self.buttonBox)
@@ -111,13 +111,12 @@ class GuiAbout(QDialog):
111
111
 
112
112
  return
113
113
 
114
- def __del__(self): # pragma: no cover
114
+ def __del__(self) -> None: # pragma: no cover
115
115
  logger.debug("Delete: GuiAbout")
116
116
  return
117
117
 
118
- def populateGUI(self):
119
- """Populate tabs with text.
120
- """
118
+ def populateGUI(self) -> None:
119
+ """Populate tabs with text."""
121
120
  qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
122
121
  self._setStyleSheet()
123
122
  self._fillAboutPage()
@@ -127,19 +126,27 @@ class GuiAbout(QDialog):
127
126
  qApp.restoreOverrideCursor()
128
127
  return
129
128
 
130
- def showReleaseNotes(self):
131
- """Show the release notes.
132
- """
129
+ def showReleaseNotes(self) -> None:
130
+ """Show the release notes."""
133
131
  self.tabBox.setCurrentWidget(self.pageNotes)
134
132
  return
135
133
 
134
+ ##
135
+ # Events
136
+ ##
137
+
138
+ def closeEvent(self, event: QCloseEvent) -> None:
139
+ """Capture the close event and perform cleanup."""
140
+ event.accept()
141
+ self.deleteLater()
142
+ return
143
+
136
144
  ##
137
145
  # Internal Functions
138
146
  ##
139
147
 
140
- def _fillAboutPage(self):
141
- """Generate the content for the About page.
142
- """
148
+ def _fillAboutPage(self) -> None:
149
+ """Generate the content for the About page."""
143
150
  aboutMsg = (
144
151
  "<h2>{title1}</h2>"
145
152
  "<p>{copy}</p>"
@@ -181,9 +188,8 @@ class GuiAbout(QDialog):
181
188
 
182
189
  return
183
190
 
184
- def _fillNotesPage(self):
185
- """Load the content for the Release Notes page.
186
- """
191
+ def _fillNotesPage(self) -> None:
192
+ """Load the content for the Release Notes page."""
187
193
  docPath = CONFIG.assetPath("text") / "release_notes.htm"
188
194
  docText = readTextFile(docPath)
189
195
  if docText:
@@ -192,9 +198,8 @@ class GuiAbout(QDialog):
192
198
  self.pageNotes.setHtml("Error loading release notes text ...")
193
199
  return
194
200
 
195
- def _fillCreditsPage(self):
196
- """Load the content for the Credits page.
197
- """
201
+ def _fillCreditsPage(self) -> None:
202
+ """Load the content for the Credits page."""
198
203
  docPath = CONFIG.assetPath("text") / "credits_en.htm"
199
204
  docText = readTextFile(docPath)
200
205
  if docText:
@@ -203,9 +208,8 @@ class GuiAbout(QDialog):
203
208
  self.pageCredits.setHtml("Error loading credits text ...")
204
209
  return
205
210
 
206
- def _fillLicensePage(self):
207
- """Load the content for the Licence page.
208
- """
211
+ def _fillLicensePage(self) -> None:
212
+ """Load the content for the Licence page."""
209
213
  docPath = CONFIG.assetPath("text") / "gplv3_en.htm"
210
214
  docText = readTextFile(docPath)
211
215
  if docText:
@@ -214,9 +218,8 @@ class GuiAbout(QDialog):
214
218
  self.pageLicense.setHtml("Error loading licence text ...")
215
219
  return
216
220
 
217
- def _setStyleSheet(self):
218
- """Set stylesheet for all browser tabs
219
- """
221
+ def _setStyleSheet(self) -> None:
222
+ """Set stylesheet for all browser tabs."""
220
223
  styleSheet = (
221
224
  "h1, h2, h3, h4 {{"
222
225
  " color: rgb({hColR},{hColG},{hColB});"
@@ -242,8 +245,4 @@ class GuiAbout(QDialog):
242
245
 
243
246
  return
244
247
 
245
- def _doClose(self):
246
- self.close()
247
- return
248
-
249
248
  # END Class GuiAbout
@@ -3,11 +3,11 @@ novelWriter – GUI Doc Merge Dialog
3
3
  ==================================
4
4
 
5
5
  File History:
6
- Created: 2020-01-23 [0.4.3]
7
- Rewritten: 2022-10-06 [2.0rc1]
6
+ Created: 2020-01-23 [0.4.3] GuiDocMerge
7
+ Rewritten: 2022-10-06 [2.0rc1] GuiDocMerge
8
8
 
9
9
  This file is a part of novelWriter
10
- Copyright 2018–2023, Veronica Berglyd Olsen
10
+ Copyright 2018–2024, Veronica Berglyd Olsen
11
11
 
12
12
  This program is free software: you can redistribute it and/or modify
13
13
  it under the terms of the GNU General Public License as published by
@@ -26,7 +26,8 @@ from __future__ import annotations
26
26
 
27
27
  import logging
28
28
 
29
- from PyQt5.QtCore import Qt, QSize
29
+ from PyQt5.QtGui import QCloseEvent
30
+ from PyQt5.QtCore import Qt, QSize, pyqtSlot
30
31
  from PyQt5.QtWidgets import (
31
32
  QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout, QLabel,
32
33
  QListWidget, QListWidgetItem, QVBoxLayout, QWidget
@@ -108,13 +109,12 @@ class GuiDocMerge(QDialog):
108
109
 
109
110
  return
110
111
 
111
- def __del__(self): # pragma: no cover
112
+ def __del__(self) -> None: # pragma: no cover
112
113
  logger.debug("Delete: GuiDocMerge")
113
114
  return
114
115
 
115
- def getData(self):
116
- """Return the user's choices.
117
- """
116
+ def getData(self) -> dict:
117
+ """Return the user's choices."""
118
118
  finalItems = []
119
119
  for i in range(self.listBox.count()):
120
120
  item = self.listBox.item(i)
@@ -127,12 +127,22 @@ class GuiDocMerge(QDialog):
127
127
  return self._data
128
128
 
129
129
  ##
130
- # Slots
130
+ # Events
131
131
  ##
132
132
 
133
- def _resetList(self):
134
- """Reset the content of the list box to its original state.
135
- """
133
+ def closeEvent(self, event: QCloseEvent) -> None:
134
+ """Capture the close event and perform cleanup."""
135
+ event.accept()
136
+ self.deleteLater()
137
+ return
138
+
139
+ ##
140
+ # Private Slots
141
+ ##
142
+
143
+ @pyqtSlot()
144
+ def _resetList(self) -> None:
145
+ """Reset the content of the list box to its original state."""
136
146
  logger.debug("Resetting list box content")
137
147
  sHandle = self._data.get("sHandle", None)
138
148
  itemList = self._data.get("origItems", [])
@@ -143,9 +153,8 @@ class GuiDocMerge(QDialog):
143
153
  # Internal Functions
144
154
  ##
145
155
 
146
- def _loadContent(self, sHandle, itemList):
147
- """Load content from a given list of items.
148
- """
156
+ def _loadContent(self, sHandle: str, itemList: list[str]) -> None:
157
+ """Load content from a given list of items."""
149
158
  self._data = {}
150
159
  self._data["sHandle"] = sHandle
151
160
  self._data["origItems"] = itemList