novelWriter 2.6.3__py3-none-any.whl → 2.7rc1__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 (325) hide show
  1. novelwriter/__init__.py +98 -75
  2. novelwriter/assets/i18n/project_en_GB.json +2 -0
  3. novelwriter/assets/icons/font_awesome.icons +109 -0
  4. novelwriter/assets/icons/material_filled_bold.icons +109 -0
  5. novelwriter/assets/icons/material_filled_normal.icons +109 -0
  6. novelwriter/assets/icons/material_filled_thin.icons +109 -0
  7. novelwriter/assets/icons/material_rounded_bold.icons +109 -0
  8. novelwriter/assets/icons/material_rounded_normal.icons +109 -0
  9. novelwriter/assets/icons/material_rounded_thin.icons +109 -0
  10. novelwriter/assets/icons/remix_filled.icons +109 -0
  11. novelwriter/assets/icons/remix_outline.icons +109 -0
  12. novelwriter/assets/images/splash.png +0 -0
  13. novelwriter/assets/manual.pdf +0 -0
  14. novelwriter/assets/{manual_fr_FR.pdf → manual_fr.pdf} +0 -0
  15. novelwriter/assets/sample.zip +0 -0
  16. novelwriter/assets/syntax/cyberpunk_night.conf +1 -1
  17. novelwriter/assets/syntax/snazzy.conf +3 -3
  18. novelwriter/assets/text/credits_en.htm +6 -6
  19. novelwriter/assets/themes/cyberpunk_night.conf +23 -7
  20. novelwriter/assets/themes/default_dark.conf +20 -4
  21. novelwriter/assets/themes/default_light.conf +21 -5
  22. novelwriter/assets/themes/dracula.conf +20 -4
  23. novelwriter/assets/themes/snazzy.conf +48 -0
  24. novelwriter/assets/themes/solarized_dark.conf +24 -8
  25. novelwriter/assets/themes/solarized_light.conf +22 -6
  26. novelwriter/common.py +43 -27
  27. novelwriter/config.py +201 -139
  28. novelwriter/constants.py +67 -36
  29. novelwriter/core/buildsettings.py +25 -16
  30. novelwriter/core/coretools.py +52 -41
  31. novelwriter/core/docbuild.py +20 -13
  32. novelwriter/core/document.py +2 -2
  33. novelwriter/core/index.py +166 -432
  34. novelwriter/core/indexdata.py +406 -0
  35. novelwriter/core/item.py +50 -32
  36. novelwriter/core/itemmodel.py +43 -38
  37. novelwriter/core/novelmodel.py +225 -0
  38. novelwriter/core/options.py +1 -1
  39. novelwriter/core/project.py +24 -25
  40. novelwriter/core/projectdata.py +47 -29
  41. novelwriter/core/projectxml.py +18 -8
  42. novelwriter/core/sessions.py +32 -15
  43. novelwriter/core/spellcheck.py +4 -3
  44. novelwriter/core/status.py +12 -15
  45. novelwriter/core/storage.py +1 -1
  46. novelwriter/core/tree.py +55 -13
  47. novelwriter/dialogs/about.py +19 -22
  48. novelwriter/dialogs/docmerge.py +23 -24
  49. novelwriter/dialogs/docsplit.py +26 -26
  50. novelwriter/dialogs/editlabel.py +19 -20
  51. novelwriter/dialogs/preferences.py +143 -69
  52. novelwriter/dialogs/projectsettings.py +51 -54
  53. novelwriter/dialogs/quotes.py +14 -19
  54. novelwriter/dialogs/wordlist.py +25 -30
  55. novelwriter/enum.py +8 -0
  56. novelwriter/error.py +16 -16
  57. novelwriter/extensions/configlayout.py +24 -20
  58. novelwriter/extensions/eventfilters.py +9 -5
  59. novelwriter/extensions/modified.py +34 -15
  60. novelwriter/extensions/novelselector.py +18 -5
  61. novelwriter/extensions/pagedsidebar.py +39 -49
  62. novelwriter/extensions/progressbars.py +10 -8
  63. novelwriter/extensions/statusled.py +6 -13
  64. novelwriter/extensions/switch.py +31 -41
  65. novelwriter/extensions/switchbox.py +8 -3
  66. novelwriter/extensions/versioninfo.py +4 -4
  67. novelwriter/formats/shared.py +1 -1
  68. novelwriter/formats/todocx.py +14 -10
  69. novelwriter/formats/tohtml.py +7 -5
  70. novelwriter/formats/tokenizer.py +37 -33
  71. novelwriter/formats/tomarkdown.py +6 -2
  72. novelwriter/formats/toodt.py +27 -22
  73. novelwriter/formats/toqdoc.py +19 -14
  74. novelwriter/formats/toraw.py +6 -2
  75. novelwriter/gui/doceditor.py +314 -305
  76. novelwriter/gui/dochighlight.py +46 -45
  77. novelwriter/gui/docviewer.py +102 -104
  78. novelwriter/gui/docviewerpanel.py +47 -51
  79. novelwriter/gui/editordocument.py +8 -5
  80. novelwriter/gui/itemdetails.py +11 -14
  81. novelwriter/gui/mainmenu.py +146 -145
  82. novelwriter/gui/noveltree.py +246 -406
  83. novelwriter/gui/outline.py +141 -72
  84. novelwriter/gui/projtree.py +139 -132
  85. novelwriter/gui/search.py +34 -31
  86. novelwriter/gui/sidebar.py +13 -18
  87. novelwriter/gui/statusbar.py +27 -21
  88. novelwriter/gui/theme.py +554 -436
  89. novelwriter/guimain.py +56 -38
  90. novelwriter/shared.py +32 -23
  91. novelwriter/splash.py +74 -0
  92. novelwriter/text/comments.py +70 -0
  93. novelwriter/text/patterns.py +4 -4
  94. novelwriter/tools/dictionaries.py +20 -29
  95. novelwriter/tools/lipsum.py +18 -18
  96. novelwriter/tools/manusbuild.py +39 -42
  97. novelwriter/tools/manuscript.py +102 -115
  98. novelwriter/tools/manussettings.py +116 -96
  99. novelwriter/tools/noveldetails.py +60 -72
  100. novelwriter/tools/welcome.py +57 -75
  101. novelwriter/tools/writingstats.py +112 -102
  102. novelwriter/types.py +5 -7
  103. {novelWriter-2.6.3.dist-info → novelwriter-2.7rc1.dist-info}/METADATA +6 -6
  104. novelwriter-2.7rc1.dist-info/RECORD +162 -0
  105. {novelWriter-2.6.3.dist-info → novelwriter-2.7rc1.dist-info}/WHEEL +1 -1
  106. novelWriter-2.6.3.dist-info/RECORD +0 -363
  107. novelwriter/assets/icons/typicons_dark/README.md +0 -29
  108. novelwriter/assets/icons/typicons_dark/icons.conf +0 -134
  109. novelwriter/assets/icons/typicons_dark/mixed_copy.svg +0 -4
  110. novelwriter/assets/icons/typicons_dark/mixed_document-chapter.svg +0 -12
  111. novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +0 -6
  112. novelwriter/assets/icons/typicons_dark/mixed_document-note.svg +0 -12
  113. novelwriter/assets/icons/typicons_dark/mixed_document-scene.svg +0 -12
  114. novelwriter/assets/icons/typicons_dark/mixed_document-section.svg +0 -12
  115. novelwriter/assets/icons/typicons_dark/mixed_document-title.svg +0 -12
  116. novelwriter/assets/icons/typicons_dark/mixed_edit.svg +0 -4
  117. novelwriter/assets/icons/typicons_dark/mixed_import.svg +0 -5
  118. novelwriter/assets/icons/typicons_dark/mixed_input-checked.svg +0 -5
  119. novelwriter/assets/icons/typicons_dark/mixed_input-none.svg +0 -5
  120. novelwriter/assets/icons/typicons_dark/mixed_input-unchecked.svg +0 -5
  121. novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +0 -6
  122. novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +0 -6
  123. novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +0 -6
  124. novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +0 -6
  125. novelwriter/assets/icons/typicons_dark/mixed_search-replace.svg +0 -6
  126. novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +0 -6
  127. novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +0 -6
  128. novelwriter/assets/icons/typicons_dark/nw_deco-h0.svg +0 -4
  129. novelwriter/assets/icons/typicons_dark/nw_deco-h1.svg +0 -4
  130. novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +0 -4
  131. novelwriter/assets/icons/typicons_dark/nw_deco-h2.svg +0 -4
  132. novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +0 -4
  133. novelwriter/assets/icons/typicons_dark/nw_deco-h3.svg +0 -4
  134. novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +0 -4
  135. novelwriter/assets/icons/typicons_dark/nw_deco-h4.svg +0 -4
  136. novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +0 -4
  137. novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg +0 -4
  138. novelwriter/assets/icons/typicons_dark/nw_font.svg +0 -4
  139. novelwriter/assets/icons/typicons_dark/nw_panel.svg +0 -4
  140. novelwriter/assets/icons/typicons_dark/nw_quote.svg +0 -4
  141. novelwriter/assets/icons/typicons_dark/nw_search-case.svg +0 -4
  142. novelwriter/assets/icons/typicons_dark/nw_search-preserve.svg +0 -4
  143. novelwriter/assets/icons/typicons_dark/nw_search-regex.svg +0 -4
  144. novelwriter/assets/icons/typicons_dark/nw_search-word.svg +0 -4
  145. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +0 -4
  146. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +0 -6
  147. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +0 -4
  148. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +0 -6
  149. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +0 -7
  150. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +0 -4
  151. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +0 -6
  152. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +0 -7
  153. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +0 -7
  154. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +0 -7
  155. novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +0 -5
  156. novelwriter/assets/icons/typicons_dark/typ_arrow-down-thick-grey.svg +0 -4
  157. novelwriter/assets/icons/typicons_dark/typ_arrow-forward.svg +0 -4
  158. novelwriter/assets/icons/typicons_dark/typ_arrow-maximise.svg +0 -4
  159. novelwriter/assets/icons/typicons_dark/typ_arrow-minimise.svg +0 -4
  160. novelwriter/assets/icons/typicons_dark/typ_arrow-repeat-grey.svg +0 -4
  161. novelwriter/assets/icons/typicons_dark/typ_book-grey.svg +0 -4
  162. novelwriter/assets/icons/typicons_dark/typ_book.svg +0 -6
  163. novelwriter/assets/icons/typicons_dark/typ_bookmark.svg +0 -4
  164. novelwriter/assets/icons/typicons_dark/typ_calendar.svg +0 -4
  165. novelwriter/assets/icons/typicons_dark/typ_cancel-grey.svg +0 -4
  166. novelwriter/assets/icons/typicons_dark/typ_cancel.svg +0 -4
  167. novelwriter/assets/icons/typicons_dark/typ_chart-bar-grey.svg +0 -4
  168. novelwriter/assets/icons/typicons_dark/typ_chevron-down.svg +0 -4
  169. novelwriter/assets/icons/typicons_dark/typ_chevron-left.svg +0 -4
  170. novelwriter/assets/icons/typicons_dark/typ_chevron-right.svg +0 -4
  171. novelwriter/assets/icons/typicons_dark/typ_chevron-up.svg +0 -4
  172. novelwriter/assets/icons/typicons_dark/typ_cog.svg +0 -4
  173. novelwriter/assets/icons/typicons_dark/typ_delete-full.svg +0 -4
  174. novelwriter/assets/icons/typicons_dark/typ_delete.svg +0 -4
  175. novelwriter/assets/icons/typicons_dark/typ_directions-full.svg +0 -4
  176. novelwriter/assets/icons/typicons_dark/typ_document-add.svg +0 -4
  177. novelwriter/assets/icons/typicons_dark/typ_document-text.svg +0 -8
  178. novelwriter/assets/icons/typicons_dark/typ_document.svg +0 -4
  179. novelwriter/assets/icons/typicons_dark/typ_export-grey.svg +0 -4
  180. novelwriter/assets/icons/typicons_dark/typ_export.svg +0 -4
  181. novelwriter/assets/icons/typicons_dark/typ_eye.svg +0 -4
  182. novelwriter/assets/icons/typicons_dark/typ_flag.svg +0 -4
  183. novelwriter/assets/icons/typicons_dark/typ_folder-open.svg +0 -4
  184. novelwriter/assets/icons/typicons_dark/typ_folder.svg +0 -5
  185. novelwriter/assets/icons/typicons_dark/typ_globe-grey.svg +0 -4
  186. novelwriter/assets/icons/typicons_dark/typ_key.svg +0 -4
  187. novelwriter/assets/icons/typicons_dark/typ_lightbulb-full.svg +0 -4
  188. novelwriter/assets/icons/typicons_dark/typ_location.svg +0 -4
  189. novelwriter/assets/icons/typicons_dark/typ_media-pause-grey.svg +0 -4
  190. novelwriter/assets/icons/typicons_dark/typ_media-record-outline.svg +0 -4
  191. novelwriter/assets/icons/typicons_dark/typ_media-record.svg +0 -4
  192. novelwriter/assets/icons/typicons_dark/typ_minus.svg +0 -4
  193. novelwriter/assets/icons/typicons_dark/typ_pencil.svg +0 -5
  194. novelwriter/assets/icons/typicons_dark/typ_pin-outline.svg +0 -4
  195. novelwriter/assets/icons/typicons_dark/typ_pin.svg +0 -4
  196. novelwriter/assets/icons/typicons_dark/typ_plus.svg +0 -4
  197. novelwriter/assets/icons/typicons_dark/typ_puzzle-outline.svg +0 -4
  198. novelwriter/assets/icons/typicons_dark/typ_puzzle.svg +0 -4
  199. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +0 -4
  200. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +0 -4
  201. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +0 -4
  202. novelwriter/assets/icons/typicons_dark/typ_search.svg +0 -4
  203. novelwriter/assets/icons/typicons_dark/typ_star.svg +0 -4
  204. novelwriter/assets/icons/typicons_dark/typ_stopwatch-grey.svg +0 -4
  205. novelwriter/assets/icons/typicons_dark/typ_th-dot-menu.svg +0 -4
  206. novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +0 -4
  207. novelwriter/assets/icons/typicons_dark/typ_th-list-grey.svg +0 -4
  208. novelwriter/assets/icons/typicons_dark/typ_th-list.svg +0 -9
  209. novelwriter/assets/icons/typicons_dark/typ_times.svg +0 -4
  210. novelwriter/assets/icons/typicons_dark/typ_trash.svg +0 -5
  211. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +0 -4
  212. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +0 -4
  213. novelwriter/assets/icons/typicons_dark/typ_user.svg +0 -5
  214. novelwriter/assets/icons/typicons_dark/typ_warning-full.svg +0 -4
  215. novelwriter/assets/icons/typicons_light/README.md +0 -29
  216. novelwriter/assets/icons/typicons_light/icons.conf +0 -134
  217. novelwriter/assets/icons/typicons_light/mixed_copy.svg +0 -4
  218. novelwriter/assets/icons/typicons_light/mixed_document-chapter.svg +0 -12
  219. novelwriter/assets/icons/typicons_light/mixed_document-new.svg +0 -6
  220. novelwriter/assets/icons/typicons_light/mixed_document-note.svg +0 -12
  221. novelwriter/assets/icons/typicons_light/mixed_document-scene.svg +0 -12
  222. novelwriter/assets/icons/typicons_light/mixed_document-section.svg +0 -12
  223. novelwriter/assets/icons/typicons_light/mixed_document-title.svg +0 -12
  224. novelwriter/assets/icons/typicons_light/mixed_edit.svg +0 -4
  225. novelwriter/assets/icons/typicons_light/mixed_import.svg +0 -5
  226. novelwriter/assets/icons/typicons_light/mixed_input-checked.svg +0 -5
  227. novelwriter/assets/icons/typicons_light/mixed_input-none.svg +0 -5
  228. novelwriter/assets/icons/typicons_light/mixed_input-unchecked.svg +0 -5
  229. novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +0 -6
  230. novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +0 -6
  231. novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +0 -6
  232. novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +0 -6
  233. novelwriter/assets/icons/typicons_light/mixed_search-replace.svg +0 -6
  234. novelwriter/assets/icons/typicons_light/mixed_size-height.svg +0 -6
  235. novelwriter/assets/icons/typicons_light/mixed_size-width.svg +0 -6
  236. novelwriter/assets/icons/typicons_light/nw_deco-h0.svg +0 -4
  237. novelwriter/assets/icons/typicons_light/nw_deco-h1.svg +0 -4
  238. novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +0 -4
  239. novelwriter/assets/icons/typicons_light/nw_deco-h2.svg +0 -4
  240. novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +0 -4
  241. novelwriter/assets/icons/typicons_light/nw_deco-h3.svg +0 -4
  242. novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +0 -4
  243. novelwriter/assets/icons/typicons_light/nw_deco-h4.svg +0 -4
  244. novelwriter/assets/icons/typicons_light/nw_deco-note.svg +0 -4
  245. novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg +0 -4
  246. novelwriter/assets/icons/typicons_light/nw_font.svg +0 -4
  247. novelwriter/assets/icons/typicons_light/nw_panel.svg +0 -4
  248. novelwriter/assets/icons/typicons_light/nw_quote.svg +0 -4
  249. novelwriter/assets/icons/typicons_light/nw_search-case.svg +0 -4
  250. novelwriter/assets/icons/typicons_light/nw_search-preserve.svg +0 -4
  251. novelwriter/assets/icons/typicons_light/nw_search-regex.svg +0 -4
  252. novelwriter/assets/icons/typicons_light/nw_search-word.svg +0 -4
  253. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +0 -4
  254. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +0 -6
  255. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +0 -4
  256. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +0 -6
  257. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +0 -7
  258. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +0 -4
  259. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +0 -6
  260. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +0 -7
  261. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +0 -7
  262. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +0 -7
  263. novelwriter/assets/icons/typicons_light/nw_toolbar.svg +0 -5
  264. novelwriter/assets/icons/typicons_light/typ_arrow-down-thick-grey.svg +0 -4
  265. novelwriter/assets/icons/typicons_light/typ_arrow-forward.svg +0 -4
  266. novelwriter/assets/icons/typicons_light/typ_arrow-maximise.svg +0 -4
  267. novelwriter/assets/icons/typicons_light/typ_arrow-minimise.svg +0 -4
  268. novelwriter/assets/icons/typicons_light/typ_arrow-repeat-grey.svg +0 -4
  269. novelwriter/assets/icons/typicons_light/typ_book-grey.svg +0 -4
  270. novelwriter/assets/icons/typicons_light/typ_book.svg +0 -6
  271. novelwriter/assets/icons/typicons_light/typ_bookmark.svg +0 -4
  272. novelwriter/assets/icons/typicons_light/typ_calendar.svg +0 -4
  273. novelwriter/assets/icons/typicons_light/typ_cancel-grey.svg +0 -4
  274. novelwriter/assets/icons/typicons_light/typ_cancel.svg +0 -4
  275. novelwriter/assets/icons/typicons_light/typ_chart-bar-grey.svg +0 -4
  276. novelwriter/assets/icons/typicons_light/typ_chevron-down.svg +0 -4
  277. novelwriter/assets/icons/typicons_light/typ_chevron-left.svg +0 -4
  278. novelwriter/assets/icons/typicons_light/typ_chevron-right.svg +0 -4
  279. novelwriter/assets/icons/typicons_light/typ_chevron-up.svg +0 -4
  280. novelwriter/assets/icons/typicons_light/typ_cog.svg +0 -4
  281. novelwriter/assets/icons/typicons_light/typ_delete-full.svg +0 -4
  282. novelwriter/assets/icons/typicons_light/typ_delete.svg +0 -4
  283. novelwriter/assets/icons/typicons_light/typ_directions-full.svg +0 -4
  284. novelwriter/assets/icons/typicons_light/typ_document-add.svg +0 -4
  285. novelwriter/assets/icons/typicons_light/typ_document-text.svg +0 -5
  286. novelwriter/assets/icons/typicons_light/typ_document.svg +0 -4
  287. novelwriter/assets/icons/typicons_light/typ_export-grey.svg +0 -4
  288. novelwriter/assets/icons/typicons_light/typ_export.svg +0 -4
  289. novelwriter/assets/icons/typicons_light/typ_eye.svg +0 -4
  290. novelwriter/assets/icons/typicons_light/typ_flag.svg +0 -4
  291. novelwriter/assets/icons/typicons_light/typ_folder-open.svg +0 -4
  292. novelwriter/assets/icons/typicons_light/typ_folder.svg +0 -5
  293. novelwriter/assets/icons/typicons_light/typ_globe-grey.svg +0 -4
  294. novelwriter/assets/icons/typicons_light/typ_key.svg +0 -4
  295. novelwriter/assets/icons/typicons_light/typ_lightbulb-full.svg +0 -4
  296. novelwriter/assets/icons/typicons_light/typ_location.svg +0 -4
  297. novelwriter/assets/icons/typicons_light/typ_media-pause-grey.svg +0 -4
  298. novelwriter/assets/icons/typicons_light/typ_media-record-outline.svg +0 -4
  299. novelwriter/assets/icons/typicons_light/typ_media-record.svg +0 -4
  300. novelwriter/assets/icons/typicons_light/typ_minus.svg +0 -4
  301. novelwriter/assets/icons/typicons_light/typ_pencil.svg +0 -5
  302. novelwriter/assets/icons/typicons_light/typ_pin-outline.svg +0 -4
  303. novelwriter/assets/icons/typicons_light/typ_pin.svg +0 -4
  304. novelwriter/assets/icons/typicons_light/typ_plus.svg +0 -4
  305. novelwriter/assets/icons/typicons_light/typ_puzzle-outline.svg +0 -4
  306. novelwriter/assets/icons/typicons_light/typ_puzzle.svg +0 -4
  307. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +0 -4
  308. novelwriter/assets/icons/typicons_light/typ_refresh.svg +0 -4
  309. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +0 -4
  310. novelwriter/assets/icons/typicons_light/typ_search.svg +0 -4
  311. novelwriter/assets/icons/typicons_light/typ_star.svg +0 -4
  312. novelwriter/assets/icons/typicons_light/typ_stopwatch-grey.svg +0 -4
  313. novelwriter/assets/icons/typicons_light/typ_th-dot-menu.svg +0 -4
  314. novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +0 -4
  315. novelwriter/assets/icons/typicons_light/typ_th-list-grey.svg +0 -4
  316. novelwriter/assets/icons/typicons_light/typ_th-list.svg +0 -9
  317. novelwriter/assets/icons/typicons_light/typ_times.svg +0 -4
  318. novelwriter/assets/icons/typicons_light/typ_trash.svg +0 -5
  319. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +0 -4
  320. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +0 -4
  321. novelwriter/assets/icons/typicons_light/typ_user.svg +0 -5
  322. novelwriter/assets/icons/typicons_light/typ_warning-full.svg +0 -4
  323. {novelWriter-2.6.3.dist-info → novelwriter-2.7rc1.dist-info}/entry_points.txt +0 -0
  324. {novelWriter-2.6.3.dist-info → novelwriter-2.7rc1.dist-info/licenses}/LICENSE.md +0 -0
  325. {novelWriter-2.6.3.dist-info → novelwriter-2.7rc1.dist-info}/top_level.txt +0 -0
@@ -26,24 +26,28 @@ from __future__ import annotations
26
26
  import logging
27
27
  import math
28
28
 
29
- from PyQt5.QtCore import pyqtSlot
30
- from PyQt5.QtGui import QCloseEvent
31
- from PyQt5.QtWidgets import (
29
+ from typing import TYPE_CHECKING
30
+
31
+ from PyQt6.QtCore import pyqtSlot
32
+ from PyQt6.QtWidgets import (
32
33
  QAbstractItemView, QDialogButtonBox, QFormLayout, QGridLayout, QHBoxLayout,
33
34
  QLabel, QSpinBox, QStackedWidget, QTreeWidget, QTreeWidgetItem,
34
35
  QVBoxLayout, QWidget
35
36
  )
36
37
 
37
- from novelwriter import CONFIG, SHARED
38
+ from novelwriter import SHARED
38
39
  from novelwriter.common import formatTime, numberToRoman
39
40
  from novelwriter.constants import nwUnicode
40
- from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
41
+ from novelwriter.extensions.configlayout import NColorLabel, NFixedPage, NScrollablePage
41
42
  from novelwriter.extensions.modified import NNonBlockingDialog
42
43
  from novelwriter.extensions.novelselector import NovelSelector
43
44
  from novelwriter.extensions.pagedsidebar import NPagedSideBar
44
45
  from novelwriter.extensions.switch import NSwitch
45
46
  from novelwriter.types import QtAlignRight, QtDecoration, QtDialogClose
46
47
 
48
+ if TYPE_CHECKING:
49
+ from PyQt6.QtGui import QCloseEvent
50
+
47
51
  logger = logging.getLogger(__name__)
48
52
 
49
53
 
@@ -60,16 +64,16 @@ class GuiNovelDetails(NNonBlockingDialog):
60
64
  self.setWindowTitle(self.tr("Novel Details"))
61
65
 
62
66
  options = SHARED.project.options
63
- self.setMinimumSize(CONFIG.pxInt(500), CONFIG.pxInt(400))
67
+ self.setMinimumSize(500, 400)
64
68
  self.resize(
65
- CONFIG.pxInt(options.getInt("GuiNovelDetails", "winWidth", CONFIG.pxInt(650))),
66
- CONFIG.pxInt(options.getInt("GuiNovelDetails", "winHeight", CONFIG.pxInt(500)))
69
+ options.getInt("GuiNovelDetails", "winWidth", 650),
70
+ options.getInt("GuiNovelDetails", "winHeight", 500),
67
71
  )
68
72
 
69
73
  # Title
70
- self.titleLabel = NColourLabel(
74
+ self.titleLabel = NColorLabel(
71
75
  self.tr("Novel Details"), self, color=SHARED.theme.helpText,
72
- scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
76
+ scale=NColorLabel.HEADER_SCALE, indent=4,
73
77
  )
74
78
 
75
79
  # Novel Selector
@@ -82,6 +86,7 @@ class GuiNovelDetails(NNonBlockingDialog):
82
86
  # SideBar
83
87
  self.sidebar = NPagedSideBar(self)
84
88
  self.sidebar.setLabelColor(SHARED.theme.helpText)
89
+ self.sidebar.setAccessibleName(self.titleLabel.text())
85
90
  self.sidebar.addButton(self.tr("Overview"), self.PAGE_OVERVIEW)
86
91
  self.sidebar.addButton(self.tr("Contents"), self.PAGE_CONTENTS)
87
92
  self.sidebar.setSelected(self.PAGE_OVERVIEW)
@@ -114,7 +119,7 @@ class GuiNovelDetails(NNonBlockingDialog):
114
119
  self.outerBox.addLayout(self.topBox)
115
120
  self.outerBox.addLayout(self.mainBox)
116
121
  self.outerBox.addWidget(self.buttonBox)
117
- self.outerBox.setSpacing(CONFIG.pxInt(8))
122
+ self.outerBox.setSpacing(8)
118
123
 
119
124
  self.setLayout(self.outerBox)
120
125
  self.setSizeGripEnabled(True)
@@ -137,9 +142,10 @@ class GuiNovelDetails(NNonBlockingDialog):
137
142
 
138
143
  def updateValues(self) -> None:
139
144
  """Load the dialogs initial values."""
140
- self.overviewPage.updateProjectData()
141
- self.overviewPage.novelValueChanged(self.novelSelector.handle)
142
- self.contentsPage.novelValueChanged(self.novelSelector.handle)
145
+ if handle := self.novelSelector.handle:
146
+ self.overviewPage.updateProjectData()
147
+ self.overviewPage.novelValueChanged(handle)
148
+ self.contentsPage.novelValueChanged(handle)
143
149
  return
144
150
 
145
151
  ##
@@ -172,18 +178,13 @@ class GuiNovelDetails(NNonBlockingDialog):
172
178
 
173
179
  def _saveSettings(self) -> None:
174
180
  """Save the user GUI settings."""
175
- winWidth = CONFIG.rpxInt(self.width())
176
- winHeight = CONFIG.rpxInt(self.height())
177
- novelRoot = self.novelSelector.handle
178
-
179
181
  logger.debug("Saving State: GuiNovelDetails")
182
+ novelRoot = self.novelSelector.handle
180
183
  options = SHARED.project.options
181
- options.setValue("GuiNovelDetails", "winWidth", winWidth)
182
- options.setValue("GuiNovelDetails", "winHeight", winHeight)
184
+ options.setValue("GuiNovelDetails", "winWidth", self.width())
185
+ options.setValue("GuiNovelDetails", "winHeight", self.height())
183
186
  options.setValue("GuiNovelDetails", "novelRoot", novelRoot)
184
-
185
187
  self.contentsPage.saveSettings()
186
-
187
188
  return
188
189
 
189
190
 
@@ -192,15 +193,10 @@ class _OverviewPage(NScrollablePage):
192
193
  def __init__(self, parent: QWidget) -> None:
193
194
  super().__init__(parent=parent)
194
195
 
195
- mPx = CONFIG.pxInt(8)
196
- sPx = CONFIG.pxInt(16)
197
- hPx = CONFIG.pxInt(24)
198
- vPx = CONFIG.pxInt(4)
199
-
200
196
  # Project Info
201
- self.projLabel = NColourLabel(
197
+ self.projLabel = NColorLabel(
202
198
  self.tr("Project"), self, color=SHARED.theme.helpText,
203
- scale=NColourLabel.HEADER_SCALE
199
+ scale=NColorLabel.HEADER_SCALE
204
200
  )
205
201
 
206
202
  self.projName = QLabel("", self)
@@ -217,14 +213,14 @@ class _OverviewPage(NScrollablePage):
217
213
  self.projForm.addRow("<b>{0}</b>".format(self.tr("Word Count")), self.projWords)
218
214
  self.projForm.addRow("<b>\u2026 {0}</b>".format(self.tr("In Novels")), self.projNovels)
219
215
  self.projForm.addRow("<b>\u2026 {0}</b>".format(self.tr("In Notes")), self.projNotes)
220
- self.projForm.setContentsMargins(mPx, 0, 0, 0)
221
- self.projForm.setHorizontalSpacing(hPx)
222
- self.projForm.setVerticalSpacing(vPx)
216
+ self.projForm.setContentsMargins(8, 0, 0, 0)
217
+ self.projForm.setHorizontalSpacing(24)
218
+ self.projForm.setVerticalSpacing(4)
223
219
 
224
220
  # Novel Info
225
- self.novelLabel = NColourLabel(
221
+ self.novelLabel = NColorLabel(
226
222
  self.tr("Selected Novel"), self, color=SHARED.theme.helpText,
227
- scale=NColourLabel.HEADER_SCALE
223
+ scale=NColorLabel.HEADER_SCALE
228
224
  )
229
225
 
230
226
  self.novelName = QLabel("", self)
@@ -237,9 +233,9 @@ class _OverviewPage(NScrollablePage):
237
233
  self.novelForm.addRow("<b>{0}</b>".format(self.tr("Word Count")), self.novelWords)
238
234
  self.novelForm.addRow("<b>{0}</b>".format(self.tr("Chapters")), self.novelChapters)
239
235
  self.novelForm.addRow("<b>{0}</b>".format(self.tr("Scenes")), self.novelScenes)
240
- self.novelForm.setContentsMargins(mPx, 0, 0, 0)
241
- self.novelForm.setHorizontalSpacing(hPx)
242
- self.novelForm.setVerticalSpacing(vPx)
236
+ self.novelForm.setContentsMargins(8, 0, 0, 0)
237
+ self.novelForm.setHorizontalSpacing(24)
238
+ self.novelForm.setVerticalSpacing(4)
243
239
 
244
240
  # Assemble
245
241
  self.outerBox = QVBoxLayout()
@@ -247,7 +243,7 @@ class _OverviewPage(NScrollablePage):
247
243
  self.outerBox.addLayout(self.projForm)
248
244
  self.outerBox.addWidget(self.novelLabel)
249
245
  self.outerBox.addLayout(self.novelForm)
250
- self.outerBox.setSpacing(sPx)
246
+ self.outerBox.setSpacing(16)
251
247
  self.outerBox.addStretch(1)
252
248
 
253
249
  self.setCentralLayout(self.outerBox)
@@ -261,8 +257,8 @@ class _OverviewPage(NScrollablePage):
261
257
  def updateProjectData(self) -> None:
262
258
  """Load information about the project."""
263
259
  project = SHARED.project
264
- project.updateWordCounts()
265
- wcNovel, wcNotes = project.data.currCounts
260
+ project.updateCounts()
261
+ wcNovel, wcNotes, _, _ = project.data.currCounts
266
262
 
267
263
  self.projName.setText(project.data.name)
268
264
  self.projRevisions.setText(f"{project.data.saveCount:n}")
@@ -309,14 +305,12 @@ class _ContentsPage(NFixedPage):
309
305
 
310
306
  iPx = SHARED.theme.baseIconHeight
311
307
  iSz = SHARED.theme.baseIconSize
312
- hPx = CONFIG.pxInt(12)
313
- vPx = CONFIG.pxInt(4)
314
308
  options = SHARED.project.options
315
309
 
316
310
  # Title
317
- self.contentLabel = NColourLabel(
311
+ self.contentLabel = NColorLabel(
318
312
  self.tr("Table of Contents"), self, color=SHARED.theme.helpText,
319
- scale=NColourLabel.HEADER_SCALE
313
+ scale=NColorLabel.HEADER_SCALE
320
314
  )
321
315
 
322
316
  # Contents Tree
@@ -341,38 +335,36 @@ class _ContentsPage(NFixedPage):
341
335
  treeHeadItem.setTextAlignment(self.C_PAGE, QtAlignRight)
342
336
  treeHeadItem.setTextAlignment(self.C_PROG, QtAlignRight)
343
337
 
344
- treeHeader = self.tocTree.header()
345
- treeHeader.setStretchLastSection(True)
346
- treeHeader.setMinimumSectionSize(hPx)
338
+ if header := self.tocTree.header():
339
+ header.setStretchLastSection(True)
340
+ header.setMinimumSectionSize(12)
347
341
 
348
- wCol0 = CONFIG.pxInt(options.getInt("GuiNovelDetails", "widthCol0", 200))
349
- wCol1 = CONFIG.pxInt(options.getInt("GuiNovelDetails", "widthCol1", 60))
350
- wCol2 = CONFIG.pxInt(options.getInt("GuiNovelDetails", "widthCol2", 60))
351
- wCol3 = CONFIG.pxInt(options.getInt("GuiNovelDetails", "widthCol3", 60))
352
- wCol4 = CONFIG.pxInt(options.getInt("GuiNovelDetails", "widthCol4", 90))
342
+ wCol0 = options.getInt("GuiNovelDetails", "widthCol0", 200)
343
+ wCol1 = options.getInt("GuiNovelDetails", "widthCol1", 60)
344
+ wCol2 = options.getInt("GuiNovelDetails", "widthCol2", 60)
345
+ wCol3 = options.getInt("GuiNovelDetails", "widthCol3", 60)
346
+ wCol4 = options.getInt("GuiNovelDetails", "widthCol4", 90)
353
347
 
354
348
  self.tocTree.setColumnWidth(0, wCol0)
355
349
  self.tocTree.setColumnWidth(1, wCol1)
356
350
  self.tocTree.setColumnWidth(2, wCol2)
357
351
  self.tocTree.setColumnWidth(3, wCol3)
358
352
  self.tocTree.setColumnWidth(4, wCol4)
359
- self.tocTree.setColumnWidth(5, hPx)
353
+ self.tocTree.setColumnWidth(5, 12)
360
354
 
361
355
  # Options
362
356
  wordsPerPage = options.getInt("GuiNovelDetails", "wordsPerPage", 350)
363
357
  countFrom = options.getInt("GuiNovelDetails", "countFrom", 1)
364
358
  clearDouble = options.getBool("GuiNovelDetails", "clearDouble", True)
365
359
 
366
- self.wpLabel = QLabel(self.tr("Words per page"), self)
367
-
368
360
  self.wpValue = QSpinBox(self)
369
361
  self.wpValue.setMinimum(10)
370
362
  self.wpValue.setMaximum(1000)
371
363
  self.wpValue.setSingleStep(10)
372
364
  self.wpValue.setValue(wordsPerPage)
373
365
  self.wpValue.valueChanged.connect(self._populateTree)
374
-
375
- self.poLabel = QLabel(self.tr("First page offset"), self)
366
+ self.wpLabel = QLabel(self.tr("Words per page"), self)
367
+ self.wpLabel.setBuddy(self.wpValue)
376
368
 
377
369
  self.poValue = QSpinBox(self)
378
370
  self.poValue.setMinimum(1)
@@ -380,12 +372,14 @@ class _ContentsPage(NFixedPage):
380
372
  self.poValue.setSingleStep(1)
381
373
  self.poValue.setValue(countFrom)
382
374
  self.poValue.valueChanged.connect(self._populateTree)
383
-
384
- self.dblLabel = QLabel(self.tr("Chapters on odd pages"), self)
375
+ self.poLabel = QLabel(self.tr("First page offset"), self)
376
+ self.poLabel.setBuddy(self.poValue)
385
377
 
386
378
  self.dblValue = NSwitch(self, height=iPx)
387
379
  self.dblValue.setChecked(clearDouble)
388
380
  self.dblValue.clicked.connect(self._populateTree)
381
+ self.dblLabel = QLabel(self.tr("Chapters on odd pages"), self)
382
+ self.dblLabel.setBuddy(self.dblValue)
389
383
 
390
384
  self.optionsBox = QGridLayout()
391
385
  self.optionsBox.addWidget(self.wpLabel, 0, 0)
@@ -394,8 +388,8 @@ class _ContentsPage(NFixedPage):
394
388
  self.optionsBox.addWidget(self.dblValue, 0, 4)
395
389
  self.optionsBox.addWidget(self.poLabel, 1, 0)
396
390
  self.optionsBox.addWidget(self.poValue, 1, 1)
397
- self.optionsBox.setHorizontalSpacing(hPx)
398
- self.optionsBox.setVerticalSpacing(vPx)
391
+ self.optionsBox.setHorizontalSpacing(12)
392
+ self.optionsBox.setVerticalSpacing(4)
399
393
  self.optionsBox.setColumnStretch(2, 1)
400
394
 
401
395
  # Assemble
@@ -410,18 +404,12 @@ class _ContentsPage(NFixedPage):
410
404
 
411
405
  def saveSettings(self) -> None:
412
406
  """Save the user GUI settings."""
413
- widthCol0 = CONFIG.rpxInt(self.tocTree.columnWidth(0))
414
- widthCol1 = CONFIG.rpxInt(self.tocTree.columnWidth(1))
415
- widthCol2 = CONFIG.rpxInt(self.tocTree.columnWidth(2))
416
- widthCol3 = CONFIG.rpxInt(self.tocTree.columnWidth(3))
417
- widthCol4 = CONFIG.rpxInt(self.tocTree.columnWidth(4))
418
-
419
407
  options = SHARED.project.options
420
- options.setValue("GuiNovelDetails", "widthCol0", widthCol0)
421
- options.setValue("GuiNovelDetails", "widthCol1", widthCol1)
422
- options.setValue("GuiNovelDetails", "widthCol2", widthCol2)
423
- options.setValue("GuiNovelDetails", "widthCol3", widthCol3)
424
- options.setValue("GuiNovelDetails", "widthCol4", widthCol4)
408
+ options.setValue("GuiNovelDetails", "widthCol0", self.tocTree.columnWidth(0))
409
+ options.setValue("GuiNovelDetails", "widthCol1", self.tocTree.columnWidth(1))
410
+ options.setValue("GuiNovelDetails", "widthCol2", self.tocTree.columnWidth(2))
411
+ options.setValue("GuiNovelDetails", "widthCol3", self.tocTree.columnWidth(3))
412
+ options.setValue("GuiNovelDetails", "widthCol4", self.tocTree.columnWidth(4))
425
413
  options.setValue("GuiNovelDetails", "wordsPerPage", self.wpValue.value())
426
414
  options.setValue("GuiNovelDetails", "countFrom", self.poValue.value())
427
415
  options.setValue("GuiNovelDetails", "clearDouble", self.dblValue.isChecked())
@@ -28,20 +28,19 @@ import logging
28
28
  from datetime import datetime
29
29
  from pathlib import Path
30
30
 
31
- from PyQt5.QtCore import (
32
- QAbstractListModel, QEvent, QModelIndex, QObject, QPoint, QSize, Qt,
33
- pyqtSignal, pyqtSlot
31
+ from PyQt6.QtCore import (
32
+ QAbstractListModel, QModelIndex, QObject, QPoint, QSize, Qt, pyqtSignal,
33
+ pyqtSlot
34
34
  )
35
- from PyQt5.QtGui import QCloseEvent, QColor, QFont, QPainter, QPaintEvent, QPen
36
- from PyQt5.QtWidgets import (
37
- QAction, QApplication, QFileDialog, QFormLayout, QHBoxLayout, QLabel,
38
- QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut,
39
- QStackedWidget, QStyledItemDelegate, QStyleOptionViewItem, QVBoxLayout,
40
- QWidget
35
+ from PyQt6.QtGui import QAction, QCloseEvent, QColor, QFont, QPainter, QPaintEvent, QPen, QShortcut
36
+ from PyQt6.QtWidgets import (
37
+ QApplication, QFileDialog, QFormLayout, QHBoxLayout, QLabel, QLineEdit,
38
+ QListView, QMenu, QPushButton, QScrollArea, QStackedWidget,
39
+ QStyledItemDelegate, QStyleOptionViewItem, QVBoxLayout, QWidget
41
40
  )
42
41
 
43
42
  from novelwriter import CONFIG, SHARED
44
- from novelwriter.common import cssCol, formatInt, makeFileNameSafe
43
+ from novelwriter.common import formatInt, makeFileNameSafe, qtAddAction, qtLambda
45
44
  from novelwriter.constants import nwFiles
46
45
  from novelwriter.core.coretools import ProjectBuilder
47
46
  from novelwriter.enum import nwItemClass
@@ -49,7 +48,7 @@ from novelwriter.extensions.configlayout import NWrappedWidgetBox
49
48
  from novelwriter.extensions.modified import NDialog, NIconToolButton, NSpinBox
50
49
  from novelwriter.extensions.switch import NSwitch
51
50
  from novelwriter.extensions.versioninfo import VersionInfoWidget
52
- from novelwriter.types import QtAlignLeft, QtAlignRightTop, QtScrollAsNeeded, QtSelected
51
+ from novelwriter.types import QtAlignLeft, QtAlignRightTop, QtHexArgb, QtScrollAsNeeded, QtSelected
53
52
 
54
53
  logger = logging.getLogger(__name__)
55
54
 
@@ -67,29 +66,21 @@ class GuiWelcome(NDialog):
67
66
  self.setObjectName("GuiWelcome")
68
67
 
69
68
  self.setWindowTitle(self.tr("Welcome"))
70
- self.setMinimumWidth(CONFIG.pxInt(650))
71
- self.setMinimumHeight(CONFIG.pxInt(450))
72
-
73
- hA = CONFIG.pxInt(8)
74
- hB = CONFIG.pxInt(16)
75
- hC = CONFIG.pxInt(24)
76
- hD = CONFIG.pxInt(36)
77
- hE = CONFIG.pxInt(48)
78
- hF = CONFIG.pxInt(128)
79
- btnIconSize = SHARED.theme.buttonIconSize
80
-
81
- self._hPx = CONFIG.pxInt(600)
69
+ self.setMinimumWidth(650)
70
+ self.setMinimumHeight(450)
82
71
  self.resize(*CONFIG.welcomeWinSize)
83
72
 
73
+ btnIconSize = SHARED.theme.buttonIconSize
74
+
84
75
  # Elements
85
76
  # ========
86
77
 
87
- self.bgImage = SHARED.theme.loadDecoration("welcome")
88
- self.nwImage = SHARED.theme.loadDecoration("nw-text", h=hD)
89
- self.bgColor = QColor(255, 255, 255) if SHARED.theme.isLightTheme else QColor(54, 54, 54)
78
+ self.bgImage = SHARED.theme.getDecoration("welcome")
79
+ self.nwImage = SHARED.theme.getDecoration("nw-text", h=36)
80
+ self.bgColor = QColor(54, 54, 54) if SHARED.theme.isDarkTheme else QColor(255, 255, 255)
90
81
 
91
82
  self.nwLogo = QLabel(self)
92
- self.nwLogo.setPixmap(SHARED.theme.getPixmap("novelwriter", (hF, hF)))
83
+ self.nwLogo.setPixmap(SHARED.theme.getPixmap("novelwriter", (128, 128)))
93
84
 
94
85
  self.nwLabel = QLabel(self)
95
86
  self.nwLabel.setPixmap(self.nwImage)
@@ -110,32 +101,32 @@ class GuiWelcome(NDialog):
110
101
  # =======
111
102
 
112
103
  self.btnList = QPushButton(self.tr("List"), self)
113
- self.btnList.setIcon(SHARED.theme.getIcon("list"))
104
+ self.btnList.setIcon(SHARED.theme.getIcon("list", "blue"))
114
105
  self.btnList.setIconSize(btnIconSize)
115
106
  self.btnList.clicked.connect(self._showOpenProjectPage)
116
107
 
117
108
  self.btnNew = QPushButton(self.tr("New"), self)
118
- self.btnNew.setIcon(SHARED.theme.getIcon("add"))
109
+ self.btnNew.setIcon(SHARED.theme.getIcon("add", "green"))
119
110
  self.btnNew.setIconSize(btnIconSize)
120
111
  self.btnNew.clicked.connect(self._showNewProjectPage)
121
112
 
122
113
  self.btnBrowse = QPushButton(self.tr("Browse"), self)
123
- self.btnBrowse.setIcon(SHARED.theme.getIcon("browse"))
114
+ self.btnBrowse.setIcon(SHARED.theme.getIcon("browse", "yellow"))
124
115
  self.btnBrowse.setIconSize(btnIconSize)
125
116
  self.btnBrowse.clicked.connect(self._browseForProject)
126
117
 
127
118
  self.btnCancel = QPushButton(self.tr("Cancel"), self)
128
- self.btnCancel.setIcon(SHARED.theme.getIcon("cross"))
119
+ self.btnCancel.setIcon(SHARED.theme.getIcon("cancel", "red"))
129
120
  self.btnCancel.setIconSize(btnIconSize)
130
- self.btnCancel.clicked.connect(self.close)
121
+ self.btnCancel.clicked.connect(qtLambda(self.close))
131
122
 
132
123
  self.btnCreate = QPushButton(self.tr("Create"), self)
133
- self.btnCreate.setIcon(SHARED.theme.getIcon("star"))
124
+ self.btnCreate.setIcon(SHARED.theme.getIcon("star", "yellow"))
134
125
  self.btnCreate.setIconSize(btnIconSize)
135
126
  self.btnCreate.clicked.connect(self.tabNew.createNewProject)
136
127
 
137
128
  self.btnOpen = QPushButton(self.tr("Open"), self)
138
- self.btnOpen.setIcon(SHARED.theme.getIcon("open"))
129
+ self.btnOpen.setIcon(SHARED.theme.getIcon("open", "blue"))
139
130
  self.btnOpen.setIconSize(btnIconSize)
140
131
  self.btnOpen.clicked.connect(self._openSelectedItem)
141
132
 
@@ -153,18 +144,18 @@ class GuiWelcome(NDialog):
153
144
  # ========
154
145
 
155
146
  self.innerBox = QVBoxLayout()
156
- self.innerBox.addSpacing(hB)
147
+ self.innerBox.addSpacing(16)
157
148
  self.innerBox.addWidget(self.nwLabel)
158
149
  self.innerBox.addWidget(self.nwInfo)
159
- self.innerBox.addSpacing(hA)
150
+ self.innerBox.addSpacing(8)
160
151
  self.innerBox.addWidget(self.mainStack)
161
- self.innerBox.addSpacing(hB)
152
+ self.innerBox.addSpacing(16)
162
153
  self.innerBox.addLayout(self.btnBox)
163
154
 
164
155
  self.outerBox = QHBoxLayout()
165
156
  self.outerBox.addWidget(self.nwLogo, 3, QtAlignRightTop)
166
157
  self.outerBox.addLayout(self.innerBox, 9)
167
- self.outerBox.setContentsMargins(hF, hE, hC, hE)
158
+ self.outerBox.setContentsMargins(128, 48, 24, 48)
168
159
 
169
160
  self.setLayout(self.outerBox)
170
161
  self.setSizeGripEnabled(True)
@@ -184,7 +175,7 @@ class GuiWelcome(NDialog):
184
175
  def paintEvent(self, event: QPaintEvent) -> None:
185
176
  """Overload the paint event to draw the background image."""
186
177
  hWin = self.height()
187
- hPix = min(hWin, self._hPx)
178
+ hPix = min(hWin, 600)
188
179
  tMode = Qt.TransformationMode.SmoothTransformation
189
180
  painter = QPainter(self)
190
181
  painter.fillRect(self.rect(), self.bgColor)
@@ -289,7 +280,7 @@ class _OpenProjectPage(QWidget):
289
280
 
290
281
  # Info / Tool
291
282
  self.aMissing = QAction(self)
292
- self.aMissing.setIcon(SHARED.theme.getIcon("alert_warn"))
283
+ self.aMissing.setIcon(SHARED.theme.getIcon("alert_warn", "orange"))
293
284
  self.aMissing.setToolTip(self.tr("The project path is not reachable."))
294
285
 
295
286
  self.selectedPath = QLineEdit(self)
@@ -310,11 +301,12 @@ class _OpenProjectPage(QWidget):
310
301
 
311
302
  self._selectFirstItem()
312
303
 
313
- mPx = CONFIG.pxInt(4)
314
- baseCol = cssCol(self.palette().base().color(), PANEL_ALPHA)
304
+ base = self.palette().base().color()
305
+ base.setAlpha(PANEL_ALPHA)
306
+ baseCol = base.name(QtHexArgb)
315
307
  self.setStyleSheet(
316
308
  f"QListView {{border: none; background: {baseCol};}} "
317
- f"QLineEdit {{border: none; background: {baseCol}; padding: {mPx}px;}} "
309
+ f"QLineEdit {{border: none; background: {baseCol}; padding: 4px;}} "
318
310
  )
319
311
 
320
312
  return
@@ -371,9 +363,9 @@ class _OpenProjectPage(QWidget):
371
363
  """Open the custom context menu."""
372
364
  ctxMenu = QMenu(self)
373
365
  ctxMenu.setObjectName("ContextMenu") # Used for testing
374
- action = ctxMenu.addAction(self.tr("Open Project"))
366
+ action = qtAddAction(ctxMenu, self.tr("Open Project"))
375
367
  action.triggered.connect(self.openSelectedItem)
376
- action = ctxMenu.addAction(self.tr("Remove Project"))
368
+ action = qtAddAction(ctxMenu, self.tr("Remove Project"))
377
369
  action.triggered.connect(self._deleteSelectedItem)
378
370
  ctxMenu.exec(self.mapToGlobal(pos))
379
371
  ctxMenu.setParent(None)
@@ -393,7 +385,7 @@ class _OpenProjectPage(QWidget):
393
385
 
394
386
  class _ProjectListItem(QStyledItemDelegate):
395
387
 
396
- __slots__ = ("_pPx", "_hPx", "_tFont", "_dFont", "_dPen", "_icon")
388
+ __slots__ = ("_dFont", "_dPen", "_hPx", "_icon", "_pPx", "_tFont")
397
389
 
398
390
  def __init__(self, parent: QWidget) -> None:
399
391
  super().__init__(parent=parent)
@@ -401,11 +393,10 @@ class _ProjectListItem(QStyledItemDelegate):
401
393
  fPx = SHARED.theme.fontPixelSize
402
394
  fPt = SHARED.theme.fontPointSize
403
395
  tPx = round(1.2 * fPx)
404
- mPx = CONFIG.pxInt(4)
405
396
  iPx = tPx + fPx
406
397
 
407
- self._pPx = (mPx//2, 3*mPx//2, iPx + mPx, mPx, mPx + tPx) # Painter coordinates
408
- self._hPx = 2*mPx + tPx + fPx # Fixed height
398
+ self._pPx = (iPx + 4, tPx + 4) # Painter coordinates
399
+ self._hPx = 8 + tPx + fPx # Fixed height
409
400
 
410
401
  self._tFont = QApplication.font()
411
402
  self._tFont.setPointSizeF(1.2*fPt)
@@ -424,7 +415,7 @@ class _ProjectListItem(QStyledItemDelegate):
424
415
  rect = opt.rect
425
416
  title, _, details = index.data()
426
417
  tFlag = Qt.TextFlag.TextSingleLine
427
- ix, iy, x, y1, y2 = self._pPx
418
+ x, y = self._pPx
428
419
 
429
420
  painter.save()
430
421
  if opt.state & QtSelected == QtSelected:
@@ -432,12 +423,12 @@ class _ProjectListItem(QStyledItemDelegate):
432
423
  painter.fillRect(rect, QApplication.palette().highlight())
433
424
  painter.setOpacity(1.0)
434
425
 
435
- painter.drawPixmap(ix, rect.top() + iy, self._icon)
426
+ painter.drawPixmap(2, rect.top() + 6, self._icon)
436
427
  painter.setFont(self._tFont)
437
- painter.drawText(rect.adjusted(x, y1, 0, 0), tFlag, title)
428
+ painter.drawText(rect.adjusted(x, 4, 0, 0), tFlag, title)
438
429
  painter.setFont(self._dFont)
439
430
  painter.setPen(self._dPen)
440
- painter.drawText(rect.adjusted(x, y2, 0, 0), tFlag, details)
431
+ painter.drawText(rect.adjusted(x, y, 0, 0), tFlag, details)
441
432
  painter.restore()
442
433
 
443
434
  return
@@ -518,7 +509,9 @@ class _NewProjectPage(QWidget):
518
509
  # Styles
519
510
  # ======
520
511
 
521
- baseCol = cssCol(self.palette().base().color(), PANEL_ALPHA)
512
+ base = self.palette().base().color()
513
+ base.setAlpha(PANEL_ALPHA)
514
+ baseCol = base.name(QtHexArgb)
522
515
  self.setStyleSheet(
523
516
  f"QScrollArea {{border: none; background: {baseCol};}} "
524
517
  f"_NewProjectForm {{border: none; background: {baseCol};}} "
@@ -558,7 +551,6 @@ class _NewProjectForm(QWidget):
558
551
 
559
552
  iPx = SHARED.theme.baseIconHeight
560
553
  iSz = SHARED.theme.baseIconSize
561
- sPx = CONFIG.pxInt(16)
562
554
 
563
555
  # Project Settings
564
556
  # ================
@@ -573,6 +565,7 @@ class _NewProjectForm(QWidget):
573
565
  self.projAuthor = QLineEdit(self)
574
566
  self.projAuthor.setMaxLength(200)
575
567
  self.projAuthor.setPlaceholderText(self.tr("Optional"))
568
+ self.projAuthor.setText(CONFIG.lastAuthor)
576
569
 
577
570
  # Project Path
578
571
  self.projPath = QLineEdit(self)
@@ -589,20 +582,20 @@ class _NewProjectForm(QWidget):
589
582
  self.projFill = QLineEdit(self)
590
583
  self.projFill.setReadOnly(True)
591
584
 
592
- self.browseFill = NIconToolButton(self, iSz, "add_document")
585
+ self.browseFill = NIconToolButton(self, iSz, "document_add", "blue")
593
586
 
594
- self.fillMenu = _PopLeftDirectionMenu(self.browseFill)
587
+ self.fillMenu = QMenu(self.browseFill)
595
588
 
596
- self.fillBlank = self.fillMenu.addAction(self.tr("Create a fresh project"))
589
+ self.fillBlank = qtAddAction(self.fillMenu, self.tr("Create a fresh project"))
597
590
  self.fillBlank.setIcon(SHARED.theme.getIcon("document"))
598
591
  self.fillBlank.triggered.connect(self._setFillBlank)
599
592
 
600
- self.fillSample = self.fillMenu.addAction(self.tr("Create an example project"))
601
- self.fillSample.setIcon(SHARED.theme.getIcon("add_document"))
593
+ self.fillSample = qtAddAction(self.fillMenu, self.tr("Create an example project"))
594
+ self.fillSample.setIcon(SHARED.theme.getIcon("document_add", "blue"))
602
595
  self.fillSample.triggered.connect(self._setFillSample)
603
596
 
604
- self.fillCopy = self.fillMenu.addAction(self.tr("Copy an existing project"))
605
- self.fillCopy.setIcon(SHARED.theme.getIcon("browse"))
597
+ self.fillCopy = qtAddAction(self.fillMenu, self.tr("Copy an existing project"))
598
+ self.fillCopy.setIcon(SHARED.theme.getIcon("project_copy", "green"))
606
599
  self.fillCopy.triggered.connect(self._setFillCopy)
607
600
 
608
601
  self.browseFill.setMenu(self.fillMenu)
@@ -676,7 +669,7 @@ class _NewProjectForm(QWidget):
676
669
  self.extraBox = QVBoxLayout()
677
670
  self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Chapters and Scenes")), self))
678
671
  self.extraBox.addLayout(self.novelForm)
679
- self.extraBox.addSpacing(sPx)
672
+ self.extraBox.addSpacing(16)
680
673
  self.extraBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Project Notes")), self))
681
674
  self.extraBox.addLayout(self.notesForm)
682
675
  self.extraBox.setContentsMargins(0, 0, 0, 0)
@@ -688,7 +681,7 @@ class _NewProjectForm(QWidget):
688
681
  self.formBox = QVBoxLayout()
689
682
  self.formBox.addWidget(QLabel("<b>{0}</b>".format(self.tr("Create New Project")), self))
690
683
  self.formBox.addLayout(self.projectForm)
691
- self.formBox.addSpacing(sPx)
684
+ self.formBox.addSpacing(16)
692
685
  self.formBox.addWidget(self.extraWidget)
693
686
  self.formBox.addStretch(1)
694
687
 
@@ -803,14 +796,3 @@ class _NewProjectForm(QWidget):
803
796
  self.extraWidget.setVisible(self._fillMode == self.FILL_BLANK)
804
797
 
805
798
  return
806
-
807
-
808
- class _PopLeftDirectionMenu(QMenu):
809
-
810
- def event(self, event: QEvent) -> bool:
811
- """Overload the show event and move the menu popup location."""
812
- if event.type() == QEvent.Type.Show:
813
- if isinstance(parent := self.parent(), QWidget):
814
- offset = QPoint(parent.width() - self.width(), parent.height())
815
- self.move(parent.mapToGlobal(offset))
816
- return super(_PopLeftDirectionMenu, self).event(event)