novelWriter 2.6.3__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 (321) hide show
  1. novelwriter/__init__.py +84 -74
  2. novelwriter/assets/i18n/project_en_GB.json +1 -0
  3. novelwriter/assets/icons/font_awesome.icons +109 -0
  4. novelwriter/assets/icons/material_filled_bold.icons +109 -0
  5. novelwriter/assets/icons/material_filled_normal.icons +109 -0
  6. novelwriter/assets/icons/material_filled_thin.icons +109 -0
  7. novelwriter/assets/icons/material_rounded_bold.icons +109 -0
  8. novelwriter/assets/icons/material_rounded_normal.icons +109 -0
  9. novelwriter/assets/icons/material_rounded_thin.icons +109 -0
  10. novelwriter/assets/icons/remix_filled.icons +108 -0
  11. novelwriter/assets/icons/remix_outline.icons +108 -0
  12. novelwriter/assets/manual.pdf +0 -0
  13. novelwriter/assets/{manual_fr_FR.pdf → manual_fr.pdf} +0 -0
  14. novelwriter/assets/sample.zip +0 -0
  15. novelwriter/assets/syntax/cyberpunk_night.conf +1 -1
  16. novelwriter/assets/text/credits_en.htm +6 -6
  17. novelwriter/assets/themes/cyberpunk_night.conf +23 -7
  18. novelwriter/assets/themes/default_dark.conf +20 -4
  19. novelwriter/assets/themes/default_light.conf +21 -5
  20. novelwriter/assets/themes/dracula.conf +20 -4
  21. novelwriter/assets/themes/solarized_dark.conf +24 -8
  22. novelwriter/assets/themes/solarized_light.conf +22 -6
  23. novelwriter/common.py +33 -26
  24. novelwriter/config.py +118 -127
  25. novelwriter/constants.py +50 -36
  26. novelwriter/core/buildsettings.py +23 -16
  27. novelwriter/core/coretools.py +11 -7
  28. novelwriter/core/docbuild.py +19 -13
  29. novelwriter/core/document.py +2 -2
  30. novelwriter/core/index.py +142 -432
  31. novelwriter/core/indexdata.py +403 -0
  32. novelwriter/core/item.py +35 -28
  33. novelwriter/core/itemmodel.py +27 -26
  34. novelwriter/core/novelmodel.py +223 -0
  35. novelwriter/core/options.py +1 -1
  36. novelwriter/core/project.py +10 -11
  37. novelwriter/core/projectdata.py +5 -5
  38. novelwriter/core/projectxml.py +1 -1
  39. novelwriter/core/sessions.py +3 -2
  40. novelwriter/core/spellcheck.py +4 -3
  41. novelwriter/core/status.py +12 -15
  42. novelwriter/core/storage.py +1 -1
  43. novelwriter/core/tree.py +46 -8
  44. novelwriter/dialogs/about.py +19 -22
  45. novelwriter/dialogs/docmerge.py +21 -23
  46. novelwriter/dialogs/docsplit.py +20 -23
  47. novelwriter/dialogs/editlabel.py +9 -13
  48. novelwriter/dialogs/preferences.py +111 -48
  49. novelwriter/dialogs/projectsettings.py +48 -54
  50. novelwriter/dialogs/quotes.py +14 -19
  51. novelwriter/dialogs/wordlist.py +25 -30
  52. novelwriter/enum.py +8 -0
  53. novelwriter/error.py +16 -16
  54. novelwriter/extensions/configlayout.py +18 -18
  55. novelwriter/extensions/eventfilters.py +9 -5
  56. novelwriter/extensions/modified.py +34 -15
  57. novelwriter/extensions/novelselector.py +18 -5
  58. novelwriter/extensions/pagedsidebar.py +39 -49
  59. novelwriter/extensions/progressbars.py +10 -8
  60. novelwriter/extensions/statusled.py +6 -13
  61. novelwriter/extensions/switch.py +19 -30
  62. novelwriter/extensions/switchbox.py +7 -3
  63. novelwriter/extensions/versioninfo.py +4 -4
  64. novelwriter/formats/shared.py +1 -1
  65. novelwriter/formats/todocx.py +14 -10
  66. novelwriter/formats/tohtml.py +7 -5
  67. novelwriter/formats/tokenizer.py +36 -33
  68. novelwriter/formats/tomarkdown.py +6 -2
  69. novelwriter/formats/toodt.py +27 -22
  70. novelwriter/formats/toqdoc.py +19 -14
  71. novelwriter/formats/toraw.py +6 -2
  72. novelwriter/gui/doceditor.py +216 -265
  73. novelwriter/gui/dochighlight.py +46 -45
  74. novelwriter/gui/docviewer.py +102 -104
  75. novelwriter/gui/docviewerpanel.py +47 -51
  76. novelwriter/gui/editordocument.py +8 -5
  77. novelwriter/gui/itemdetails.py +11 -14
  78. novelwriter/gui/mainmenu.py +146 -145
  79. novelwriter/gui/noveltree.py +239 -405
  80. novelwriter/gui/outline.py +133 -72
  81. novelwriter/gui/projtree.py +138 -132
  82. novelwriter/gui/search.py +33 -31
  83. novelwriter/gui/sidebar.py +13 -18
  84. novelwriter/gui/statusbar.py +13 -15
  85. novelwriter/gui/theme.py +533 -430
  86. novelwriter/guimain.py +27 -29
  87. novelwriter/shared.py +32 -23
  88. novelwriter/text/comments.py +70 -0
  89. novelwriter/text/patterns.py +4 -4
  90. novelwriter/tools/dictionaries.py +20 -29
  91. novelwriter/tools/lipsum.py +16 -17
  92. novelwriter/tools/manusbuild.py +39 -42
  93. novelwriter/tools/manuscript.py +101 -114
  94. novelwriter/tools/manussettings.py +78 -83
  95. novelwriter/tools/noveldetails.py +51 -64
  96. novelwriter/tools/welcome.py +56 -75
  97. novelwriter/tools/writingstats.py +44 -57
  98. novelwriter/types.py +5 -7
  99. {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/METADATA +6 -6
  100. novelwriter-2.7b1.dist-info/RECORD +159 -0
  101. {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/WHEEL +1 -1
  102. novelWriter-2.6.3.dist-info/RECORD +0 -363
  103. novelwriter/assets/icons/typicons_dark/README.md +0 -29
  104. novelwriter/assets/icons/typicons_dark/icons.conf +0 -134
  105. novelwriter/assets/icons/typicons_dark/mixed_copy.svg +0 -4
  106. novelwriter/assets/icons/typicons_dark/mixed_document-chapter.svg +0 -12
  107. novelwriter/assets/icons/typicons_dark/mixed_document-new.svg +0 -6
  108. novelwriter/assets/icons/typicons_dark/mixed_document-note.svg +0 -12
  109. novelwriter/assets/icons/typicons_dark/mixed_document-scene.svg +0 -12
  110. novelwriter/assets/icons/typicons_dark/mixed_document-section.svg +0 -12
  111. novelwriter/assets/icons/typicons_dark/mixed_document-title.svg +0 -12
  112. novelwriter/assets/icons/typicons_dark/mixed_edit.svg +0 -4
  113. novelwriter/assets/icons/typicons_dark/mixed_import.svg +0 -5
  114. novelwriter/assets/icons/typicons_dark/mixed_input-checked.svg +0 -5
  115. novelwriter/assets/icons/typicons_dark/mixed_input-none.svg +0 -5
  116. novelwriter/assets/icons/typicons_dark/mixed_input-unchecked.svg +0 -5
  117. novelwriter/assets/icons/typicons_dark/mixed_margin-bottom.svg +0 -6
  118. novelwriter/assets/icons/typicons_dark/mixed_margin-left.svg +0 -6
  119. novelwriter/assets/icons/typicons_dark/mixed_margin-right.svg +0 -6
  120. novelwriter/assets/icons/typicons_dark/mixed_margin-top.svg +0 -6
  121. novelwriter/assets/icons/typicons_dark/mixed_search-replace.svg +0 -6
  122. novelwriter/assets/icons/typicons_dark/mixed_size-height.svg +0 -6
  123. novelwriter/assets/icons/typicons_dark/mixed_size-width.svg +0 -6
  124. novelwriter/assets/icons/typicons_dark/nw_deco-h0.svg +0 -4
  125. novelwriter/assets/icons/typicons_dark/nw_deco-h1.svg +0 -4
  126. novelwriter/assets/icons/typicons_dark/nw_deco-h2-narrow.svg +0 -4
  127. novelwriter/assets/icons/typicons_dark/nw_deco-h2.svg +0 -4
  128. novelwriter/assets/icons/typicons_dark/nw_deco-h3-narrow.svg +0 -4
  129. novelwriter/assets/icons/typicons_dark/nw_deco-h3.svg +0 -4
  130. novelwriter/assets/icons/typicons_dark/nw_deco-h4-narrow.svg +0 -4
  131. novelwriter/assets/icons/typicons_dark/nw_deco-h4.svg +0 -4
  132. novelwriter/assets/icons/typicons_dark/nw_deco-note.svg +0 -4
  133. novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg +0 -4
  134. novelwriter/assets/icons/typicons_dark/nw_font.svg +0 -4
  135. novelwriter/assets/icons/typicons_dark/nw_panel.svg +0 -4
  136. novelwriter/assets/icons/typicons_dark/nw_quote.svg +0 -4
  137. novelwriter/assets/icons/typicons_dark/nw_search-case.svg +0 -4
  138. novelwriter/assets/icons/typicons_dark/nw_search-preserve.svg +0 -4
  139. novelwriter/assets/icons/typicons_dark/nw_search-regex.svg +0 -4
  140. novelwriter/assets/icons/typicons_dark/nw_search-word.svg +0 -4
  141. novelwriter/assets/icons/typicons_dark/nw_tb-bold-md.svg +0 -4
  142. novelwriter/assets/icons/typicons_dark/nw_tb-bold.svg +0 -6
  143. novelwriter/assets/icons/typicons_dark/nw_tb-italic-md.svg +0 -4
  144. novelwriter/assets/icons/typicons_dark/nw_tb-italic.svg +0 -6
  145. novelwriter/assets/icons/typicons_dark/nw_tb-mark.svg +0 -7
  146. novelwriter/assets/icons/typicons_dark/nw_tb-strike-md.svg +0 -4
  147. novelwriter/assets/icons/typicons_dark/nw_tb-strike.svg +0 -6
  148. novelwriter/assets/icons/typicons_dark/nw_tb-subscript.svg +0 -7
  149. novelwriter/assets/icons/typicons_dark/nw_tb-superscript.svg +0 -7
  150. novelwriter/assets/icons/typicons_dark/nw_tb-underline.svg +0 -7
  151. novelwriter/assets/icons/typicons_dark/nw_toolbar.svg +0 -5
  152. novelwriter/assets/icons/typicons_dark/typ_arrow-down-thick-grey.svg +0 -4
  153. novelwriter/assets/icons/typicons_dark/typ_arrow-forward.svg +0 -4
  154. novelwriter/assets/icons/typicons_dark/typ_arrow-maximise.svg +0 -4
  155. novelwriter/assets/icons/typicons_dark/typ_arrow-minimise.svg +0 -4
  156. novelwriter/assets/icons/typicons_dark/typ_arrow-repeat-grey.svg +0 -4
  157. novelwriter/assets/icons/typicons_dark/typ_book-grey.svg +0 -4
  158. novelwriter/assets/icons/typicons_dark/typ_book.svg +0 -6
  159. novelwriter/assets/icons/typicons_dark/typ_bookmark.svg +0 -4
  160. novelwriter/assets/icons/typicons_dark/typ_calendar.svg +0 -4
  161. novelwriter/assets/icons/typicons_dark/typ_cancel-grey.svg +0 -4
  162. novelwriter/assets/icons/typicons_dark/typ_cancel.svg +0 -4
  163. novelwriter/assets/icons/typicons_dark/typ_chart-bar-grey.svg +0 -4
  164. novelwriter/assets/icons/typicons_dark/typ_chevron-down.svg +0 -4
  165. novelwriter/assets/icons/typicons_dark/typ_chevron-left.svg +0 -4
  166. novelwriter/assets/icons/typicons_dark/typ_chevron-right.svg +0 -4
  167. novelwriter/assets/icons/typicons_dark/typ_chevron-up.svg +0 -4
  168. novelwriter/assets/icons/typicons_dark/typ_cog.svg +0 -4
  169. novelwriter/assets/icons/typicons_dark/typ_delete-full.svg +0 -4
  170. novelwriter/assets/icons/typicons_dark/typ_delete.svg +0 -4
  171. novelwriter/assets/icons/typicons_dark/typ_directions-full.svg +0 -4
  172. novelwriter/assets/icons/typicons_dark/typ_document-add.svg +0 -4
  173. novelwriter/assets/icons/typicons_dark/typ_document-text.svg +0 -8
  174. novelwriter/assets/icons/typicons_dark/typ_document.svg +0 -4
  175. novelwriter/assets/icons/typicons_dark/typ_export-grey.svg +0 -4
  176. novelwriter/assets/icons/typicons_dark/typ_export.svg +0 -4
  177. novelwriter/assets/icons/typicons_dark/typ_eye.svg +0 -4
  178. novelwriter/assets/icons/typicons_dark/typ_flag.svg +0 -4
  179. novelwriter/assets/icons/typicons_dark/typ_folder-open.svg +0 -4
  180. novelwriter/assets/icons/typicons_dark/typ_folder.svg +0 -5
  181. novelwriter/assets/icons/typicons_dark/typ_globe-grey.svg +0 -4
  182. novelwriter/assets/icons/typicons_dark/typ_key.svg +0 -4
  183. novelwriter/assets/icons/typicons_dark/typ_lightbulb-full.svg +0 -4
  184. novelwriter/assets/icons/typicons_dark/typ_location.svg +0 -4
  185. novelwriter/assets/icons/typicons_dark/typ_media-pause-grey.svg +0 -4
  186. novelwriter/assets/icons/typicons_dark/typ_media-record-outline.svg +0 -4
  187. novelwriter/assets/icons/typicons_dark/typ_media-record.svg +0 -4
  188. novelwriter/assets/icons/typicons_dark/typ_minus.svg +0 -4
  189. novelwriter/assets/icons/typicons_dark/typ_pencil.svg +0 -5
  190. novelwriter/assets/icons/typicons_dark/typ_pin-outline.svg +0 -4
  191. novelwriter/assets/icons/typicons_dark/typ_pin.svg +0 -4
  192. novelwriter/assets/icons/typicons_dark/typ_plus.svg +0 -4
  193. novelwriter/assets/icons/typicons_dark/typ_puzzle-outline.svg +0 -4
  194. novelwriter/assets/icons/typicons_dark/typ_puzzle.svg +0 -4
  195. novelwriter/assets/icons/typicons_dark/typ_refresh-flipped.svg +0 -4
  196. novelwriter/assets/icons/typicons_dark/typ_refresh.svg +0 -4
  197. novelwriter/assets/icons/typicons_dark/typ_search-grey.svg +0 -4
  198. novelwriter/assets/icons/typicons_dark/typ_search.svg +0 -4
  199. novelwriter/assets/icons/typicons_dark/typ_star.svg +0 -4
  200. novelwriter/assets/icons/typicons_dark/typ_stopwatch-grey.svg +0 -4
  201. novelwriter/assets/icons/typicons_dark/typ_th-dot-menu.svg +0 -4
  202. novelwriter/assets/icons/typicons_dark/typ_th-dot-more.svg +0 -4
  203. novelwriter/assets/icons/typicons_dark/typ_th-list-grey.svg +0 -4
  204. novelwriter/assets/icons/typicons_dark/typ_th-list.svg +0 -9
  205. novelwriter/assets/icons/typicons_dark/typ_times.svg +0 -4
  206. novelwriter/assets/icons/typicons_dark/typ_trash.svg +0 -5
  207. novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg +0 -4
  208. novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg +0 -4
  209. novelwriter/assets/icons/typicons_dark/typ_user.svg +0 -5
  210. novelwriter/assets/icons/typicons_dark/typ_warning-full.svg +0 -4
  211. novelwriter/assets/icons/typicons_light/README.md +0 -29
  212. novelwriter/assets/icons/typicons_light/icons.conf +0 -134
  213. novelwriter/assets/icons/typicons_light/mixed_copy.svg +0 -4
  214. novelwriter/assets/icons/typicons_light/mixed_document-chapter.svg +0 -12
  215. novelwriter/assets/icons/typicons_light/mixed_document-new.svg +0 -6
  216. novelwriter/assets/icons/typicons_light/mixed_document-note.svg +0 -12
  217. novelwriter/assets/icons/typicons_light/mixed_document-scene.svg +0 -12
  218. novelwriter/assets/icons/typicons_light/mixed_document-section.svg +0 -12
  219. novelwriter/assets/icons/typicons_light/mixed_document-title.svg +0 -12
  220. novelwriter/assets/icons/typicons_light/mixed_edit.svg +0 -4
  221. novelwriter/assets/icons/typicons_light/mixed_import.svg +0 -5
  222. novelwriter/assets/icons/typicons_light/mixed_input-checked.svg +0 -5
  223. novelwriter/assets/icons/typicons_light/mixed_input-none.svg +0 -5
  224. novelwriter/assets/icons/typicons_light/mixed_input-unchecked.svg +0 -5
  225. novelwriter/assets/icons/typicons_light/mixed_margin-bottom.svg +0 -6
  226. novelwriter/assets/icons/typicons_light/mixed_margin-left.svg +0 -6
  227. novelwriter/assets/icons/typicons_light/mixed_margin-right.svg +0 -6
  228. novelwriter/assets/icons/typicons_light/mixed_margin-top.svg +0 -6
  229. novelwriter/assets/icons/typicons_light/mixed_search-replace.svg +0 -6
  230. novelwriter/assets/icons/typicons_light/mixed_size-height.svg +0 -6
  231. novelwriter/assets/icons/typicons_light/mixed_size-width.svg +0 -6
  232. novelwriter/assets/icons/typicons_light/nw_deco-h0.svg +0 -4
  233. novelwriter/assets/icons/typicons_light/nw_deco-h1.svg +0 -4
  234. novelwriter/assets/icons/typicons_light/nw_deco-h2-narrow.svg +0 -4
  235. novelwriter/assets/icons/typicons_light/nw_deco-h2.svg +0 -4
  236. novelwriter/assets/icons/typicons_light/nw_deco-h3-narrow.svg +0 -4
  237. novelwriter/assets/icons/typicons_light/nw_deco-h3.svg +0 -4
  238. novelwriter/assets/icons/typicons_light/nw_deco-h4-narrow.svg +0 -4
  239. novelwriter/assets/icons/typicons_light/nw_deco-h4.svg +0 -4
  240. novelwriter/assets/icons/typicons_light/nw_deco-note.svg +0 -4
  241. novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg +0 -4
  242. novelwriter/assets/icons/typicons_light/nw_font.svg +0 -4
  243. novelwriter/assets/icons/typicons_light/nw_panel.svg +0 -4
  244. novelwriter/assets/icons/typicons_light/nw_quote.svg +0 -4
  245. novelwriter/assets/icons/typicons_light/nw_search-case.svg +0 -4
  246. novelwriter/assets/icons/typicons_light/nw_search-preserve.svg +0 -4
  247. novelwriter/assets/icons/typicons_light/nw_search-regex.svg +0 -4
  248. novelwriter/assets/icons/typicons_light/nw_search-word.svg +0 -4
  249. novelwriter/assets/icons/typicons_light/nw_tb-bold-md.svg +0 -4
  250. novelwriter/assets/icons/typicons_light/nw_tb-bold.svg +0 -6
  251. novelwriter/assets/icons/typicons_light/nw_tb-italic-md.svg +0 -4
  252. novelwriter/assets/icons/typicons_light/nw_tb-italic.svg +0 -6
  253. novelwriter/assets/icons/typicons_light/nw_tb-mark.svg +0 -7
  254. novelwriter/assets/icons/typicons_light/nw_tb-strike-md.svg +0 -4
  255. novelwriter/assets/icons/typicons_light/nw_tb-strike.svg +0 -6
  256. novelwriter/assets/icons/typicons_light/nw_tb-subscript.svg +0 -7
  257. novelwriter/assets/icons/typicons_light/nw_tb-superscript.svg +0 -7
  258. novelwriter/assets/icons/typicons_light/nw_tb-underline.svg +0 -7
  259. novelwriter/assets/icons/typicons_light/nw_toolbar.svg +0 -5
  260. novelwriter/assets/icons/typicons_light/typ_arrow-down-thick-grey.svg +0 -4
  261. novelwriter/assets/icons/typicons_light/typ_arrow-forward.svg +0 -4
  262. novelwriter/assets/icons/typicons_light/typ_arrow-maximise.svg +0 -4
  263. novelwriter/assets/icons/typicons_light/typ_arrow-minimise.svg +0 -4
  264. novelwriter/assets/icons/typicons_light/typ_arrow-repeat-grey.svg +0 -4
  265. novelwriter/assets/icons/typicons_light/typ_book-grey.svg +0 -4
  266. novelwriter/assets/icons/typicons_light/typ_book.svg +0 -6
  267. novelwriter/assets/icons/typicons_light/typ_bookmark.svg +0 -4
  268. novelwriter/assets/icons/typicons_light/typ_calendar.svg +0 -4
  269. novelwriter/assets/icons/typicons_light/typ_cancel-grey.svg +0 -4
  270. novelwriter/assets/icons/typicons_light/typ_cancel.svg +0 -4
  271. novelwriter/assets/icons/typicons_light/typ_chart-bar-grey.svg +0 -4
  272. novelwriter/assets/icons/typicons_light/typ_chevron-down.svg +0 -4
  273. novelwriter/assets/icons/typicons_light/typ_chevron-left.svg +0 -4
  274. novelwriter/assets/icons/typicons_light/typ_chevron-right.svg +0 -4
  275. novelwriter/assets/icons/typicons_light/typ_chevron-up.svg +0 -4
  276. novelwriter/assets/icons/typicons_light/typ_cog.svg +0 -4
  277. novelwriter/assets/icons/typicons_light/typ_delete-full.svg +0 -4
  278. novelwriter/assets/icons/typicons_light/typ_delete.svg +0 -4
  279. novelwriter/assets/icons/typicons_light/typ_directions-full.svg +0 -4
  280. novelwriter/assets/icons/typicons_light/typ_document-add.svg +0 -4
  281. novelwriter/assets/icons/typicons_light/typ_document-text.svg +0 -5
  282. novelwriter/assets/icons/typicons_light/typ_document.svg +0 -4
  283. novelwriter/assets/icons/typicons_light/typ_export-grey.svg +0 -4
  284. novelwriter/assets/icons/typicons_light/typ_export.svg +0 -4
  285. novelwriter/assets/icons/typicons_light/typ_eye.svg +0 -4
  286. novelwriter/assets/icons/typicons_light/typ_flag.svg +0 -4
  287. novelwriter/assets/icons/typicons_light/typ_folder-open.svg +0 -4
  288. novelwriter/assets/icons/typicons_light/typ_folder.svg +0 -5
  289. novelwriter/assets/icons/typicons_light/typ_globe-grey.svg +0 -4
  290. novelwriter/assets/icons/typicons_light/typ_key.svg +0 -4
  291. novelwriter/assets/icons/typicons_light/typ_lightbulb-full.svg +0 -4
  292. novelwriter/assets/icons/typicons_light/typ_location.svg +0 -4
  293. novelwriter/assets/icons/typicons_light/typ_media-pause-grey.svg +0 -4
  294. novelwriter/assets/icons/typicons_light/typ_media-record-outline.svg +0 -4
  295. novelwriter/assets/icons/typicons_light/typ_media-record.svg +0 -4
  296. novelwriter/assets/icons/typicons_light/typ_minus.svg +0 -4
  297. novelwriter/assets/icons/typicons_light/typ_pencil.svg +0 -5
  298. novelwriter/assets/icons/typicons_light/typ_pin-outline.svg +0 -4
  299. novelwriter/assets/icons/typicons_light/typ_pin.svg +0 -4
  300. novelwriter/assets/icons/typicons_light/typ_plus.svg +0 -4
  301. novelwriter/assets/icons/typicons_light/typ_puzzle-outline.svg +0 -4
  302. novelwriter/assets/icons/typicons_light/typ_puzzle.svg +0 -4
  303. novelwriter/assets/icons/typicons_light/typ_refresh-flipped.svg +0 -4
  304. novelwriter/assets/icons/typicons_light/typ_refresh.svg +0 -4
  305. novelwriter/assets/icons/typicons_light/typ_search-grey.svg +0 -4
  306. novelwriter/assets/icons/typicons_light/typ_search.svg +0 -4
  307. novelwriter/assets/icons/typicons_light/typ_star.svg +0 -4
  308. novelwriter/assets/icons/typicons_light/typ_stopwatch-grey.svg +0 -4
  309. novelwriter/assets/icons/typicons_light/typ_th-dot-menu.svg +0 -4
  310. novelwriter/assets/icons/typicons_light/typ_th-dot-more.svg +0 -4
  311. novelwriter/assets/icons/typicons_light/typ_th-list-grey.svg +0 -4
  312. novelwriter/assets/icons/typicons_light/typ_th-list.svg +0 -9
  313. novelwriter/assets/icons/typicons_light/typ_times.svg +0 -4
  314. novelwriter/assets/icons/typicons_light/typ_trash.svg +0 -5
  315. novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg +0 -4
  316. novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg +0 -4
  317. novelwriter/assets/icons/typicons_light/typ_user.svg +0 -5
  318. novelwriter/assets/icons/typicons_light/typ_warning-full.svg +0 -4
  319. {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/entry_points.txt +0 -0
  320. {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info/licenses}/LICENSE.md +0 -0
  321. {novelWriter-2.6.3.dist-info → novelwriter-2.7b1.dist-info}/top_level.txt +0 -0
@@ -28,11 +28,12 @@ import logging
28
28
  from pathlib import Path
29
29
  from typing import TYPE_CHECKING
30
30
 
31
- from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
32
- from PyQt5.QtWidgets import QAction, QMenuBar
31
+ from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
32
+ from PyQt6.QtGui import QAction
33
+ from PyQt6.QtWidgets import QMenuBar
33
34
 
34
35
  from novelwriter import CONFIG, SHARED
35
- from novelwriter.common import openExternalPath, qtLambda
36
+ from novelwriter.common import openExternalPath, qtAddAction, qtAddMenu, qtLambda
36
37
  from novelwriter.constants import (
37
38
  nwConst, nwKeyWords, nwLabels, nwShortcode, nwStats, nwStyles, nwUnicode,
38
39
  trConst, trStats
@@ -40,7 +41,7 @@ from novelwriter.constants import (
40
41
  from novelwriter.enum import nwDocAction, nwDocInsert, nwFocus, nwView
41
42
  from novelwriter.extensions.eventfilters import StatusTipFilter
42
43
 
43
- if TYPE_CHECKING: # pragma: no cover
44
+ if TYPE_CHECKING:
44
45
  from novelwriter.guimain import GuiMain
45
46
 
46
47
  logger = logging.getLogger(__name__)
@@ -127,21 +128,21 @@ class GuiMainMenu(QMenuBar):
127
128
  def _buildProjectMenu(self) -> None:
128
129
  """Assemble the Project menu."""
129
130
  # Project
130
- self.projMenu = self.addMenu(self.tr("&Project"))
131
+ self.projMenu = qtAddMenu(self, self.tr("&Project"))
131
132
 
132
133
  # Project > Create or Open Project
133
- self.aOpenProject = self.projMenu.addAction(self.tr("Create or Open Project"))
134
+ self.aOpenProject = qtAddAction(self.projMenu, self.tr("Create or Open Project"))
134
135
  self.aOpenProject.setShortcut("Ctrl+Shift+O")
135
136
  self.aOpenProject.triggered.connect(self.mainGui.showWelcomeDialog)
136
137
 
137
138
  # Project > Save Project
138
- self.aSaveProject = self.projMenu.addAction(self.tr("Save Project"))
139
+ self.aSaveProject = qtAddAction(self.projMenu, self.tr("Save Project"))
139
140
  self.aSaveProject.setShortcut("Ctrl+Shift+S")
140
141
  self.aSaveProject.triggered.connect(qtLambda(self.mainGui.saveProject))
141
142
  self.mainGui.addAction(self.aSaveProject)
142
143
 
143
144
  # Project > Close Project
144
- self.aCloseProject = self.projMenu.addAction(self.tr("Close Project"))
145
+ self.aCloseProject = qtAddAction(self.projMenu, self.tr("Close Project"))
145
146
  self.aCloseProject.setShortcut("Ctrl+Shift+W")
146
147
  self.aCloseProject.triggered.connect(qtLambda(self.mainGui.closeProject, False))
147
148
 
@@ -149,12 +150,12 @@ class GuiMainMenu(QMenuBar):
149
150
  self.projMenu.addSeparator()
150
151
 
151
152
  # Project > Project Settings
152
- self.aProjectSettings = self.projMenu.addAction(self.tr("Project Settings"))
153
+ self.aProjectSettings = qtAddAction(self.projMenu, self.tr("Project Settings"))
153
154
  self.aProjectSettings.setShortcut("Ctrl+Shift+,")
154
155
  self.aProjectSettings.triggered.connect(self.mainGui.showProjectSettingsDialog)
155
156
 
156
157
  # Project > Novel Details
157
- self.aNovelDetails = self.projMenu.addAction(self.tr("Novel Details"))
158
+ self.aNovelDetails = qtAddAction(self.projMenu, self.tr("Novel Details"))
158
159
  self.aNovelDetails.setShortcut("Shift+F6")
159
160
  self.aNovelDetails.triggered.connect(self.mainGui.showNovelDetailsDialog)
160
161
 
@@ -162,16 +163,16 @@ class GuiMainMenu(QMenuBar):
162
163
  self.projMenu.addSeparator()
163
164
 
164
165
  # Project > Edit
165
- self.aRenameItem = self.projMenu.addAction(self.tr("Rename Item"))
166
+ self.aRenameItem = qtAddAction(self.projMenu, self.tr("Rename Item"))
166
167
  self.aRenameItem.setShortcut("F2")
167
168
 
168
169
  # Project > Delete
169
- self.aDeleteItem = self.projMenu.addAction(self.tr("Delete Item"))
170
+ self.aDeleteItem = qtAddAction(self.projMenu, self.tr("Delete Item"))
170
171
  self.aDeleteItem.setShortcut("Del")
171
172
  self.aDeleteItem.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
172
173
 
173
174
  # Project > Empty Trash
174
- self.aEmptyTrash = self.projMenu.addAction(self.tr("Empty Trash"))
175
+ self.aEmptyTrash = qtAddAction(self.projMenu, self.tr("Empty Trash"))
175
176
 
176
177
  self.mainGui.projView.connectMenuActions(
177
178
  self.aRenameItem, self.aDeleteItem, self.aEmptyTrash
@@ -181,7 +182,7 @@ class GuiMainMenu(QMenuBar):
181
182
  self.projMenu.addSeparator()
182
183
 
183
184
  # Project > Exit
184
- self.aExitNW = self.projMenu.addAction(self.tr("Exit"))
185
+ self.aExitNW = qtAddAction(self.projMenu, self.tr("Exit"))
185
186
  self.aExitNW.setShortcut("Ctrl+Q")
186
187
  self.aExitNW.setMenuRole(QAction.MenuRole.QuitRole)
187
188
  self.aExitNW.triggered.connect(qtLambda(self.mainGui.closeMain))
@@ -192,21 +193,21 @@ class GuiMainMenu(QMenuBar):
192
193
  def _buildDocumentMenu(self) -> None:
193
194
  """Assemble the Document menu."""
194
195
  # Document
195
- self.docuMenu = self.addMenu(self.tr("&Document"))
196
+ self.docuMenu = qtAddMenu(self, self.tr("&Document"))
196
197
 
197
198
  # Document > Open
198
- self.aOpenDoc = self.docuMenu.addAction(self.tr("Open Document"))
199
+ self.aOpenDoc = qtAddAction(self.docuMenu, self.tr("Open Document"))
199
200
  self.aOpenDoc.setShortcut("Ctrl+O")
200
201
  self.aOpenDoc.triggered.connect(self.mainGui.openSelectedItem)
201
202
 
202
203
  # Document > Save
203
- self.aSaveDoc = self.docuMenu.addAction(self.tr("Save Document"))
204
+ self.aSaveDoc = qtAddAction(self.docuMenu, self.tr("Save Document"))
204
205
  self.aSaveDoc.setShortcut("Ctrl+S")
205
206
  self.aSaveDoc.triggered.connect(self.mainGui.forceSaveDocument)
206
207
  self.mainGui.addAction(self.aSaveDoc)
207
208
 
208
209
  # Document > Close
209
- self.aCloseDoc = self.docuMenu.addAction(self.tr("Close Document"))
210
+ self.aCloseDoc = qtAddAction(self.docuMenu, self.tr("Close Document"))
210
211
  self.aCloseDoc.setShortcut("Ctrl+W")
211
212
  self.aCloseDoc.triggered.connect(self.mainGui.closeDocEditor)
212
213
  self.mainGui.addAction(self.aCloseDoc)
@@ -215,12 +216,12 @@ class GuiMainMenu(QMenuBar):
215
216
  self.docuMenu.addSeparator()
216
217
 
217
218
  # Document > Preview
218
- self.aViewDoc = self.docuMenu.addAction(self.tr("View Document"))
219
+ self.aViewDoc = qtAddAction(self.docuMenu, self.tr("View Document"))
219
220
  self.aViewDoc.setShortcut("Ctrl+R")
220
221
  self.aViewDoc.triggered.connect(qtLambda(self.mainGui.viewDocument, None))
221
222
 
222
223
  # Document > Close Preview
223
- self.aCloseView = self.docuMenu.addAction(self.tr("Close Document View"))
224
+ self.aCloseView = qtAddAction(self.docuMenu, self.tr("Close Document View"))
224
225
  self.aCloseView.setShortcut("Ctrl+Shift+R")
225
226
  self.aCloseView.triggered.connect(self.mainGui.closeDocViewer)
226
227
 
@@ -228,11 +229,11 @@ class GuiMainMenu(QMenuBar):
228
229
  self.docuMenu.addSeparator()
229
230
 
230
231
  # Document > Show File Details
231
- self.aFileDetails = self.docuMenu.addAction(self.tr("Show File Details"))
232
+ self.aFileDetails = qtAddAction(self.docuMenu, self.tr("Show File Details"))
232
233
  self.aFileDetails.triggered.connect(qtLambda(self.mainGui.docEditor.revealLocation))
233
234
 
234
235
  # Document > Import From File
235
- self.aImportFile = self.docuMenu.addAction(self.tr("Import Text from File"))
236
+ self.aImportFile = qtAddAction(self.docuMenu, self.tr("Import Text from File"))
236
237
  self.aImportFile.triggered.connect(qtLambda(self.mainGui.importDocument))
237
238
 
238
239
  return
@@ -240,10 +241,10 @@ class GuiMainMenu(QMenuBar):
240
241
  def _buildEditMenu(self) -> None:
241
242
  """Assemble the Edit menu."""
242
243
  # Edit
243
- self.editMenu = self.addMenu(self.tr("&Edit"))
244
+ self.editMenu = qtAddMenu(self, self.tr("&Edit"))
244
245
 
245
246
  # Edit > Undo
246
- self.aEditUndo = self.editMenu.addAction(self.tr("Undo"))
247
+ self.aEditUndo = qtAddAction(self.editMenu, self.tr("Undo"))
247
248
  self.aEditUndo.setShortcut("Ctrl+Z")
248
249
  self.aEditUndo.triggered.connect(
249
250
  lambda: self.requestDocAction.emit(nwDocAction.UNDO)
@@ -251,7 +252,7 @@ class GuiMainMenu(QMenuBar):
251
252
  self.mainGui.addAction(self.aEditUndo)
252
253
 
253
254
  # Edit > Redo
254
- self.aEditRedo = self.editMenu.addAction(self.tr("Redo"))
255
+ self.aEditRedo = qtAddAction(self.editMenu, self.tr("Redo"))
255
256
  self.aEditRedo.setShortcut("Ctrl+Y")
256
257
  self.aEditRedo.triggered.connect(
257
258
  lambda: self.requestDocAction.emit(nwDocAction.REDO)
@@ -262,7 +263,7 @@ class GuiMainMenu(QMenuBar):
262
263
  self.editMenu.addSeparator()
263
264
 
264
265
  # Edit > Cut
265
- self.aEditCut = self.editMenu.addAction(self.tr("Cut"))
266
+ self.aEditCut = qtAddAction(self.editMenu, self.tr("Cut"))
266
267
  self.aEditCut.setShortcut("Ctrl+X")
267
268
  self.aEditCut.triggered.connect(
268
269
  lambda: self.requestDocAction.emit(nwDocAction.CUT)
@@ -270,7 +271,7 @@ class GuiMainMenu(QMenuBar):
270
271
  self.mainGui.addAction(self.aEditCut)
271
272
 
272
273
  # Edit > Copy
273
- self.aEditCopy = self.editMenu.addAction(self.tr("Copy"))
274
+ self.aEditCopy = qtAddAction(self.editMenu, self.tr("Copy"))
274
275
  self.aEditCopy.setShortcut("Ctrl+C")
275
276
  self.aEditCopy.triggered.connect(
276
277
  lambda: self.requestDocAction.emit(nwDocAction.COPY)
@@ -278,7 +279,7 @@ class GuiMainMenu(QMenuBar):
278
279
  self.mainGui.addAction(self.aEditCopy)
279
280
 
280
281
  # Edit > Paste
281
- self.aEditPaste = self.editMenu.addAction(self.tr("Paste"))
282
+ self.aEditPaste = qtAddAction(self.editMenu, self.tr("Paste"))
282
283
  self.aEditPaste.setShortcut("Ctrl+V")
283
284
  self.aEditPaste.triggered.connect(
284
285
  lambda: self.requestDocAction.emit(nwDocAction.PASTE)
@@ -289,7 +290,7 @@ class GuiMainMenu(QMenuBar):
289
290
  self.editMenu.addSeparator()
290
291
 
291
292
  # Edit > Select All
292
- self.aSelectAll = self.editMenu.addAction(self.tr("Select All"))
293
+ self.aSelectAll = qtAddAction(self.editMenu, self.tr("Select All"))
293
294
  self.aSelectAll.setShortcut("Ctrl+A")
294
295
  self.aSelectAll.triggered.connect(
295
296
  lambda: self.requestDocAction.emit(nwDocAction.SEL_ALL)
@@ -297,7 +298,7 @@ class GuiMainMenu(QMenuBar):
297
298
  self.mainGui.addAction(self.aSelectAll)
298
299
 
299
300
  # Edit > Select Paragraph
300
- self.aSelectPar = self.editMenu.addAction(self.tr("Select Paragraph"))
301
+ self.aSelectPar = qtAddAction(self.editMenu, self.tr("Select Paragraph"))
301
302
  self.aSelectPar.setShortcut("Ctrl+Shift+A")
302
303
  self.aSelectPar.triggered.connect(
303
304
  lambda: self.requestDocAction.emit(nwDocAction.SEL_PARA)
@@ -309,24 +310,24 @@ class GuiMainMenu(QMenuBar):
309
310
  def _buildViewMenu(self) -> None:
310
311
  """Assemble the View menu."""
311
312
  # View
312
- self.viewMenu = self.addMenu(self.tr("&View"))
313
+ self.viewMenu = qtAddMenu(self, self.tr("&View"))
313
314
 
314
315
  # View > TreeView
315
- self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Tree View"))
316
+ self.aFocusTree = qtAddAction(self.viewMenu, self.tr("Go to Tree View"))
316
317
  self.aFocusTree.setShortcut("Ctrl+T")
317
318
  self.aFocusTree.triggered.connect(
318
319
  lambda: self.requestFocusChange.emit(nwFocus.TREE)
319
320
  )
320
321
 
321
322
  # View > Document Editor
322
- self.aFocusDocument = self.viewMenu.addAction(self.tr("Go to Document"))
323
+ self.aFocusDocument = qtAddAction(self.viewMenu, self.tr("Go to Document"))
323
324
  self.aFocusDocument.setShortcut("Ctrl+E")
324
325
  self.aFocusDocument.triggered.connect(
325
326
  lambda: self.requestFocusChange.emit(nwFocus.DOCUMENT)
326
327
  )
327
328
 
328
329
  # View > Outline
329
- self.aFocusOutline = self.viewMenu.addAction(self.tr("Go to Outline"))
330
+ self.aFocusOutline = qtAddAction(self.viewMenu, self.tr("Go to Outline"))
330
331
  self.aFocusOutline.setShortcut("Ctrl+Shift+T")
331
332
  self.aFocusOutline.triggered.connect(
332
333
  lambda: self.requestFocusChange.emit(nwFocus.OUTLINE)
@@ -336,14 +337,14 @@ class GuiMainMenu(QMenuBar):
336
337
  self.viewMenu.addSeparator()
337
338
 
338
339
  # View > Go Backward
339
- self.aViewPrev = self.viewMenu.addAction(self.tr("Navigate Backward"))
340
+ self.aViewPrev = qtAddAction(self.viewMenu, self.tr("Navigate Backward"))
340
341
  self.aViewPrev.setShortcut("Alt+Left")
341
342
  self.aViewPrev.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
342
343
  self.aViewPrev.triggered.connect(self.mainGui.docViewer.navBackward)
343
344
  self.mainGui.docViewer.addAction(self.aViewPrev)
344
345
 
345
346
  # View > Go Forward
346
- self.aViewNext = self.viewMenu.addAction(self.tr("Navigate Forward"))
347
+ self.aViewNext = qtAddAction(self.viewMenu, self.tr("Navigate Forward"))
347
348
  self.aViewNext.setShortcut("Alt+Right")
348
349
  self.aViewNext.setShortcutContext(Qt.ShortcutContext.WidgetShortcut)
349
350
  self.aViewNext.triggered.connect(self.mainGui.docViewer.navForward)
@@ -353,13 +354,13 @@ class GuiMainMenu(QMenuBar):
353
354
  self.viewMenu.addSeparator()
354
355
 
355
356
  # View > Focus Mode
356
- self.aFocusMode = self.viewMenu.addAction(self.tr("Focus Mode"))
357
+ self.aFocusMode = qtAddAction(self.viewMenu, self.tr("Focus Mode"))
357
358
  self.aFocusMode.setShortcut("F8")
358
359
  self.aFocusMode.triggered.connect(self.mainGui.toggleFocusMode)
359
360
  self.mainGui.addAction(self.aFocusMode)
360
361
 
361
362
  # View > Toggle Full Screen
362
- self.aFullScreen = self.viewMenu.addAction(self.tr("Full Screen Mode"))
363
+ self.aFullScreen = qtAddAction(self.viewMenu, self.tr("Full Screen Mode"))
363
364
  self.aFullScreen.setShortcut("F11")
364
365
  self.aFullScreen.triggered.connect(self.mainGui.toggleFullScreenMode)
365
366
  self.mainGui.addAction(self.aFullScreen)
@@ -369,13 +370,13 @@ class GuiMainMenu(QMenuBar):
369
370
  def _buildInsertMenu(self) -> None:
370
371
  """Assemble the Insert menu."""
371
372
  # Insert
372
- self.insMenu = self.addMenu(self.tr("&Insert"))
373
+ self.insMenu = qtAddMenu(self, self.tr("&Insert"))
373
374
 
374
375
  # Insert > Dashes and Dots
375
- self.mInsDashes = self.insMenu.addMenu(self.tr("Dashes"))
376
+ self.mInsDashes = qtAddMenu(self.insMenu, self.tr("Dashes"))
376
377
 
377
378
  # Insert > Short Dash
378
- self.aInsENDash = self.mInsDashes.addAction(self.tr("Short Dash"))
379
+ self.aInsENDash = qtAddAction(self.mInsDashes, self.tr("Short Dash"))
379
380
  self.aInsENDash.setShortcut("Ctrl+K, -")
380
381
  self.aInsENDash.triggered.connect(
381
382
  lambda: self.requestDocInsertText.emit(nwUnicode.U_ENDASH)
@@ -383,7 +384,7 @@ class GuiMainMenu(QMenuBar):
383
384
  self.mainGui.addAction(self.aInsENDash)
384
385
 
385
386
  # Insert > Long Dash
386
- self.aInsEMDash = self.mInsDashes.addAction(self.tr("Long Dash"))
387
+ self.aInsEMDash = qtAddAction(self.mInsDashes, self.tr("Long Dash"))
387
388
  self.aInsEMDash.setShortcut("Ctrl+K, _")
388
389
  self.aInsEMDash.triggered.connect(
389
390
  lambda: self.requestDocInsertText.emit(nwUnicode.U_EMDASH)
@@ -391,7 +392,7 @@ class GuiMainMenu(QMenuBar):
391
392
  self.mainGui.addAction(self.aInsEMDash)
392
393
 
393
394
  # Insert > Long Dash
394
- self.aInsHorBar = self.mInsDashes.addAction(self.tr("Horizontal Bar"))
395
+ self.aInsHorBar = qtAddAction(self.mInsDashes, self.tr("Horizontal Bar"))
395
396
  self.aInsHorBar.setShortcut("Ctrl+K, Ctrl+_")
396
397
  self.aInsHorBar.triggered.connect(
397
398
  lambda: self.requestDocInsertText.emit(nwUnicode.U_HBAR)
@@ -399,7 +400,7 @@ class GuiMainMenu(QMenuBar):
399
400
  self.mainGui.addAction(self.aInsHorBar)
400
401
 
401
402
  # Insert > Figure Dash
402
- self.aInsFigDash = self.mInsDashes.addAction(self.tr("Figure Dash"))
403
+ self.aInsFigDash = qtAddAction(self.mInsDashes, self.tr("Figure Dash"))
403
404
  self.aInsFigDash.setShortcut("Ctrl+K, ~")
404
405
  self.aInsFigDash.triggered.connect(
405
406
  lambda: self.requestDocInsertText.emit(nwUnicode.U_FGDASH)
@@ -407,10 +408,10 @@ class GuiMainMenu(QMenuBar):
407
408
  self.mainGui.addAction(self.aInsFigDash)
408
409
 
409
410
  # Insert > Quote Marks
410
- self.mInsQuotes = self.insMenu.addMenu(self.tr("Quote Marks"))
411
+ self.mInsQuotes = qtAddMenu(self.insMenu, self.tr("Quote Marks"))
411
412
 
412
413
  # Insert > Left Single Quote
413
- self.aInsQuoteLS = self.mInsQuotes.addAction(self.tr("Left Single Quote"))
414
+ self.aInsQuoteLS = qtAddAction(self.mInsQuotes, self.tr("Left Single Quote"))
414
415
  self.aInsQuoteLS.setShortcut("Ctrl+K, 1")
415
416
  self.aInsQuoteLS.triggered.connect(
416
417
  lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LS)
@@ -418,7 +419,7 @@ class GuiMainMenu(QMenuBar):
418
419
  self.mainGui.addAction(self.aInsQuoteLS)
419
420
 
420
421
  # Insert > Right Single Quote
421
- self.aInsQuoteRS = self.mInsQuotes.addAction(self.tr("Right Single Quote"))
422
+ self.aInsQuoteRS = qtAddAction(self.mInsQuotes, self.tr("Right Single Quote"))
422
423
  self.aInsQuoteRS.setShortcut("Ctrl+K, 2")
423
424
  self.aInsQuoteRS.triggered.connect(
424
425
  lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RS)
@@ -426,7 +427,7 @@ class GuiMainMenu(QMenuBar):
426
427
  self.mainGui.addAction(self.aInsQuoteRS)
427
428
 
428
429
  # Insert > Left Double Quote
429
- self.aInsQuoteLD = self.mInsQuotes.addAction(self.tr("Left Double Quote"))
430
+ self.aInsQuoteLD = qtAddAction(self.mInsQuotes, self.tr("Left Double Quote"))
430
431
  self.aInsQuoteLD.setShortcut("Ctrl+K, 3")
431
432
  self.aInsQuoteLD.triggered.connect(
432
433
  lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_LD)
@@ -434,7 +435,7 @@ class GuiMainMenu(QMenuBar):
434
435
  self.mainGui.addAction(self.aInsQuoteLD)
435
436
 
436
437
  # Insert > Right Double Quote
437
- self.aInsQuoteRD = self.mInsQuotes.addAction(self.tr("Right Double Quote"))
438
+ self.aInsQuoteRD = qtAddAction(self.mInsQuotes, self.tr("Right Double Quote"))
438
439
  self.aInsQuoteRD.setShortcut("Ctrl+K, 4")
439
440
  self.aInsQuoteRD.triggered.connect(
440
441
  lambda: self.requestDocInsert.emit(nwDocInsert.QUOTE_RD)
@@ -442,7 +443,7 @@ class GuiMainMenu(QMenuBar):
442
443
  self.mainGui.addAction(self.aInsQuoteRD)
443
444
 
444
445
  # Insert > Alternative Apostrophe
445
- self.aInsMSApos = self.mInsQuotes.addAction(self.tr("Alternative Apostrophe"))
446
+ self.aInsMSApos = qtAddAction(self.mInsQuotes, self.tr("Alternative Apostrophe"))
446
447
  self.aInsMSApos.setShortcut("Ctrl+K, '")
447
448
  self.aInsMSApos.triggered.connect(
448
449
  lambda: self.requestDocInsertText.emit(nwUnicode.U_MAPOS)
@@ -450,10 +451,10 @@ class GuiMainMenu(QMenuBar):
450
451
  self.mainGui.addAction(self.aInsMSApos)
451
452
 
452
453
  # Insert > Symbols
453
- self.mInsPunct = self.insMenu.addMenu(self.tr("General Punctuation"))
454
+ self.mInsPunct = qtAddMenu(self.insMenu, self.tr("General Punctuation"))
454
455
 
455
456
  # Insert > Ellipsis
456
- self.aInsEllipsis = self.mInsPunct.addAction(self.tr("Ellipsis"))
457
+ self.aInsEllipsis = qtAddAction(self.mInsPunct, self.tr("Ellipsis"))
457
458
  self.aInsEllipsis.setShortcut("Ctrl+K, .")
458
459
  self.aInsEllipsis.triggered.connect(
459
460
  lambda: self.requestDocInsertText.emit(nwUnicode.U_HELLIP)
@@ -461,7 +462,7 @@ class GuiMainMenu(QMenuBar):
461
462
  self.mainGui.addAction(self.aInsEllipsis)
462
463
 
463
464
  # Insert > Prime
464
- self.aInsPrime = self.mInsPunct.addAction(self.tr("Prime"))
465
+ self.aInsPrime = qtAddAction(self.mInsPunct, self.tr("Prime"))
465
466
  self.aInsPrime.setShortcut("Ctrl+K, Ctrl+'")
466
467
  self.aInsPrime.triggered.connect(
467
468
  lambda: self.requestDocInsertText.emit(nwUnicode.U_PRIME)
@@ -469,18 +470,18 @@ class GuiMainMenu(QMenuBar):
469
470
  self.mainGui.addAction(self.aInsPrime)
470
471
 
471
472
  # Insert > Double Prime
472
- self.aInsDPrime = self.mInsPunct.addAction(self.tr("Double Prime"))
473
- self.aInsDPrime.setShortcut("Ctrl+K, Ctrl+\"")
473
+ self.aInsDPrime = qtAddAction(self.mInsPunct, self.tr("Double Prime"))
474
+ self.aInsDPrime.setShortcut('Ctrl+K, Ctrl+"')
474
475
  self.aInsDPrime.triggered.connect(
475
476
  lambda: self.requestDocInsertText.emit(nwUnicode.U_DPRIME)
476
477
  )
477
478
  self.mainGui.addAction(self.aInsDPrime)
478
479
 
479
480
  # Insert > White Spaces
480
- self.mInsSpace = self.insMenu.addMenu(self.tr("White Spaces"))
481
+ self.mInsSpace = qtAddMenu(self.insMenu, self.tr("White Spaces"))
481
482
 
482
483
  # Insert > Non-Breaking Space
483
- self.aInsNBSpace = self.mInsSpace.addAction(self.tr("Non-Breaking Space"))
484
+ self.aInsNBSpace = qtAddAction(self.mInsSpace, self.tr("Non-Breaking Space"))
484
485
  self.aInsNBSpace.setShortcut("Ctrl+K, Space")
485
486
  self.aInsNBSpace.triggered.connect(
486
487
  lambda: self.requestDocInsertText.emit(nwUnicode.U_NBSP)
@@ -488,7 +489,7 @@ class GuiMainMenu(QMenuBar):
488
489
  self.mainGui.addAction(self.aInsNBSpace)
489
490
 
490
491
  # Insert > Thin Space
491
- self.aInsThinSpace = self.mInsSpace.addAction(self.tr("Thin Space"))
492
+ self.aInsThinSpace = qtAddAction(self.mInsSpace, self.tr("Thin Space"))
492
493
  self.aInsThinSpace.setShortcut("Ctrl+K, Shift+Space")
493
494
  self.aInsThinSpace.triggered.connect(
494
495
  lambda: self.requestDocInsertText.emit(nwUnicode.U_THSP)
@@ -496,7 +497,7 @@ class GuiMainMenu(QMenuBar):
496
497
  self.mainGui.addAction(self.aInsThinSpace)
497
498
 
498
499
  # Insert > Thin Non-Breaking Space
499
- self.aInsThinNBSpace = self.mInsSpace.addAction(self.tr("Thin Non-Breaking Space"))
500
+ self.aInsThinNBSpace = qtAddAction(self.mInsSpace, self.tr("Thin Non-Breaking Space"))
500
501
  self.aInsThinNBSpace.setShortcut("Ctrl+K, Ctrl+Space")
501
502
  self.aInsThinNBSpace.triggered.connect(
502
503
  lambda: self.requestDocInsertText.emit(nwUnicode.U_THNBSP)
@@ -504,10 +505,10 @@ class GuiMainMenu(QMenuBar):
504
505
  self.mainGui.addAction(self.aInsThinNBSpace)
505
506
 
506
507
  # Insert > Symbols
507
- self.mInsSymbol = self.insMenu.addMenu(self.tr("Other Symbols"))
508
+ self.mInsSymbol = qtAddMenu(self.insMenu, self.tr("Other Symbols"))
508
509
 
509
510
  # Insert > List Bullet
510
- self.aInsBullet = self.mInsSymbol.addAction(self.tr("List Bullet"))
511
+ self.aInsBullet = qtAddAction(self.mInsSymbol, self.tr("List Bullet"))
511
512
  self.aInsBullet.setShortcut("Ctrl+K, *")
512
513
  self.aInsBullet.triggered.connect(
513
514
  lambda: self.requestDocInsertText.emit(nwUnicode.U_BULL)
@@ -515,7 +516,7 @@ class GuiMainMenu(QMenuBar):
515
516
  self.mainGui.addAction(self.aInsBullet)
516
517
 
517
518
  # Insert > Hyphen Bullet
518
- self.aInsHyBull = self.mInsSymbol.addAction(self.tr("Hyphen Bullet"))
519
+ self.aInsHyBull = qtAddAction(self.mInsSymbol, self.tr("Hyphen Bullet"))
519
520
  self.aInsHyBull.setShortcut("Ctrl+K, Ctrl+-")
520
521
  self.aInsHyBull.triggered.connect(
521
522
  lambda: self.requestDocInsertText.emit(nwUnicode.U_HYBULL)
@@ -523,7 +524,7 @@ class GuiMainMenu(QMenuBar):
523
524
  self.mainGui.addAction(self.aInsHyBull)
524
525
 
525
526
  # Insert > Flower Mark
526
- self.aInsFlower = self.mInsSymbol.addAction(self.tr("Flower Mark"))
527
+ self.aInsFlower = qtAddAction(self.mInsSymbol, self.tr("Flower Mark"))
527
528
  self.aInsFlower.setShortcut("Ctrl+K, Ctrl+*")
528
529
  self.aInsFlower.triggered.connect(
529
530
  lambda: self.requestDocInsertText.emit(nwUnicode.U_FLOWER)
@@ -531,7 +532,7 @@ class GuiMainMenu(QMenuBar):
531
532
  self.mainGui.addAction(self.aInsFlower)
532
533
 
533
534
  # Insert > Per Mille
534
- self.aInsPerMille = self.mInsSymbol.addAction(self.tr("Per Mille"))
535
+ self.aInsPerMille = qtAddAction(self.mInsSymbol, self.tr("Per Mille"))
535
536
  self.aInsPerMille.setShortcut("Ctrl+K, %")
536
537
  self.aInsPerMille.triggered.connect(
537
538
  lambda: self.requestDocInsertText.emit(nwUnicode.U_PERMIL)
@@ -539,7 +540,7 @@ class GuiMainMenu(QMenuBar):
539
540
  self.mainGui.addAction(self.aInsPerMille)
540
541
 
541
542
  # Insert > Degree Symbol
542
- self.aInsDegree = self.mInsSymbol.addAction(self.tr("Degree Symbol"))
543
+ self.aInsDegree = qtAddAction(self.mInsSymbol, self.tr("Degree Symbol"))
543
544
  self.aInsDegree.setShortcut("Ctrl+K, Ctrl+O")
544
545
  self.aInsDegree.triggered.connect(
545
546
  lambda: self.requestDocInsertText.emit(nwUnicode.U_DEGREE)
@@ -547,7 +548,7 @@ class GuiMainMenu(QMenuBar):
547
548
  self.mainGui.addAction(self.aInsDegree)
548
549
 
549
550
  # Insert > Minus Sign
550
- self.aInsMinus = self.mInsSymbol.addAction(self.tr("Minus Sign"))
551
+ self.aInsMinus = qtAddAction(self.mInsSymbol, self.tr("Minus Sign"))
551
552
  self.aInsMinus.setShortcut("Ctrl+K, Ctrl+M")
552
553
  self.aInsMinus.triggered.connect(
553
554
  lambda: self.requestDocInsertText.emit(nwUnicode.U_MINUS)
@@ -555,7 +556,7 @@ class GuiMainMenu(QMenuBar):
555
556
  self.mainGui.addAction(self.aInsMinus)
556
557
 
557
558
  # Insert > Times Sign
558
- self.aInsTimes = self.mInsSymbol.addAction(self.tr("Times Sign"))
559
+ self.aInsTimes = qtAddAction(self.mInsSymbol, self.tr("Times Sign"))
559
560
  self.aInsTimes.setShortcut("Ctrl+K, Ctrl+X")
560
561
  self.aInsTimes.triggered.connect(
561
562
  lambda: self.requestDocInsertText.emit(nwUnicode.U_TIMES)
@@ -563,7 +564,7 @@ class GuiMainMenu(QMenuBar):
563
564
  self.mainGui.addAction(self.aInsTimes)
564
565
 
565
566
  # Insert > Division
566
- self.aInsDivide = self.mInsSymbol.addAction(self.tr("Division Sign"))
567
+ self.aInsDivide = qtAddAction(self.mInsSymbol, self.tr("Division Sign"))
567
568
  self.aInsDivide.setShortcut("Ctrl+K, Ctrl+D")
568
569
  self.aInsDivide.triggered.connect(
569
570
  lambda: self.requestDocInsertText.emit(nwUnicode.U_DIVIDE)
@@ -571,18 +572,18 @@ class GuiMainMenu(QMenuBar):
571
572
  self.mainGui.addAction(self.aInsDivide)
572
573
 
573
574
  # Insert > Tags and References
574
- self.mInsKeywords = self.insMenu.addMenu(self.tr("Tags and References"))
575
+ self.mInsKeywords = qtAddMenu(self.insMenu, self.tr("Tags and References"))
575
576
  for key in nwKeyWords.ALL_KEYS:
576
- action = self.mInsKeywords.addAction(trConst(nwLabels.KEY_NAME[key]))
577
+ action = qtAddAction(self.mInsKeywords, trConst(nwLabels.KEY_NAME[key]))
577
578
  action.setShortcut(nwLabels.KEY_SHORTCUT[key])
578
579
  action.triggered.connect(qtLambda(self.requestDocKeyWordInsert.emit, key))
579
580
  self.mainGui.addAction(action)
580
581
 
581
582
  # Insert > Special Comments
582
- self.mInsComments = self.insMenu.addMenu(self.tr("Special Comments"))
583
+ self.mInsComments = qtAddMenu(self.insMenu, self.tr("Special Comments"))
583
584
 
584
585
  # Insert > Synopsis Comment
585
- self.aInsSynopsis = self.mInsComments.addAction(self.tr("Synopsis Comment"))
586
+ self.aInsSynopsis = qtAddAction(self.mInsComments, self.tr("Synopsis Comment"))
586
587
  self.aInsSynopsis.setShortcut("Ctrl+K, S")
587
588
  self.aInsSynopsis.triggered.connect(
588
589
  lambda: self.requestDocInsert.emit(nwDocInsert.SYNOPSIS)
@@ -590,7 +591,7 @@ class GuiMainMenu(QMenuBar):
590
591
  self.mainGui.addAction(self.aInsSynopsis)
591
592
 
592
593
  # Insert > Short Description Comment
593
- self.aInsShort = self.mInsComments.addAction(self.tr("Short Description Comment"))
594
+ self.aInsShort = qtAddAction(self.mInsComments, self.tr("Short Description Comment"))
594
595
  self.aInsShort.setShortcut("Ctrl+K, H")
595
596
  self.aInsShort.triggered.connect(
596
597
  lambda: self.requestDocInsert.emit(nwDocInsert.SHORT)
@@ -598,47 +599,47 @@ class GuiMainMenu(QMenuBar):
598
599
  self.mainGui.addAction(self.aInsShort)
599
600
 
600
601
  # Insert > Word/Character Count
601
- self.mInsField = self.insMenu.addMenu(self.tr("Word/Character Count"))
602
+ self.mInsField = qtAddMenu(self.insMenu, self.tr("Word/Character Count"))
602
603
  for field in nwStats.ALL_FIELDS:
603
604
  value = nwShortcode.FIELD_VALUE.format(field)
604
- action = self.mInsField.addAction(trStats(nwLabels.STATS_NAME[field]))
605
+ action = qtAddAction(self.mInsField, trStats(nwLabels.STATS_NAME[field]))
605
606
  action.triggered.connect(qtLambda(self.requestDocInsertText.emit, value))
606
607
 
607
608
  # Insert > Breaks and Vertical Space
608
- self.mInsBreaks = self.insMenu.addMenu(self.tr("Breaks and Vertical Space"))
609
+ self.mInsBreaks = qtAddMenu(self.insMenu, self.tr("Breaks and Vertical Space"))
609
610
 
610
611
  # Insert > New Page
611
- self.aInsNewPage = self.mInsBreaks.addAction(self.tr("Page Break"))
612
+ self.aInsNewPage = qtAddAction(self.mInsBreaks, self.tr("Page Break"))
612
613
  self.aInsNewPage.triggered.connect(
613
614
  lambda: self.requestDocInsert.emit(nwDocInsert.NEW_PAGE)
614
615
  )
615
616
 
616
617
  # Insert > Forced Line Break
617
- self.aInsLineBreak = self.mInsBreaks.addAction(self.tr("Forced Line Break"))
618
+ self.aInsLineBreak = qtAddAction(self.mInsBreaks, self.tr("Forced Line Break"))
618
619
  self.aInsLineBreak.triggered.connect(
619
620
  lambda: self.requestDocInsert.emit(nwDocInsert.LINE_BRK)
620
621
  )
621
622
 
622
623
  # Insert > Vertical Space (Single)
623
- self.aInsVSpaceS = self.mInsBreaks.addAction(self.tr("Vertical Space (Single)"))
624
+ self.aInsVSpaceS = qtAddAction(self.mInsBreaks, self.tr("Vertical Space (Single)"))
624
625
  self.aInsVSpaceS.triggered.connect(
625
626
  lambda: self.requestDocInsert.emit(nwDocInsert.VSPACE_S)
626
627
  )
627
628
 
628
629
  # Insert > Vertical Space (Multi)
629
- self.aInsVSpaceM = self.mInsBreaks.addAction(self.tr("Vertical Space (Multi)"))
630
+ self.aInsVSpaceM = qtAddAction(self.mInsBreaks, self.tr("Vertical Space (Multi)"))
630
631
  self.aInsVSpaceM.triggered.connect(
631
632
  lambda: self.requestDocInsert.emit(nwDocInsert.VSPACE_M)
632
633
  )
633
634
 
634
635
  # Insert > Placeholder Text
635
- self.aLipsumText = self.insMenu.addAction(self.tr("Placeholder Text"))
636
+ self.aLipsumText = qtAddAction(self.insMenu, self.tr("Placeholder Text"))
636
637
  self.aLipsumText.triggered.connect(
637
638
  lambda: self.requestDocInsert.emit(nwDocInsert.LIPSUM)
638
639
  )
639
640
 
640
641
  # Insert > Footnote
641
- self.aFootnote = self.insMenu.addAction(self.tr("Footnote"))
642
+ self.aFootnote = qtAddAction(self.insMenu, self.tr("Footnote"))
642
643
  self.aFootnote.triggered.connect(
643
644
  lambda: self.requestDocInsert.emit(nwDocInsert.FOOTNOTE)
644
645
  )
@@ -648,10 +649,10 @@ class GuiMainMenu(QMenuBar):
648
649
  def _buildFormatMenu(self) -> None:
649
650
  """Assemble the Format menu."""
650
651
  # Format
651
- self.fmtMenu = self.addMenu(self.tr("&Format"))
652
+ self.fmtMenu = qtAddMenu(self, self.tr("&Format"))
652
653
 
653
654
  # Format > Bold
654
- self.aFmtBold = self.fmtMenu.addAction(self.tr("Bold"))
655
+ self.aFmtBold = qtAddAction(self.fmtMenu, self.tr("Bold"))
655
656
  self.aFmtBold.setShortcut("Ctrl+B")
656
657
  self.aFmtBold.triggered.connect(
657
658
  lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
@@ -659,7 +660,7 @@ class GuiMainMenu(QMenuBar):
659
660
  self.mainGui.addAction(self.aFmtBold)
660
661
 
661
662
  # Format > Italic
662
- self.aFmtItalic = self.fmtMenu.addAction(self.tr("Italic"))
663
+ self.aFmtItalic = qtAddAction(self.fmtMenu, self.tr("Italic"))
663
664
  self.aFmtItalic.setShortcut("Ctrl+I")
664
665
  self.aFmtItalic.triggered.connect(
665
666
  lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
@@ -667,7 +668,7 @@ class GuiMainMenu(QMenuBar):
667
668
  self.mainGui.addAction(self.aFmtItalic)
668
669
 
669
670
  # Format > Strikethrough
670
- self.aFmtStrike = self.fmtMenu.addAction(self.tr("Strikethrough"))
671
+ self.aFmtStrike = qtAddAction(self.fmtMenu, self.tr("Strikethrough"))
671
672
  self.aFmtStrike.setShortcut("Ctrl+D")
672
673
  self.aFmtStrike.triggered.connect(
673
674
  lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
@@ -678,15 +679,15 @@ class GuiMainMenu(QMenuBar):
678
679
  self.fmtMenu.addSeparator()
679
680
 
680
681
  # Format > Double Quotes
681
- self.aFmtDQuote = self.fmtMenu.addAction(self.tr("Wrap Double Quotes"))
682
- self.aFmtDQuote.setShortcut("Ctrl+\"")
682
+ self.aFmtDQuote = qtAddAction(self.fmtMenu, self.tr("Wrap Double Quotes"))
683
+ self.aFmtDQuote.setShortcut('Ctrl+"')
683
684
  self.aFmtDQuote.triggered.connect(
684
685
  lambda: self.requestDocAction.emit(nwDocAction.D_QUOTE)
685
686
  )
686
687
  self.mainGui.addAction(self.aFmtDQuote)
687
688
 
688
689
  # Format > Single Quotes
689
- self.aFmtSQuote = self.fmtMenu.addAction(self.tr("Wrap Single Quotes"))
690
+ self.aFmtSQuote = qtAddAction(self.fmtMenu, self.tr("Wrap Single Quotes"))
690
691
  self.aFmtSQuote.setShortcut("Ctrl+'")
691
692
  self.aFmtSQuote.triggered.connect(
692
693
  lambda: self.requestDocAction.emit(nwDocAction.S_QUOTE)
@@ -697,46 +698,46 @@ class GuiMainMenu(QMenuBar):
697
698
  self.fmtMenu.addSeparator()
698
699
 
699
700
  # Shortcodes
700
- self.mShortcodes = self.fmtMenu.addMenu(self.tr("More Formats ..."))
701
+ self.mShortcodes = qtAddMenu(self.fmtMenu, self.tr("More Formats ..."))
701
702
 
702
703
  # Shortcode Bold
703
- self.aScBold = self.mShortcodes.addAction(self.tr("Bold (Shortcode)"))
704
+ self.aScBold = qtAddAction(self.mShortcodes, self.tr("Bold (Shortcode)"))
704
705
  self.aScBold.triggered.connect(
705
706
  lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
706
707
  )
707
708
 
708
709
  # Shortcode Italic
709
- self.aScItalic = self.mShortcodes.addAction(self.tr("Italics (Shortcode)"))
710
+ self.aScItalic = qtAddAction(self.mShortcodes, self.tr("Italics (Shortcode)"))
710
711
  self.aScItalic.triggered.connect(
711
712
  lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
712
713
  )
713
714
 
714
715
  # Shortcode Strikethrough
715
- self.aScStrike = self.mShortcodes.addAction(self.tr("Strikethrough (Shortcode)"))
716
+ self.aScStrike = qtAddAction(self.mShortcodes, self.tr("Strikethrough (Shortcode)"))
716
717
  self.aScStrike.triggered.connect(
717
718
  lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE)
718
719
  )
719
720
 
720
721
  # Shortcode Underline
721
- self.aScULine = self.mShortcodes.addAction(self.tr("Underline"))
722
+ self.aScULine = qtAddAction(self.mShortcodes, self.tr("Underline"))
722
723
  self.aScULine.triggered.connect(
723
724
  lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
724
725
  )
725
726
 
726
727
  # Shortcode Mark
727
- self.aScMark = self.mShortcodes.addAction(self.tr("Highlight"))
728
+ self.aScMark = qtAddAction(self.mShortcodes, self.tr("Highlight"))
728
729
  self.aScMark.triggered.connect(
729
730
  lambda: self.requestDocAction.emit(nwDocAction.SC_MARK)
730
731
  )
731
732
 
732
733
  # Shortcode Superscript
733
- self.aScSuper = self.mShortcodes.addAction(self.tr("Superscript"))
734
+ self.aScSuper = qtAddAction(self.mShortcodes, self.tr("Superscript"))
734
735
  self.aScSuper.triggered.connect(
735
736
  lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
736
737
  )
737
738
 
738
739
  # Shortcode Subscript
739
- self.aScSub = self.mShortcodes.addAction(self.tr("Subscript"))
740
+ self.aScSub = qtAddAction(self.mShortcodes, self.tr("Subscript"))
740
741
  self.aScSub.triggered.connect(
741
742
  lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
742
743
  )
@@ -745,7 +746,7 @@ class GuiMainMenu(QMenuBar):
745
746
  self.fmtMenu.addSeparator()
746
747
 
747
748
  # Format > Heading 1 (Partition)
748
- self.aFmtHead1 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H1"]))
749
+ self.aFmtHead1 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H1"]))
749
750
  self.aFmtHead1.setShortcut("Ctrl+1")
750
751
  self.aFmtHead1.triggered.connect(
751
752
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H1)
@@ -753,7 +754,7 @@ class GuiMainMenu(QMenuBar):
753
754
  self.mainGui.addAction(self.aFmtHead1)
754
755
 
755
756
  # Format > Heading 2 (Chapter)
756
- self.aFmtHead2 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H2"]))
757
+ self.aFmtHead2 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H2"]))
757
758
  self.aFmtHead2.setShortcut("Ctrl+2")
758
759
  self.aFmtHead2.triggered.connect(
759
760
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H2)
@@ -761,7 +762,7 @@ class GuiMainMenu(QMenuBar):
761
762
  self.mainGui.addAction(self.aFmtHead2)
762
763
 
763
764
  # Format > Heading 3 (Scene)
764
- self.aFmtHead3 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H3"]))
765
+ self.aFmtHead3 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H3"]))
765
766
  self.aFmtHead3.setShortcut("Ctrl+3")
766
767
  self.aFmtHead3.triggered.connect(
767
768
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H3)
@@ -769,7 +770,7 @@ class GuiMainMenu(QMenuBar):
769
770
  self.mainGui.addAction(self.aFmtHead3)
770
771
 
771
772
  # Format > Heading 4 (Section)
772
- self.aFmtHead4 = self.fmtMenu.addAction(trConst(nwStyles.T_LABEL["H4"]))
773
+ self.aFmtHead4 = qtAddAction(self.fmtMenu, trConst(nwStyles.T_LABEL["H4"]))
773
774
  self.aFmtHead4.setShortcut("Ctrl+4")
774
775
  self.aFmtHead4.triggered.connect(
775
776
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_H4)
@@ -780,19 +781,19 @@ class GuiMainMenu(QMenuBar):
780
781
  self.fmtMenu.addSeparator()
781
782
 
782
783
  # Format > Novel Title
783
- self.aFmtTitle = self.fmtMenu.addAction(self.tr("Novel Title"))
784
+ self.aFmtTitle = qtAddAction(self.fmtMenu, self.tr("Novel Title"))
784
785
  self.aFmtTitle.triggered.connect(
785
786
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TTL)
786
787
  )
787
788
 
788
789
  # Format > Unnumbered Chapter
789
- self.aFmtUnNum = self.fmtMenu.addAction(self.tr("Unnumbered Chapter"))
790
+ self.aFmtUnNum = qtAddAction(self.fmtMenu, self.tr("Unnumbered Chapter"))
790
791
  self.aFmtUnNum.triggered.connect(
791
792
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_UNN)
792
793
  )
793
794
 
794
795
  # Format > Alternative Scene
795
- self.aFmtHardSc = self.fmtMenu.addAction(self.tr("Alternative Scene"))
796
+ self.aFmtHardSc = qtAddAction(self.fmtMenu, self.tr("Alternative Scene"))
796
797
  self.aFmtHardSc.triggered.connect(
797
798
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_HSC)
798
799
  )
@@ -801,7 +802,7 @@ class GuiMainMenu(QMenuBar):
801
802
  self.fmtMenu.addSeparator()
802
803
 
803
804
  # Format > Align Left
804
- self.aFmtAlignLeft = self.fmtMenu.addAction(self.tr("Align Left"))
805
+ self.aFmtAlignLeft = qtAddAction(self.fmtMenu, self.tr("Align Left"))
805
806
  self.aFmtAlignLeft.setShortcut("Ctrl+5")
806
807
  self.aFmtAlignLeft.triggered.connect(
807
808
  lambda: self.requestDocAction.emit(nwDocAction.ALIGN_L)
@@ -809,7 +810,7 @@ class GuiMainMenu(QMenuBar):
809
810
  self.mainGui.addAction(self.aFmtAlignLeft)
810
811
 
811
812
  # Format > Align Centre
812
- self.aFmtAlignCentre = self.fmtMenu.addAction(self.tr("Align Centre"))
813
+ self.aFmtAlignCentre = qtAddAction(self.fmtMenu, self.tr("Align Centre"))
813
814
  self.aFmtAlignCentre.setShortcut("Ctrl+6")
814
815
  self.aFmtAlignCentre.triggered.connect(
815
816
  lambda: self.requestDocAction.emit(nwDocAction.ALIGN_C)
@@ -817,7 +818,7 @@ class GuiMainMenu(QMenuBar):
817
818
  self.mainGui.addAction(self.aFmtAlignCentre)
818
819
 
819
820
  # Format > Align Right
820
- self.aFmtAlignRight = self.fmtMenu.addAction(self.tr("Align Right"))
821
+ self.aFmtAlignRight = qtAddAction(self.fmtMenu, self.tr("Align Right"))
821
822
  self.aFmtAlignRight.setShortcut("Ctrl+7")
822
823
  self.aFmtAlignRight.triggered.connect(
823
824
  lambda: self.requestDocAction.emit(nwDocAction.ALIGN_R)
@@ -828,7 +829,7 @@ class GuiMainMenu(QMenuBar):
828
829
  self.fmtMenu.addSeparator()
829
830
 
830
831
  # Format > Indent Left
831
- self.aFmtIndentLeft = self.fmtMenu.addAction(self.tr("Indent Left"))
832
+ self.aFmtIndentLeft = qtAddAction(self.fmtMenu, self.tr("Indent Left"))
832
833
  self.aFmtIndentLeft.setShortcut("Ctrl+8")
833
834
  self.aFmtIndentLeft.triggered.connect(
834
835
  lambda: self.requestDocAction.emit(nwDocAction.INDENT_L)
@@ -836,7 +837,7 @@ class GuiMainMenu(QMenuBar):
836
837
  self.mainGui.addAction(self.aFmtIndentLeft)
837
838
 
838
839
  # Format > Indent Right
839
- self.aFmtIndentRight = self.fmtMenu.addAction(self.tr("Indent Right"))
840
+ self.aFmtIndentRight = qtAddAction(self.fmtMenu, self.tr("Indent Right"))
840
841
  self.aFmtIndentRight.setShortcut("Ctrl+9")
841
842
  self.aFmtIndentRight.triggered.connect(
842
843
  lambda: self.requestDocAction.emit(nwDocAction.INDENT_R)
@@ -847,7 +848,7 @@ class GuiMainMenu(QMenuBar):
847
848
  self.fmtMenu.addSeparator()
848
849
 
849
850
  # Format > Comment
850
- self.aFmtComment = self.fmtMenu.addAction(self.tr("Toggle Comment"))
851
+ self.aFmtComment = qtAddAction(self.fmtMenu, self.tr("Toggle Comment"))
851
852
  self.aFmtComment.setShortcut("Ctrl+/")
852
853
  self.aFmtComment.triggered.connect(
853
854
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_COM)
@@ -855,14 +856,14 @@ class GuiMainMenu(QMenuBar):
855
856
  self.mainGui.addAction(self.aFmtComment)
856
857
 
857
858
  # Format > Ignore Text
858
- self.aFmtIgnore = self.fmtMenu.addAction(self.tr("Toggle Ignore Text"))
859
+ self.aFmtIgnore = qtAddAction(self.fmtMenu, self.tr("Toggle Ignore Text"))
859
860
  self.aFmtIgnore.setShortcut("Ctrl+Shift+D")
860
861
  self.aFmtIgnore.triggered.connect(
861
862
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_IGN)
862
863
  )
863
864
 
864
865
  # Format > Remove Block Format
865
- self.aFmtNoFormat = self.fmtMenu.addAction(self.tr("Remove Block Format"))
866
+ self.aFmtNoFormat = qtAddAction(self.fmtMenu, self.tr("Remove Block Format"))
866
867
  self.aFmtNoFormat.setShortcuts(["Ctrl+0", "Ctrl+Shift+/"])
867
868
  self.aFmtNoFormat.triggered.connect(
868
869
  lambda: self.requestDocAction.emit(nwDocAction.BLOCK_TXT)
@@ -873,19 +874,19 @@ class GuiMainMenu(QMenuBar):
873
874
  self.fmtMenu.addSeparator()
874
875
 
875
876
  # Format > Replace Straight Single Quotes
876
- self.aFmtReplSng = self.fmtMenu.addAction(self.tr("Replace Straight Single Quotes"))
877
+ self.aFmtReplSng = qtAddAction(self.fmtMenu, self.tr("Replace Straight Single Quotes"))
877
878
  self.aFmtReplSng.triggered.connect(
878
879
  lambda: self.requestDocAction.emit(nwDocAction.REPL_SNG)
879
880
  )
880
881
 
881
882
  # Format > Replace Straight Double Quotes
882
- self.aFmtReplDbl = self.fmtMenu.addAction(self.tr("Replace Straight Double Quotes"))
883
+ self.aFmtReplDbl = qtAddAction(self.fmtMenu, self.tr("Replace Straight Double Quotes"))
883
884
  self.aFmtReplDbl.triggered.connect(
884
885
  lambda: self.requestDocAction.emit(nwDocAction.REPL_DBL)
885
886
  )
886
887
 
887
888
  # Format > Remove In-Paragraph Breaks
888
- self.aFmtRmBreaks = self.fmtMenu.addAction(self.tr("Remove In-Paragraph Breaks"))
889
+ self.aFmtRmBreaks = qtAddAction(self.fmtMenu, self.tr("Remove In-Paragraph Breaks"))
889
890
  self.aFmtRmBreaks.triggered.connect(
890
891
  lambda: self.requestDocAction.emit(nwDocAction.RM_BREAKS)
891
892
  )
@@ -895,28 +896,28 @@ class GuiMainMenu(QMenuBar):
895
896
  def _buildSearchMenu(self) -> None:
896
897
  """Assemble the Search menu."""
897
898
  # Search
898
- self.srcMenu = self.addMenu(self.tr("&Search"))
899
+ self.srcMenu = qtAddMenu(self, self.tr("&Search"))
899
900
 
900
901
  # Search > Find
901
- self.aFind = self.srcMenu.addAction(self.tr("Find"))
902
+ self.aFind = qtAddAction(self.srcMenu, self.tr("Find"))
902
903
  self.aFind.setShortcut("Ctrl+F")
903
904
  self.aFind.triggered.connect(qtLambda(self.mainGui.docEditor.beginSearch))
904
905
  self.mainGui.addAction(self.aFind)
905
906
 
906
907
  # Search > Replace
907
- self.aReplace = self.srcMenu.addAction(self.tr("Replace"))
908
+ self.aReplace = qtAddAction(self.srcMenu, self.tr("Replace"))
908
909
  self.aReplace.setShortcut("Ctrl+=" if CONFIG.osDarwin else "Ctrl+H")
909
910
  self.aReplace.triggered.connect(qtLambda(self.mainGui.docEditor.beginReplace))
910
911
  self.mainGui.addAction(self.aReplace)
911
912
 
912
913
  # Search > Find Next
913
- self.aFindNext = self.srcMenu.addAction(self.tr("Find Next"))
914
+ self.aFindNext = qtAddAction(self.srcMenu, self.tr("Find Next"))
914
915
  self.aFindNext.setShortcuts(["Ctrl+G", "F3"] if CONFIG.osDarwin else ["F3", "Ctrl+G"])
915
916
  self.aFindNext.triggered.connect(qtLambda(self.mainGui.docEditor.findNext))
916
917
  self.mainGui.addAction(self.aFindNext)
917
918
 
918
919
  # Search > Find Prev
919
- self.aFindPrev = self.srcMenu.addAction(self.tr("Find Previous"))
920
+ self.aFindPrev = qtAddAction(self.srcMenu, self.tr("Find Previous"))
920
921
  self.aFindPrev.setShortcuts(
921
922
  ["Ctrl+Shift+G", "Shift+F3"] if CONFIG.osDarwin else ["Shift+F3", "Ctrl+Shift+G"]
922
923
  )
@@ -924,7 +925,7 @@ class GuiMainMenu(QMenuBar):
924
925
  self.mainGui.addAction(self.aFindPrev)
925
926
 
926
927
  # Search > Replace Next
927
- self.aReplaceNext = self.srcMenu.addAction(self.tr("Replace Next"))
928
+ self.aReplaceNext = qtAddAction(self.srcMenu, self.tr("Replace Next"))
928
929
  self.aReplaceNext.setShortcut("Ctrl+Shift+1")
929
930
  self.aReplaceNext.triggered.connect(qtLambda(self.mainGui.docEditor.replaceNext))
930
931
  self.mainGui.addAction(self.aReplaceNext)
@@ -933,54 +934,54 @@ class GuiMainMenu(QMenuBar):
933
934
  self.srcMenu.addSeparator()
934
935
 
935
936
  # Search > Find in Project
936
- self.aFindProj = self.srcMenu.addAction(self.tr("Find in Project"))
937
+ self.aFindProj = qtAddAction(self.srcMenu, self.tr("Find in Project"))
937
938
  self.aFindProj.setShortcut("Ctrl+Shift+F")
938
- self.aFindProj.triggered.connect(lambda: self.requestViewChange.emit(nwView.SEARCH))
939
+ self.aFindProj.triggered.connect(qtLambda(self.requestViewChange.emit, nwView.SEARCH))
939
940
 
940
941
  return
941
942
 
942
943
  def _buildToolsMenu(self) -> None:
943
944
  """Assemble the Tools menu."""
944
945
  # Tools
945
- self.toolsMenu = self.addMenu(self.tr("&Tools"))
946
+ self.toolsMenu = qtAddMenu(self, self.tr("&Tools"))
946
947
 
947
948
  # Tools > Check Spelling
948
- self.aSpellCheck = self.toolsMenu.addAction(self.tr("Check Spelling"))
949
+ self.aSpellCheck = qtAddAction(self.toolsMenu, self.tr("Check Spelling"))
949
950
  self.aSpellCheck.setCheckable(True)
950
951
  self.aSpellCheck.setChecked(SHARED.project.data.spellCheck)
951
952
  self.aSpellCheck.triggered.connect(self._toggleSpellCheck) # triggered, not toggled!
952
953
  self.aSpellCheck.setShortcut("Ctrl+F7")
953
954
  self.mainGui.addAction(self.aSpellCheck)
954
955
 
955
- self.mSelectLanguage = self.toolsMenu.addMenu(self.tr("Spell Check Language"))
956
+ self.mSelectLanguage = qtAddMenu(self.toolsMenu, self.tr("Spell Check Language"))
956
957
  languages = SHARED.spelling.listDictionaries()
957
958
  languages.insert(0, ("None", self.tr("Default")))
958
- for n, (tag, language) in enumerate(languages):
959
+ for tag, language in languages:
959
960
  aSpell = QAction(self.mSelectLanguage)
960
961
  aSpell.setText(language)
961
- aSpell.triggered.connect(lambda n, tag=tag: self._changeSpelling(tag))
962
+ aSpell.triggered.connect(qtLambda(self._changeSpelling, tag))
962
963
  self.mSelectLanguage.addAction(aSpell)
963
964
 
964
965
  # Tools > Re-Run Spell Check
965
- self.aReRunSpell = self.toolsMenu.addAction(self.tr("Re-Run Spell Check"))
966
+ self.aReRunSpell = qtAddAction(self.toolsMenu, self.tr("Re-Run Spell Check"))
966
967
  self.aReRunSpell.setShortcut("F7")
967
968
  self.aReRunSpell.triggered.connect(qtLambda(self.mainGui.docEditor.spellCheckDocument))
968
969
  self.mainGui.addAction(self.aReRunSpell)
969
970
 
970
971
  # Tools > Project Word List
971
- self.aEditWordList = self.toolsMenu.addAction(self.tr("Project Word List"))
972
+ self.aEditWordList = qtAddAction(self.toolsMenu, self.tr("Project Word List"))
972
973
  self.aEditWordList.triggered.connect(self.mainGui.showProjectWordListDialog)
973
974
 
974
975
  # Tools > Add Dictionaries
975
976
  if CONFIG.osWindows or CONFIG.isDebug:
976
- self.aAddDicts = self.toolsMenu.addAction(self.tr("Add Dictionaries"))
977
+ self.aAddDicts = qtAddAction(self.toolsMenu, self.tr("Add Dictionaries"))
977
978
  self.aAddDicts.triggered.connect(self.mainGui.showDictionariesDialog)
978
979
 
979
980
  # Tools > Separator
980
981
  self.toolsMenu.addSeparator()
981
982
 
982
983
  # Tools > Rebuild Index
983
- self.aRebuildIndex = self.toolsMenu.addAction(self.tr("Rebuild Index"))
984
+ self.aRebuildIndex = qtAddAction(self.toolsMenu, self.tr("Rebuild Index"))
984
985
  self.aRebuildIndex.setShortcut("F9")
985
986
  self.aRebuildIndex.triggered.connect(qtLambda(self.mainGui.rebuildIndex))
986
987
 
@@ -988,21 +989,21 @@ class GuiMainMenu(QMenuBar):
988
989
  self.toolsMenu.addSeparator()
989
990
 
990
991
  # Tools > Backup Project
991
- self.aBackupProject = self.toolsMenu.addAction(self.tr("Backup Project"))
992
+ self.aBackupProject = qtAddAction(self.toolsMenu, self.tr("Backup Project"))
992
993
  self.aBackupProject.triggered.connect(qtLambda(SHARED.project.backupProject, True))
993
994
 
994
995
  # Tools > Build Manuscript
995
- self.aBuildManuscript = self.toolsMenu.addAction(self.tr("Build Manuscript"))
996
+ self.aBuildManuscript = qtAddAction(self.toolsMenu, self.tr("Build Manuscript"))
996
997
  self.aBuildManuscript.setShortcut("F5")
997
998
  self.aBuildManuscript.triggered.connect(self.mainGui.showBuildManuscriptDialog)
998
999
 
999
1000
  # Tools > Writing Statistics
1000
- self.aWritingStats = self.toolsMenu.addAction(self.tr("Writing Statistics"))
1001
+ self.aWritingStats = qtAddAction(self.toolsMenu, self.tr("Writing Statistics"))
1001
1002
  self.aWritingStats.setShortcut("F6")
1002
1003
  self.aWritingStats.triggered.connect(self.mainGui.showWritingStatsDialog)
1003
1004
 
1004
1005
  # Tools > Preferences
1005
- self.aPreferences = self.toolsMenu.addAction(self.tr("Preferences"))
1006
+ self.aPreferences = qtAddAction(self.toolsMenu, self.tr("Preferences"))
1006
1007
  self.aPreferences.setShortcut("Ctrl+,")
1007
1008
  self.aPreferences.setMenuRole(QAction.MenuRole.PreferencesRole)
1008
1009
  self.aPreferences.triggered.connect(self.mainGui.showPreferencesDialog)
@@ -1013,15 +1014,15 @@ class GuiMainMenu(QMenuBar):
1013
1014
  def _buildHelpMenu(self) -> None:
1014
1015
  """Assemble the Help menu."""
1015
1016
  # Help
1016
- self.helpMenu = self.addMenu(self.tr("&Help"))
1017
+ self.helpMenu = qtAddMenu(self, self.tr("&Help"))
1017
1018
 
1018
1019
  # Help > About
1019
- self.aAboutNW = self.helpMenu.addAction(self.tr("About novelWriter"))
1020
+ self.aAboutNW = qtAddAction(self.helpMenu, self.tr("About novelWriter"))
1020
1021
  self.aAboutNW.setMenuRole(QAction.MenuRole.AboutRole)
1021
1022
  self.aAboutNW.triggered.connect(self.mainGui.showAboutNWDialog)
1022
1023
 
1023
- # Help > About Qt5
1024
- self.aAboutQt = self.helpMenu.addAction(self.tr("About Qt5"))
1024
+ # Help > About Qt
1025
+ self.aAboutQt = qtAddAction(self.helpMenu, self.tr("About Qt"))
1025
1026
  self.aAboutQt.setMenuRole(QAction.MenuRole.AboutQtRole)
1026
1027
  self.aAboutQt.triggered.connect(self.mainGui.showAboutQtDialog)
1027
1028
 
@@ -1029,14 +1030,14 @@ class GuiMainMenu(QMenuBar):
1029
1030
  self.helpMenu.addSeparator()
1030
1031
 
1031
1032
  # Help > User Manual (Online)
1032
- self.aHelpDocs = self.helpMenu.addAction(self.tr("User Manual (Online)"))
1033
+ self.aHelpDocs = qtAddAction(self.helpMenu, self.tr("User Manual (Online)"))
1033
1034
  self.aHelpDocs.setShortcut("F1")
1034
1035
  self.aHelpDocs.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_DOCS))
1035
1036
  self.mainGui.addAction(self.aHelpDocs)
1036
1037
 
1037
1038
  # Help > User Manual (PDF)
1038
1039
  if isinstance(CONFIG.pdfDocs, Path):
1039
- self.aPdfDocs = self.helpMenu.addAction(self.tr("User Manual (PDF)"))
1040
+ self.aPdfDocs = qtAddAction(self.helpMenu, self.tr("User Manual (PDF)"))
1040
1041
  self.aPdfDocs.setShortcut("Shift+F1")
1041
1042
  self.aPdfDocs.triggered.connect(self._openUserManualFile)
1042
1043
  self.mainGui.addAction(self.aPdfDocs)
@@ -1045,15 +1046,15 @@ class GuiMainMenu(QMenuBar):
1045
1046
  self.helpMenu.addSeparator()
1046
1047
 
1047
1048
  # Document > Report an Issue
1048
- self.aIssue = self.helpMenu.addAction(self.tr("Report an Issue (GitHub)"))
1049
+ self.aIssue = qtAddAction(self.helpMenu, self.tr("Report an Issue (GitHub)"))
1049
1050
  self.aIssue.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_REPORT))
1050
1051
 
1051
1052
  # Document > Ask a Question
1052
- self.aQuestion = self.helpMenu.addAction(self.tr("Ask a Question (GitHub)"))
1053
+ self.aQuestion = qtAddAction(self.helpMenu, self.tr("Ask a Question (GitHub)"))
1053
1054
  self.aQuestion.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_HELP))
1054
1055
 
1055
1056
  # Document > Main Website
1056
- self.aWebsite = self.helpMenu.addAction(self.tr("The novelWriter Website"))
1057
+ self.aWebsite = qtAddAction(self.helpMenu, self.tr("The novelWriter Website"))
1057
1058
  self.aWebsite.triggered.connect(qtLambda(SHARED.openWebsite, nwConst.URL_WEB))
1058
1059
 
1059
1060
  return