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
@@ -27,13 +27,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
27
27
  """
28
28
  from __future__ import annotations
29
29
 
30
- from PyQt5.QtGui import QColor, QFont, QPalette, QPixmap
31
- from PyQt5.QtWidgets import (
30
+ from PyQt6.QtGui import QColor, QFont, QPalette, QPixmap
31
+ from PyQt6.QtWidgets import (
32
32
  QAbstractButton, QFrame, QHBoxLayout, QLabel, QLayout, QScrollArea,
33
33
  QVBoxLayout, QWidget
34
34
  )
35
35
 
36
- from novelwriter import CONFIG
37
36
  from novelwriter.types import QtScrollAsNeeded
38
37
 
39
38
  DEFAULT_SCALE = 0.9
@@ -99,14 +98,14 @@ class NScrollableForm(QScrollArea):
99
98
  self._helpCol = QColor(0, 0, 0)
100
99
  self._fontScale = DEFAULT_SCALE
101
100
  self._first = True
102
- self._indent = CONFIG.pxInt(12)
101
+ self._indent = 12
103
102
 
104
103
  self._sections: dict[int, QLabel] = {}
105
- self._editable: dict[str, NColourLabel] = {}
104
+ self._editable: dict[str, NColorLabel] = {}
106
105
  self._index: dict[str, QWidget] = {}
107
106
 
108
107
  self._layout = QVBoxLayout()
109
- self._layout.setSpacing(CONFIG.pxInt(12))
108
+ self._layout.setSpacing(12)
110
109
 
111
110
  self._widget = QWidget(self)
112
111
  self._widget.setLayout(self._layout)
@@ -156,24 +155,25 @@ class NScrollableForm(QScrollArea):
156
155
  def scrollToSection(self, identifier: int) -> None:
157
156
  """Scroll to the requested section identifier."""
158
157
  if identifier in self._sections:
159
- yPos = self._sections[identifier].pos().y() - CONFIG.pxInt(8)
160
- self.verticalScrollBar().setValue(yPos)
158
+ yPos = self._sections[identifier].pos().y() - 8
159
+ if vBar := self.verticalScrollBar():
160
+ vBar.setValue(yPos)
161
161
  return
162
162
 
163
163
  def scrollToLabel(self, label: str) -> None:
164
164
  """Scroll to the requested label."""
165
165
  if label in self._index:
166
- yPos = self._index[label].pos().y() - CONFIG.pxInt(8)
167
- self.verticalScrollBar().setValue(yPos)
166
+ yPos = self._index[label].pos().y() - 8
167
+ if vBar := self.verticalScrollBar():
168
+ vBar.setValue(yPos)
168
169
  return
169
170
 
170
171
  def addGroupLabel(self, label: str, identifier: int | None = None) -> None:
171
172
  """Add a text label to separate groups of settings."""
172
- hM = CONFIG.pxInt(4)
173
173
  qLabel = QLabel(f"<b>{label}</b>", self)
174
- qLabel.setContentsMargins(0, hM, 0, hM)
174
+ qLabel.setContentsMargins(0, 4, 0, 4)
175
175
  if not self._first:
176
- self._layout.addSpacing(5*hM)
176
+ self._layout.addSpacing(20)
177
177
  self._layout.addWidget(qLabel)
178
178
  self._first = False
179
179
  if identifier is not None:
@@ -192,7 +192,7 @@ class NScrollableForm(QScrollArea):
192
192
  ) -> None:
193
193
  """Add a label and a widget as a new row of the form."""
194
194
  row = QHBoxLayout()
195
- row.setSpacing(CONFIG.pxInt(12))
195
+ row.setSpacing(12)
196
196
 
197
197
  if isinstance(widget, list):
198
198
  wBox = QHBoxLayout()
@@ -205,7 +205,7 @@ class NScrollableForm(QScrollArea):
205
205
  icon.setPixmap(item)
206
206
  wBox.addWidget(icon)
207
207
  elif isinstance(item, int):
208
- wBox.addSpacing(CONFIG.pxInt(item))
208
+ wBox.addSpacing(item)
209
209
  qWidget = QWidget(self)
210
210
  qWidget.setLayout(wBox)
211
211
  else:
@@ -216,7 +216,7 @@ class NScrollableForm(QScrollArea):
216
216
  qLabel.setBuddy(qWidget)
217
217
 
218
218
  if helpText:
219
- qHelp = NColourLabel(
219
+ qHelp = NColorLabel(
220
220
  str(helpText), self, color=self._helpCol,
221
221
  scale=self._fontScale, wrap=True, indent=self._indent
222
222
  )
@@ -252,12 +252,12 @@ class NScrollableForm(QScrollArea):
252
252
 
253
253
  def finalise(self) -> None:
254
254
  """Finalise the layout when the form is built."""
255
- self._layout.addSpacing(CONFIG.pxInt(20))
255
+ self._layout.addSpacing(20)
256
256
  self._layout.addStretch(1)
257
257
  return
258
258
 
259
259
 
260
- class NColourLabel(QLabel):
260
+ class NColorLabel(QLabel):
261
261
  """Extension: A Coloured Label
262
262
 
263
263
  A custom widget that draws a label in a specific colour, and
@@ -24,9 +24,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
24
24
  """
25
25
  from __future__ import annotations
26
26
 
27
- from PyQt5.QtCore import QEvent, QObject
28
- from PyQt5.QtGui import QStatusTipEvent, QWheelEvent
29
- from PyQt5.QtWidgets import QWidget
27
+ from typing import TYPE_CHECKING
28
+
29
+ from PyQt6.QtCore import QEvent, QObject
30
+ from PyQt6.QtGui import QStatusTipEvent, QWheelEvent
31
+
32
+ if TYPE_CHECKING:
33
+ from PyQt6.QtWidgets import QWidget
30
34
 
31
35
 
32
36
  class WheelEventFilter(QObject):
@@ -40,7 +44,7 @@ class WheelEventFilter(QObject):
40
44
  Reference: https://stackoverflow.com/a/17739995/5825851
41
45
  """
42
46
 
43
- __slots__ = ("_parent", "_locked")
47
+ __slots__ = ("_locked", "_parent")
44
48
 
45
49
  def __init__(self, parent: QWidget) -> None:
46
50
  super().__init__(parent=parent)
@@ -48,7 +52,7 @@ class WheelEventFilter(QObject):
48
52
  self._locked = False
49
53
  return
50
54
 
51
- def eventFilter(self, object: QObject, event: QEvent) -> bool:
55
+ def eventFilter(self, obj: QObject, event: QEvent) -> bool:
52
56
  """Filter events of type QWheelEvent and forward them to the
53
57
  parent widget's wheelEvent handler.
54
58
  """
@@ -27,20 +27,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
27
27
  """
28
28
  from __future__ import annotations
29
29
 
30
- from enum import Enum
31
30
  from typing import TYPE_CHECKING
32
31
 
33
- from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot
34
- from PyQt5.QtGui import QMouseEvent, QWheelEvent
35
- from PyQt5.QtWidgets import (
32
+ from PyQt6.QtCore import QModelIndex, QSize, Qt, pyqtSignal, pyqtSlot
33
+ from PyQt6.QtWidgets import (
36
34
  QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel, QSpinBox,
37
- QToolButton, QWidget
35
+ QToolButton, QTreeView, QWidget
38
36
  )
39
37
 
40
38
  from novelwriter import CONFIG, SHARED
41
- from novelwriter.types import QtMouseLeft
39
+ from novelwriter.types import QtMouseLeft, QtMouseMiddle
40
+
41
+ if TYPE_CHECKING:
42
+ from enum import Enum
43
+
44
+ from PyQt6.QtGui import QMouseEvent, QWheelEvent
42
45
 
43
- if TYPE_CHECKING: # pragma: no cover
44
46
  from novelwriter.guimain import GuiMain
45
47
 
46
48
 
@@ -99,6 +101,20 @@ class NNonBlockingDialog(NDialog):
99
101
  return
100
102
 
101
103
 
104
+ class NTreeView(QTreeView):
105
+
106
+ middleClicked = pyqtSignal(QModelIndex)
107
+
108
+ def mousePressEvent(self, event: QMouseEvent | None) -> None:
109
+ """Emit a signal on mouse middle click."""
110
+ if (
111
+ event and event.button() == QtMouseMiddle
112
+ and (index := self.indexAt(event.pos())).isValid()
113
+ ):
114
+ self.middleClicked.emit(index)
115
+ return super().mousePressEvent(event)
116
+
117
+
102
118
  class NComboBox(QComboBox):
103
119
 
104
120
  def __init__(self, parent: QWidget | None = None) -> None:
@@ -141,15 +157,15 @@ class NDoubleSpinBox(QDoubleSpinBox):
141
157
  self,
142
158
  parent: QWidget | None = None,
143
159
  *,
144
- min: float = 0.0,
145
- max: float = 15.0,
160
+ minVal: float = 0.0,
161
+ maxVal: float = 15.0,
146
162
  step: float = 0.1,
147
163
  prec: int = 2,
148
164
  ) -> None:
149
165
  super().__init__(parent=parent)
150
166
  self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
151
- self.setMinimum(min)
152
- self.setMaximum(max)
167
+ self.setMinimum(minVal)
168
+ self.setMaximum(maxVal)
153
169
  self.setSingleStep(step)
154
170
  self.setDecimals(prec)
155
171
  return
@@ -164,18 +180,21 @@ class NDoubleSpinBox(QDoubleSpinBox):
164
180
 
165
181
  class NIconToolButton(QToolButton):
166
182
 
167
- def __init__(self, parent: QWidget, iconSize: QSize, icon: str | None = None) -> None:
183
+ def __init__(
184
+ self, parent: QWidget, iconSize: QSize,
185
+ icon: str | None = None, color: str | None = None
186
+ ) -> None:
168
187
  super().__init__(parent=parent)
169
188
  self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
170
189
  self.setIconSize(iconSize)
171
190
  self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
172
191
  if icon:
173
- self.setThemeIcon(icon)
192
+ self.setThemeIcon(icon, color)
174
193
  return
175
194
 
176
- def setThemeIcon(self, iconKey: str) -> None:
195
+ def setThemeIcon(self, iconKey: str, color: str | None = None) -> None:
177
196
  """Set an icon from the current theme."""
178
- self.setIcon(SHARED.theme.getIcon(iconKey))
197
+ self.setIcon(SHARED.theme.getIcon(iconKey, color))
179
198
  return
180
199
 
181
200
 
@@ -25,8 +25,9 @@ from __future__ import annotations
25
25
 
26
26
  import logging
27
27
 
28
- from PyQt5.QtCore import pyqtSignal, pyqtSlot
29
- from PyQt5.QtWidgets import QComboBox, QWidget
28
+ from PyQt6.QtCore import pyqtSignal, pyqtSlot
29
+ from PyQt6.QtGui import QPalette
30
+ from PyQt6.QtWidgets import QComboBox, QWidget
30
31
 
31
32
  from novelwriter import SHARED
32
33
  from novelwriter.constants import nwLabels
@@ -46,6 +47,7 @@ class NovelSelector(QComboBox):
46
47
  self._includeAll = False
47
48
  self._listFormat = None
48
49
  self.currentIndexChanged.connect(self._indexChanged)
50
+ self.updateTheme()
49
51
  return
50
52
 
51
53
  ##
@@ -53,8 +55,11 @@ class NovelSelector(QComboBox):
53
55
  ##
54
56
 
55
57
  @property
56
- def handle(self) -> str:
57
- return self.currentData()
58
+ def handle(self) -> str | None:
59
+ """Return the selected handle, if any."""
60
+ if tHandle := self.currentData():
61
+ return tHandle
62
+ return None
58
63
 
59
64
  @property
60
65
  def firstHandle(self) -> str | None:
@@ -83,6 +88,14 @@ class NovelSelector(QComboBox):
83
88
  self._listFormat = value
84
89
  return
85
90
 
91
+ def updateTheme(self) -> None:
92
+ """Update theme colours."""
93
+ palette = self.palette()
94
+ palette.setBrush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, palette.text())
95
+ self.setPalette(palette)
96
+ self.refreshNovelList()
97
+ return
98
+
86
99
  ##
87
100
  # Public Slots
88
101
  ##
@@ -96,7 +109,7 @@ class NovelSelector(QComboBox):
96
109
  self._firstHandle = None
97
110
  self.clear()
98
111
 
99
- icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL])
112
+ icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL], "blue")
100
113
  for tHandle, nwItem in SHARED.project.tree.iterRoots(nwItemClass.NOVEL):
101
114
  if self._listFormat:
102
115
  name = self._listFormat.format(nwItem.itemName)
@@ -25,11 +25,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
25
25
  """
26
26
  from __future__ import annotations
27
27
 
28
- from PyQt5.QtCore import QPoint, QRectF, QSize, Qt, pyqtSignal, pyqtSlot
29
- from PyQt5.QtGui import QColor, QPainter, QPaintEvent, QPolygon
30
- from PyQt5.QtWidgets import (
31
- QAbstractButton, QAction, QButtonGroup, QLabel, QStyle,
32
- QStyleOptionToolButton, QToolBar, QToolButton, QWidget
28
+ from PyQt6.QtCore import QPoint, QRectF, QSize, Qt, pyqtSignal, pyqtSlot
29
+ from PyQt6.QtGui import QColor, QPainter, QPaintEvent, QPolygon
30
+ from PyQt6.QtWidgets import (
31
+ QAbstractButton, QButtonGroup, QLabel, QStyleOptionToolButton, QToolBar,
32
+ QToolButton, QWidget
33
33
  )
34
34
 
35
35
  from novelwriter.types import (
@@ -83,21 +83,19 @@ class NPagedSideBar(QToolBar):
83
83
  self.insertWidget(self._stretchAction, label)
84
84
  return
85
85
 
86
- def addButton(self, text: str, buttonId: int = -1) -> QAction:
86
+ def addButton(self, text: str, buttonId: int = -1) -> None:
87
87
  """Add a new button to the toolbar."""
88
88
  button = _PagedToolButton(self)
89
89
  button.setText(text)
90
-
91
- action = self.insertWidget(self._stretchAction, button)
90
+ self.insertWidget(self._stretchAction, button)
92
91
  self._group.addButton(button, id=buttonId)
93
-
94
92
  self._buttons[buttonId] = button
95
-
96
- return action
93
+ return
97
94
 
98
95
  def setSelected(self, buttonId: int) -> None:
99
96
  """Set the selected button."""
100
- self._group.button(buttonId).setChecked(True)
97
+ if button := self._group.button(buttonId):
98
+ button.setChecked(True)
101
99
  return
102
100
 
103
101
  ##
@@ -115,7 +113,7 @@ class NPagedSideBar(QToolBar):
115
113
 
116
114
  class _PagedToolButton(QToolButton):
117
115
 
118
- __slots__ = ("_bH", "_tM", "_lM", "_cR", "_aH")
116
+ __slots__ = ("_aH", "_bH", "_tM")
119
117
 
120
118
  def __init__(self, parent: QWidget) -> None:
121
119
  super().__init__(parent=parent)
@@ -126,8 +124,6 @@ class _PagedToolButton(QToolButton):
126
124
  fH = self.fontMetrics().height()
127
125
  self._bH = round(fH * 1.7)
128
126
  self._tM = (self._bH - fH)//2
129
- self._lM = 3*self.style().pixelMetric(QStyle.PixelMetric.PM_ButtonMargin)//2
130
- self._cR = self._lM//2
131
127
  self._aH = 2*fH//7
132
128
  self.setFixedHeight(self._bH)
133
129
 
@@ -145,53 +141,51 @@ class _PagedToolButton(QToolButton):
145
141
  opt = QStyleOptionToolButton()
146
142
  opt.initFrom(self)
147
143
 
148
- paint = QPainter(self)
149
- paint.setRenderHint(QtPaintAntiAlias, True)
150
- paint.setPen(QtNoPen)
151
- paint.setBrush(QtNoBrush)
144
+ painter = QPainter(self)
145
+ painter.setRenderHint(QtPaintAntiAlias, True)
146
+ painter.setPen(QtNoPen)
147
+ painter.setBrush(QtNoBrush)
152
148
 
153
149
  width = self.width()
154
150
  height = self.height()
155
151
  palette = self.palette()
156
152
 
157
153
  if opt.state & QtMouseOver == QtMouseOver: # pragma: no cover
158
- backCol = palette.base()
159
- paint.setBrush(backCol)
160
- paint.setOpacity(0.75)
161
- paint.drawRoundedRect(0, 0, width, height, self._cR, self._cR)
154
+ painter.setBrush(palette.light())
155
+ painter.drawRoundedRect(0, 0, width, height, 4, 4)
162
156
 
163
157
  if self.isChecked():
164
- backCol = palette.highlight()
165
- paint.setBrush(backCol)
166
- paint.setOpacity(0.35)
167
- paint.drawRoundedRect(0, 0, width, height, self._cR, self._cR)
158
+ painter.setBrush(palette.highlight())
159
+ painter.setOpacity(0.35)
160
+ painter.drawRoundedRect(0, 0, width, height, 4, 4)
168
161
  textCol = palette.highlightedText().color()
169
162
  else:
170
163
  textCol = palette.text().color()
171
164
 
172
- tW = width - 2*self._lM
165
+ tW = width - 24
173
166
  tH = height - 2*self._tM
174
167
 
175
- paint.setPen(textCol)
176
- paint.setOpacity(1.0)
177
- paint.drawText(QRectF(self._lM, self._tM, tW, tH), QtAlignLeft, self.text())
168
+ painter.setPen(textCol)
169
+ painter.setOpacity(1.0)
170
+ painter.drawText(QRectF(12, self._tM, tW, tH), QtAlignLeft, self.text())
178
171
 
179
172
  tC = self.height()//2
180
- tW = self.width() - self._aH - self._lM
173
+ tW = self.width() - self._aH - 12
181
174
  if self.isChecked():
182
- paint.setBrush(textCol)
183
- paint.drawPolygon(QPolygon([
175
+ painter.setBrush(textCol)
176
+ painter.drawPolygon(QPolygon([
184
177
  QPoint(tW, tC - self._aH),
185
178
  QPoint(tW + self._aH, tC),
186
179
  QPoint(tW, tC + self._aH),
187
180
  ]))
181
+ painter.end()
188
182
 
189
183
  return
190
184
 
191
185
 
192
186
  class _NPagedToolLabel(QLabel):
193
187
 
194
- __slots__ = ("_bH", "_tM", "_lM", "_textCol")
188
+ __slots__ = ("_bH", "_tM", "_textCol")
195
189
 
196
190
  def __init__(self, parent: QWidget, textColor: QColor | None = None) -> None:
197
191
  super().__init__(parent=parent)
@@ -201,7 +195,6 @@ class _NPagedToolLabel(QLabel):
201
195
  fH = self.fontMetrics().height()
202
196
  self._bH = round(fH * 1.7)
203
197
  self._tM = (self._bH - fH)//2
204
- self._lM = self.style().pixelMetric(QStyle.PixelMetric.PM_ButtonMargin)//2
205
198
  self.setFixedHeight(self._bH)
206
199
 
207
200
  self._textCol = textColor or self.palette().text().color()
@@ -212,18 +205,15 @@ class _NPagedToolLabel(QLabel):
212
205
  """Overload the paint event to draw a simple, left aligned text
213
206
  label that matches the button style.
214
207
  """
215
- paint = QPainter(self)
216
- paint.setRenderHint(QtPaintAntiAlias, True)
217
- paint.setPen(QtNoPen)
218
-
219
- width = self.width()
220
- height = self.height()
221
-
222
- tW = width - 2*self._lM
223
- tH = height - 2*self._tM
224
-
225
- paint.setPen(self._textCol)
226
- paint.setOpacity(1.0)
227
- paint.drawText(QRectF(self._lM, self._tM, tW, tH), QtAlignLeft, self.text())
208
+ tW = self.width() - 8
209
+ tH = self.height() - 2*self._tM
210
+
211
+ painter = QPainter(self)
212
+ painter.setRenderHint(QtPaintAntiAlias, True)
213
+ painter.setPen(QtNoPen)
214
+ painter.setPen(self._textCol)
215
+ painter.setOpacity(1.0)
216
+ painter.drawText(QRectF(4, self._tM, tW, tH), QtAlignLeft, self.text())
217
+ painter.end()
228
218
 
229
219
  return
@@ -26,9 +26,9 @@ from __future__ import annotations
26
26
 
27
27
  from math import ceil
28
28
 
29
- from PyQt5.QtCore import QRect
30
- from PyQt5.QtGui import QBrush, QColor, QPainter, QPaintEvent, QPen
31
- from PyQt5.QtWidgets import QProgressBar, QWidget
29
+ from PyQt6.QtCore import QRect
30
+ from PyQt6.QtGui import QBrush, QColor, QPainter, QPaintEvent, QPen
31
+ from PyQt6.QtWidgets import QProgressBar, QWidget
32
32
 
33
33
  from novelwriter.types import (
34
34
  QtAlignCenter, QtPaintAntiAlias, QtRoundCap, QtSizeFixed, QtSolidLine,
@@ -44,8 +44,8 @@ class NProgressCircle(QProgressBar):
44
44
  """
45
45
 
46
46
  __slots__ = (
47
- "_text", "_point", "_dRect", "_cRect", "_dPen", "_dBrush",
48
- "_cPen", "_bPen", "_tColor"
47
+ "_bPen", "_cPen", "_cRect", "_dBrush", "_dPen", "_dRect", "_point",
48
+ "_tColor", "_text",
49
49
  )
50
50
 
51
51
  def __init__(self, parent: QWidget, size: int, point: int) -> None:
@@ -56,7 +56,7 @@ class NProgressCircle(QProgressBar):
56
56
  self._cRect = QRect(point, point, size - 2*point, size - 2*point)
57
57
  self._dPen = QPen(QtTransparent)
58
58
  self._dBrush = QBrush(QtTransparent)
59
- self.setColours(
59
+ self.setColors(
60
60
  track=self.palette().alternateBase().color(),
61
61
  bar=self.palette().highlight().color(),
62
62
  text=self.palette().text().color()
@@ -66,8 +66,10 @@ class NProgressCircle(QProgressBar):
66
66
  self.setFixedHeight(size)
67
67
  return
68
68
 
69
- def setColours(self, back: QColor | None = None, track: QColor | None = None,
70
- bar: QColor | None = None, text: QColor | None = None) -> None:
69
+ def setColors(
70
+ self, back: QColor | None = None, track: QColor | None = None,
71
+ bar: QColor | None = None, text: QColor | None = None
72
+ ) -> None:
71
73
  """Set the colours of the widget."""
72
74
  if isinstance(back, QColor):
73
75
  self._dPen = QPen(back)
@@ -25,10 +25,9 @@ from __future__ import annotations
25
25
 
26
26
  import logging
27
27
 
28
- from PyQt5.QtGui import QColor, QPainter, QPaintEvent
29
- from PyQt5.QtWidgets import QAbstractButton, QWidget
28
+ from PyQt6.QtGui import QColor, QPainter, QPaintEvent
29
+ from PyQt6.QtWidgets import QAbstractButton, QWidget
30
30
 
31
- from novelwriter import CONFIG
32
31
  from novelwriter.types import QtBlack, QtPaintAntiAlias
33
32
 
34
33
  logger = logging.getLogger(__name__)
@@ -36,9 +35,7 @@ logger = logging.getLogger(__name__)
36
35
 
37
36
  class StatusLED(QAbstractButton):
38
37
 
39
- __slots__ = (
40
- "_neutral", "_postitve", "_negative", "_color", "_state", "_bPx"
41
- )
38
+ __slots__ = ("_color", "_negative", "_neutral", "_postitve", "_state")
42
39
 
43
40
  def __init__(self, sW: int, sH: int, parent: QWidget | None = None) -> None:
44
41
  super().__init__(parent=parent)
@@ -47,7 +44,6 @@ class StatusLED(QAbstractButton):
47
44
  self._negative = QtBlack
48
45
  self._color = QtBlack
49
46
  self._state = None
50
- self._bPx = CONFIG.pxInt(1)
51
47
  self.setFixedWidth(sW)
52
48
  self.setFixedHeight(sH)
53
49
  return
@@ -81,12 +77,9 @@ class StatusLED(QAbstractButton):
81
77
  """Draw the LED."""
82
78
  painter = QPainter(self)
83
79
  painter.setRenderHint(QtPaintAntiAlias, True)
84
- painter.setPen(self.palette().windowText().color())
80
+ painter.setPen(self.palette().text().color())
85
81
  painter.setBrush(self._color)
86
82
  painter.setOpacity(1.0)
87
- painter.drawEllipse(
88
- self._bPx, self._bPx,
89
- self.width() - 2*self._bPx,
90
- self.height() - 2*self._bPx
91
- )
83
+ painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
84
+ painter.end()
92
85
  return
@@ -23,17 +23,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- from PyQt5.QtCore import QEvent, QPropertyAnimation, Qt, pyqtProperty
27
- from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent
28
- from PyQt5.QtWidgets import QAbstractButton, QWidget
26
+ from PyQt6.QtCore import QPropertyAnimation, Qt, pyqtProperty # pyright: ignore
27
+ from PyQt6.QtGui import QEnterEvent, QMouseEvent, QPainter, QPaintEvent, QResizeEvent
28
+ from PyQt6.QtWidgets import QAbstractButton, QWidget
29
29
 
30
- from novelwriter import CONFIG, SHARED
30
+ from novelwriter import SHARED
31
31
  from novelwriter.types import QtMouseLeft, QtNoPen, QtPaintAntiAlias, QtSizeFixed
32
32
 
33
33
 
34
34
  class NSwitch(QAbstractButton):
35
35
 
36
- __slots__ = ("_xW", "_xH", "_xR", "_rB", "_rH", "_rR", "_offset")
36
+ __slots__ = ("_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
37
37
 
38
38
  def __init__(self, parent: QWidget, height: int = 0) -> None:
39
39
  super().__init__(parent=parent)
@@ -41,9 +41,8 @@ class NSwitch(QAbstractButton):
41
41
  self._xH = height or SHARED.theme.baseButtonHeight
42
42
  self._xW = 2*self._xH
43
43
  self._xR = int(self._xH*0.5)
44
- self._rB = CONFIG.pxInt(2)
45
- self._rH = self._xH - 2*self._rB
46
- self._rR = self._xR - self._rB
44
+ self._rH = self._xH - 4
45
+ self._rR = self._xR - 2
47
46
 
48
47
  self.setCheckable(True)
49
48
  self.setSizePolicy(QtSizeFixed, QtSizeFixed)
@@ -57,7 +56,7 @@ class NSwitch(QAbstractButton):
57
56
  # Properties
58
57
  ##
59
58
 
60
- @pyqtProperty(int) # type: ignore
59
+ @pyqtProperty(int)
61
60
  def offset(self) -> int: # type: ignore
62
61
  return self._offset
63
62
 
@@ -89,31 +88,21 @@ class NSwitch(QAbstractButton):
89
88
 
90
89
  def paintEvent(self, event: QPaintEvent) -> None:
91
90
  """Drawing the switch itself."""
91
+ palette = self.palette()
92
+
92
93
  painter = QPainter(self)
93
94
  painter.setRenderHint(QtPaintAntiAlias, True)
94
- painter.setPen(QtNoPen)
95
+ painter.setOpacity(1.0 if self.isEnabled() else 0.5)
95
96
 
96
- palette = self.palette()
97
- if self.isChecked():
98
- trackBrush = palette.highlight()
99
- thumbBrush = palette.highlightedText()
100
- else:
101
- trackBrush = palette.dark()
102
- thumbBrush = palette.light()
103
-
104
- if self.isEnabled():
105
- trackOpacity = 1.0
106
- else:
107
- trackOpacity = 0.6
108
- trackBrush = palette.shadow()
109
- thumbBrush = palette.mid()
110
-
111
- painter.setBrush(trackBrush)
112
- painter.setOpacity(trackOpacity)
97
+ painter.setPen(palette.mid().color())
98
+ painter.setBrush(palette.highlight() if self.isChecked() else palette.alternateBase())
113
99
  painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
114
100
 
115
- painter.setBrush(thumbBrush)
116
- painter.drawEllipse(self._offset - self._rR, self._rB, self._rH, self._rH)
101
+ painter.setPen(QtNoPen)
102
+ painter.setBrush(palette.highlightedText())
103
+ painter.drawEllipse(self._offset - self._rR, 2, self._rH, self._rH)
104
+
105
+ painter.end()
117
106
 
118
107
  return
119
108
 
@@ -128,7 +117,7 @@ class NSwitch(QAbstractButton):
128
117
  anim.start()
129
118
  return
130
119
 
131
- def enterEvent(self, event: QEvent) -> None:
120
+ def enterEvent(self, event: QEnterEvent) -> None:
132
121
  """Change the cursor when hovering the button."""
133
122
  self.setCursor(Qt.CursorShape.PointingHandCursor)
134
123
  super().enterEvent(event)
@@ -23,9 +23,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
  """
24
24
  from __future__ import annotations
25
25
 
26
- from PyQt5.QtCore import pyqtSignal
27
- from PyQt5.QtGui import QIcon
28
- from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QWidget
26
+ from typing import TYPE_CHECKING
27
+
28
+ from PyQt6.QtCore import pyqtSignal
29
+ from PyQt6.QtWidgets import QGridLayout, QLabel, QScrollArea, QWidget
29
30
 
30
31
  from novelwriter.extensions.switch import NSwitch
31
32
  from novelwriter.types import (
@@ -33,6 +34,9 @@ from novelwriter.types import (
33
34
  QtSizeMinimumExpanding
34
35
  )
35
36
 
37
+ if TYPE_CHECKING:
38
+ from PyQt6.QtGui import QIcon
39
+
36
40
 
37
41
  class NSwitchBox(QScrollArea):
38
42
  """Extension: Switch Box Widget