setiastrosuitepro 1.6.0__py3-none-any.whl → 1.6.4.post1__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.

Potentially problematic release.


This version of setiastrosuitepro might be problematic. Click here for more details.

Files changed (293) hide show
  1. setiastro/data/SASP_data.fits +0 -0
  2. setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +488 -0
  3. setiastro/data/catalogs/astrobin_filters.csv +890 -0
  4. setiastro/data/catalogs/astrobin_filters_page1_local.csv +51 -0
  5. setiastro/data/catalogs/cali2.csv +63 -0
  6. setiastro/data/catalogs/cali2color.csv +65 -0
  7. setiastro/data/catalogs/celestial_catalog - original.csv +16471 -0
  8. setiastro/data/catalogs/celestial_catalog.csv +24031 -0
  9. setiastro/data/catalogs/detected_stars.csv +24784 -0
  10. setiastro/data/catalogs/fits_header_data.csv +46 -0
  11. setiastro/data/catalogs/test.csv +8 -0
  12. setiastro/data/catalogs/updated_celestial_catalog.csv +16471 -0
  13. setiastro/images/Astro_Spikes.png +0 -0
  14. setiastro/images/Background_startup.jpg +0 -0
  15. setiastro/images/HRDiagram.png +0 -0
  16. setiastro/images/LExtract.png +0 -0
  17. setiastro/images/LInsert.png +0 -0
  18. setiastro/images/Oxygenation-atm-2.svg.png +0 -0
  19. setiastro/images/RGB080604.png +0 -0
  20. setiastro/images/abeicon.png +0 -0
  21. setiastro/images/aberration.png +0 -0
  22. setiastro/images/andromedatry.png +0 -0
  23. setiastro/images/andromedatry_satellited.png +0 -0
  24. setiastro/images/annotated.png +0 -0
  25. setiastro/images/aperture.png +0 -0
  26. setiastro/images/astrosuite.ico +0 -0
  27. setiastro/images/astrosuite.png +0 -0
  28. setiastro/images/astrosuitepro.icns +0 -0
  29. setiastro/images/astrosuitepro.ico +0 -0
  30. setiastro/images/astrosuitepro.png +0 -0
  31. setiastro/images/background.png +0 -0
  32. setiastro/images/background2.png +0 -0
  33. setiastro/images/benchmark.png +0 -0
  34. setiastro/images/big_moon_stabilizer_timeline.png +0 -0
  35. setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
  36. setiastro/images/blaster.png +0 -0
  37. setiastro/images/blink.png +0 -0
  38. setiastro/images/clahe.png +0 -0
  39. setiastro/images/collage.png +0 -0
  40. setiastro/images/colorwheel.png +0 -0
  41. setiastro/images/contsub.png +0 -0
  42. setiastro/images/convo.png +0 -0
  43. setiastro/images/copyslot.png +0 -0
  44. setiastro/images/cosmic.png +0 -0
  45. setiastro/images/cosmicsat.png +0 -0
  46. setiastro/images/crop1.png +0 -0
  47. setiastro/images/cropicon.png +0 -0
  48. setiastro/images/curves.png +0 -0
  49. setiastro/images/cvs.png +0 -0
  50. setiastro/images/debayer.png +0 -0
  51. setiastro/images/denoise_cnn_custom.png +0 -0
  52. setiastro/images/denoise_cnn_graph.png +0 -0
  53. setiastro/images/disk.png +0 -0
  54. setiastro/images/dse.png +0 -0
  55. setiastro/images/exoicon.png +0 -0
  56. setiastro/images/eye.png +0 -0
  57. setiastro/images/fliphorizontal.png +0 -0
  58. setiastro/images/flipvertical.png +0 -0
  59. setiastro/images/font.png +0 -0
  60. setiastro/images/freqsep.png +0 -0
  61. setiastro/images/functionbundle.png +0 -0
  62. setiastro/images/graxpert.png +0 -0
  63. setiastro/images/green.png +0 -0
  64. setiastro/images/gridicon.png +0 -0
  65. setiastro/images/halo.png +0 -0
  66. setiastro/images/hdr.png +0 -0
  67. setiastro/images/histogram.png +0 -0
  68. setiastro/images/hubble.png +0 -0
  69. setiastro/images/imagecombine.png +0 -0
  70. setiastro/images/invert.png +0 -0
  71. setiastro/images/isophote.png +0 -0
  72. setiastro/images/isophote_demo_figure.png +0 -0
  73. setiastro/images/isophote_demo_image.png +0 -0
  74. setiastro/images/isophote_demo_model.png +0 -0
  75. setiastro/images/isophote_demo_residual.png +0 -0
  76. setiastro/images/jwstpupil.png +0 -0
  77. setiastro/images/linearfit.png +0 -0
  78. setiastro/images/livestacking.png +0 -0
  79. setiastro/images/mask.png +0 -0
  80. setiastro/images/maskapply.png +0 -0
  81. setiastro/images/maskcreate.png +0 -0
  82. setiastro/images/maskremove.png +0 -0
  83. setiastro/images/morpho.png +0 -0
  84. setiastro/images/mosaic.png +0 -0
  85. setiastro/images/multiscale_decomp.png +0 -0
  86. setiastro/images/nbtorgb.png +0 -0
  87. setiastro/images/neutral.png +0 -0
  88. setiastro/images/nuke.png +0 -0
  89. setiastro/images/openfile.png +0 -0
  90. setiastro/images/pedestal.png +0 -0
  91. setiastro/images/pen.png +0 -0
  92. setiastro/images/pixelmath.png +0 -0
  93. setiastro/images/platesolve.png +0 -0
  94. setiastro/images/ppp.png +0 -0
  95. setiastro/images/pro.png +0 -0
  96. setiastro/images/project.png +0 -0
  97. setiastro/images/psf.png +0 -0
  98. setiastro/images/redo.png +0 -0
  99. setiastro/images/redoicon.png +0 -0
  100. setiastro/images/rescale.png +0 -0
  101. setiastro/images/rgbalign.png +0 -0
  102. setiastro/images/rgbcombo.png +0 -0
  103. setiastro/images/rgbextract.png +0 -0
  104. setiastro/images/rotate180.png +0 -0
  105. setiastro/images/rotatearbitrary.png +0 -0
  106. setiastro/images/rotateclockwise.png +0 -0
  107. setiastro/images/rotatecounterclockwise.png +0 -0
  108. setiastro/images/satellite.png +0 -0
  109. setiastro/images/script.png +0 -0
  110. setiastro/images/selectivecolor.png +0 -0
  111. setiastro/images/simbad.png +0 -0
  112. setiastro/images/slot0.png +0 -0
  113. setiastro/images/slot1.png +0 -0
  114. setiastro/images/slot2.png +0 -0
  115. setiastro/images/slot3.png +0 -0
  116. setiastro/images/slot4.png +0 -0
  117. setiastro/images/slot5.png +0 -0
  118. setiastro/images/slot6.png +0 -0
  119. setiastro/images/slot7.png +0 -0
  120. setiastro/images/slot8.png +0 -0
  121. setiastro/images/slot9.png +0 -0
  122. setiastro/images/spcc.png +0 -0
  123. setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
  124. setiastro/images/spinner.gif +0 -0
  125. setiastro/images/stacking.png +0 -0
  126. setiastro/images/staradd.png +0 -0
  127. setiastro/images/staralign.png +0 -0
  128. setiastro/images/starnet.png +0 -0
  129. setiastro/images/starregistration.png +0 -0
  130. setiastro/images/starspike.png +0 -0
  131. setiastro/images/starstretch.png +0 -0
  132. setiastro/images/statstretch.png +0 -0
  133. setiastro/images/supernova.png +0 -0
  134. setiastro/images/uhs.png +0 -0
  135. setiastro/images/undoicon.png +0 -0
  136. setiastro/images/upscale.png +0 -0
  137. setiastro/images/viewbundle.png +0 -0
  138. setiastro/images/whitebalance.png +0 -0
  139. setiastro/images/wimi_icon_256x256.png +0 -0
  140. setiastro/images/wimilogo.png +0 -0
  141. setiastro/images/wims.png +0 -0
  142. setiastro/images/wrench_icon.png +0 -0
  143. setiastro/images/xisfliberator.png +0 -0
  144. setiastro/qml/ResourceMonitor.qml +126 -0
  145. setiastro/saspro/__main__.py +228 -67
  146. setiastro/saspro/_generated/build_info.py +2 -1
  147. setiastro/saspro/abe.py +76 -25
  148. setiastro/saspro/aberration_ai.py +14 -14
  149. setiastro/saspro/add_stars.py +15 -12
  150. setiastro/saspro/astrobin_exporter.py +61 -58
  151. setiastro/saspro/astrospike_python.py +3 -1
  152. setiastro/saspro/autostretch.py +4 -2
  153. setiastro/saspro/backgroundneutral.py +65 -14
  154. setiastro/saspro/batch_convert.py +8 -5
  155. setiastro/saspro/batch_renamer.py +39 -36
  156. setiastro/saspro/blemish_blaster.py +15 -12
  157. setiastro/saspro/blink_comparator_pro.py +605 -379
  158. setiastro/saspro/cheat_sheet.py +62 -17
  159. setiastro/saspro/clahe.py +34 -8
  160. setiastro/saspro/comet_stacking.py +103 -38
  161. setiastro/saspro/common_tr.py +107 -0
  162. setiastro/saspro/continuum_subtract.py +7 -7
  163. setiastro/saspro/convo.py +12 -9
  164. setiastro/saspro/copyastro.py +3 -0
  165. setiastro/saspro/cosmicclarity.py +77 -52
  166. setiastro/saspro/crop_dialog_pro.py +80 -45
  167. setiastro/saspro/curve_editor_pro.py +51 -33
  168. setiastro/saspro/debayer.py +6 -3
  169. setiastro/saspro/doc_manager.py +49 -19
  170. setiastro/saspro/exoplanet_detector.py +11 -11
  171. setiastro/saspro/fitsmodifier.py +48 -44
  172. setiastro/saspro/fix_bom.py +32 -0
  173. setiastro/saspro/frequency_separation.py +18 -12
  174. setiastro/saspro/function_bundle.py +18 -16
  175. setiastro/saspro/generate_translations.py +3092 -0
  176. setiastro/saspro/ghs_dialog_pro.py +19 -16
  177. setiastro/saspro/graxpert.py +3 -0
  178. setiastro/saspro/gui/main_window.py +471 -126
  179. setiastro/saspro/gui/mixins/dock_mixin.py +123 -11
  180. setiastro/saspro/gui/mixins/file_mixin.py +25 -20
  181. setiastro/saspro/gui/mixins/geometry_mixin.py +115 -15
  182. setiastro/saspro/gui/mixins/header_mixin.py +6 -6
  183. setiastro/saspro/gui/mixins/mask_mixin.py +8 -8
  184. setiastro/saspro/gui/mixins/menu_mixin.py +62 -33
  185. setiastro/saspro/gui/mixins/toolbar_mixin.py +382 -226
  186. setiastro/saspro/gui/mixins/update_mixin.py +26 -26
  187. setiastro/saspro/gui/statistics_dialog.py +47 -0
  188. setiastro/saspro/halobgon.py +29 -3
  189. setiastro/saspro/header_viewer.py +21 -18
  190. setiastro/saspro/histogram.py +29 -26
  191. setiastro/saspro/history_explorer.py +2 -0
  192. setiastro/saspro/i18n.py +168 -0
  193. setiastro/saspro/image_combine.py +3 -0
  194. setiastro/saspro/image_peeker_pro.py +52 -44
  195. setiastro/saspro/imageops/stretch.py +5 -13
  196. setiastro/saspro/isophote.py +3 -0
  197. setiastro/saspro/legacy/numba_utils.py +64 -47
  198. setiastro/saspro/linear_fit.py +3 -0
  199. setiastro/saspro/live_stacking.py +13 -2
  200. setiastro/saspro/mask_creation.py +180 -22
  201. setiastro/saspro/mfdeconv.py +5 -0
  202. setiastro/saspro/morphology.py +38 -13
  203. setiastro/saspro/multiscale_decomp.py +713 -256
  204. setiastro/saspro/nbtorgb_stars.py +12 -2
  205. setiastro/saspro/numba_utils.py +149 -48
  206. setiastro/saspro/ops/scripts.py +77 -17
  207. setiastro/saspro/ops/settings.py +177 -100
  208. setiastro/saspro/perfect_palette_picker.py +25 -7
  209. setiastro/saspro/pixelmath.py +114 -110
  210. setiastro/saspro/plate_solver.py +118 -108
  211. setiastro/saspro/remove_green.py +24 -7
  212. setiastro/saspro/remove_stars.py +136 -162
  213. setiastro/saspro/remove_stars_preset.py +55 -13
  214. setiastro/saspro/resources.py +46 -15
  215. setiastro/saspro/rgb_combination.py +19 -18
  216. setiastro/saspro/rgbalign.py +11 -11
  217. setiastro/saspro/save_options.py +5 -4
  218. setiastro/saspro/selective_color.py +84 -25
  219. setiastro/saspro/sfcc.py +119 -72
  220. setiastro/saspro/shortcuts.py +345 -36
  221. setiastro/saspro/signature_insert.py +4 -1
  222. setiastro/saspro/stacking_suite.py +2066 -1119
  223. setiastro/saspro/star_alignment.py +291 -331
  224. setiastro/saspro/star_spikes.py +137 -53
  225. setiastro/saspro/star_stretch.py +47 -10
  226. setiastro/saspro/stat_stretch.py +52 -16
  227. setiastro/saspro/status_log_dock.py +1 -1
  228. setiastro/saspro/subwindow.py +97 -36
  229. setiastro/saspro/supernovaasteroidhunter.py +68 -61
  230. setiastro/saspro/swap_manager.py +77 -42
  231. setiastro/saspro/translations/all_source_strings.json +4726 -0
  232. setiastro/saspro/translations/ar_translations.py +4096 -0
  233. setiastro/saspro/translations/de_translations.py +3728 -0
  234. setiastro/saspro/translations/es_translations.py +4169 -0
  235. setiastro/saspro/translations/fr_translations.py +4090 -0
  236. setiastro/saspro/translations/hi_translations.py +3803 -0
  237. setiastro/saspro/translations/integrate_translations.py +271 -0
  238. setiastro/saspro/translations/it_translations.py +4728 -0
  239. setiastro/saspro/translations/ja_translations.py +3834 -0
  240. setiastro/saspro/translations/pt_translations.py +3847 -0
  241. setiastro/saspro/translations/ru_translations.py +3082 -0
  242. setiastro/saspro/translations/saspro_ar.qm +0 -0
  243. setiastro/saspro/translations/saspro_ar.ts +16019 -0
  244. setiastro/saspro/translations/saspro_de.qm +0 -0
  245. setiastro/saspro/translations/saspro_de.ts +14548 -0
  246. setiastro/saspro/translations/saspro_es.qm +0 -0
  247. setiastro/saspro/translations/saspro_es.ts +16202 -0
  248. setiastro/saspro/translations/saspro_fr.qm +0 -0
  249. setiastro/saspro/translations/saspro_fr.ts +15870 -0
  250. setiastro/saspro/translations/saspro_hi.qm +0 -0
  251. setiastro/saspro/translations/saspro_hi.ts +14855 -0
  252. setiastro/saspro/translations/saspro_it.qm +0 -0
  253. setiastro/saspro/translations/saspro_it.ts +19046 -0
  254. setiastro/saspro/translations/saspro_ja.qm +0 -0
  255. setiastro/saspro/translations/saspro_ja.ts +14980 -0
  256. setiastro/saspro/translations/saspro_pt.qm +0 -0
  257. setiastro/saspro/translations/saspro_pt.ts +15024 -0
  258. setiastro/saspro/translations/saspro_ru.qm +0 -0
  259. setiastro/saspro/translations/saspro_ru.ts +11835 -0
  260. setiastro/saspro/translations/saspro_sw.qm +0 -0
  261. setiastro/saspro/translations/saspro_sw.ts +15237 -0
  262. setiastro/saspro/translations/saspro_uk.qm +0 -0
  263. setiastro/saspro/translations/saspro_uk.ts +15248 -0
  264. setiastro/saspro/translations/saspro_zh.qm +0 -0
  265. setiastro/saspro/translations/saspro_zh.ts +15289 -0
  266. setiastro/saspro/translations/sw_translations.py +3897 -0
  267. setiastro/saspro/translations/uk_translations.py +3929 -0
  268. setiastro/saspro/translations/zh_translations.py +3910 -0
  269. setiastro/saspro/versioning.py +77 -0
  270. setiastro/saspro/view_bundle.py +20 -17
  271. setiastro/saspro/wavescale_hdr.py +54 -33
  272. setiastro/saspro/wavescale_hdr_preset.py +6 -5
  273. setiastro/saspro/wavescalede.py +54 -31
  274. setiastro/saspro/wavescalede_preset.py +9 -7
  275. setiastro/saspro/whitebalance.py +58 -22
  276. setiastro/saspro/widgets/common_utilities.py +12 -11
  277. setiastro/saspro/widgets/minigame/game.js +991 -0
  278. setiastro/saspro/widgets/minigame/index.html +53 -0
  279. setiastro/saspro/widgets/minigame/style.css +241 -0
  280. setiastro/saspro/widgets/preview_dialogs.py +8 -8
  281. setiastro/saspro/widgets/resource_monitor.py +263 -0
  282. setiastro/saspro/widgets/spinboxes.py +18 -0
  283. setiastro/saspro/widgets/wavelet_utils.py +52 -20
  284. setiastro/saspro/wimi.py +7996 -0
  285. setiastro/saspro/wims.py +578 -0
  286. setiastro/saspro/window_shelf.py +2 -2
  287. {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/METADATA +15 -3
  288. setiastrosuitepro-1.6.4.post1.dist-info/RECORD +368 -0
  289. setiastrosuitepro-1.6.0.dist-info/RECORD +0 -174
  290. {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/WHEEL +0 -0
  291. {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/entry_points.txt +0 -0
  292. {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/LICENSE +0 -0
  293. {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/license.txt +0 -0
@@ -25,6 +25,28 @@ class MenuMixin:
25
25
  # This method will be implemented as part of the main window
26
26
  # For now, this is a placeholder showing the mixin pattern
27
27
  pass
28
+
29
+ def _show_statistics(self):
30
+ from setiastro.saspro.gui.statistics_dialog import StatisticsDialog
31
+ dlg = StatisticsDialog(self)
32
+ dlg.exec()
33
+
34
+ def _hook_tool_stats(self, menus):
35
+ if not hasattr(self, "_on_tool_triggered"):
36
+ return
37
+
38
+ seen = set()
39
+ for menu in menus:
40
+ for action in self._iter_menu_actions(menu):
41
+ if action in seen: continue
42
+ seen.add(action)
43
+ if action.isSeparator(): continue
44
+
45
+ try:
46
+ action.triggered.connect(self._on_tool_triggered)
47
+ except Exception:
48
+ pass
49
+
28
50
 
29
51
  def _rebuild_recent_menus(self):
30
52
  """Rebuild the recent files and projects menus."""
@@ -73,7 +95,7 @@ class MenuMixin:
73
95
  mb = self.menuBar()
74
96
 
75
97
  # File
76
- m_file = mb.addMenu("&File")
98
+ m_file = mb.addMenu(self.tr("&File"))
77
99
  m_file.addAction(self.act_open)
78
100
  m_file.addSeparator()
79
101
  m_file.addAction(self.act_save)
@@ -85,8 +107,8 @@ class MenuMixin:
85
107
  m_file.addAction(self.act_project_load)
86
108
  # --- Recent submenus ----------------------------------------
87
109
  m_file.addSeparator()
88
- self.m_recent_images_menu = m_file.addMenu("Open Recent Images")
89
- self.m_recent_projects_menu = m_file.addMenu("Open Recent Projects")
110
+ self.m_recent_images_menu = m_file.addMenu(self.tr("Open Recent Images"))
111
+ self.m_recent_projects_menu = m_file.addMenu(self.tr("Open Recent Projects"))
90
112
 
91
113
  m_file.addSeparator()
92
114
  m_file.addAction(self.act_exit)
@@ -95,12 +117,12 @@ class MenuMixin:
95
117
  self._rebuild_recent_menus()
96
118
 
97
119
  # Edit (with icons)
98
- m_edit = mb.addMenu("&Edit")
120
+ m_edit = mb.addMenu(self.tr("&Edit"))
99
121
  m_edit.addAction(self.act_undo)
100
122
  m_edit.addAction(self.act_redo)
101
123
 
102
124
  # Functions
103
- m_fn = mb.addMenu("&Functions")
125
+ m_fn = mb.addMenu(self.tr("&Functions"))
104
126
 
105
127
  m_fn.addAction(self.act_abe)
106
128
  m_fn.addAction(self.act_add_stars)
@@ -133,14 +155,14 @@ class MenuMixin:
133
155
  m_fn.addAction(self.act_white_balance)
134
156
 
135
157
 
136
- mCosmic = mb.addMenu("&Smart Tools")
158
+ mCosmic = mb.addMenu(self.tr("&Smart Tools"))
137
159
  mCosmic.addAction(self.actAberrationAI)
138
160
  mCosmic.addAction(self.actCosmicUI)
139
161
  mCosmic.addAction(self.actCosmicSat)
140
162
  mCosmic.addAction(self.act_graxpert)
141
163
  mCosmic.addAction(self.act_remove_stars)
142
164
 
143
- m_tools = mb.addMenu("&Tools")
165
+ m_tools = mb.addMenu(self.tr("&Tools"))
144
166
 
145
167
  m_tools.addAction(self.act_blink)
146
168
  m_tools.addAction(self.act_contsub)
@@ -154,7 +176,7 @@ class MenuMixin:
154
176
  m_tools.addAction(self.act_view_bundles)
155
177
  m_tools.addAction(self.act_function_bundles)
156
178
 
157
- m_geom = mb.addMenu("&Geometry")
179
+ m_geom = mb.addMenu(self.tr("&Geometry"))
158
180
  m_geom.addAction(self.act_geom_invert)
159
181
  m_geom.addSeparator()
160
182
  m_geom.addAction(self.act_geom_flip_h)
@@ -163,12 +185,13 @@ class MenuMixin:
163
185
  m_geom.addAction(self.act_geom_rot_cw)
164
186
  m_geom.addAction(self.act_geom_rot_ccw)
165
187
  m_geom.addAction(self.act_geom_rot_180)
188
+ m_geom.addAction(self.act_geom_rot_any)
166
189
  m_geom.addSeparator()
167
190
  m_geom.addAction(self.act_geom_rescale)
168
191
  m_geom.addSeparator()
169
192
  m_geom.addAction(self.act_debayer)
170
193
 
171
- m_star = mb.addMenu("&Star Stuff")
194
+ m_star = mb.addMenu(self.tr("&Star Stuff"))
172
195
 
173
196
  m_star.addAction(self.act_astrospike)
174
197
  m_star.addAction(self.act_exo_detector)
@@ -185,7 +208,7 @@ class MenuMixin:
185
208
  m_star.addAction(self.act_stacking_suite)
186
209
  m_star.addAction(self.act_supernova_hunter)
187
210
 
188
- m_masks = mb.addMenu("&Masks")
211
+ m_masks = mb.addMenu(self.tr("&Masks"))
189
212
  m_masks.addAction(self.act_create_mask)
190
213
  m_masks.addSeparator()
191
214
  m_masks.addAction(self.act_apply_mask)
@@ -196,16 +219,16 @@ class MenuMixin:
196
219
  m_masks.addSeparator()
197
220
  m_masks.addAction(self.act_invert_mask)
198
221
 
199
- m_wim = mb.addMenu("&What's In My...")
222
+ m_wim = mb.addMenu(self.tr("&What's In My..."))
200
223
  m_wim.addAction(self.act_whats_in_my_sky)
201
224
  m_wim.addAction(self.act_wimi)
202
225
 
203
- m_scripts = mb.addMenu("&Scripts")
226
+ m_scripts = mb.addMenu(self.tr("&Scripts"))
204
227
  self.menu_scripts = m_scripts
205
228
  self.scriptman.rebuild_menu(m_scripts)
206
229
 
207
230
 
208
- m_header = mb.addMenu("&Header Mods && Misc")
231
+ m_header = mb.addMenu(self.tr("&Header Mods && Misc"))
209
232
  m_header.addAction(self.act_astrobin_exporter)
210
233
  m_header.addAction(self.act_batch_convert)
211
234
  m_header.addAction(self.act_batch_renamer)
@@ -214,20 +237,20 @@ class MenuMixin:
214
237
  m_header.addAction(self.act_fits_modifier)
215
238
 
216
239
 
217
- m_hist = mb.addMenu("&History")
240
+ m_hist = mb.addMenu(self.tr("&History"))
218
241
  m_hist.addAction(self.act_history_explorer)
219
242
 
220
- m_short = mb.addMenu("&Shortcuts")
243
+ m_short = mb.addMenu(self.tr("&Shortcuts"))
221
244
 
222
- act_cheats = QAction("Keyboard Shortcut Cheat Sheet...", self)
245
+ act_cheats = QAction(self.tr("Keyboard Shortcut Cheat Sheet..."), self)
223
246
  act_cheats.triggered.connect(self._show_cheat_sheet)
224
247
  m_short.addAction(act_cheats)
225
248
 
226
249
  # act_save_sc = QAction("Save Shortcuts Now", self, triggered=self.shortcuts.save_shortcuts)
227
250
  # Keep it if you like, but add explicit export/import:
228
- act_export_sc = QAction("Export Shortcuts...", self, triggered=self._export_shortcuts_dialog)
229
- act_import_sc = QAction("Import Shortcuts...", self, triggered=self._import_shortcuts_dialog)
230
- act_clear_sc = QAction("Clear All Shortcuts", self, triggered=self.shortcuts.clear)
251
+ act_export_sc = QAction(self.tr("Export Shortcuts..."), self, triggered=self._export_shortcuts_dialog)
252
+ act_import_sc = QAction(self.tr("Import Shortcuts..."), self, triggered=self._import_shortcuts_dialog)
253
+ act_clear_sc = QAction(self.tr("Clear All Shortcuts"), self, triggered=self.shortcuts.clear)
231
254
 
232
255
  m_short.addAction(act_export_sc)
233
256
  m_short.addAction(act_import_sc)
@@ -235,7 +258,7 @@ class MenuMixin:
235
258
  # m_short.addAction(act_save_sc) # optional: keep
236
259
  m_short.addAction(act_clear_sc)
237
260
 
238
- m_view = mb.addMenu("&View")
261
+ m_view = mb.addMenu(self.tr("&View"))
239
262
  m_view.addAction(self.act_cascade)
240
263
  m_view.addAction(self.act_tile)
241
264
  m_view.addAction(self.act_tile_vert)
@@ -250,11 +273,11 @@ class MenuMixin:
250
273
  self._link_btn.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
251
274
 
252
275
  link_menu = QMenu(self._link_btn)
253
- a_none = link_menu.addAction("None")
254
- a_A = link_menu.addAction("Group A")
255
- a_B = link_menu.addAction("Group B")
256
- a_C = link_menu.addAction("Group C")
257
- a_D = link_menu.addAction("Group D")
276
+ a_none = link_menu.addAction(self.tr("None"))
277
+ a_A = link_menu.addAction(self.tr("Group A"))
278
+ a_B = link_menu.addAction(self.tr("Group B"))
279
+ a_C = link_menu.addAction(self.tr("Group C"))
280
+ a_D = link_menu.addAction(self.tr("Group D"))
258
281
  self._link_btn.setMenu(link_menu)
259
282
 
260
283
  a_none.setCheckable(True)
@@ -288,16 +311,22 @@ class MenuMixin:
288
311
  # first-time sync of label/checked state
289
312
  self._sync_link_action_state()
290
313
 
291
- m_settings = mb.addMenu("&Settings")
292
- m_settings.addAction("Preferences...", self._open_settings)
314
+ m_settings = mb.addMenu(self.tr("&Settings"))
315
+ m_settings.addAction(self.tr("Preferences..."), self._open_settings)
293
316
 
294
- m_about = mb.addMenu("&About")
317
+ m_about = mb.addMenu(self.tr("&About"))
295
318
  m_about.addAction(self.act_docs)
296
319
  m_about.addSeparator()
297
- m_about.addAction("About...", self._about)
320
+ m_about.addAction(self.tr("About..."), self._about)
298
321
  m_about.addAction(self.act_check_updates)
299
322
 
300
323
 
324
+ m_about.addSeparator()
325
+ m_about.addAction(self.tr("Statistics..."), self._show_statistics)
326
+
327
+ # Connect tool stats
328
+ self._hook_tool_stats([m_fn, m_tools, mCosmic, m_geom, m_star, m_masks, m_header, m_scripts])
329
+
301
330
  # initialize enabled state + names
302
331
  self.update_undo_redo_action_labels()
303
332
 
@@ -320,7 +349,7 @@ class MenuMixin:
320
349
  # ---- Images ----------------------------------------
321
350
  self.m_recent_images_menu.clear()
322
351
  if not self._recent_image_paths:
323
- act = self.m_recent_images_menu.addAction("No recent images")
352
+ act = self.m_recent_images_menu.addAction(self.tr("No recent images"))
324
353
  act.setEnabled(False)
325
354
  else:
326
355
  for path in self._recent_image_paths:
@@ -331,13 +360,13 @@ class MenuMixin:
331
360
  lambda checked=False, p=path: self._open_recent_image(p)
332
361
  )
333
362
  self.m_recent_images_menu.addSeparator()
334
- clear_act = self.m_recent_images_menu.addAction("Clear List")
363
+ clear_act = self.m_recent_images_menu.addAction(self.tr("Clear List"))
335
364
  clear_act.triggered.connect(self._clear_recent_images)
336
365
 
337
366
  # ---- Projects ----------------------------------------
338
367
  self.m_recent_projects_menu.clear()
339
368
  if not self._recent_project_paths:
340
- act = self.m_recent_projects_menu.addAction("No recent projects")
369
+ act = self.m_recent_projects_menu.addAction(self.tr("No recent projects"))
341
370
  act.setEnabled(False)
342
371
  else:
343
372
  for path in self._recent_project_paths:
@@ -348,7 +377,7 @@ class MenuMixin:
348
377
  lambda checked=False, p=path: self._open_recent_project(p)
349
378
  )
350
379
  self.m_recent_projects_menu.addSeparator()
351
- clear_act = self.m_recent_projects_menu.addAction("Clear List")
380
+ clear_act = self.m_recent_projects_menu.addAction(self.tr("Clear List"))
352
381
  clear_act.triggered.connect(self._clear_recent_projects)
353
382
 
354
383
  def _iter_menu_actions(self, menu: QMenu):