novelWriter 2.6.3__py3-none-any.whl → 2.7__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 (348) hide show
  1. novelwriter/__init__.py +98 -75
  2. novelwriter/assets/i18n/nw_cs_CZ.qm +0 -0
  3. novelwriter/assets/i18n/nw_de_DE.qm +0 -0
  4. novelwriter/assets/i18n/nw_en_US.qm +0 -0
  5. novelwriter/assets/i18n/nw_es_419.qm +0 -0
  6. novelwriter/assets/i18n/nw_fr_FR.qm +0 -0
  7. novelwriter/assets/i18n/nw_it_IT.qm +0 -0
  8. novelwriter/assets/i18n/nw_ja_JP.qm +0 -0
  9. novelwriter/assets/i18n/nw_nb_NO.qm +0 -0
  10. novelwriter/assets/i18n/nw_nl_NL.qm +0 -0
  11. novelwriter/assets/i18n/nw_pl_PL.qm +0 -0
  12. novelwriter/assets/i18n/nw_pt_BR.qm +0 -0
  13. novelwriter/assets/i18n/nw_ru_RU.qm +0 -0
  14. novelwriter/assets/i18n/nw_zh_CN.qm +0 -0
  15. novelwriter/assets/i18n/project_de_DE.json +3 -1
  16. novelwriter/assets/i18n/project_en_GB.json +2 -0
  17. novelwriter/assets/i18n/project_en_US.json +2 -0
  18. novelwriter/assets/i18n/project_it_IT.json +2 -0
  19. novelwriter/assets/i18n/project_ja_JP.json +2 -0
  20. novelwriter/assets/i18n/project_nb_NO.json +2 -0
  21. novelwriter/assets/i18n/project_nn_NO.json +5 -0
  22. novelwriter/assets/i18n/project_pl_PL.json +2 -0
  23. novelwriter/assets/i18n/project_pt_BR.json +2 -0
  24. novelwriter/assets/i18n/project_ru_RU.json +2 -0
  25. novelwriter/assets/i18n/project_zh_CN.json +2 -0
  26. novelwriter/assets/icons/font_awesome.icons +109 -0
  27. novelwriter/assets/icons/material_filled_bold.icons +109 -0
  28. novelwriter/assets/icons/material_filled_normal.icons +109 -0
  29. novelwriter/assets/icons/material_filled_thin.icons +109 -0
  30. novelwriter/assets/icons/material_rounded_bold.icons +109 -0
  31. novelwriter/assets/icons/material_rounded_normal.icons +109 -0
  32. novelwriter/assets/icons/material_rounded_thin.icons +109 -0
  33. novelwriter/assets/icons/remix_filled.icons +109 -0
  34. novelwriter/assets/icons/remix_outline.icons +109 -0
  35. novelwriter/assets/images/splash.png +0 -0
  36. novelwriter/assets/manual.pdf +0 -0
  37. novelwriter/assets/{manual_fr_FR.pdf → manual_fr.pdf} +0 -0
  38. novelwriter/assets/sample.zip +0 -0
  39. novelwriter/assets/syntax/cyberpunk_night.conf +1 -1
  40. novelwriter/assets/syntax/snazzy.conf +3 -3
  41. novelwriter/assets/text/credits_en.htm +12 -6
  42. novelwriter/assets/themes/cyberpunk_night.conf +23 -7
  43. novelwriter/assets/themes/default_dark.conf +20 -4
  44. novelwriter/assets/themes/default_light.conf +21 -5
  45. novelwriter/assets/themes/dracula.conf +20 -4
  46. novelwriter/assets/themes/snazzy.conf +48 -0
  47. novelwriter/assets/themes/solarized_dark.conf +24 -8
  48. novelwriter/assets/themes/solarized_light.conf +22 -6
  49. novelwriter/common.py +43 -27
  50. novelwriter/config.py +201 -139
  51. novelwriter/constants.py +67 -36
  52. novelwriter/core/buildsettings.py +26 -17
  53. novelwriter/core/coretools.py +52 -41
  54. novelwriter/core/docbuild.py +20 -13
  55. novelwriter/core/document.py +2 -2
  56. novelwriter/core/index.py +166 -432
  57. novelwriter/core/indexdata.py +406 -0
  58. novelwriter/core/item.py +50 -32
  59. novelwriter/core/itemmodel.py +43 -38
  60. novelwriter/core/novelmodel.py +225 -0
  61. novelwriter/core/options.py +1 -1
  62. novelwriter/core/project.py +24 -25
  63. novelwriter/core/projectdata.py +47 -29
  64. novelwriter/core/projectxml.py +18 -8
  65. novelwriter/core/sessions.py +32 -15
  66. novelwriter/core/spellcheck.py +4 -3
  67. novelwriter/core/status.py +12 -15
  68. novelwriter/core/storage.py +1 -1
  69. novelwriter/core/tree.py +55 -13
  70. novelwriter/dialogs/about.py +19 -22
  71. novelwriter/dialogs/docmerge.py +23 -24
  72. novelwriter/dialogs/docsplit.py +26 -26
  73. novelwriter/dialogs/editlabel.py +19 -20
  74. novelwriter/dialogs/preferences.py +143 -69
  75. novelwriter/dialogs/projectsettings.py +51 -54
  76. novelwriter/dialogs/quotes.py +14 -19
  77. novelwriter/dialogs/wordlist.py +25 -30
  78. novelwriter/enum.py +8 -0
  79. novelwriter/error.py +16 -16
  80. novelwriter/extensions/configlayout.py +24 -20
  81. novelwriter/extensions/eventfilters.py +9 -5
  82. novelwriter/extensions/modified.py +34 -15
  83. novelwriter/extensions/novelselector.py +18 -5
  84. novelwriter/extensions/pagedsidebar.py +39 -49
  85. novelwriter/extensions/progressbars.py +10 -8
  86. novelwriter/extensions/statusled.py +6 -13
  87. novelwriter/extensions/switch.py +31 -41
  88. novelwriter/extensions/switchbox.py +8 -3
  89. novelwriter/extensions/versioninfo.py +4 -4
  90. novelwriter/formats/shared.py +1 -1
  91. novelwriter/formats/todocx.py +14 -10
  92. novelwriter/formats/tohtml.py +7 -5
  93. novelwriter/formats/tokenizer.py +37 -33
  94. novelwriter/formats/tomarkdown.py +6 -2
  95. novelwriter/formats/toodt.py +27 -22
  96. novelwriter/formats/toqdoc.py +19 -14
  97. novelwriter/formats/toraw.py +6 -2
  98. novelwriter/gui/doceditor.py +314 -305
  99. novelwriter/gui/dochighlight.py +46 -45
  100. novelwriter/gui/docviewer.py +102 -104
  101. novelwriter/gui/docviewerpanel.py +47 -51
  102. novelwriter/gui/editordocument.py +8 -5
  103. novelwriter/gui/itemdetails.py +11 -14
  104. novelwriter/gui/mainmenu.py +146 -145
  105. novelwriter/gui/noveltree.py +246 -406
  106. novelwriter/gui/outline.py +141 -72
  107. novelwriter/gui/projtree.py +139 -132
  108. novelwriter/gui/search.py +34 -31
  109. novelwriter/gui/sidebar.py +13 -18
  110. novelwriter/gui/statusbar.py +27 -21
  111. novelwriter/gui/theme.py +554 -436
  112. novelwriter/guimain.py +56 -38
  113. novelwriter/shared.py +32 -23
  114. novelwriter/splash.py +74 -0
  115. novelwriter/text/comments.py +70 -0
  116. novelwriter/text/patterns.py +4 -4
  117. novelwriter/tools/dictionaries.py +20 -29
  118. novelwriter/tools/lipsum.py +18 -18
  119. novelwriter/tools/manusbuild.py +39 -42
  120. novelwriter/tools/manuscript.py +102 -115
  121. novelwriter/tools/manussettings.py +129 -102
  122. novelwriter/tools/noveldetails.py +60 -72
  123. novelwriter/tools/welcome.py +57 -75
  124. novelwriter/tools/writingstats.py +112 -102
  125. novelwriter/types.py +5 -7
  126. {novelWriter-2.6.3.dist-info → novelwriter-2.7.dist-info}/METADATA +6 -6
  127. novelwriter-2.7.dist-info/RECORD +162 -0
  128. {novelWriter-2.6.3.dist-info → novelwriter-2.7.dist-info}/WHEEL +1 -1
  129. novelWriter-2.6.3.dist-info/RECORD +0 -363
  130. novelwriter/assets/icons/typicons_dark/README.md +0 -29
  131. novelwriter/assets/icons/typicons_dark/icons.conf +0 -134
  132. novelwriter/assets/icons/typicons_dark/mixed_copy.svg +0 -4
  133. novelwriter/assets/icons/typicons_dark/mixed_document-chapter.svg +0 -12
  134. novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +0 -6
  135. novelwriter/assets/icons/typicons_dark/mixed_document-note.svg +0 -12
  136. novelwriter/assets/icons/typicons_dark/mixed_document-scene.svg +0 -12
  137. novelwriter/assets/icons/typicons_dark/mixed_document-section.svg +0 -12
  138. novelwriter/assets/icons/typicons_dark/mixed_document-title.svg +0 -12
  139. novelwriter/assets/icons/typicons_dark/mixed_edit.svg +0 -4
  140. novelwriter/assets/icons/typicons_dark/mixed_import.svg +0 -5
  141. novelwriter/assets/icons/typicons_dark/mixed_input-checked.svg +0 -5
  142. novelwriter/assets/icons/typicons_dark/mixed_input-none.svg +0 -5
  143. novelwriter/assets/icons/typicons_dark/mixed_input-unchecked.svg +0 -5
  144. novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +0 -6
  145. novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +0 -6
  146. novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +0 -6
  147. novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +0 -6
  148. novelwriter/assets/icons/typicons_dark/mixed_search-replace.svg +0 -6
  149. novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +0 -6
  150. novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +0 -6
  151. novelwriter/assets/icons/typicons_dark/nw_deco-h0.svg +0 -4
  152. novelwriter/assets/icons/typicons_dark/nw_deco-h1.svg +0 -4
  153. novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +0 -4
  154. novelwriter/assets/icons/typicons_dark/nw_deco-h2.svg +0 -4
  155. novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +0 -4
  156. novelwriter/assets/icons/typicons_dark/nw_deco-h3.svg +0 -4
  157. novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +0 -4
  158. novelwriter/assets/icons/typicons_dark/nw_deco-h4.svg +0 -4
  159. novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +0 -4
  160. novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg +0 -4
  161. novelwriter/assets/icons/typicons_dark/nw_font.svg +0 -4
  162. novelwriter/assets/icons/typicons_dark/nw_panel.svg +0 -4
  163. novelwriter/assets/icons/typicons_dark/nw_quote.svg +0 -4
  164. novelwriter/assets/icons/typicons_dark/nw_search-case.svg +0 -4
  165. novelwriter/assets/icons/typicons_dark/nw_search-preserve.svg +0 -4
  166. novelwriter/assets/icons/typicons_dark/nw_search-regex.svg +0 -4
  167. novelwriter/assets/icons/typicons_dark/nw_search-word.svg +0 -4
  168. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +0 -4
  169. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +0 -6
  170. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +0 -4
  171. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +0 -6
  172. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +0 -7
  173. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +0 -4
  174. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +0 -6
  175. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +0 -7
  176. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +0 -7
  177. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +0 -7
  178. novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +0 -5
  179. novelwriter/assets/icons/typicons_dark/typ_arrow-down-thick-grey.svg +0 -4
  180. novelwriter/assets/icons/typicons_dark/typ_arrow-forward.svg +0 -4
  181. novelwriter/assets/icons/typicons_dark/typ_arrow-maximise.svg +0 -4
  182. novelwriter/assets/icons/typicons_dark/typ_arrow-minimise.svg +0 -4
  183. novelwriter/assets/icons/typicons_dark/typ_arrow-repeat-grey.svg +0 -4
  184. novelwriter/assets/icons/typicons_dark/typ_book-grey.svg +0 -4
  185. novelwriter/assets/icons/typicons_dark/typ_book.svg +0 -6
  186. novelwriter/assets/icons/typicons_dark/typ_bookmark.svg +0 -4
  187. novelwriter/assets/icons/typicons_dark/typ_calendar.svg +0 -4
  188. novelwriter/assets/icons/typicons_dark/typ_cancel-grey.svg +0 -4
  189. novelwriter/assets/icons/typicons_dark/typ_cancel.svg +0 -4
  190. novelwriter/assets/icons/typicons_dark/typ_chart-bar-grey.svg +0 -4
  191. novelwriter/assets/icons/typicons_dark/typ_chevron-down.svg +0 -4
  192. novelwriter/assets/icons/typicons_dark/typ_chevron-left.svg +0 -4
  193. novelwriter/assets/icons/typicons_dark/typ_chevron-right.svg +0 -4
  194. novelwriter/assets/icons/typicons_dark/typ_chevron-up.svg +0 -4
  195. novelwriter/assets/icons/typicons_dark/typ_cog.svg +0 -4
  196. novelwriter/assets/icons/typicons_dark/typ_delete-full.svg +0 -4
  197. novelwriter/assets/icons/typicons_dark/typ_delete.svg +0 -4
  198. novelwriter/assets/icons/typicons_dark/typ_directions-full.svg +0 -4
  199. novelwriter/assets/icons/typicons_dark/typ_document-add.svg +0 -4
  200. novelwriter/assets/icons/typicons_dark/typ_document-text.svg +0 -8
  201. novelwriter/assets/icons/typicons_dark/typ_document.svg +0 -4
  202. novelwriter/assets/icons/typicons_dark/typ_export-grey.svg +0 -4
  203. novelwriter/assets/icons/typicons_dark/typ_export.svg +0 -4
  204. novelwriter/assets/icons/typicons_dark/typ_eye.svg +0 -4
  205. novelwriter/assets/icons/typicons_dark/typ_flag.svg +0 -4
  206. novelwriter/assets/icons/typicons_dark/typ_folder-open.svg +0 -4
  207. novelwriter/assets/icons/typicons_dark/typ_folder.svg +0 -5
  208. novelwriter/assets/icons/typicons_dark/typ_globe-grey.svg +0 -4
  209. novelwriter/assets/icons/typicons_dark/typ_key.svg +0 -4
  210. novelwriter/assets/icons/typicons_dark/typ_lightbulb-full.svg +0 -4
  211. novelwriter/assets/icons/typicons_dark/typ_location.svg +0 -4
  212. novelwriter/assets/icons/typicons_dark/typ_media-pause-grey.svg +0 -4
  213. novelwriter/assets/icons/typicons_dark/typ_media-record-outline.svg +0 -4
  214. novelwriter/assets/icons/typicons_dark/typ_media-record.svg +0 -4
  215. novelwriter/assets/icons/typicons_dark/typ_minus.svg +0 -4
  216. novelwriter/assets/icons/typicons_dark/typ_pencil.svg +0 -5
  217. novelwriter/assets/icons/typicons_dark/typ_pin-outline.svg +0 -4
  218. novelwriter/assets/icons/typicons_dark/typ_pin.svg +0 -4
  219. novelwriter/assets/icons/typicons_dark/typ_plus.svg +0 -4
  220. novelwriter/assets/icons/typicons_dark/typ_puzzle-outline.svg +0 -4
  221. novelwriter/assets/icons/typicons_dark/typ_puzzle.svg +0 -4
  222. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +0 -4
  223. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +0 -4
  224. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +0 -4
  225. novelwriter/assets/icons/typicons_dark/typ_search.svg +0 -4
  226. novelwriter/assets/icons/typicons_dark/typ_star.svg +0 -4
  227. novelwriter/assets/icons/typicons_dark/typ_stopwatch-grey.svg +0 -4
  228. novelwriter/assets/icons/typicons_dark/typ_th-dot-menu.svg +0 -4
  229. novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +0 -4
  230. novelwriter/assets/icons/typicons_dark/typ_th-list-grey.svg +0 -4
  231. novelwriter/assets/icons/typicons_dark/typ_th-list.svg +0 -9
  232. novelwriter/assets/icons/typicons_dark/typ_times.svg +0 -4
  233. novelwriter/assets/icons/typicons_dark/typ_trash.svg +0 -5
  234. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +0 -4
  235. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +0 -4
  236. novelwriter/assets/icons/typicons_dark/typ_user.svg +0 -5
  237. novelwriter/assets/icons/typicons_dark/typ_warning-full.svg +0 -4
  238. novelwriter/assets/icons/typicons_light/README.md +0 -29
  239. novelwriter/assets/icons/typicons_light/icons.conf +0 -134
  240. novelwriter/assets/icons/typicons_light/mixed_copy.svg +0 -4
  241. novelwriter/assets/icons/typicons_light/mixed_document-chapter.svg +0 -12
  242. novelwriter/assets/icons/typicons_light/mixed_document-new.svg +0 -6
  243. novelwriter/assets/icons/typicons_light/mixed_document-note.svg +0 -12
  244. novelwriter/assets/icons/typicons_light/mixed_document-scene.svg +0 -12
  245. novelwriter/assets/icons/typicons_light/mixed_document-section.svg +0 -12
  246. novelwriter/assets/icons/typicons_light/mixed_document-title.svg +0 -12
  247. novelwriter/assets/icons/typicons_light/mixed_edit.svg +0 -4
  248. novelwriter/assets/icons/typicons_light/mixed_import.svg +0 -5
  249. novelwriter/assets/icons/typicons_light/mixed_input-checked.svg +0 -5
  250. novelwriter/assets/icons/typicons_light/mixed_input-none.svg +0 -5
  251. novelwriter/assets/icons/typicons_light/mixed_input-unchecked.svg +0 -5
  252. novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +0 -6
  253. novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +0 -6
  254. novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +0 -6
  255. novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +0 -6
  256. novelwriter/assets/icons/typicons_light/mixed_search-replace.svg +0 -6
  257. novelwriter/assets/icons/typicons_light/mixed_size-height.svg +0 -6
  258. novelwriter/assets/icons/typicons_light/mixed_size-width.svg +0 -6
  259. novelwriter/assets/icons/typicons_light/nw_deco-h0.svg +0 -4
  260. novelwriter/assets/icons/typicons_light/nw_deco-h1.svg +0 -4
  261. novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +0 -4
  262. novelwriter/assets/icons/typicons_light/nw_deco-h2.svg +0 -4
  263. novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +0 -4
  264. novelwriter/assets/icons/typicons_light/nw_deco-h3.svg +0 -4
  265. novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +0 -4
  266. novelwriter/assets/icons/typicons_light/nw_deco-h4.svg +0 -4
  267. novelwriter/assets/icons/typicons_light/nw_deco-note.svg +0 -4
  268. novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg +0 -4
  269. novelwriter/assets/icons/typicons_light/nw_font.svg +0 -4
  270. novelwriter/assets/icons/typicons_light/nw_panel.svg +0 -4
  271. novelwriter/assets/icons/typicons_light/nw_quote.svg +0 -4
  272. novelwriter/assets/icons/typicons_light/nw_search-case.svg +0 -4
  273. novelwriter/assets/icons/typicons_light/nw_search-preserve.svg +0 -4
  274. novelwriter/assets/icons/typicons_light/nw_search-regex.svg +0 -4
  275. novelwriter/assets/icons/typicons_light/nw_search-word.svg +0 -4
  276. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +0 -4
  277. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +0 -6
  278. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +0 -4
  279. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +0 -6
  280. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +0 -7
  281. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +0 -4
  282. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +0 -6
  283. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +0 -7
  284. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +0 -7
  285. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +0 -7
  286. novelwriter/assets/icons/typicons_light/nw_toolbar.svg +0 -5
  287. novelwriter/assets/icons/typicons_light/typ_arrow-down-thick-grey.svg +0 -4
  288. novelwriter/assets/icons/typicons_light/typ_arrow-forward.svg +0 -4
  289. novelwriter/assets/icons/typicons_light/typ_arrow-maximise.svg +0 -4
  290. novelwriter/assets/icons/typicons_light/typ_arrow-minimise.svg +0 -4
  291. novelwriter/assets/icons/typicons_light/typ_arrow-repeat-grey.svg +0 -4
  292. novelwriter/assets/icons/typicons_light/typ_book-grey.svg +0 -4
  293. novelwriter/assets/icons/typicons_light/typ_book.svg +0 -6
  294. novelwriter/assets/icons/typicons_light/typ_bookmark.svg +0 -4
  295. novelwriter/assets/icons/typicons_light/typ_calendar.svg +0 -4
  296. novelwriter/assets/icons/typicons_light/typ_cancel-grey.svg +0 -4
  297. novelwriter/assets/icons/typicons_light/typ_cancel.svg +0 -4
  298. novelwriter/assets/icons/typicons_light/typ_chart-bar-grey.svg +0 -4
  299. novelwriter/assets/icons/typicons_light/typ_chevron-down.svg +0 -4
  300. novelwriter/assets/icons/typicons_light/typ_chevron-left.svg +0 -4
  301. novelwriter/assets/icons/typicons_light/typ_chevron-right.svg +0 -4
  302. novelwriter/assets/icons/typicons_light/typ_chevron-up.svg +0 -4
  303. novelwriter/assets/icons/typicons_light/typ_cog.svg +0 -4
  304. novelwriter/assets/icons/typicons_light/typ_delete-full.svg +0 -4
  305. novelwriter/assets/icons/typicons_light/typ_delete.svg +0 -4
  306. novelwriter/assets/icons/typicons_light/typ_directions-full.svg +0 -4
  307. novelwriter/assets/icons/typicons_light/typ_document-add.svg +0 -4
  308. novelwriter/assets/icons/typicons_light/typ_document-text.svg +0 -5
  309. novelwriter/assets/icons/typicons_light/typ_document.svg +0 -4
  310. novelwriter/assets/icons/typicons_light/typ_export-grey.svg +0 -4
  311. novelwriter/assets/icons/typicons_light/typ_export.svg +0 -4
  312. novelwriter/assets/icons/typicons_light/typ_eye.svg +0 -4
  313. novelwriter/assets/icons/typicons_light/typ_flag.svg +0 -4
  314. novelwriter/assets/icons/typicons_light/typ_folder-open.svg +0 -4
  315. novelwriter/assets/icons/typicons_light/typ_folder.svg +0 -5
  316. novelwriter/assets/icons/typicons_light/typ_globe-grey.svg +0 -4
  317. novelwriter/assets/icons/typicons_light/typ_key.svg +0 -4
  318. novelwriter/assets/icons/typicons_light/typ_lightbulb-full.svg +0 -4
  319. novelwriter/assets/icons/typicons_light/typ_location.svg +0 -4
  320. novelwriter/assets/icons/typicons_light/typ_media-pause-grey.svg +0 -4
  321. novelwriter/assets/icons/typicons_light/typ_media-record-outline.svg +0 -4
  322. novelwriter/assets/icons/typicons_light/typ_media-record.svg +0 -4
  323. novelwriter/assets/icons/typicons_light/typ_minus.svg +0 -4
  324. novelwriter/assets/icons/typicons_light/typ_pencil.svg +0 -5
  325. novelwriter/assets/icons/typicons_light/typ_pin-outline.svg +0 -4
  326. novelwriter/assets/icons/typicons_light/typ_pin.svg +0 -4
  327. novelwriter/assets/icons/typicons_light/typ_plus.svg +0 -4
  328. novelwriter/assets/icons/typicons_light/typ_puzzle-outline.svg +0 -4
  329. novelwriter/assets/icons/typicons_light/typ_puzzle.svg +0 -4
  330. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +0 -4
  331. novelwriter/assets/icons/typicons_light/typ_refresh.svg +0 -4
  332. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +0 -4
  333. novelwriter/assets/icons/typicons_light/typ_search.svg +0 -4
  334. novelwriter/assets/icons/typicons_light/typ_star.svg +0 -4
  335. novelwriter/assets/icons/typicons_light/typ_stopwatch-grey.svg +0 -4
  336. novelwriter/assets/icons/typicons_light/typ_th-dot-menu.svg +0 -4
  337. novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +0 -4
  338. novelwriter/assets/icons/typicons_light/typ_th-list-grey.svg +0 -4
  339. novelwriter/assets/icons/typicons_light/typ_th-list.svg +0 -9
  340. novelwriter/assets/icons/typicons_light/typ_times.svg +0 -4
  341. novelwriter/assets/icons/typicons_light/typ_trash.svg +0 -5
  342. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +0 -4
  343. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +0 -4
  344. novelwriter/assets/icons/typicons_light/typ_user.svg +0 -5
  345. novelwriter/assets/icons/typicons_light/typ_warning-full.svg +0 -4
  346. {novelWriter-2.6.3.dist-info → novelwriter-2.7.dist-info}/entry_points.txt +0 -0
  347. {novelWriter-2.6.3.dist-info → novelwriter-2.7.dist-info/licenses}/LICENSE.md +0 -0
  348. {novelWriter-2.6.3.dist-info → novelwriter-2.7.dist-info}/top_level.txt +0 -0
@@ -29,20 +29,20 @@ import logging
29
29
 
30
30
  from pathlib import Path
31
31
 
32
- from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
33
- from PyQt5.QtGui import QCloseEvent, QColor
34
- from PyQt5.QtWidgets import (
32
+ from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
33
+ from PyQt6.QtGui import QCloseEvent, QColor
34
+ from PyQt6.QtWidgets import (
35
35
  QAbstractItemView, QApplication, QColorDialog, QDialogButtonBox,
36
36
  QFileDialog, QGridLayout, QHBoxLayout, QLineEdit, QMenu, QStackedWidget,
37
37
  QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
38
38
  )
39
39
 
40
40
  from novelwriter import CONFIG, SHARED
41
- from novelwriter.common import formatFileFilter, qtLambda, simplified
41
+ from novelwriter.common import formatFileFilter, qtAddAction, qtLambda, simplified
42
42
  from novelwriter.constants import nwLabels, trConst
43
43
  from novelwriter.core.status import NWStatus, StatusEntry
44
44
  from novelwriter.enum import nwStatusShape
45
- from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
45
+ from novelwriter.extensions.configlayout import NColorLabel, NFixedPage, NScrollableForm
46
46
  from novelwriter.extensions.modified import NComboBox, NDialog, NIconToolButton
47
47
  from novelwriter.extensions.pagedsidebar import NPagedSideBar
48
48
  from novelwriter.extensions.switch import NSwitch
@@ -71,21 +71,22 @@ class GuiProjectSettings(NDialog):
71
71
  self.setWindowTitle(self.tr("Project Settings"))
72
72
 
73
73
  options = SHARED.project.options
74
- self.setMinimumSize(CONFIG.pxInt(500), CONFIG.pxInt(400))
74
+ self.setMinimumSize(500, 400)
75
75
  self.resize(
76
- CONFIG.pxInt(options.getInt("GuiProjectSettings", "winWidth", CONFIG.pxInt(650))),
77
- CONFIG.pxInt(options.getInt("GuiProjectSettings", "winHeight", CONFIG.pxInt(500)))
76
+ options.getInt("GuiProjectSettings", "winWidth", 650),
77
+ options.getInt("GuiProjectSettings", "winHeight", 500),
78
78
  )
79
79
 
80
80
  # Title
81
- self.titleLabel = NColourLabel(
81
+ self.titleLabel = NColorLabel(
82
82
  self.tr("Project Settings"), self, color=SHARED.theme.helpText,
83
- scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
83
+ scale=NColorLabel.HEADER_SCALE, indent=4,
84
84
  )
85
85
 
86
86
  # SideBar
87
87
  self.sidebar = NPagedSideBar(self)
88
88
  self.sidebar.setLabelColor(SHARED.theme.helpText)
89
+ self.sidebar.setAccessibleName(self.titleLabel.text())
89
90
  self.sidebar.addButton(self.tr("Settings"), self.PAGE_SETTINGS)
90
91
  self.sidebar.addButton(self.tr("Status"), self.PAGE_STATUS)
91
92
  self.sidebar.addButton(self.tr("Importance"), self.PAGE_IMPORT)
@@ -125,7 +126,7 @@ class GuiProjectSettings(NDialog):
125
126
  self.outerBox.addLayout(self.topBox)
126
127
  self.outerBox.addLayout(self.mainBox)
127
128
  self.outerBox.addWidget(self.buttonBox)
128
- self.outerBox.setSpacing(CONFIG.pxInt(8))
129
+ self.outerBox.setSpacing(8)
129
130
 
130
131
  self.setLayout(self.outerBox)
131
132
  self.setSizeGripEnabled(True)
@@ -210,16 +211,14 @@ class GuiProjectSettings(NDialog):
210
211
 
211
212
  def _saveSettings(self) -> None:
212
213
  """Save GUI settings."""
213
- winWidth = CONFIG.rpxInt(self.width())
214
- winHeight = CONFIG.rpxInt(self.height())
215
- statusColW = CONFIG.rpxInt(self.statusPage.columnWidth())
216
- importColW = CONFIG.rpxInt(self.importPage.columnWidth())
217
- replaceColW = CONFIG.rpxInt(self.replacePage.columnWidth())
214
+ statusColW = self.statusPage.columnWidth()
215
+ importColW = self.importPage.columnWidth()
216
+ replaceColW = self.replacePage.columnWidth()
218
217
 
219
218
  logger.debug("Saving State: GuiProjectSettings")
220
219
  options = SHARED.project.options
221
- options.setValue("GuiProjectSettings", "winWidth", winWidth)
222
- options.setValue("GuiProjectSettings", "winHeight", winHeight)
220
+ options.setValue("GuiProjectSettings", "winWidth", self.width())
221
+ options.setValue("GuiProjectSettings", "winHeight", self.height())
223
222
  options.setValue("GuiProjectSettings", "statusColW", statusColW)
224
223
  options.setValue("GuiProjectSettings", "importColW", importColW)
225
224
  options.setValue("GuiProjectSettings", "replaceColW", replaceColW)
@@ -232,7 +231,6 @@ class _SettingsPage(NScrollableForm):
232
231
  def __init__(self, parent: QWidget) -> None:
233
232
  super().__init__(parent=parent)
234
233
 
235
- xW = CONFIG.pxInt(200)
236
234
  data = SHARED.project.data
237
235
  self.setHelpTextStyle(SHARED.theme.helpText)
238
236
  self.setRowIndent(0)
@@ -240,7 +238,7 @@ class _SettingsPage(NScrollableForm):
240
238
  # Project Name
241
239
  self.projName = QLineEdit(self)
242
240
  self.projName.setMaxLength(200)
243
- self.projName.setMinimumWidth(xW)
241
+ self.projName.setMinimumWidth(200)
244
242
  self.projName.setText(data.name)
245
243
  self.addRow(
246
244
  self.tr("Project name"), self.projName,
@@ -251,7 +249,7 @@ class _SettingsPage(NScrollableForm):
251
249
  # Project Author
252
250
  self.projAuthor = QLineEdit(self)
253
251
  self.projAuthor.setMaxLength(200)
254
- self.projAuthor.setMinimumWidth(xW)
252
+ self.projAuthor.setMinimumWidth(200)
255
253
  self.projAuthor.setText(data.author)
256
254
  self.addRow(
257
255
  self.tr("Author(s)"), self.projAuthor,
@@ -262,7 +260,7 @@ class _SettingsPage(NScrollableForm):
262
260
  # Project Language
263
261
  projLang = data.language or CONFIG.guiLocale
264
262
  self.projLang = NComboBox(self)
265
- self.projLang.setMinimumWidth(xW)
263
+ self.projLang.setMinimumWidth(200)
266
264
  for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ):
267
265
  self.projLang.addItem(language, tag)
268
266
  self.projLang.setCurrentData(projLang, projLang)
@@ -274,7 +272,7 @@ class _SettingsPage(NScrollableForm):
274
272
 
275
273
  # Spell Check Language
276
274
  self.spellLang = NComboBox(self)
277
- self.spellLang.setMinimumWidth(xW)
275
+ self.spellLang.setMinimumWidth(200)
278
276
  self.spellLang.addItem(self.tr("Default"), "None")
279
277
  if CONFIG.hasEnchant:
280
278
  for tag, language in SHARED.spelling.listDictionaries():
@@ -323,9 +321,7 @@ class _StatusPage(NFixedPage):
323
321
  pageLabel = self.tr("Project Note Importance Levels")
324
322
  colSetting = "importColW"
325
323
 
326
- wCol0 = CONFIG.pxInt(
327
- SHARED.project.options.getInt("GuiProjectSettings", colSetting, 130)
328
- )
324
+ wCol0 = SHARED.project.options.getInt("GuiProjectSettings", colSetting, 130)
329
325
 
330
326
  self._changed = False
331
327
  self._color = QColor(100, 100, 100)
@@ -334,7 +330,6 @@ class _StatusPage(NFixedPage):
334
330
 
335
331
  self._iPx = SHARED.theme.baseIconHeight
336
332
  iSz = SHARED.theme.baseIconSize
337
- bPd = CONFIG.pxInt(4)
338
333
 
339
334
  iColor = self.palette().text().color()
340
335
 
@@ -345,9 +340,9 @@ class _StatusPage(NFixedPage):
345
340
  self.trSelColor = self.tr("Select Colour")
346
341
 
347
342
  # Title
348
- self.pageTitle = NColourLabel(
343
+ self.pageTitle = NColorLabel(
349
344
  pageLabel, self, color=SHARED.theme.helpText,
350
- scale=NColourLabel.HEADER_SCALE
345
+ scale=NColorLabel.HEADER_SCALE
351
346
  )
352
347
 
353
348
  # List Box
@@ -355,6 +350,7 @@ class _StatusPage(NFixedPage):
355
350
  self.listBox.setHeaderLabels([self.tr("Label"), self.tr("Usage")])
356
351
  self.listBox.setColumnWidth(self.C_LABEL, wCol0)
357
352
  self.listBox.setIndentation(0)
353
+ self.listBox.setAccessibleName(pageLabel)
358
354
  self.listBox.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
359
355
  self.listBox.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
360
356
  self.listBox.itemSelectionChanged.connect(self._onSelectionChanged)
@@ -363,27 +359,27 @@ class _StatusPage(NFixedPage):
363
359
  self._addItem(key, StatusEntry.duplicate(entry))
364
360
 
365
361
  # List Controls
366
- self.addButton = NIconToolButton(self, iSz, "add")
362
+ self.addButton = NIconToolButton(self, iSz, "add", "green")
367
363
  self.addButton.setToolTip(self.tr("Add Label"))
368
364
  self.addButton.clicked.connect(self._onItemCreate)
369
365
 
370
- self.delButton = NIconToolButton(self, iSz, "remove")
366
+ self.delButton = NIconToolButton(self, iSz, "remove", "red")
371
367
  self.delButton.setToolTip(self.tr("Delete Label"))
372
368
  self.delButton.clicked.connect(self._onItemDelete)
373
369
 
374
- self.upButton = NIconToolButton(self, iSz, "up")
370
+ self.upButton = NIconToolButton(self, iSz, "chevron_up", "blue")
375
371
  self.upButton.setToolTip(self.tr("Move Up"))
376
372
  self.upButton.clicked.connect(qtLambda(self._moveItem, -1))
377
373
 
378
- self.downButton = NIconToolButton(self, iSz, "down")
374
+ self.downButton = NIconToolButton(self, iSz, "chevron_down", "blue")
379
375
  self.downButton.setToolTip(self.tr("Move Down"))
380
376
  self.downButton.clicked.connect(qtLambda(self._moveItem, 1))
381
377
 
382
- self.importButton = NIconToolButton(self, iSz, "import")
378
+ self.importButton = NIconToolButton(self, iSz, "import", "green")
383
379
  self.importButton.setToolTip(self.tr("Import Labels"))
384
380
  self.importButton.clicked.connect(self._importLabels)
385
381
 
386
- self.exportButton = NIconToolButton(self, iSz, "export")
382
+ self.exportButton = NIconToolButton(self, iSz, "export", "blue")
387
383
  self.exportButton.setToolTip(self.tr("Export Labels"))
388
384
  self.exportButton.clicked.connect(self._exportLabels)
389
385
 
@@ -395,7 +391,7 @@ class _StatusPage(NFixedPage):
395
391
  self.labelText.textEdited.connect(self._onNameEdit)
396
392
 
397
393
  buttonStyle = (
398
- f"QToolButton {{padding: 0 {bPd}px;}} "
394
+ "QToolButton {padding: 0 4px;} "
399
395
  "QToolButton::menu-indicator {image: none;}"
400
396
  )
401
397
 
@@ -404,14 +400,17 @@ class _StatusPage(NFixedPage):
404
400
  self.colorButton.setSizePolicy(QtSizeMinimum, QtSizeMinimumExpanding)
405
401
  self.colorButton.setStyleSheet(buttonStyle)
406
402
  self.colorButton.setEnabled(False)
407
- self.colorButton.clicked.connect(self._onColourSelect)
408
-
409
- def buildMenu(menu: QMenu, items: dict[nwStatusShape, str]) -> None:
410
- for shape, label in items.items():
411
- icon = NWStatus.createIcon(self._iPx, iColor, shape)
412
- action = menu.addAction(icon, trConst(label))
413
- action.triggered.connect(qtLambda(self._selectShape, shape))
414
- self._icons[shape] = icon
403
+ self.colorButton.clicked.connect(self._onColorSelect)
404
+
405
+ def buildMenu(menu: QMenu | None, items: dict[nwStatusShape, str]) -> None:
406
+ if menu is not None:
407
+ for shape, label in items.items():
408
+ icon = NWStatus.createIcon(self._iPx, iColor, shape)
409
+ action = qtAddAction(menu, trConst(label))
410
+ action.setIcon(icon)
411
+ action.triggered.connect(qtLambda(self._selectShape, shape))
412
+ menu.addAction(action)
413
+ self._icons[shape] = icon
415
414
 
416
415
  self.shapeMenu = QMenu(self)
417
416
  buildMenu(self.shapeMenu, nwLabels.SHAPES_PLAIN)
@@ -498,7 +497,7 @@ class _StatusPage(NFixedPage):
498
497
  return
499
498
 
500
499
  @pyqtSlot()
501
- def _onColourSelect(self) -> None:
500
+ def _onColorSelect(self) -> None:
502
501
  """Open a dialog to select the status icon colour."""
503
502
  if (color := QColorDialog.getColor(self._color, self, self.trSelColor)).isValid():
504
503
  self._color = color
@@ -676,15 +675,12 @@ class _ReplacePage(NFixedPage):
676
675
  self._changed = False
677
676
 
678
677
  iSz = SHARED.theme.baseIconSize
679
-
680
- wCol0 = CONFIG.pxInt(
681
- SHARED.project.options.getInt("GuiProjectSettings", "replaceColW", 130)
682
- )
678
+ wCol0 = SHARED.project.options.getInt("GuiProjectSettings", "replaceColW", 130)
683
679
 
684
680
  # Title
685
- self.pageTitle = NColourLabel(
681
+ self.pageTitle = NColorLabel(
686
682
  self.tr("Text Auto-Replace for Preview and Build"), self,
687
- color=SHARED.theme.helpText, scale=NColourLabel.HEADER_SCALE
683
+ color=SHARED.theme.helpText, scale=NColorLabel.HEADER_SCALE
688
684
  )
689
685
 
690
686
  # List Box
@@ -692,22 +688,23 @@ class _ReplacePage(NFixedPage):
692
688
  self.listBox.setHeaderLabels([self.tr("Keyword"), self.tr("Replace With")])
693
689
  self.listBox.setColumnWidth(self.C_KEY, wCol0)
694
690
  self.listBox.setIndentation(0)
691
+ self.listBox.setAccessibleName(self.pageTitle.text())
695
692
  self.listBox.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
696
693
  self.listBox.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
697
694
  self.listBox.itemSelectionChanged.connect(self._onSelectionChanged)
698
695
 
699
696
  for aKey, aVal in SHARED.project.data.autoReplace.items():
700
- newItem = QTreeWidgetItem(["<%s>" % aKey, aVal])
697
+ newItem = QTreeWidgetItem([f"<{aKey}>", aVal])
701
698
  self.listBox.addTopLevelItem(newItem)
702
699
 
703
700
  self.listBox.sortByColumn(self.C_KEY, Qt.SortOrder.AscendingOrder)
704
701
  self.listBox.setSortingEnabled(True)
705
702
 
706
703
  # List Controls
707
- self.addButton = NIconToolButton(self, iSz, "add")
704
+ self.addButton = NIconToolButton(self, iSz, "add", "green")
708
705
  self.addButton.clicked.connect(self._onEntryCreated)
709
706
 
710
- self.delButton = NIconToolButton(self, iSz, "remove")
707
+ self.delButton = NIconToolButton(self, iSz, "remove", "red")
711
708
  self.delButton.clicked.connect(self._onEntryDeleted)
712
709
 
713
710
  # Edit Form
@@ -25,14 +25,13 @@ from __future__ import annotations
25
25
 
26
26
  import logging
27
27
 
28
- from PyQt5.QtCore import QSize, pyqtSlot
29
- from PyQt5.QtGui import QFontMetrics
30
- from PyQt5.QtWidgets import (
28
+ from PyQt6.QtCore import QSize, pyqtSlot
29
+ from PyQt6.QtGui import QFontMetrics
30
+ from PyQt6.QtWidgets import (
31
31
  QDialogButtonBox, QFrame, QHBoxLayout, QLabel, QListWidget,
32
32
  QListWidgetItem, QVBoxLayout, QWidget
33
33
  )
34
34
 
35
- from novelwriter import CONFIG
36
35
  from novelwriter.constants import nwQuotes, trConst
37
36
  from novelwriter.extensions.modified import NDialog
38
37
  from novelwriter.types import (
@@ -62,18 +61,14 @@ class GuiQuoteSelect(NDialog):
62
61
 
63
62
  self._selected = current
64
63
 
65
- qMetrics = QFontMetrics(self.font())
66
- pxW = 7*qMetrics.boundingRectChar("M").width()
67
- pxH = 7*qMetrics.boundingRectChar("M").height()
68
- pxH = 7*qMetrics.boundingRectChar("M").height()
69
-
70
64
  lblFont = self.font()
71
65
  lblFont.setPointSizeF(4*lblFont.pointSizeF())
66
+ metrics = QFontMetrics(self.font())
72
67
 
73
68
  # Preview Label
74
69
  self.previewLabel = QLabel(current, self)
75
70
  self.previewLabel.setFont(lblFont)
76
- self.previewLabel.setFixedSize(QSize(pxW, pxH))
71
+ self.previewLabel.setFixedSize(QSize(4*metrics.maxWidth(), 5*metrics.height()))
77
72
  self.previewLabel.setAlignment(QtAlignCenter)
78
73
  self.previewLabel.setFrameStyle(QFrame.Shape.Box | QFrame.Shadow.Plain)
79
74
 
@@ -83,16 +78,16 @@ class GuiQuoteSelect(NDialog):
83
78
 
84
79
  minSize = 100
85
80
  for sKey, sLabel in nwQuotes.SYMBOLS.items():
86
- text = "[ %s ] %s" % (sKey, trConst(sLabel))
87
- minSize = max(minSize, qMetrics.boundingRect(text).width())
81
+ text = f"[ {sKey} ] {trConst(sLabel)}"
82
+ minSize = max(minSize, metrics.boundingRect(text).width())
88
83
  qtItem = QListWidgetItem(text)
89
84
  qtItem.setData(self.D_KEY, sKey)
90
85
  self.listBox.addItem(qtItem)
91
86
  if sKey == current:
92
87
  self.listBox.setCurrentItem(qtItem)
93
88
 
94
- self.listBox.setMinimumWidth(minSize + CONFIG.pxInt(40))
95
- self.listBox.setMinimumHeight(CONFIG.pxInt(150))
89
+ self.listBox.setMinimumWidth(minSize + 40)
90
+ self.listBox.setMinimumHeight(150)
96
91
 
97
92
  # Buttons
98
93
  self.buttonBox = QDialogButtonBox(QtDialogOk | QtDialogCancel, self)
@@ -127,11 +122,11 @@ class GuiQuoteSelect(NDialog):
127
122
  @classmethod
128
123
  def getQuote(cls, parent: QWidget, current: str = "") -> tuple[str, bool]:
129
124
  """Pop the dialog and return the result."""
130
- cls = GuiQuoteSelect(parent, current=current)
131
- cls.exec()
132
- quote = cls._selected
133
- accepted = cls.result() == QtAccepted
134
- cls.softDelete()
125
+ dialog = cls(parent, current=current)
126
+ dialog.exec()
127
+ quote = dialog._selected
128
+ accepted = dialog.result() == QtAccepted
129
+ dialog.softDelete()
135
130
  return quote, accepted
136
131
 
137
132
  ##
@@ -26,10 +26,10 @@ from __future__ import annotations
26
26
  import logging
27
27
 
28
28
  from pathlib import Path
29
+ from typing import TYPE_CHECKING
29
30
 
30
- from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
31
- from PyQt5.QtGui import QCloseEvent
32
- from PyQt5.QtWidgets import (
31
+ from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
32
+ from PyQt6.QtWidgets import (
33
33
  QAbstractItemView, QApplication, QDialogButtonBox, QFileDialog,
34
34
  QHBoxLayout, QLineEdit, QListWidget, QVBoxLayout, QWidget
35
35
  )
@@ -37,10 +37,13 @@ from PyQt5.QtWidgets import (
37
37
  from novelwriter import CONFIG, SHARED
38
38
  from novelwriter.common import formatFileFilter
39
39
  from novelwriter.core.spellcheck import UserDictionary
40
- from novelwriter.extensions.configlayout import NColourLabel
40
+ from novelwriter.extensions.configlayout import NColorLabel
41
41
  from novelwriter.extensions.modified import NDialog, NIconToolButton
42
42
  from novelwriter.types import QtDialogClose, QtDialogSave
43
43
 
44
+ if TYPE_CHECKING:
45
+ from PyQt6.QtGui import QCloseEvent
46
+
44
47
  logger = logging.getLogger(__name__)
45
48
 
46
49
 
@@ -56,28 +59,25 @@ class GuiWordList(NDialog):
56
59
  self.setWindowTitle(self.tr("Project Word List"))
57
60
 
58
61
  iSz = SHARED.theme.baseIconSize
59
- mS = CONFIG.pxInt(250)
60
- wW = CONFIG.pxInt(320)
61
- wH = CONFIG.pxInt(340)
62
62
 
63
- self.setMinimumWidth(mS)
64
- self.setMinimumHeight(mS)
63
+ self.setMinimumWidth(250)
64
+ self.setMinimumHeight(250)
65
65
  self.resize(
66
- CONFIG.pxInt(SHARED.project.options.getInt("GuiWordList", "winWidth", wW)),
67
- CONFIG.pxInt(SHARED.project.options.getInt("GuiWordList", "winHeight", wH))
66
+ SHARED.project.options.getInt("GuiWordList", "winWidth", 320),
67
+ SHARED.project.options.getInt("GuiWordList", "winHeight", 340),
68
68
  )
69
69
 
70
70
  # Header
71
- self.headLabel = NColourLabel(
71
+ self.headLabel = NColorLabel(
72
72
  self.tr("Project Word List"), self, color=SHARED.theme.helpText,
73
- scale=NColourLabel.HEADER_SCALE
73
+ scale=NColorLabel.HEADER_SCALE
74
74
  )
75
75
 
76
- self.importButton = NIconToolButton(self, iSz, "import")
76
+ self.importButton = NIconToolButton(self, iSz, "import", "green")
77
77
  self.importButton.setToolTip(self.tr("Import words from text file"))
78
78
  self.importButton.clicked.connect(self._importWords)
79
79
 
80
- self.exportButton = NIconToolButton(self, iSz, "export")
80
+ self.exportButton = NIconToolButton(self, iSz, "export", "blue")
81
81
  self.exportButton.setToolTip(self.tr("Export words to text file"))
82
82
  self.exportButton.clicked.connect(self._exportWords)
83
83
 
@@ -95,11 +95,11 @@ class GuiWordList(NDialog):
95
95
  # Add/Remove Form
96
96
  self.newEntry = QLineEdit(self)
97
97
 
98
- self.addButton = NIconToolButton(self, iSz, "add")
98
+ self.addButton = NIconToolButton(self, iSz, "add", "green")
99
99
  self.addButton.setToolTip(self.tr("Add Word"))
100
100
  self.addButton.clicked.connect(self._doAdd)
101
101
 
102
- self.delButton = NIconToolButton(self, iSz, "remove")
102
+ self.delButton = NIconToolButton(self, iSz, "remove", "red")
103
103
  self.delButton.setToolTip(self.tr("Remove Word"))
104
104
  self.delButton.clicked.connect(self._doDelete)
105
105
 
@@ -118,9 +118,9 @@ class GuiWordList(NDialog):
118
118
  self.outerBox.addLayout(self.headerBox, 0)
119
119
  self.outerBox.addWidget(self.listBox, 1)
120
120
  self.outerBox.addLayout(self.editBox, 0)
121
- self.outerBox.addSpacing(CONFIG.pxInt(12))
121
+ self.outerBox.addSpacing(12)
122
122
  self.outerBox.addWidget(self.buttonBox, 0)
123
- self.outerBox.setSpacing(CONFIG.pxInt(4))
123
+ self.outerBox.setSpacing(4)
124
124
 
125
125
  self.setLayout(self.outerBox)
126
126
 
@@ -230,14 +230,10 @@ class GuiWordList(NDialog):
230
230
 
231
231
  def _saveGuiSettings(self) -> None:
232
232
  """Save GUI settings."""
233
- winWidth = CONFIG.rpxInt(self.width())
234
- winHeight = CONFIG.rpxInt(self.height())
235
-
236
233
  logger.debug("Saving State: GuiWordList")
237
234
  pOptions = SHARED.project.options
238
- pOptions.setValue("GuiWordList", "winWidth", winWidth)
239
- pOptions.setValue("GuiWordList", "winHeight", winHeight)
240
-
235
+ pOptions.setValue("GuiWordList", "winWidth", self.width())
236
+ pOptions.setValue("GuiWordList", "winHeight", self.height())
241
237
  return
242
238
 
243
239
  def _addWord(self, word: str) -> None:
@@ -249,8 +245,7 @@ class GuiWordList(NDialog):
249
245
 
250
246
  def _listWords(self) -> list[str]:
251
247
  """List all words in the list box."""
252
- result = []
253
- for i in range(self.listBox.count()):
254
- if (item := self.listBox.item(i)) and (word := item.text().strip()):
255
- result.append(word)
256
- return result
248
+ return [
249
+ word for i in range(self.listBox.count())
250
+ if (item := self.listBox.item(i)) and (word := item.text().strip())
251
+ ]
novelwriter/enum.py CHANGED
@@ -180,6 +180,14 @@ class nwOutline(Enum):
180
180
  SYNOP = 19
181
181
 
182
182
 
183
+ class nwNovelExtra(Enum):
184
+
185
+ HIDDEN = 0
186
+ POV = 1
187
+ FOCUS = 2
188
+ PLOT = 3
189
+
190
+
183
191
  class nwBuildFmt(Enum):
184
192
 
185
193
  ODT = 0
novelwriter/error.py CHANGED
@@ -29,14 +29,14 @@ import sys
29
29
 
30
30
  from typing import TYPE_CHECKING
31
31
 
32
- from PyQt5.QtCore import Qt, pyqtSlot
33
- from PyQt5.QtGui import QFont, QFontDatabase
34
- from PyQt5.QtWidgets import (
32
+ from PyQt6.QtCore import Qt, pyqtSlot
33
+ from PyQt6.QtGui import QFont, QFontDatabase
34
+ from PyQt6.QtWidgets import (
35
35
  QApplication, QDialog, QDialogButtonBox, QGridLayout, QLabel,
36
36
  QPlainTextEdit, QStyle, QWidget
37
37
  )
38
38
 
39
- if TYPE_CHECKING: # pragma: no cover
39
+ if TYPE_CHECKING:
40
40
  from types import TracebackType
41
41
 
42
42
  logger = logging.getLogger(__name__)
@@ -46,7 +46,7 @@ def logException() -> None:
46
46
  """Log the content of an exception message."""
47
47
  exType, exValue, _ = sys.exc_info()
48
48
  if exType is not None:
49
- logger.error(f"{exType.__name__}: {str(exValue)}", stacklevel=2)
49
+ logger.error(f"{exType.__name__}: {exValue!s}", stacklevel=2)
50
50
  return
51
51
 
52
52
 
@@ -54,7 +54,7 @@ def formatException(exc: BaseException) -> str:
54
54
  """Format an exception as a string the same way the default
55
55
  exception handler does.
56
56
  """
57
- return f"{type(exc).__name__}: {str(exc)}"
57
+ return f"{type(exc).__name__}: {exc!s}"
58
58
 
59
59
 
60
60
  class NWErrorMessage(QDialog):
@@ -65,11 +65,11 @@ class NWErrorMessage(QDialog):
65
65
 
66
66
  # Widgets
67
67
  self.msgIcon = QLabel()
68
- self.msgIcon.setPixmap(
69
- QApplication.style().standardIcon(
70
- QStyle.StandardPixmap.SP_MessageBoxCritical
71
- ).pixmap(64, 64)
72
- )
68
+ if style := QApplication.style():
69
+ self.msgIcon.setPixmap(
70
+ style.standardIcon(QStyle.StandardPixmap.SP_MessageBoxCritical).pixmap(64, 64)
71
+ )
72
+
73
73
  self.msgHead = QLabel()
74
74
  self.msgHead.setOpenExternalLinks(True)
75
75
  self.msgHead.setWordWrap(True)
@@ -118,7 +118,7 @@ class NWErrorMessage(QDialog):
118
118
  """
119
119
  from traceback import format_tb
120
120
 
121
- from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, QSysInfo
121
+ from PyQt6.QtCore import PYQT_VERSION_STR, QT_VERSION_STR, QSysInfo
122
122
 
123
123
  from novelwriter import __version__
124
124
  from novelwriter.constants import nwConst
@@ -144,16 +144,16 @@ class NWErrorMessage(QDialog):
144
144
 
145
145
  try:
146
146
  txtTrace = "\n".join(format_tb(exTrace))
147
- self.msgBody.setPlainText((
147
+ self.msgBody.setPlainText(
148
148
  "Environment:\n"
149
149
  f"novelWriter Version: {__version__}\n"
150
150
  f"Host OS: {sys.platform} ({kernelVersion})\n"
151
151
  f"Python: {sys.version.split()[0]} ({sys.hexversion:#x})\n"
152
152
  f"Qt: {QT_VERSION_STR}, PyQt: {PYQT_VERSION_STR}\n"
153
153
  f"enchant: {enchantVersion}\n\n"
154
- f"{exType.__name__}:\n{str(exValue)}\n\n"
154
+ f"{exType.__name__}:\n{exValue!s}\n\n"
155
155
  f"Traceback:\n{txtTrace}\n"
156
- ))
156
+ )
157
157
  except Exception:
158
158
  self.msgBody.setPlainText("Failed to generate error report ...")
159
159
 
@@ -174,7 +174,7 @@ def exceptionHandler(exType: type, exValue: BaseException, exTrace: TracebackTyp
174
174
  """Function to catch unhandled global exceptions."""
175
175
  from traceback import print_tb
176
176
 
177
- from PyQt5.QtWidgets import QApplication
177
+ from PyQt6.QtWidgets import QApplication
178
178
 
179
179
  logger.critical("%s: %s", exType.__name__, str(exValue))
180
180
  print_tb(exTrace)