novelWriter 2.6.2__py3-none-any.whl → 2.7b1__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 (334) hide show
  1. novelwriter/__init__.py +84 -74
  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_en_GB.json +1 -0
  16. novelwriter/assets/icons/font_awesome.icons +109 -0
  17. novelwriter/assets/icons/material_filled_bold.icons +109 -0
  18. novelwriter/assets/icons/material_filled_normal.icons +109 -0
  19. novelwriter/assets/icons/material_filled_thin.icons +109 -0
  20. novelwriter/assets/icons/material_rounded_bold.icons +109 -0
  21. novelwriter/assets/icons/material_rounded_normal.icons +109 -0
  22. novelwriter/assets/icons/material_rounded_thin.icons +109 -0
  23. novelwriter/assets/icons/remix_filled.icons +108 -0
  24. novelwriter/assets/icons/remix_outline.icons +108 -0
  25. novelwriter/assets/manual.pdf +0 -0
  26. novelwriter/assets/{manual_fr_FR.pdf → manual_fr.pdf} +0 -0
  27. novelwriter/assets/sample.zip +0 -0
  28. novelwriter/assets/syntax/cyberpunk_night.conf +1 -1
  29. novelwriter/assets/text/credits_en.htm +6 -6
  30. novelwriter/assets/themes/cyberpunk_night.conf +23 -7
  31. novelwriter/assets/themes/default_dark.conf +20 -4
  32. novelwriter/assets/themes/default_light.conf +21 -5
  33. novelwriter/assets/themes/dracula.conf +20 -4
  34. novelwriter/assets/themes/solarized_dark.conf +24 -8
  35. novelwriter/assets/themes/solarized_light.conf +22 -6
  36. novelwriter/common.py +33 -26
  37. novelwriter/config.py +118 -127
  38. novelwriter/constants.py +75 -56
  39. novelwriter/core/buildsettings.py +23 -16
  40. novelwriter/core/coretools.py +11 -7
  41. novelwriter/core/docbuild.py +19 -13
  42. novelwriter/core/document.py +2 -2
  43. novelwriter/core/index.py +142 -432
  44. novelwriter/core/indexdata.py +403 -0
  45. novelwriter/core/item.py +35 -28
  46. novelwriter/core/itemmodel.py +27 -26
  47. novelwriter/core/novelmodel.py +223 -0
  48. novelwriter/core/options.py +1 -1
  49. novelwriter/core/project.py +10 -11
  50. novelwriter/core/projectdata.py +5 -5
  51. novelwriter/core/projectxml.py +1 -1
  52. novelwriter/core/sessions.py +3 -2
  53. novelwriter/core/spellcheck.py +4 -3
  54. novelwriter/core/status.py +12 -15
  55. novelwriter/core/storage.py +1 -1
  56. novelwriter/core/tree.py +46 -8
  57. novelwriter/dialogs/about.py +19 -22
  58. novelwriter/dialogs/docmerge.py +21 -23
  59. novelwriter/dialogs/docsplit.py +20 -23
  60. novelwriter/dialogs/editlabel.py +9 -13
  61. novelwriter/dialogs/preferences.py +111 -48
  62. novelwriter/dialogs/projectsettings.py +48 -54
  63. novelwriter/dialogs/quotes.py +14 -19
  64. novelwriter/dialogs/wordlist.py +25 -30
  65. novelwriter/enum.py +8 -0
  66. novelwriter/error.py +16 -16
  67. novelwriter/extensions/configlayout.py +18 -18
  68. novelwriter/extensions/eventfilters.py +9 -5
  69. novelwriter/extensions/modified.py +34 -15
  70. novelwriter/extensions/novelselector.py +18 -5
  71. novelwriter/extensions/pagedsidebar.py +39 -49
  72. novelwriter/extensions/progressbars.py +10 -8
  73. novelwriter/extensions/statusled.py +6 -13
  74. novelwriter/extensions/switch.py +19 -30
  75. novelwriter/extensions/switchbox.py +7 -3
  76. novelwriter/extensions/versioninfo.py +4 -4
  77. novelwriter/formats/shared.py +1 -1
  78. novelwriter/formats/todocx.py +14 -10
  79. novelwriter/formats/tohtml.py +7 -5
  80. novelwriter/formats/tokenizer.py +36 -33
  81. novelwriter/formats/tomarkdown.py +6 -2
  82. novelwriter/formats/toodt.py +27 -22
  83. novelwriter/formats/toqdoc.py +19 -14
  84. novelwriter/formats/toraw.py +6 -2
  85. novelwriter/gui/doceditor.py +216 -265
  86. novelwriter/gui/dochighlight.py +46 -45
  87. novelwriter/gui/docviewer.py +102 -104
  88. novelwriter/gui/docviewerpanel.py +47 -51
  89. novelwriter/gui/editordocument.py +8 -5
  90. novelwriter/gui/itemdetails.py +15 -18
  91. novelwriter/gui/mainmenu.py +147 -146
  92. novelwriter/gui/noveltree.py +239 -405
  93. novelwriter/gui/outline.py +137 -76
  94. novelwriter/gui/projtree.py +138 -132
  95. novelwriter/gui/search.py +33 -31
  96. novelwriter/gui/sidebar.py +13 -18
  97. novelwriter/gui/statusbar.py +13 -15
  98. novelwriter/gui/theme.py +533 -430
  99. novelwriter/guimain.py +27 -29
  100. novelwriter/shared.py +32 -23
  101. novelwriter/text/comments.py +70 -0
  102. novelwriter/text/patterns.py +4 -4
  103. novelwriter/tools/dictionaries.py +20 -29
  104. novelwriter/tools/lipsum.py +16 -17
  105. novelwriter/tools/manusbuild.py +39 -42
  106. novelwriter/tools/manuscript.py +113 -126
  107. novelwriter/tools/manussettings.py +78 -83
  108. novelwriter/tools/noveldetails.py +51 -64
  109. novelwriter/tools/welcome.py +56 -75
  110. novelwriter/tools/writingstats.py +44 -57
  111. novelwriter/types.py +5 -7
  112. {novelWriter-2.6.2.dist-info → novelwriter-2.7b1.dist-info}/METADATA +6 -6
  113. novelwriter-2.7b1.dist-info/RECORD +159 -0
  114. {novelWriter-2.6.2.dist-info → novelwriter-2.7b1.dist-info}/WHEEL +1 -1
  115. novelWriter-2.6.2.dist-info/RECORD +0 -363
  116. novelwriter/assets/icons/typicons_dark/README.md +0 -29
  117. novelwriter/assets/icons/typicons_dark/icons.conf +0 -134
  118. novelwriter/assets/icons/typicons_dark/mixed_copy.svg +0 -4
  119. novelwriter/assets/icons/typicons_dark/mixed_document-chapter.svg +0 -12
  120. novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +0 -6
  121. novelwriter/assets/icons/typicons_dark/mixed_document-note.svg +0 -12
  122. novelwriter/assets/icons/typicons_dark/mixed_document-scene.svg +0 -12
  123. novelwriter/assets/icons/typicons_dark/mixed_document-section.svg +0 -12
  124. novelwriter/assets/icons/typicons_dark/mixed_document-title.svg +0 -12
  125. novelwriter/assets/icons/typicons_dark/mixed_edit.svg +0 -4
  126. novelwriter/assets/icons/typicons_dark/mixed_import.svg +0 -5
  127. novelwriter/assets/icons/typicons_dark/mixed_input-checked.svg +0 -5
  128. novelwriter/assets/icons/typicons_dark/mixed_input-none.svg +0 -5
  129. novelwriter/assets/icons/typicons_dark/mixed_input-unchecked.svg +0 -5
  130. novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +0 -6
  131. novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +0 -6
  132. novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +0 -6
  133. novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +0 -6
  134. novelwriter/assets/icons/typicons_dark/mixed_search-replace.svg +0 -6
  135. novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +0 -6
  136. novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +0 -6
  137. novelwriter/assets/icons/typicons_dark/nw_deco-h0.svg +0 -4
  138. novelwriter/assets/icons/typicons_dark/nw_deco-h1.svg +0 -4
  139. novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +0 -4
  140. novelwriter/assets/icons/typicons_dark/nw_deco-h2.svg +0 -4
  141. novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +0 -4
  142. novelwriter/assets/icons/typicons_dark/nw_deco-h3.svg +0 -4
  143. novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +0 -4
  144. novelwriter/assets/icons/typicons_dark/nw_deco-h4.svg +0 -4
  145. novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +0 -4
  146. novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg +0 -4
  147. novelwriter/assets/icons/typicons_dark/nw_font.svg +0 -4
  148. novelwriter/assets/icons/typicons_dark/nw_panel.svg +0 -4
  149. novelwriter/assets/icons/typicons_dark/nw_quote.svg +0 -4
  150. novelwriter/assets/icons/typicons_dark/nw_search-case.svg +0 -4
  151. novelwriter/assets/icons/typicons_dark/nw_search-preserve.svg +0 -4
  152. novelwriter/assets/icons/typicons_dark/nw_search-regex.svg +0 -4
  153. novelwriter/assets/icons/typicons_dark/nw_search-word.svg +0 -4
  154. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +0 -4
  155. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +0 -6
  156. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +0 -4
  157. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +0 -6
  158. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +0 -7
  159. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +0 -4
  160. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +0 -6
  161. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +0 -7
  162. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +0 -7
  163. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +0 -7
  164. novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +0 -5
  165. novelwriter/assets/icons/typicons_dark/typ_arrow-down-thick-grey.svg +0 -4
  166. novelwriter/assets/icons/typicons_dark/typ_arrow-forward.svg +0 -4
  167. novelwriter/assets/icons/typicons_dark/typ_arrow-maximise.svg +0 -4
  168. novelwriter/assets/icons/typicons_dark/typ_arrow-minimise.svg +0 -4
  169. novelwriter/assets/icons/typicons_dark/typ_arrow-repeat-grey.svg +0 -4
  170. novelwriter/assets/icons/typicons_dark/typ_book-grey.svg +0 -4
  171. novelwriter/assets/icons/typicons_dark/typ_book.svg +0 -6
  172. novelwriter/assets/icons/typicons_dark/typ_bookmark.svg +0 -4
  173. novelwriter/assets/icons/typicons_dark/typ_calendar.svg +0 -4
  174. novelwriter/assets/icons/typicons_dark/typ_cancel-grey.svg +0 -4
  175. novelwriter/assets/icons/typicons_dark/typ_cancel.svg +0 -4
  176. novelwriter/assets/icons/typicons_dark/typ_chart-bar-grey.svg +0 -4
  177. novelwriter/assets/icons/typicons_dark/typ_chevron-down.svg +0 -4
  178. novelwriter/assets/icons/typicons_dark/typ_chevron-left.svg +0 -4
  179. novelwriter/assets/icons/typicons_dark/typ_chevron-right.svg +0 -4
  180. novelwriter/assets/icons/typicons_dark/typ_chevron-up.svg +0 -4
  181. novelwriter/assets/icons/typicons_dark/typ_cog.svg +0 -4
  182. novelwriter/assets/icons/typicons_dark/typ_delete-full.svg +0 -4
  183. novelwriter/assets/icons/typicons_dark/typ_delete.svg +0 -4
  184. novelwriter/assets/icons/typicons_dark/typ_directions-full.svg +0 -4
  185. novelwriter/assets/icons/typicons_dark/typ_document-add.svg +0 -4
  186. novelwriter/assets/icons/typicons_dark/typ_document-text.svg +0 -8
  187. novelwriter/assets/icons/typicons_dark/typ_document.svg +0 -4
  188. novelwriter/assets/icons/typicons_dark/typ_export-grey.svg +0 -4
  189. novelwriter/assets/icons/typicons_dark/typ_export.svg +0 -4
  190. novelwriter/assets/icons/typicons_dark/typ_eye.svg +0 -4
  191. novelwriter/assets/icons/typicons_dark/typ_flag.svg +0 -4
  192. novelwriter/assets/icons/typicons_dark/typ_folder-open.svg +0 -4
  193. novelwriter/assets/icons/typicons_dark/typ_folder.svg +0 -5
  194. novelwriter/assets/icons/typicons_dark/typ_globe-grey.svg +0 -4
  195. novelwriter/assets/icons/typicons_dark/typ_key.svg +0 -4
  196. novelwriter/assets/icons/typicons_dark/typ_lightbulb-full.svg +0 -4
  197. novelwriter/assets/icons/typicons_dark/typ_location.svg +0 -4
  198. novelwriter/assets/icons/typicons_dark/typ_media-pause-grey.svg +0 -4
  199. novelwriter/assets/icons/typicons_dark/typ_media-record-outline.svg +0 -4
  200. novelwriter/assets/icons/typicons_dark/typ_media-record.svg +0 -4
  201. novelwriter/assets/icons/typicons_dark/typ_minus.svg +0 -4
  202. novelwriter/assets/icons/typicons_dark/typ_pencil.svg +0 -5
  203. novelwriter/assets/icons/typicons_dark/typ_pin-outline.svg +0 -4
  204. novelwriter/assets/icons/typicons_dark/typ_pin.svg +0 -4
  205. novelwriter/assets/icons/typicons_dark/typ_plus.svg +0 -4
  206. novelwriter/assets/icons/typicons_dark/typ_puzzle-outline.svg +0 -4
  207. novelwriter/assets/icons/typicons_dark/typ_puzzle.svg +0 -4
  208. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +0 -4
  209. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +0 -4
  210. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +0 -4
  211. novelwriter/assets/icons/typicons_dark/typ_search.svg +0 -4
  212. novelwriter/assets/icons/typicons_dark/typ_star.svg +0 -4
  213. novelwriter/assets/icons/typicons_dark/typ_stopwatch-grey.svg +0 -4
  214. novelwriter/assets/icons/typicons_dark/typ_th-dot-menu.svg +0 -4
  215. novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +0 -4
  216. novelwriter/assets/icons/typicons_dark/typ_th-list-grey.svg +0 -4
  217. novelwriter/assets/icons/typicons_dark/typ_th-list.svg +0 -9
  218. novelwriter/assets/icons/typicons_dark/typ_times.svg +0 -4
  219. novelwriter/assets/icons/typicons_dark/typ_trash.svg +0 -5
  220. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +0 -4
  221. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +0 -4
  222. novelwriter/assets/icons/typicons_dark/typ_user.svg +0 -5
  223. novelwriter/assets/icons/typicons_dark/typ_warning-full.svg +0 -4
  224. novelwriter/assets/icons/typicons_light/README.md +0 -29
  225. novelwriter/assets/icons/typicons_light/icons.conf +0 -134
  226. novelwriter/assets/icons/typicons_light/mixed_copy.svg +0 -4
  227. novelwriter/assets/icons/typicons_light/mixed_document-chapter.svg +0 -12
  228. novelwriter/assets/icons/typicons_light/mixed_document-new.svg +0 -6
  229. novelwriter/assets/icons/typicons_light/mixed_document-note.svg +0 -12
  230. novelwriter/assets/icons/typicons_light/mixed_document-scene.svg +0 -12
  231. novelwriter/assets/icons/typicons_light/mixed_document-section.svg +0 -12
  232. novelwriter/assets/icons/typicons_light/mixed_document-title.svg +0 -12
  233. novelwriter/assets/icons/typicons_light/mixed_edit.svg +0 -4
  234. novelwriter/assets/icons/typicons_light/mixed_import.svg +0 -5
  235. novelwriter/assets/icons/typicons_light/mixed_input-checked.svg +0 -5
  236. novelwriter/assets/icons/typicons_light/mixed_input-none.svg +0 -5
  237. novelwriter/assets/icons/typicons_light/mixed_input-unchecked.svg +0 -5
  238. novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +0 -6
  239. novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +0 -6
  240. novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +0 -6
  241. novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +0 -6
  242. novelwriter/assets/icons/typicons_light/mixed_search-replace.svg +0 -6
  243. novelwriter/assets/icons/typicons_light/mixed_size-height.svg +0 -6
  244. novelwriter/assets/icons/typicons_light/mixed_size-width.svg +0 -6
  245. novelwriter/assets/icons/typicons_light/nw_deco-h0.svg +0 -4
  246. novelwriter/assets/icons/typicons_light/nw_deco-h1.svg +0 -4
  247. novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +0 -4
  248. novelwriter/assets/icons/typicons_light/nw_deco-h2.svg +0 -4
  249. novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +0 -4
  250. novelwriter/assets/icons/typicons_light/nw_deco-h3.svg +0 -4
  251. novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +0 -4
  252. novelwriter/assets/icons/typicons_light/nw_deco-h4.svg +0 -4
  253. novelwriter/assets/icons/typicons_light/nw_deco-note.svg +0 -4
  254. novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg +0 -4
  255. novelwriter/assets/icons/typicons_light/nw_font.svg +0 -4
  256. novelwriter/assets/icons/typicons_light/nw_panel.svg +0 -4
  257. novelwriter/assets/icons/typicons_light/nw_quote.svg +0 -4
  258. novelwriter/assets/icons/typicons_light/nw_search-case.svg +0 -4
  259. novelwriter/assets/icons/typicons_light/nw_search-preserve.svg +0 -4
  260. novelwriter/assets/icons/typicons_light/nw_search-regex.svg +0 -4
  261. novelwriter/assets/icons/typicons_light/nw_search-word.svg +0 -4
  262. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +0 -4
  263. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +0 -6
  264. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +0 -4
  265. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +0 -6
  266. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +0 -7
  267. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +0 -4
  268. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +0 -6
  269. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +0 -7
  270. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +0 -7
  271. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +0 -7
  272. novelwriter/assets/icons/typicons_light/nw_toolbar.svg +0 -5
  273. novelwriter/assets/icons/typicons_light/typ_arrow-down-thick-grey.svg +0 -4
  274. novelwriter/assets/icons/typicons_light/typ_arrow-forward.svg +0 -4
  275. novelwriter/assets/icons/typicons_light/typ_arrow-maximise.svg +0 -4
  276. novelwriter/assets/icons/typicons_light/typ_arrow-minimise.svg +0 -4
  277. novelwriter/assets/icons/typicons_light/typ_arrow-repeat-grey.svg +0 -4
  278. novelwriter/assets/icons/typicons_light/typ_book-grey.svg +0 -4
  279. novelwriter/assets/icons/typicons_light/typ_book.svg +0 -6
  280. novelwriter/assets/icons/typicons_light/typ_bookmark.svg +0 -4
  281. novelwriter/assets/icons/typicons_light/typ_calendar.svg +0 -4
  282. novelwriter/assets/icons/typicons_light/typ_cancel-grey.svg +0 -4
  283. novelwriter/assets/icons/typicons_light/typ_cancel.svg +0 -4
  284. novelwriter/assets/icons/typicons_light/typ_chart-bar-grey.svg +0 -4
  285. novelwriter/assets/icons/typicons_light/typ_chevron-down.svg +0 -4
  286. novelwriter/assets/icons/typicons_light/typ_chevron-left.svg +0 -4
  287. novelwriter/assets/icons/typicons_light/typ_chevron-right.svg +0 -4
  288. novelwriter/assets/icons/typicons_light/typ_chevron-up.svg +0 -4
  289. novelwriter/assets/icons/typicons_light/typ_cog.svg +0 -4
  290. novelwriter/assets/icons/typicons_light/typ_delete-full.svg +0 -4
  291. novelwriter/assets/icons/typicons_light/typ_delete.svg +0 -4
  292. novelwriter/assets/icons/typicons_light/typ_directions-full.svg +0 -4
  293. novelwriter/assets/icons/typicons_light/typ_document-add.svg +0 -4
  294. novelwriter/assets/icons/typicons_light/typ_document-text.svg +0 -5
  295. novelwriter/assets/icons/typicons_light/typ_document.svg +0 -4
  296. novelwriter/assets/icons/typicons_light/typ_export-grey.svg +0 -4
  297. novelwriter/assets/icons/typicons_light/typ_export.svg +0 -4
  298. novelwriter/assets/icons/typicons_light/typ_eye.svg +0 -4
  299. novelwriter/assets/icons/typicons_light/typ_flag.svg +0 -4
  300. novelwriter/assets/icons/typicons_light/typ_folder-open.svg +0 -4
  301. novelwriter/assets/icons/typicons_light/typ_folder.svg +0 -5
  302. novelwriter/assets/icons/typicons_light/typ_globe-grey.svg +0 -4
  303. novelwriter/assets/icons/typicons_light/typ_key.svg +0 -4
  304. novelwriter/assets/icons/typicons_light/typ_lightbulb-full.svg +0 -4
  305. novelwriter/assets/icons/typicons_light/typ_location.svg +0 -4
  306. novelwriter/assets/icons/typicons_light/typ_media-pause-grey.svg +0 -4
  307. novelwriter/assets/icons/typicons_light/typ_media-record-outline.svg +0 -4
  308. novelwriter/assets/icons/typicons_light/typ_media-record.svg +0 -4
  309. novelwriter/assets/icons/typicons_light/typ_minus.svg +0 -4
  310. novelwriter/assets/icons/typicons_light/typ_pencil.svg +0 -5
  311. novelwriter/assets/icons/typicons_light/typ_pin-outline.svg +0 -4
  312. novelwriter/assets/icons/typicons_light/typ_pin.svg +0 -4
  313. novelwriter/assets/icons/typicons_light/typ_plus.svg +0 -4
  314. novelwriter/assets/icons/typicons_light/typ_puzzle-outline.svg +0 -4
  315. novelwriter/assets/icons/typicons_light/typ_puzzle.svg +0 -4
  316. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +0 -4
  317. novelwriter/assets/icons/typicons_light/typ_refresh.svg +0 -4
  318. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +0 -4
  319. novelwriter/assets/icons/typicons_light/typ_search.svg +0 -4
  320. novelwriter/assets/icons/typicons_light/typ_star.svg +0 -4
  321. novelwriter/assets/icons/typicons_light/typ_stopwatch-grey.svg +0 -4
  322. novelwriter/assets/icons/typicons_light/typ_th-dot-menu.svg +0 -4
  323. novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +0 -4
  324. novelwriter/assets/icons/typicons_light/typ_th-list-grey.svg +0 -4
  325. novelwriter/assets/icons/typicons_light/typ_th-list.svg +0 -9
  326. novelwriter/assets/icons/typicons_light/typ_times.svg +0 -4
  327. novelwriter/assets/icons/typicons_light/typ_trash.svg +0 -5
  328. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +0 -4
  329. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +0 -4
  330. novelwriter/assets/icons/typicons_light/typ_user.svg +0 -5
  331. novelwriter/assets/icons/typicons_light/typ_warning-full.svg +0 -4
  332. {novelWriter-2.6.2.dist-info → novelwriter-2.7b1.dist-info}/entry_points.txt +0 -0
  333. {novelWriter-2.6.2.dist-info → novelwriter-2.7b1.dist-info/licenses}/LICENSE.md +0 -0
  334. {novelWriter-2.6.2.dist-info → novelwriter-2.7b1.dist-info}/top_level.txt +0 -0
@@ -26,19 +26,18 @@ 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 QTimer, pyqtSlot
31
- from PyQt5.QtGui import QCloseEvent
32
- from PyQt5.QtWidgets import (
31
+ from PyQt6.QtCore import QTimer, pyqtSlot
32
+ from PyQt6.QtWidgets import (
33
33
  QAbstractButton, QAbstractItemView, QDialogButtonBox, QFileDialog,
34
34
  QGridLayout, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem,
35
35
  QPushButton, QSplitter, QVBoxLayout, QWidget
36
36
  )
37
37
 
38
- from novelwriter import CONFIG, SHARED
38
+ from novelwriter import SHARED
39
39
  from novelwriter.common import makeFileNameSafe, openExternalPath
40
40
  from novelwriter.constants import nwLabels
41
- from novelwriter.core.buildsettings import BuildSettings
42
41
  from novelwriter.core.docbuild import NWBuildDocument
43
42
  from novelwriter.core.item import NWItem
44
43
  from novelwriter.enum import nwBuildFmt
@@ -46,6 +45,11 @@ from novelwriter.extensions.modified import NDialog, NIconToolButton
46
45
  from novelwriter.extensions.progressbars import NProgressSimple
47
46
  from novelwriter.types import QtAlignCenter, QtDialogClose, QtRoleAction, QtRoleReject, QtUserRole
48
47
 
48
+ if TYPE_CHECKING:
49
+ from PyQt6.QtGui import QCloseEvent
50
+
51
+ from novelwriter.core.buildsettings import BuildSettings
52
+
49
53
  logger = logging.getLogger(__name__)
50
54
 
51
55
 
@@ -68,21 +72,16 @@ class GuiManuscriptBuild(NDialog):
68
72
  self._build = build
69
73
 
70
74
  self.setWindowTitle(self.tr("Build Manuscript"))
71
- self.setMinimumWidth(CONFIG.pxInt(500))
72
- self.setMinimumHeight(CONFIG.pxInt(300))
75
+ self.setMinimumWidth(500)
76
+ self.setMinimumHeight(300)
73
77
 
74
78
  iSz = SHARED.theme.baseIconSize
75
79
  bSz = SHARED.theme.buttonIconSize
76
- sp4 = CONFIG.pxInt(4)
77
- sp8 = CONFIG.pxInt(8)
78
- sp16 = CONFIG.pxInt(16)
79
- wWin = CONFIG.pxInt(620)
80
- hWin = CONFIG.pxInt(360)
81
80
 
82
81
  pOptions = SHARED.project.options
83
82
  self.resize(
84
- CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "winWidth", wWin)),
85
- CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "winHeight", hWin))
83
+ pOptions.getInt("GuiManuscriptBuild", "winWidth", 620),
84
+ pOptions.getInt("GuiManuscriptBuild", "winHeight", 360),
86
85
  )
87
86
 
88
87
  # Output Format
@@ -149,25 +148,25 @@ class GuiManuscriptBuild(NDialog):
149
148
  self.pathBox = QHBoxLayout()
150
149
  self.pathBox.addWidget(self.buildPath)
151
150
  self.pathBox.addWidget(self.btnBrowse)
152
- self.pathBox.setSpacing(sp8)
151
+ self.pathBox.setSpacing(8)
153
152
 
154
153
  # Build Name
155
154
  self.lblName = QLabel(self.tr("File Name"), self)
156
155
  self.buildName = QLineEdit(self)
157
- self.btnReset = NIconToolButton(self, iSz, "revert")
156
+ self.btnReset = NIconToolButton(self, iSz, "revert", "green")
158
157
  self.btnReset.setToolTip(self.tr("Reset file name to default"))
159
158
 
160
159
  self.nameBox = QHBoxLayout()
161
160
  self.nameBox.addWidget(self.buildName)
162
161
  self.nameBox.addWidget(self.btnReset)
163
- self.nameBox.setSpacing(sp8)
162
+ self.nameBox.setSpacing(8)
164
163
 
165
164
  # Build Progress
166
165
  self.buildProgress = NProgressSimple(self)
167
166
  self.buildProgress.setMinimum(0)
168
167
  self.buildProgress.setValue(0)
169
168
  self.buildProgress.setTextVisible(False)
170
- self.buildProgress.setFixedHeight(sp8)
169
+ self.buildProgress.setFixedHeight(8)
171
170
 
172
171
  # Build Box
173
172
  self.buildBox = QGridLayout()
@@ -175,24 +174,29 @@ class GuiManuscriptBuild(NDialog):
175
174
  self.buildBox.addLayout(self.pathBox, 0, 1)
176
175
  self.buildBox.addWidget(self.lblName, 1, 0)
177
176
  self.buildBox.addLayout(self.nameBox, 1, 1)
178
- self.buildBox.setHorizontalSpacing(sp8)
179
- self.buildBox.setVerticalSpacing(sp4)
177
+ self.buildBox.setHorizontalSpacing(8)
178
+ self.buildBox.setVerticalSpacing(4)
180
179
 
181
180
  # Dialog Buttons
182
181
  self.buttonBox = QDialogButtonBox(self)
183
182
 
184
- self.btnOpen = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Open Folder"), self)
183
+ self.btnOpen = QPushButton(
184
+ SHARED.theme.getIcon("browse", "yellow"), self.tr("Open Folder"), self
185
+ )
185
186
  self.btnOpen.setIconSize(bSz)
186
187
  self.btnOpen.setAutoDefault(False)
187
188
  self.buttonBox.addButton(self.btnOpen, QtRoleAction)
188
189
 
189
- self.btnBuild = QPushButton(SHARED.theme.getIcon("export"), self.tr("&Build"), self)
190
+ self.btnBuild = QPushButton(
191
+ SHARED.theme.getIcon("sb_build", "blue"), self.tr("&Build"), self
192
+ )
190
193
  self.btnBuild.setIconSize(bSz)
191
194
  self.btnBuild.setAutoDefault(True)
192
195
  self.buttonBox.addButton(self.btnBuild, QtRoleAction)
193
196
 
194
197
  self.btnClose = self.buttonBox.addButton(QtDialogClose)
195
- self.btnClose.setAutoDefault(False)
198
+ if self.btnClose:
199
+ self.btnClose.setAutoDefault(False)
196
200
 
197
201
  # Assemble GUI
198
202
  # ============
@@ -200,25 +204,25 @@ class GuiManuscriptBuild(NDialog):
200
204
  self.mainSplit = QSplitter(self)
201
205
  self.mainSplit.addWidget(self.formatWidget)
202
206
  self.mainSplit.addWidget(self.contentWidget)
203
- self.mainSplit.setHandleWidth(sp16)
207
+ self.mainSplit.setHandleWidth(16)
204
208
  self.mainSplit.setCollapsible(0, False)
205
209
  self.mainSplit.setCollapsible(1, False)
206
210
  self.mainSplit.setStretchFactor(0, 0)
207
211
  self.mainSplit.setStretchFactor(1, 1)
208
212
  self.mainSplit.setSizes([
209
- CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "fmtWidth", wWin//2)),
210
- CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "sumWidth", wWin//2)),
213
+ pOptions.getInt("GuiManuscriptBuild", "fmtWidth", 360),
214
+ pOptions.getInt("GuiManuscriptBuild", "sumWidth", 360),
211
215
  ])
212
216
 
213
217
  self.outerBox = QVBoxLayout()
214
218
  self.outerBox.addWidget(self.lblMain, 0, QtAlignCenter)
215
- self.outerBox.addSpacing(sp16)
219
+ self.outerBox.addSpacing(16)
216
220
  self.outerBox.addWidget(self.mainSplit, 1)
217
- self.outerBox.addSpacing(sp4)
221
+ self.outerBox.addSpacing(4)
218
222
  self.outerBox.addWidget(self.buildProgress, 0)
219
- self.outerBox.addSpacing(sp4)
223
+ self.outerBox.addSpacing(4)
220
224
  self.outerBox.addLayout(self.buildBox, 0)
221
- self.outerBox.addSpacing(sp16)
225
+ self.outerBox.addSpacing(16)
222
226
  self.outerBox.addWidget(self.buttonBox, 0)
223
227
  self.outerBox.setSpacing(0)
224
228
 
@@ -359,21 +363,14 @@ class GuiManuscriptBuild(NDialog):
359
363
 
360
364
  def _saveSettings(self) -> None:
361
365
  """Save the user GUI settings."""
362
- winWidth = CONFIG.rpxInt(self.width())
363
- winHeight = CONFIG.rpxInt(self.height())
364
-
365
- mainSplit = self.mainSplit.sizes()
366
- fmtWidth = CONFIG.rpxInt(mainSplit[0])
367
- sumWidth = CONFIG.rpxInt(mainSplit[1])
368
-
369
366
  logger.debug("Saving State: GuiManuscriptBuild")
367
+ mainSplit = self.mainSplit.sizes()
370
368
  pOptions = SHARED.project.options
371
- pOptions.setValue("GuiManuscriptBuild", "winWidth", winWidth)
372
- pOptions.setValue("GuiManuscriptBuild", "winHeight", winHeight)
373
- pOptions.setValue("GuiManuscriptBuild", "fmtWidth", fmtWidth)
374
- pOptions.setValue("GuiManuscriptBuild", "sumWidth", sumWidth)
369
+ pOptions.setValue("GuiManuscriptBuild", "winWidth", self.width())
370
+ pOptions.setValue("GuiManuscriptBuild", "winHeight", self.height())
371
+ pOptions.setValue("GuiManuscriptBuild", "fmtWidth", mainSplit[0])
372
+ pOptions.setValue("GuiManuscriptBuild", "sumWidth", mainSplit[1])
375
373
  pOptions.saveSettings()
376
-
377
374
  return
378
375
 
379
376
  def _populateContentList(self) -> None:
@@ -28,13 +28,13 @@ import logging
28
28
  from time import time
29
29
  from typing import TYPE_CHECKING
30
30
 
31
- from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
32
- from PyQt5.QtGui import (
33
- QCloseEvent, QColor, QCursor, QDesktopServices, QFont, QPalette,
34
- QResizeEvent, QTextDocument
31
+ from PyQt6.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
32
+ from PyQt6.QtGui import (
33
+ QCloseEvent, QColor, QCursor, QDesktopServices, QFont, QPageLayout,
34
+ QPalette, QResizeEvent, QTextDocument
35
35
  )
36
- from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
37
- from PyQt5.QtWidgets import (
36
+ from PyQt6.QtPrintSupport import QPrinter, QPrintPreviewDialog
37
+ from PyQt6.QtWidgets import (
38
38
  QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout,
39
39
  QLabel, QListWidget, QListWidgetItem, QPushButton, QSplitter,
40
40
  QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem,
@@ -42,8 +42,8 @@ from PyQt5.QtWidgets import (
42
42
  )
43
43
 
44
44
  from novelwriter import CONFIG, SHARED
45
- from novelwriter.common import fuzzyTime
46
- from novelwriter.constants import nwLabels, nwStats, trConst
45
+ from novelwriter.common import fuzzyTime, qtLambda
46
+ from novelwriter.constants import nwLabels, nwStats, trStats
47
47
  from novelwriter.core.buildsettings import BuildCollection, BuildSettings
48
48
  from novelwriter.core.docbuild import NWBuildDocument
49
49
  from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
@@ -59,7 +59,7 @@ from novelwriter.types import (
59
59
  QtUserRole
60
60
  )
61
61
 
62
- if TYPE_CHECKING: # pragma: no cover
62
+ if TYPE_CHECKING:
63
63
  from novelwriter.guimain import GuiMain
64
64
 
65
65
  logger = logging.getLogger(__name__)
@@ -85,18 +85,16 @@ class GuiManuscript(NToolDialog):
85
85
  self._buildMap: dict[str, QListWidgetItem] = {}
86
86
 
87
87
  self.setWindowTitle(self.tr("Build Manuscript"))
88
- self.setMinimumWidth(CONFIG.pxInt(600))
89
- self.setMinimumHeight(CONFIG.pxInt(500))
88
+ self.setMinimumWidth(600)
89
+ self.setMinimumHeight(500)
90
90
 
91
91
  iPx = SHARED.theme.baseIconHeight
92
92
  iSz = SHARED.theme.baseIconSize
93
- wWin = CONFIG.pxInt(900)
94
- hWin = CONFIG.pxInt(600)
95
93
 
96
94
  pOptions = SHARED.project.options
97
95
  self.resize(
98
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "winWidth", wWin)),
99
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "winHeight", hWin))
96
+ pOptions.getInt("GuiManuscript", "winWidth", 900),
97
+ pOptions.getInt("GuiManuscript", "winHeight", 600),
100
98
  )
101
99
 
102
100
  # Build Controls
@@ -108,22 +106,22 @@ class GuiManuscript(NToolDialog):
108
106
 
109
107
  buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
110
108
 
111
- self.tbAdd = NIconToolButton(self, iSz, "add")
109
+ self.tbAdd = NIconToolButton(self, iSz, "add", "green")
112
110
  self.tbAdd.setToolTip(self.tr("Add New Build"))
113
111
  self.tbAdd.setStyleSheet(buttonStyle)
114
112
  self.tbAdd.clicked.connect(self._createNewBuild)
115
113
 
116
- self.tbDel = NIconToolButton(self, iSz, "remove")
114
+ self.tbDel = NIconToolButton(self, iSz, "remove", "red")
117
115
  self.tbDel.setToolTip(self.tr("Delete Selected Build"))
118
116
  self.tbDel.setStyleSheet(buttonStyle)
119
117
  self.tbDel.clicked.connect(self._deleteSelectedBuild)
120
118
 
121
- self.tbCopy = NIconToolButton(self, iSz, "copy")
119
+ self.tbCopy = NIconToolButton(self, iSz, "copy", "blue")
122
120
  self.tbCopy.setToolTip(self.tr("Duplicate Selected Build"))
123
121
  self.tbCopy.setStyleSheet(buttonStyle)
124
122
  self.tbCopy.clicked.connect(self._copySelectedBuild)
125
123
 
126
- self.tbEdit = NIconToolButton(self, iSz, "edit")
124
+ self.tbEdit = NIconToolButton(self, iSz, "edit", "green")
127
125
  self.tbEdit.setToolTip(self.tr("Edit Selected Build"))
128
126
  self.tbEdit.setStyleSheet(buttonStyle)
129
127
  self.tbEdit.clicked.connect(self._editSelectedBuild)
@@ -153,9 +151,7 @@ class GuiManuscript(NToolDialog):
153
151
  # ============
154
152
 
155
153
  self.buildDetails = _DetailsWidget(self)
156
- self.buildDetails.setColumnWidth(
157
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "detailsWidth", 100)),
158
- )
154
+ self.buildDetails.setColumnWidth(pOptions.getInt("GuiManuscript", "detailsWidth", 100))
159
155
 
160
156
  self.buildOutline = _OutlineWidget(self)
161
157
 
@@ -168,8 +164,8 @@ class GuiManuscript(NToolDialog):
168
164
  self.buildSplit.addWidget(self.buildList)
169
165
  self.buildSplit.addWidget(self.detailsTabs)
170
166
  self.buildSplit.setSizes([
171
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "listHeight", 50)),
172
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "detailsHeight", 50)),
167
+ pOptions.getInt("GuiManuscript", "listHeight", 50),
168
+ pOptions.getInt("GuiManuscript", "detailsHeight", 50),
173
169
  ])
174
170
 
175
171
  # Process Controls
@@ -185,7 +181,7 @@ class GuiManuscript(NToolDialog):
185
181
  self.btnBuild.clicked.connect(self._buildManuscript)
186
182
 
187
183
  self.btnClose = QPushButton(self.tr("Close"), self)
188
- self.btnClose.clicked.connect(self.close)
184
+ self.btnClose.clicked.connect(qtLambda(self.close))
189
185
 
190
186
  self.processBox = QGridLayout()
191
187
  self.processBox.addWidget(self.btnPreview, 0, 0)
@@ -240,8 +236,8 @@ class GuiManuscript(NToolDialog):
240
236
  self.mainSplit.setStretchFactor(0, 0)
241
237
  self.mainSplit.setStretchFactor(1, 1)
242
238
  self.mainSplit.setSizes([
243
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "optsWidth", wWin//4)),
244
- CONFIG.pxInt(pOptions.getInt("GuiManuscript", "viewWidth", 3*wWin//4)),
239
+ pOptions.getInt("GuiManuscript", "optsWidth", 225),
240
+ pOptions.getInt("GuiManuscript", "viewWidth", 675),
245
241
  ])
246
242
 
247
243
  self.outerBox = QVBoxLayout()
@@ -337,7 +333,7 @@ class GuiManuscript(NToolDialog):
337
333
  def _deleteSelectedBuild(self) -> None:
338
334
  """Delete the currently selected build settings entry."""
339
335
  if build := self._getSelectedBuild():
340
- if SHARED.question(self.tr("Delete build '{0}'?".format(build.name))):
336
+ if SHARED.question(self.tr("Delete build '{0}'?").format(build.name)):
341
337
  if dialog := self._findSettingsDialog(build.buildID):
342
338
  dialog.close()
343
339
  self._builds.removeBuild(build.buildID)
@@ -431,38 +427,30 @@ class GuiManuscript(NToolDialog):
431
427
 
432
428
  def _saveSettings(self) -> None:
433
429
  """Save the user GUI settings."""
434
- buildOrder = []
435
- for i in range(self.buildList.count()):
436
- if item := self.buildList.item(i):
437
- buildOrder.append(item.data(self.D_KEY))
430
+ buildOrder = [
431
+ item.data(self.D_KEY) for i in range(self.buildList.count())
432
+ if (item := self.buildList.item(i))
433
+ ]
438
434
 
439
435
  current = self.buildList.currentItem()
440
436
  lastBuild = current.data(self.D_KEY) if isinstance(current, QListWidgetItem) else ""
441
437
 
442
438
  self._builds.setBuildsState(lastBuild, buildOrder)
443
439
 
444
- winWidth = CONFIG.rpxInt(self.width())
445
- winHeight = CONFIG.rpxInt(self.height())
446
-
447
440
  mainSplit = self.mainSplit.sizes()
448
- optsWidth = CONFIG.rpxInt(mainSplit[0])
449
- viewWidth = CONFIG.rpxInt(mainSplit[1])
450
-
451
441
  buildSplit = self.buildSplit.sizes()
452
- listHeight = CONFIG.rpxInt(buildSplit[0])
453
- detailsHeight = CONFIG.rpxInt(buildSplit[1])
454
- detailsWidth = CONFIG.rpxInt(self.buildDetails.getColumnWidth())
442
+ detailsWidth = self.buildDetails.getColumnWidth()
455
443
  detailsExpanded = self.buildDetails.getExpandedState()
456
444
  showNewPage = self.swtNewPage.isChecked()
457
445
 
458
446
  logger.debug("Saving State: GuiManuscript")
459
447
  pOptions = SHARED.project.options
460
- pOptions.setValue("GuiManuscript", "winWidth", winWidth)
461
- pOptions.setValue("GuiManuscript", "winHeight", winHeight)
462
- pOptions.setValue("GuiManuscript", "optsWidth", optsWidth)
463
- pOptions.setValue("GuiManuscript", "viewWidth", viewWidth)
464
- pOptions.setValue("GuiManuscript", "listHeight", listHeight)
465
- pOptions.setValue("GuiManuscript", "detailsHeight", detailsHeight)
448
+ pOptions.setValue("GuiManuscript", "winWidth", self.width())
449
+ pOptions.setValue("GuiManuscript", "winHeight", self.height())
450
+ pOptions.setValue("GuiManuscript", "optsWidth", mainSplit[0])
451
+ pOptions.setValue("GuiManuscript", "viewWidth", mainSplit[1])
452
+ pOptions.setValue("GuiManuscript", "listHeight", buildSplit[0])
453
+ pOptions.setValue("GuiManuscript", "detailsHeight", buildSplit[1])
466
454
  pOptions.setValue("GuiManuscript", "detailsWidth", detailsWidth)
467
455
  pOptions.setValue("GuiManuscript", "detailsExpanded", detailsExpanded)
468
456
  pOptions.setValue("GuiManuscript", "showNewPage", showNewPage)
@@ -490,7 +478,7 @@ class GuiManuscript(NToolDialog):
490
478
  for key, name in self._builds.builds():
491
479
  bItem = QListWidgetItem()
492
480
  bItem.setText(name)
493
- bItem.setIcon(SHARED.theme.getIcon("export"))
481
+ bItem.setIcon(SHARED.theme.getIcon("build_settings", "blue"))
494
482
  bItem.setData(self.D_KEY, key)
495
483
  self.buildList.addItem(bItem)
496
484
  self._buildMap[key] = bItem
@@ -585,8 +573,8 @@ class _DetailsWidget(QWidget):
585
573
 
586
574
  self.listView.clear()
587
575
 
588
- on = SHARED.theme.getIcon("bullet-on")
589
- off = SHARED.theme.getIcon("bullet-off")
576
+ on = SHARED.theme.getIcon("bullet-on", "blue")
577
+ off = SHARED.theme.getIcon("bullet-off", "blue")
590
578
 
591
579
  # Name
592
580
  item = QTreeWidgetItem()
@@ -641,7 +629,7 @@ class _DetailsWidget(QWidget):
641
629
  item.setText(1, "")
642
630
  self.listView.addTopLevelItem(item)
643
631
  for key in [
644
- "text.includeSynopsis", "text.includeComments",
632
+ "text.includeSynopsis", "text.includeComments", "text.includeStory",
645
633
  "text.includeKeywords", "text.includeBodyText",
646
634
  ]:
647
635
  sub = QTreeWidgetItem()
@@ -693,33 +681,31 @@ class _OutlineWidget(QWidget):
693
681
  hFont.setBold(True)
694
682
  hFont.setUnderline(True)
695
683
 
696
- root = self.listView.invisibleRootItem()
697
- parent = root
698
684
  indent = False
699
- for anchor, entry in data.items():
700
- prefix, _, text = entry.partition("|")
701
- if prefix in ("TT", "PT", "CH", "SC", "H1", "H2"):
702
- item = QTreeWidgetItem([text])
703
- item.setData(0, self.D_LINE, anchor)
704
- if prefix == "TT":
705
- item.setFont(0, tFont)
706
- item.setForeground(0, tBrush)
707
- root.addChild(item)
708
- parent = root
709
- elif prefix == "PT":
710
- item.setFont(0, hFont)
711
- root.addChild(item)
712
- parent = root
713
- elif prefix in ("CH", "H1"):
714
- root.addChild(item)
715
- parent = item
716
- elif prefix in ("SC", "H2"):
717
- parent.addChild(item)
718
- indent = True
719
-
720
- self.listView.setIndentation(
721
- SHARED.theme.baseIconHeight if indent else CONFIG.pxInt(4)
722
- )
685
+ if root := self.listView.invisibleRootItem():
686
+ parent = root
687
+ for anchor, entry in data.items():
688
+ prefix, _, text = entry.partition("|")
689
+ if prefix in ("TT", "PT", "CH", "SC", "H1", "H2"):
690
+ item = QTreeWidgetItem([text])
691
+ item.setData(0, self.D_LINE, anchor)
692
+ if prefix == "TT":
693
+ item.setFont(0, tFont)
694
+ item.setForeground(0, tBrush)
695
+ root.addChild(item)
696
+ parent = root
697
+ elif prefix == "PT":
698
+ item.setFont(0, hFont)
699
+ root.addChild(item)
700
+ parent = root
701
+ elif prefix in ("CH", "H1"):
702
+ root.addChild(item)
703
+ parent = item
704
+ elif prefix in ("SC", "H2"):
705
+ parent.addChild(item)
706
+ indent = True
707
+
708
+ self.listView.setIndentation(SHARED.theme.baseIconHeight if indent else 4)
723
709
  self._outline = data
724
710
 
725
711
  return
@@ -750,13 +736,15 @@ class _PreviewWidget(QTextBrowser):
750
736
  self.setPalette(dPalette)
751
737
 
752
738
  self.setMinimumWidth(40*SHARED.theme.textNWidth)
753
- self.setTabStopDistance(CONFIG.getTabWidth())
739
+ self.setTabStopDistance(CONFIG.tabWidth)
754
740
  self.setOpenExternalLinks(False)
755
741
  self.setOpenLinks(False)
756
742
 
757
- self.document().setDocumentMargin(CONFIG.getTextMargin())
743
+ if document := self.document():
744
+ document.setDocumentMargin(CONFIG.textMargin)
745
+
758
746
  self.setPlaceholderText(self.tr(
759
- "Press the \"Preview\" button to generate ..."
747
+ 'Press the "Preview" button to generate ...'
760
748
  ))
761
749
 
762
750
  self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
@@ -781,11 +769,11 @@ class _PreviewWidget(QTextBrowser):
781
769
  self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize))
782
770
 
783
771
  # Progress
784
- self.buildProgress = NProgressCircle(self, CONFIG.pxInt(160), CONFIG.pxInt(16))
772
+ self.buildProgress = NProgressCircle(self, 160, 16)
785
773
  self.buildProgress.setVisible(False)
786
774
  self.buildProgress.setMaximum(1)
787
775
  self.buildProgress.setValue(0)
788
- self.buildProgress.setColours(
776
+ self.buildProgress.setColors(
789
777
  back=QColor(255, 255, 255, 224),
790
778
  track=QColor(196, 196, 196, 128),
791
779
  text=QColor(0, 0, 0)
@@ -834,7 +822,8 @@ class _PreviewWidget(QTextBrowser):
834
822
  self.buildProgress.setValue(0)
835
823
  self.buildProgress.setCentreText(None)
836
824
  self.buildProgress.setVisible(True)
837
- self._scrollPos = self.verticalScrollBar().value()
825
+ if vBar := self.verticalScrollBar():
826
+ self._scrollPos = vBar.value()
838
827
  self.setPlaceholderText("")
839
828
  self.clear()
840
829
  return
@@ -852,9 +841,9 @@ class _PreviewWidget(QTextBrowser):
852
841
  self.buildProgress.setCentreText(self.tr("Processing ..."))
853
842
  QApplication.processEvents()
854
843
 
855
- document.setDocumentMargin(CONFIG.getTextMargin())
844
+ document.setDocumentMargin(CONFIG.textMargin)
856
845
  self.setDocument(document)
857
- self.setTabStopDistance(CONFIG.getTabWidth())
846
+ self.setTabStopDistance(CONFIG.tabWidth)
858
847
 
859
848
  self._docTime = int(time())
860
849
  self._updateBuildAge()
@@ -883,10 +872,11 @@ class _PreviewWidget(QTextBrowser):
883
872
  @pyqtSlot("QPrinter*")
884
873
  def printPreview(self, printer: QPrinter) -> None:
885
874
  """Connect the print preview painter to the document viewer."""
886
- QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
887
- printer.setOrientation(QPrinter.Orientation.Portrait)
888
- self.document().print(printer)
889
- QApplication.restoreOverrideCursor()
875
+ if document := self.document():
876
+ QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
877
+ printer.setPageOrientation(QPageLayout.Orientation.Portrait)
878
+ document.print(printer)
879
+ QApplication.restoreOverrideCursor()
890
880
  return
891
881
 
892
882
  @pyqtSlot(str)
@@ -928,7 +918,8 @@ class _PreviewWidget(QTextBrowser):
928
918
  def _postUpdate(self) -> None:
929
919
  """Run tasks after content update."""
930
920
  self.buildProgress.setVisible(False)
931
- self.verticalScrollBar().setValue(self._scrollPos)
921
+ if vBar := self.verticalScrollBar():
922
+ vBar.setValue(self._scrollPos)
932
923
  return
933
924
 
934
925
  ##
@@ -941,7 +932,7 @@ class _PreviewWidget(QTextBrowser):
941
932
  """
942
933
  vBar = self.verticalScrollBar()
943
934
  tB = self.frameWidth()
944
- vW = self.width() - 2*tB - vBar.width()
935
+ vW = self.width() - 2*tB - (vBar.width() if vBar else 0)
945
936
  vH = self.height() - 2*tB
946
937
  tH = self.ageLabel.height()
947
938
  pS = self.buildProgress.width()
@@ -986,23 +977,23 @@ class _StatsWidget(QWidget):
986
977
  def updateStats(self, data: dict[str, int]) -> None:
987
978
  """Update the stats values from a Tokenizer stats dict."""
988
979
  # Minimal
989
- self.minWordCount.setText("{0:n}".format(data.get(nwStats.WORDS, 0)))
990
- self.minCharCount.setText("{0:n}".format(data.get(nwStats.CHARS, 0)))
980
+ self.minWordCount.setText(f"{data.get(nwStats.WORDS, 0):n}")
981
+ self.minCharCount.setText(f"{data.get(nwStats.CHARS, 0):n}")
991
982
 
992
983
  # Maximal
993
- self.maxTotalWords.setText("{0:n}".format(data.get(nwStats.WORDS, 0)))
994
- self.maxHeadWords.setText("{0:n}".format(data.get(nwStats.WORDS_TITLE, 0)))
995
- self.maxTextWords.setText("{0:n}".format(data.get(nwStats.WORDS_TEXT, 0)))
996
- self.maxTitleCount.setText("{0:n}".format(data.get(nwStats.TITLES, 0)))
997
- self.maxParCount.setText("{0:n}".format(data.get(nwStats.PARAGRAPHS, 0)))
984
+ self.maxTotalWords.setText(f"{data.get(nwStats.WORDS, 0):n}")
985
+ self.maxHeadWords.setText(f"{data.get(nwStats.WORDS_TITLE, 0):n}")
986
+ self.maxTextWords.setText(f"{data.get(nwStats.WORDS_TEXT, 0):n}")
987
+ self.maxTitleCount.setText(f"{data.get(nwStats.TITLES, 0):n}")
988
+ self.maxParCount.setText(f"{data.get(nwStats.PARAGRAPHS, 0):n}")
998
989
 
999
- self.maxTotalChars.setText("{0:n}".format(data.get(nwStats.CHARS, 0)))
1000
- self.maxHeaderChars.setText("{0:n}".format(data.get(nwStats.CHARS_TITLE, 0)))
1001
- self.maxTextChars.setText("{0:n}".format(data.get(nwStats.CHARS_TEXT, 0)))
990
+ self.maxTotalChars.setText(f"{data.get(nwStats.CHARS, 0):n}")
991
+ self.maxHeaderChars.setText(f"{data.get(nwStats.CHARS_TITLE, 0):n}")
992
+ self.maxTextChars.setText(f"{data.get(nwStats.CHARS_TEXT, 0):n}")
1002
993
 
1003
- self.maxTotalWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_ALL, 0)))
1004
- self.maxHeadWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_TITLE, 0)))
1005
- self.maxTextWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_TEXT, 0)))
994
+ self.maxTotalWordChars.setText(f"{data.get(nwStats.WCHARS_ALL, 0):n}")
995
+ self.maxHeadWordChars.setText(f"{data.get(nwStats.WCHARS_TITLE, 0):n}")
996
+ self.maxTextWordChars.setText(f"{data.get(nwStats.WCHARS_TEXT, 0):n}")
1006
997
 
1007
998
  return
1008
999
 
@@ -1033,21 +1024,17 @@ class _StatsWidget(QWidget):
1033
1024
 
1034
1025
  def _buildBottomPanel(self) -> None:
1035
1026
  """Build the bottom page."""
1036
- mPx = CONFIG.pxInt(8)
1037
- hPx = CONFIG.pxInt(12)
1038
- vPx = CONFIG.pxInt(4)
1039
-
1040
- trAllChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS])
1041
- trTextChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS_TEXT])
1042
- trTitleChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS_TITLE])
1043
- trParagraphCount = trConst(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
1044
- trTitleCount = trConst(nwLabels.STATS_NAME[nwStats.TITLES])
1045
- trAllWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_ALL])
1046
- trTextWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_TEXT])
1047
- trTitleWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_TITLE])
1048
- trAllWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS])
1049
- trTextWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS_TEXT])
1050
- trTitleWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS_TITLE])
1027
+ trAllChars = trStats(nwLabels.STATS_NAME[nwStats.CHARS])
1028
+ trTextChars = trStats(nwLabels.STATS_NAME[nwStats.CHARS_TEXT])
1029
+ trTitleChars = trStats(nwLabels.STATS_NAME[nwStats.CHARS_TITLE])
1030
+ trParagraphCount = trStats(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
1031
+ trTitleCount = trStats(nwLabels.STATS_NAME[nwStats.TITLES])
1032
+ trAllWordChars = trStats(nwLabels.STATS_NAME[nwStats.WCHARS_ALL])
1033
+ trTextWordChars = trStats(nwLabels.STATS_NAME[nwStats.WCHARS_TEXT])
1034
+ trTitleWordChars = trStats(nwLabels.STATS_NAME[nwStats.WCHARS_TITLE])
1035
+ trAllWords = trStats(nwLabels.STATS_NAME[nwStats.WORDS])
1036
+ trTextWords = trStats(nwLabels.STATS_NAME[nwStats.WORDS_TEXT])
1037
+ trTitleWords = trStats(nwLabels.STATS_NAME[nwStats.WORDS_TITLE])
1051
1038
 
1052
1039
  # Minimal Form
1053
1040
  self.minWordCount = QLabel(self)
@@ -1073,8 +1060,8 @@ class _StatsWidget(QWidget):
1073
1060
  self.leftForm.addRow("", QLabel(self))
1074
1061
  self.leftForm.addRow(trTitleCount, self.maxTitleCount)
1075
1062
  self.leftForm.addRow(trParagraphCount, self.maxParCount)
1076
- self.leftForm.setHorizontalSpacing(hPx)
1077
- self.leftForm.setVerticalSpacing(vPx)
1063
+ self.leftForm.setHorizontalSpacing(12)
1064
+ self.leftForm.setVerticalSpacing(4)
1078
1065
 
1079
1066
  # Maximal Form, Right Column
1080
1067
  self.maxTotalChars = QLabel(self)
@@ -1098,25 +1085,25 @@ class _StatsWidget(QWidget):
1098
1085
  self.rightForm.addRow(trAllWordChars, self.maxTotalWordChars)
1099
1086
  self.rightForm.addRow(trTitleWordChars, self.maxHeadWordChars)
1100
1087
  self.rightForm.addRow(trTextWordChars, self.maxTextWordChars)
1101
- self.rightForm.setHorizontalSpacing(hPx)
1102
- self.rightForm.setVerticalSpacing(vPx)
1088
+ self.rightForm.setHorizontalSpacing(12)
1089
+ self.rightForm.setVerticalSpacing(4)
1103
1090
 
1104
1091
  # Assemble
1105
1092
  self.minLayout = QHBoxLayout()
1106
1093
  self.minLayout.addWidget(QLabel(trAllWords, self))
1107
1094
  self.minLayout.addWidget(self.minWordCount)
1108
- self.minLayout.addSpacing(mPx)
1095
+ self.minLayout.addSpacing(8)
1109
1096
  self.minLayout.addWidget(QLabel(trAllChars, self))
1110
1097
  self.minLayout.addWidget(self.minCharCount)
1111
1098
  self.minLayout.addStretch(1)
1112
- self.minLayout.setSpacing(mPx)
1099
+ self.minLayout.setSpacing(8)
1113
1100
  self.minLayout.setContentsMargins(0, 0, 0, 0)
1114
1101
 
1115
1102
  self.maxLayout = QHBoxLayout()
1116
1103
  self.maxLayout.addLayout(self.leftForm)
1117
1104
  self.maxLayout.addLayout(self.rightForm)
1118
1105
  self.maxLayout.addStretch(1)
1119
- self.maxLayout.setSpacing(CONFIG.pxInt(32))
1106
+ self.maxLayout.setSpacing(32)
1120
1107
  self.maxLayout.setContentsMargins(0, 0, 0, 0)
1121
1108
 
1122
1109
  self.minWidget.setLayout(self.minLayout)