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
novelwriter/config.py CHANGED
@@ -29,17 +29,16 @@ import json
29
29
  import logging
30
30
  import sys
31
31
 
32
- from datetime import datetime
33
32
  from pathlib import Path
34
33
  from time import time
35
- from typing import TYPE_CHECKING
34
+ from typing import TYPE_CHECKING, Final
36
35
 
37
- from PyQt5.QtCore import (
36
+ from PyQt6.QtCore import (
38
37
  PYQT_VERSION, PYQT_VERSION_STR, QT_VERSION, QT_VERSION_STR, QLibraryInfo,
39
38
  QLocale, QStandardPaths, QSysInfo, QTranslator
40
39
  )
41
- from PyQt5.QtGui import QFont, QFontDatabase
42
- from PyQt5.QtWidgets import QApplication
40
+ from PyQt6.QtGui import QFont, QFontDatabase
41
+ from PyQt6.QtWidgets import QApplication
43
42
 
44
43
  from novelwriter.common import (
45
44
  NWConfigParser, checkInt, checkPath, describeFont, fontMatcher,
@@ -48,14 +47,45 @@ from novelwriter.common import (
48
47
  from novelwriter.constants import nwFiles, nwUnicode
49
48
  from novelwriter.error import formatException, logException
50
49
 
51
- if TYPE_CHECKING: # pragma: no cover
50
+ if TYPE_CHECKING:
51
+ from datetime import datetime
52
+
52
53
  from novelwriter.core.projectdata import NWProjectData
53
54
 
54
55
  logger = logging.getLogger(__name__)
55
56
 
57
+ DEF_GUI = "default"
58
+ DEF_SYNTAX = "default_light"
59
+ DEF_ICONS = "material_rounded_normal"
60
+ DEF_TREECOL = "theme"
61
+
56
62
 
57
63
  class Config:
58
64
 
65
+ __slots__ = (
66
+ "_appPath", "_appRoot", "_backPath", "_backupPath", "_confPath", "_dLocale", "_dShortDate",
67
+ "_dShortDateTime", "_dataPath", "_errData", "_hasError", "_homePath", "_manuals",
68
+ "_nwLangPath", "_qLocale", "_qtLangPath", "_qtTrans", "_recentPaths", "_recentProjects",
69
+ "allowOpenDial", "altDialogClose", "altDialogOpen", "appHandle", "appName",
70
+ "askBeforeBackup", "askBeforeExit", "autoSaveDoc", "autoSaveProj", "autoScroll",
71
+ "autoScrollPos", "autoSelect", "backupOnClose", "cursorWidth", "dialogLine", "dialogStyle",
72
+ "doJustify", "doReplace", "doReplaceDQuote", "doReplaceDash", "doReplaceDots",
73
+ "doReplaceSQuote", "emphLabels", "fmtApostrophe", "fmtDQuoteClose", "fmtDQuoteOpen",
74
+ "fmtPadAfter", "fmtPadBefore", "fmtPadThin", "fmtSQuoteClose", "fmtSQuoteOpen",
75
+ "focusWidth", "guiFont", "guiLocale", "guiSyntax", "guiTheme", "hasEnchant",
76
+ "hideFocusFooter", "hideHScroll", "hideVScroll", "highlightEmph", "hostName",
77
+ "iconColDocs", "iconColTree", "iconTheme", "incNotesWCount", "isDebug", "kernelVer",
78
+ "lastNotes", "mainPanePos", "mainWinSize", "memInfo", "narratorBreak", "narratorDialog",
79
+ "nativeFont", "osDarwin", "osLinux", "osType", "osUnknown", "osWindows", "outlinePanePos",
80
+ "prefsWinSize", "scrollPastEnd", "searchCase", "searchLoop", "searchMatchCap",
81
+ "searchNextFile", "searchProjCase", "searchProjRegEx", "searchProjWord", "searchRegEx",
82
+ "searchWord", "showEditToolBar", "showFullPath", "showLineEndings", "showMultiSpaces",
83
+ "showSessionTime", "showTabsNSpaces", "showViewerPanel", "spellLanguage", "stopWhenIdle",
84
+ "tabWidth", "textFont", "textMargin", "textWidth", "useCharCount", "userIdleTime",
85
+ "verPyQtString", "verPyQtValue", "verPyString", "verQtString", "verQtValue",
86
+ "viewComments", "viewPanePos", "viewSynopsis", "welcomeWinSize",
87
+ )
88
+
59
89
  LANG_NW = 1
60
90
  LANG_PROJ = 2
61
91
 
@@ -83,10 +113,10 @@ class Config:
83
113
 
84
114
  self._appPath = Path(__file__).parent.absolute()
85
115
  self._appRoot = self._appPath.parent
86
- if self._appRoot.is_file():
87
- # novelWriter is packaged as a single file
88
- self._appRoot = self._appRoot.parent
89
- self._appPath = self._appRoot
116
+ if getattr(sys, "frozen", False): # pragma: no cover
117
+ # novelWriter is packaged as an exe
118
+ self._appPath = Path(__file__).parent.parent.absolute()
119
+ self._appRoot = self._appPath
90
120
 
91
121
  # Runtime Settings and Variables
92
122
  self._hasError = False # True if the config class encountered an error
@@ -95,7 +125,7 @@ class Config:
95
125
  # Localisation
96
126
  # Note that these paths must be strings
97
127
  self._nwLangPath = self._appPath / "assets" / "i18n"
98
- self._qtLangPath = QLibraryInfo.location(QLibraryInfo.LibraryLocation.TranslationsPath)
128
+ self._qtLangPath = QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath)
99
129
 
100
130
  hasLocale = (self._nwLangPath / f"nw_{QLocale.system().name()}.qm").exists()
101
131
  self._qLocale = QLocale.system() if hasLocale else QLocale("en_GB")
@@ -119,22 +149,27 @@ class Config:
119
149
 
120
150
  # General GUI Settings
121
151
  self.guiLocale = self._qLocale.name()
122
- self.guiTheme = "default_light" # GUI theme
123
- self.guiSyntax = "default_light" # Syntax theme
124
- self.guiFont = QFont() # Main GUI font
125
- self.guiScale = 1.0 # Set automatically by Theme class
126
- self.hideVScroll = False # Hide vertical scroll bars on main widgets
127
- self.hideHScroll = False # Hide horizontal scroll bars on main widgets
128
- self.lastNotes = "0x0" # The latest release notes that have been shown
129
- self.nativeFont = True # Use native font dialog
152
+ self.guiTheme = DEF_GUI # GUI theme
153
+ self.guiSyntax = DEF_SYNTAX # Syntax theme
154
+ self.guiFont = QFont() # Main GUI font
155
+ self.hideVScroll = False # Hide vertical scroll bars on main widgets
156
+ self.hideHScroll = False # Hide horizontal scroll bars on main widgets
157
+ self.lastNotes = "0x0" # The latest release notes that have been shown
158
+ self.nativeFont = True # Use native font dialog
159
+ self.useCharCount = False # Use character count as primary count
160
+
161
+ # Icons
162
+ self.iconTheme = DEF_ICONS # Icons theme
163
+ self.iconColTree = DEF_TREECOL # Project tree icon colours
164
+ self.iconColDocs = False # Keep theme colours on documents
130
165
 
131
166
  # Size Settings
132
- self._mainWinSize = [1200, 650] # Last size of the main GUI window
133
- self._welcomeSize = [800, 550] # Last size of the welcome window
134
- self._prefsWinSize = [700, 615] # Last size of the Preferences dialog
135
- self._mainPanePos = [300, 800] # Last position of the main window splitter
136
- self._viewPanePos = [500, 150] # Last position of the document viewer splitter
137
- self._outlnPanePos = [500, 150] # Last position of the outline panel splitter
167
+ self.mainWinSize = [1200, 650] # Last size of the main GUI window
168
+ self.welcomeWinSize = [800, 550] # Last size of the welcome window
169
+ self.prefsWinSize = [700, 615] # Last size of the Preferences dialog
170
+ self.mainPanePos = [300, 800] # Last position of the main window splitter
171
+ self.viewPanePos = [500, 150] # Last position of the document viewer splitter
172
+ self.outlinePanePos = [500, 150] # Last position of the outline panel splitter
138
173
 
139
174
  # Project Settings
140
175
  self.autoSaveProj = 60 # Interval for auto-saving project, in seconds
@@ -149,6 +184,7 @@ class Config:
149
184
  self.textWidth = 700 # Editor text width
150
185
  self.textMargin = 40 # Editor/viewer text margin
151
186
  self.tabWidth = 40 # Editor tabulator width
187
+ self.cursorWidth = 1 # Editor cursor width
152
188
 
153
189
  self.focusWidth = 800 # Focus Mode text width
154
190
  self.hideFocusFooter = False # Hide document footer in Focus Mode
@@ -220,7 +256,7 @@ class Config:
220
256
  # System and App Information
221
257
  # ==========================
222
258
 
223
- # Check Qt5 Versions
259
+ # Check Qt Versions
224
260
  self.verQtString = QT_VERSION_STR
225
261
  self.verQtValue = QT_VERSION
226
262
  self.verPyQtString = PYQT_VERSION_STR
@@ -267,7 +303,12 @@ class Config:
267
303
 
268
304
  @property
269
305
  def pdfDocs(self) -> Path | None:
270
- return self._manuals.get(f"manual_{self.locale.name()}", self._manuals.get("manual"))
306
+ """Return the local manual PDF file, if any exist."""
307
+ return self._manuals.get(f"manual_{self.locale.bcp47Name()}", self._manuals.get("manual"))
308
+
309
+ @property
310
+ def nwLangPath(self) -> Path:
311
+ return self._nwLangPath
271
312
 
272
313
  @property
273
314
  def locale(self) -> QLocale:
@@ -277,30 +318,6 @@ class Config:
277
318
  def recentProjects(self) -> RecentProjects:
278
319
  return self._recentProjects
279
320
 
280
- @property
281
- def mainWinSize(self) -> list[int]:
282
- return [int(x*self.guiScale) for x in self._mainWinSize]
283
-
284
- @property
285
- def welcomeWinSize(self) -> list[int]:
286
- return [int(x*self.guiScale) for x in self._welcomeSize]
287
-
288
- @property
289
- def preferencesWinSize(self) -> list[int]:
290
- return [int(x*self.guiScale) for x in self._prefsWinSize]
291
-
292
- @property
293
- def mainPanePos(self) -> list[int]:
294
- return [int(x*self.guiScale) for x in self._mainPanePos]
295
-
296
- @property
297
- def viewPanePos(self) -> list[int]:
298
- return [int(x*self.guiScale) for x in self._viewPanePos]
299
-
300
- @property
301
- def outlinePanePos(self) -> list[int]:
302
- return [int(x*self.guiScale) for x in self._outlnPanePos]
303
-
304
321
  ##
305
322
  # Getters
306
323
  ##
@@ -308,17 +325,9 @@ class Config:
308
325
  def getTextWidth(self, focusMode: bool = False) -> int:
309
326
  """Get the text with for the correct editor mode."""
310
327
  if focusMode:
311
- return self.pxInt(max(self.focusWidth, 200))
328
+ return max(self.focusWidth, 200)
312
329
  else:
313
- return self.pxInt(max(self.textWidth, 200))
314
-
315
- def getTextMargin(self) -> int:
316
- """Get the scaled text margin."""
317
- return self.pxInt(max(self.textMargin, 0))
318
-
319
- def getTabWidth(self) -> int:
320
- """Get the scaled tab width."""
321
- return self.pxInt(max(self.tabWidth, 0))
330
+ return max(self.textWidth, 200)
322
331
 
323
332
  ##
324
333
  # Setters
@@ -330,46 +339,27 @@ class Config:
330
339
  adjust it a bit, and we don't want the main window to shrink or
331
340
  grow each time the app is opened.
332
341
  """
333
- width = int(width/self.guiScale)
334
- height = int(height/self.guiScale)
335
- if abs(self._mainWinSize[0] - width) > 5:
336
- self._mainWinSize[0] = width
337
- if abs(self._mainWinSize[1] - height) > 5:
338
- self._mainWinSize[1] = height
342
+ if abs(self.mainWinSize[0] - width) > 5:
343
+ self.mainWinSize[0] = width
344
+ if abs(self.mainWinSize[1] - height) > 5:
345
+ self.mainWinSize[1] = height
339
346
  return
340
347
 
341
348
  def setWelcomeWinSize(self, width: int, height: int) -> None:
342
349
  """Set the size of the Preferences dialog window."""
343
- self._welcomeSize[0] = int(width/self.guiScale)
344
- self._welcomeSize[1] = int(height/self.guiScale)
350
+ self.welcomeWinSize = [width, height]
345
351
  return
346
352
 
347
353
  def setPreferencesWinSize(self, width: int, height: int) -> None:
348
354
  """Set the size of the Preferences dialog window."""
349
- self._prefsWinSize[0] = int(width/self.guiScale)
350
- self._prefsWinSize[1] = int(height/self.guiScale)
351
- return
352
-
353
- def setMainPanePos(self, pos: list[int]) -> None:
354
- """Set the position of the main GUI splitter."""
355
- self._mainPanePos = [int(x/self.guiScale) for x in pos]
356
- return
357
-
358
- def setViewPanePos(self, pos: list[int]) -> None:
359
- """Set the position of the viewer meta data splitter."""
360
- self._viewPanePos = [int(x/self.guiScale) for x in pos]
361
- return
362
-
363
- def setOutlinePanePos(self, pos: list[int]) -> None:
364
- """Set the position of the outline details splitter."""
365
- self._outlnPanePos = [int(x/self.guiScale) for x in pos]
355
+ self.prefsWinSize = [width, height]
366
356
  return
367
357
 
368
358
  def setLastPath(self, key: str, path: str | Path) -> None:
369
359
  """Set the last used path. Only the folder is saved, so if the
370
360
  path is not a folder, the parent of the path is used instead.
371
361
  """
372
- if isinstance(path, (str, Path)):
362
+ if isinstance(path, str | Path):
373
363
  path = checkPath(path, self._homePath)
374
364
  if not path.is_dir():
375
365
  path = path.parent
@@ -392,13 +382,12 @@ class Config:
392
382
  self.guiFont = fontMatcher(font)
393
383
  else:
394
384
  font = QFont()
395
- fontDB = QFontDatabase()
396
- if self.osWindows and "Arial" in fontDB.families():
385
+ if self.osWindows and "Arial" in QFontDatabase.families():
397
386
  # On Windows we default to Arial if possible
398
387
  font.setFamily("Arial")
399
388
  font.setPointSize(10)
400
389
  else:
401
- font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
390
+ font = QFontDatabase.systemFont(QFontDatabase.SystemFont.GeneralFont)
402
391
  self.guiFont = fontMatcher(font)
403
392
  logger.debug("GUI font set to: %s", describeFont(font))
404
393
  QApplication.setFont(self.guiFont)
@@ -415,8 +404,7 @@ class Config:
415
404
  font.fromString(value)
416
405
  self.textFont = fontMatcher(font)
417
406
  else:
418
- fontDB = QFontDatabase()
419
- fontFam = fontDB.families()
407
+ fontFam = QFontDatabase.families()
420
408
  if self.osWindows and "Arial" in fontFam:
421
409
  font = QFont()
422
410
  font.setFamily("Arial")
@@ -426,7 +414,7 @@ class Config:
426
414
  font.setFamily("Helvetica")
427
415
  font.setPointSize(12)
428
416
  else:
429
- font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
417
+ font = QFontDatabase.systemFont(QFontDatabase.SystemFont.GeneralFont)
430
418
  self.textFont = fontMatcher(font)
431
419
  logger.debug("Text font set to: %s", describeFont(self.textFont))
432
420
  return
@@ -435,14 +423,6 @@ class Config:
435
423
  # Methods
436
424
  ##
437
425
 
438
- def pxInt(self, value: int) -> int:
439
- """Scale fixed gui sizes by the screen scale factor."""
440
- return int(value*self.guiScale)
441
-
442
- def rpxInt(self, value: int) -> int:
443
- """Un-scale fixed gui sizes by the screen scale factor."""
444
- return int(value/self.guiScale)
445
-
446
426
  def homePath(self) -> Path:
447
427
  """The user's home folder."""
448
428
  return self._homePath
@@ -521,16 +501,17 @@ class Config:
521
501
  # Config Actions
522
502
  ##
523
503
 
524
- def initConfig(self, confPath: str | Path | None = None,
525
- dataPath: str | Path | None = None) -> None:
504
+ def initConfig(
505
+ self, confPath: str | Path | None = None, dataPath: str | Path | None = None
506
+ ) -> None:
526
507
  """Initialise the config class. The manual setting of confPath
527
508
  and dataPath is mainly intended for the test suite.
528
509
  """
529
510
  logger.debug("Initialising Config ...")
530
- if isinstance(confPath, (str, Path)):
511
+ if isinstance(confPath, str | Path):
531
512
  logger.info("Setting alternative config path: %s", confPath)
532
513
  self._confPath = Path(confPath)
533
- if isinstance(dataPath, (str, Path)):
514
+ if isinstance(dataPath, str | Path):
534
515
  logger.info("Setting alternative data path: %s", dataPath)
535
516
  self._dataPath = Path(dataPath)
536
517
 
@@ -572,13 +553,13 @@ class Config:
572
553
  self._dShortDateTime = self._dLocale.dateTimeFormat(QLocale.FormatType.ShortFormat)
573
554
 
574
555
  langList = [
575
- (self._qtLangPath, "qtbase"), # Qt 5.x
556
+ (self._qtLangPath, "qtbase"), # Qt
576
557
  (str(self._nwLangPath), "nw"), # novelWriter
577
558
  ]
578
559
  for lngPath, lngBase in langList:
579
560
  for lngCode in self._qLocale.uiLanguages():
580
561
  qTrans = QTranslator()
581
- lngFile = "%s_%s" % (lngBase, lngCode.replace("-", "_"))
562
+ lngFile = "{0}_{1}".format(lngBase, lngCode.replace("-", "_"))
582
563
  if lngFile not in self._qtTrans:
583
564
  if qTrans.load(lngFile, lngPath):
584
565
  logger.debug("Loaded: %s.qm", lngFile)
@@ -615,22 +596,26 @@ class Config:
615
596
  # Main
616
597
  sec = "Main"
617
598
  self.setGuiFont(conf.rdStr(sec, "font", ""))
618
- self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
619
- self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
620
- self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
621
- self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
622
- self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
623
- self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
624
- self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont)
599
+ self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
600
+ self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
601
+ self.iconTheme = conf.rdStr(sec, "icons", self.iconTheme)
602
+ self.iconColTree = conf.rdStr(sec, "iconcoltree", self.iconColTree)
603
+ self.iconColDocs = conf.rdBool(sec, "iconcoldocs", self.iconColDocs)
604
+ self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
605
+ self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
606
+ self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
607
+ self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
608
+ self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont)
609
+ self.useCharCount = conf.rdBool(sec, "usecharcount", self.useCharCount)
625
610
 
626
611
  # Sizes
627
612
  sec = "Sizes"
628
- self._mainWinSize = conf.rdIntList(sec, "mainwindow", self._mainWinSize)
629
- self._welcomeSize = conf.rdIntList(sec, "welcome", self._welcomeSize)
630
- self._prefsWinSize = conf.rdIntList(sec, "preferences", self._prefsWinSize)
631
- self._mainPanePos = conf.rdIntList(sec, "mainpane", self._mainPanePos)
632
- self._viewPanePos = conf.rdIntList(sec, "viewpane", self._viewPanePos)
633
- self._outlnPanePos = conf.rdIntList(sec, "outlinepane", self._outlnPanePos)
613
+ self.mainWinSize = conf.rdIntList(sec, "mainwindow", self.mainWinSize)
614
+ self.welcomeWinSize = conf.rdIntList(sec, "welcome", self.welcomeWinSize)
615
+ self.prefsWinSize = conf.rdIntList(sec, "preferences", self.prefsWinSize)
616
+ self.mainPanePos = conf.rdIntList(sec, "mainpane", self.mainPanePos)
617
+ self.viewPanePos = conf.rdIntList(sec, "viewpane", self.viewPanePos)
618
+ self.outlinePanePos = conf.rdIntList(sec, "outlinepane", self.outlinePanePos)
634
619
 
635
620
  # Project
636
621
  sec = "Project"
@@ -648,6 +633,7 @@ class Config:
648
633
  self.textWidth = conf.rdInt(sec, "width", self.textWidth)
649
634
  self.textMargin = conf.rdInt(sec, "margin", self.textMargin)
650
635
  self.tabWidth = conf.rdInt(sec, "tabwidth", self.tabWidth)
636
+ self.cursorWidth = conf.rdInt(sec, "cursorwidth", self.cursorWidth)
651
637
  self.focusWidth = conf.rdInt(sec, "focuswidth", self.focusWidth)
652
638
  self.hideFocusFooter = conf.rdBool(sec, "hidefocusfooter", self.hideFocusFooter)
653
639
  self.doJustify = conf.rdBool(sec, "justify", self.doJustify)
@@ -729,20 +715,24 @@ class Config:
729
715
  "font": self.guiFont.toString(),
730
716
  "theme": str(self.guiTheme),
731
717
  "syntax": str(self.guiSyntax),
718
+ "icons": str(self.iconTheme),
719
+ "iconcoltree": str(self.iconColTree),
720
+ "iconcoldocs": str(self.iconColDocs),
732
721
  "localisation": str(self.guiLocale),
733
722
  "hidevscroll": str(self.hideVScroll),
734
723
  "hidehscroll": str(self.hideHScroll),
735
724
  "lastnotes": str(self.lastNotes),
736
725
  "nativefont": str(self.nativeFont),
726
+ "usecharcount": str(self.useCharCount),
737
727
  }
738
728
 
739
729
  conf["Sizes"] = {
740
- "mainwindow": self._packList(self._mainWinSize),
741
- "welcome": self._packList(self._welcomeSize),
742
- "preferences": self._packList(self._prefsWinSize),
743
- "mainpane": self._packList(self._mainPanePos),
744
- "viewpane": self._packList(self._viewPanePos),
745
- "outlinepane": self._packList(self._outlnPanePos),
730
+ "mainwindow": self._packList(self.mainWinSize),
731
+ "welcome": self._packList(self.welcomeWinSize),
732
+ "preferences": self._packList(self.prefsWinSize),
733
+ "mainpane": self._packList(self.mainPanePos),
734
+ "viewpane": self._packList(self.viewPanePos),
735
+ "outlinepane": self._packList(self.outlinePanePos),
746
736
  }
747
737
 
748
738
  conf["Project"] = {
@@ -760,6 +750,7 @@ class Config:
760
750
  "width": str(self.textWidth),
761
751
  "margin": str(self.textMargin),
762
752
  "tabwidth": str(self.tabWidth),
753
+ "cursorwidth": str(self.cursorWidth),
763
754
  "focuswidth": str(self.focusWidth),
764
755
  "hidefocusfooter": str(self.hideFocusFooter),
765
756
  "justify": str(self.doJustify),
@@ -931,7 +922,7 @@ class RecentProjects:
931
922
 
932
923
  class RecentPaths:
933
924
 
934
- KEYS = ["default", "project", "import", "outline", "stats"]
925
+ KEYS: Final[list[str]] = ["default", "project", "import", "outline", "stats"]
935
926
 
936
927
  def __init__(self, config: Config) -> None:
937
928
  self._conf = config