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
@@ -191,10 +191,18 @@ def apply_white_balance_to_doc(doc, preset: Optional[Dict] = None):
191
191
  class WhiteBalanceDialog(QDialog):
192
192
  def __init__(self, parent, doc, icon: QIcon | None = None):
193
193
  super().__init__(parent)
194
+ self._main = parent
194
195
  self.doc = doc
196
+
197
+ # Connect to active document change signal
198
+ if hasattr(self._main, "currentDocumentChanged"):
199
+ self._main.currentDocumentChanged.connect(self._on_active_doc_changed)
195
200
  if icon:
196
201
  self.setWindowIcon(icon)
197
- self.setWindowTitle("White Balance")
202
+ self.setWindowTitle(self.tr("White Balance"))
203
+ self.setWindowFlag(Qt.WindowType.Window, True)
204
+ self.setWindowModality(Qt.WindowModality.NonModal)
205
+ self.setModal(False)
198
206
  self.resize(900, 600)
199
207
 
200
208
  self._build_ui()
@@ -212,29 +220,29 @@ class WhiteBalanceDialog(QDialog):
212
220
 
213
221
  # Type selector
214
222
  row = QHBoxLayout()
215
- row.addWidget(QLabel("White Balance Type:"))
223
+ row.addWidget(QLabel(self.tr("White Balance Type:")))
216
224
  self.type_combo = QComboBox()
217
- self.type_combo.addItems(["Star-Based", "Manual", "Auto"])
225
+ self.type_combo.addItems([self.tr("Star-Based"), self.tr("Manual"), self.tr("Auto")])
218
226
  row.addWidget(self.type_combo); row.addStretch()
219
227
  self.main_layout.addLayout(row)
220
228
 
221
229
  # Manual group
222
- self.manual_group = QGroupBox("Manual Gains")
230
+ self.manual_group = QGroupBox(self.tr("Manual Gains"))
223
231
  g = QGridLayout(self.manual_group)
224
232
  self.r_spin = QDoubleSpinBox(); self._cfg_gain(self.r_spin, 1.0)
225
233
  self.g_spin = QDoubleSpinBox(); self._cfg_gain(self.g_spin, 1.0)
226
234
  self.b_spin = QDoubleSpinBox(); self._cfg_gain(self.b_spin, 1.0)
227
- g.addWidget(QLabel("Red gain:"), 0, 0); g.addWidget(self.r_spin, 0, 1)
228
- g.addWidget(QLabel("Green gain:"), 1, 0); g.addWidget(self.g_spin, 1, 1)
229
- g.addWidget(QLabel("Blue gain:"), 2, 0); g.addWidget(self.b_spin, 2, 1)
235
+ g.addWidget(QLabel(self.tr("Red gain:")), 0, 0); g.addWidget(self.r_spin, 0, 1)
236
+ g.addWidget(QLabel(self.tr("Green gain:")), 1, 0); g.addWidget(self.g_spin, 1, 1)
237
+ g.addWidget(QLabel(self.tr("Blue gain:")), 2, 0); g.addWidget(self.b_spin, 2, 1)
230
238
  self.main_layout.addWidget(self.manual_group)
231
239
 
232
240
  # Star-based controls + preview
233
- self.star_group = QGroupBox("Star-Based Settings")
241
+ self.star_group = QGroupBox(self.tr("Star-Based Settings"))
234
242
  sg = QVBoxLayout(self.star_group)
235
243
  # threshold slider
236
244
  thr_row = QHBoxLayout()
237
- thr_row.addWidget(QLabel("Detection threshold (σ):"))
245
+ thr_row.addWidget(QLabel(self.tr("Detection threshold (σ):")))
238
246
  self.thr_slider = QSlider(Qt.Orientation.Horizontal)
239
247
  self.thr_slider.setMinimum(1); self.thr_slider.setMaximum(100)
240
248
  self.thr_slider.setValue(50); self.thr_slider.setTickInterval(10)
@@ -243,14 +251,14 @@ class WhiteBalanceDialog(QDialog):
243
251
  thr_row.addWidget(self.thr_slider); thr_row.addWidget(self.thr_label)
244
252
  sg.addLayout(thr_row)
245
253
 
246
- self.chk_reuse = QCheckBox("Reuse cached star detections"); self.chk_reuse.setChecked(True)
254
+ self.chk_reuse = QCheckBox(self.tr("Reuse cached star detections")); self.chk_reuse.setChecked(True)
247
255
  sg.addWidget(self.chk_reuse)
248
256
 
249
- self.chk_autostretch_overlay = QCheckBox("Autostretch overlay preview"); self.chk_autostretch_overlay.setChecked(True)
257
+ self.chk_autostretch_overlay = QCheckBox(self.tr("Autostretch overlay preview")); self.chk_autostretch_overlay.setChecked(True)
250
258
  sg.addWidget(self.chk_autostretch_overlay)
251
259
 
252
260
  # star count + image preview
253
- self.star_count = QLabel("Detecting stars")
261
+ self.star_count = QLabel(self.tr("Detecting stars..."))
254
262
  sg.addWidget(self.star_count)
255
263
 
256
264
  self.preview = QLabel(); self.preview.setMinimumSize(640, 360)
@@ -261,8 +269,8 @@ class WhiteBalanceDialog(QDialog):
261
269
  # Buttons
262
270
  btn_row = QHBoxLayout()
263
271
  btn_row.addStretch()
264
- self.btn_apply = QPushButton("Apply")
265
- self.btn_cancel = QPushButton("Cancel")
272
+ self.btn_apply = QPushButton(self.tr("Apply"))
273
+ self.btn_cancel = QPushButton(self.tr("Cancel"))
266
274
  btn_row.addWidget(self.btn_apply)
267
275
  btn_row.addWidget(self.btn_cancel)
268
276
  self.main_layout.addLayout(btn_row)
@@ -291,6 +299,18 @@ class WhiteBalanceDialog(QDialog):
291
299
  self.manual_group.setVisible(t == "Manual")
292
300
  self.star_group.setVisible(t == "Star-Based")
293
301
 
302
+ # ---- active document change ------------------------------------
303
+ def _on_active_doc_changed(self, doc):
304
+ """Called when user clicks a different image window."""
305
+ if doc is None or getattr(doc, "image", None) is None:
306
+ return
307
+ self.doc = doc
308
+ # Force fresh star detection by temporarily disabling cache
309
+ old_reuse = self.chk_reuse.isChecked()
310
+ self.chk_reuse.setChecked(False)
311
+ self._update_star_preview()
312
+ self.chk_reuse.setChecked(old_reuse)
313
+
294
314
  # ---- preview --------------------------------------------------------
295
315
  def _update_star_preview(self):
296
316
  if self.type_combo.currentText() != "Star-Based":
@@ -305,7 +325,7 @@ class WhiteBalanceDialog(QDialog):
305
325
  img, threshold=thr, autostretch=auto,
306
326
  reuse_cached_sources=reuse, return_star_colors=False
307
327
  )
308
- self.star_count.setText(f"Detected {count} stars.")
328
+ self.star_count.setText(self.tr("Detected {0} stars.").format(count))
309
329
  # to pixmap
310
330
  h, w, _ = overlay.shape
311
331
  qimg = QImage((overlay * 255).astype(np.uint8).data, w, h, 3 * w, QImage.Format.Format_RGB888)
@@ -314,7 +334,7 @@ class WhiteBalanceDialog(QDialog):
314
334
  Qt.TransformationMode.SmoothTransformation)
315
335
  self.preview.setPixmap(pm)
316
336
  except Exception as e:
317
- self.star_count.setText("Detection failed.")
337
+ self.star_count.setText(self.tr("Detection failed."))
318
338
  self.preview.clear()
319
339
 
320
340
  # ---- apply ----------------------------------------------------------
@@ -373,7 +393,8 @@ class WhiteBalanceDialog(QDialog):
373
393
 
374
394
  # Use the headless helper so doc metadata is consistent
375
395
  apply_white_balance_to_doc(self.doc, preset)
376
- self.accept()
396
+ # Dialog stays open - refresh document for next operation
397
+ self._refresh_document_from_active()
377
398
 
378
399
  elif mode == "Auto":
379
400
  preset = {"mode": "auto"}
@@ -382,7 +403,8 @@ class WhiteBalanceDialog(QDialog):
382
403
  _record_preset_for_replay(preset)
383
404
 
384
405
  apply_white_balance_to_doc(self.doc, preset)
385
- self.accept()
406
+ # Dialog stays open - refresh document for next operation
407
+ self._refresh_document_from_active()
386
408
 
387
409
  else: # --- Star-Based: compute here so we can plot like SASv2 ---
388
410
  thr = float(self.thr_slider.value())
@@ -446,11 +468,25 @@ class WhiteBalanceDialog(QDialog):
446
468
 
447
469
  QMessageBox.information(
448
470
  self,
449
- "White Balance",
450
- f"Star-Based WB applied.\nDetected {int(star_count)} stars.",
471
+ self.tr("White Balance"),
472
+ self.tr("Star-Based WB applied.\nDetected {0} stars.").format(int(star_count)),
451
473
  )
452
- self.accept()
474
+ # Dialog stays open - refresh document for next operation
475
+ self._refresh_document_from_active()
453
476
 
454
477
  except Exception as e:
455
- QMessageBox.critical(self, "White Balance", f"Failed to apply White Balance:\n{e}")
478
+ QMessageBox.critical(self, self.tr("White Balance"), self.tr("Failed to apply White Balance:\n{0}").format(e))
456
479
 
480
+ def _refresh_document_from_active(self):
481
+ """
482
+ Refresh the dialog's document reference to the currently active document.
483
+ This allows reusing the same dialog on different images.
484
+ """
485
+ try:
486
+ main = self.parent()
487
+ if main and hasattr(main, "_active_doc"):
488
+ new_doc = main._active_doc()
489
+ if new_doc is not None and new_doc is not self.doc:
490
+ self.doc = new_doc
491
+ except Exception:
492
+ pass
@@ -21,7 +21,7 @@ import logging
21
21
  import atexit
22
22
  from typing import TYPE_CHECKING, Optional, List, Any
23
23
 
24
- from PyQt6.QtCore import QThread, pyqtSignal, QTimer, Qt
24
+ from PyQt6.QtCore import QThread, pyqtSignal, QTimer, Qt, QCoreApplication
25
25
  from PyQt6.QtWidgets import QDialog, QVBoxLayout, QLabel, QMessageBox
26
26
 
27
27
  if TYPE_CHECKING:
@@ -65,7 +65,7 @@ class AboutDialog(QDialog):
65
65
 
66
66
  def __init__(self, parent: Optional[Any] = None, version: str = "", build_timestamp: str = ""):
67
67
  super().__init__(parent)
68
- self.setWindowTitle("About Seti Astro Suite")
68
+ self.setWindowTitle(self.tr("About Seti Astro Suite"))
69
69
 
70
70
  # Get version info if not provided
71
71
  if not version:
@@ -84,17 +84,17 @@ class AboutDialog(QDialog):
84
84
  # Build about text with optional build timestamp
85
85
  about_lines = [
86
86
  f"<h2>Seti Astro's Suite Pro {version}</h2>",
87
- "<p>Written by Franklin Marek</p>",
88
- "<p>Collaborators: Fabio Tempera</p>",
89
- "<p>Copyright © 2025 Seti Astro</p>",
87
+ f"<p>{self.tr('Written by Franklin Marek')}</p>",
88
+ f"<p>{self.tr('Collaborators: Fabio Tempera')}</p>",
89
+ f"<p>{self.tr('Copyright © 2025 Seti Astro')}</p>",
90
90
  ]
91
91
 
92
92
  if build_timestamp and build_timestamp != "Unknown":
93
- about_lines.append(f"<p><b>Build:</b> {build_timestamp}</p>")
93
+ about_lines.append(f"<p><b>{self.tr('Build:')}</b> {build_timestamp}</p>")
94
94
 
95
95
  about_lines.extend([
96
- "<p>Website: <a href='http://www.setiastro.com'>www.setiastro.com</a></p>",
97
- "<p>Donations: <a href='https://www.setiastro.com/checkout/donate?donatePageId=65ae7e7bac20370d8c04c1ab'>Click here to donate</a></p>",
96
+ f"<p>{self.tr('Website:')} <a href='http://www.setiastro.com'>www.setiastro.com</a></p>",
97
+ f"<p>{self.tr('Donations:')} <a href='https://www.setiastro.com/checkout/donate?donatePageId=65ae7e7bac20370d8c04c1ab'>{self.tr('Click here to donate')}</a></p>",
98
98
  ])
99
99
 
100
100
  about_text = "".join(about_lines)
@@ -254,7 +254,8 @@ def install_crash_handlers(app: 'QApplication') -> None:
254
254
  m.setIcon(QMessageBox.Icon.Critical)
255
255
  m.setWindowTitle(title)
256
256
  m.setText(head)
257
- m.setInformativeText("Details are available below and in saspro.log.")
257
+ from PyQt6.QtCore import QCoreApplication
258
+ m.setInformativeText(QCoreApplication.translate("CrashHandler", "Details are available below and in saspro.log."))
258
259
  if details:
259
260
  m.setDetailedText(details)
260
261
  m.setStandardButtons(QMessageBox.StandardButton.Ok)
@@ -266,7 +267,7 @@ def install_crash_handlers(app: 'QApplication') -> None:
266
267
  tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
267
268
  logging.error("Uncaught exception:\n%s", tb)
268
269
  _show_dialog(
269
- "Unhandled Exception",
270
+ QCoreApplication.translate("CrashHandler", "Unhandled Exception"),
270
271
  f"{exc_type.__name__}: {exc_value}",
271
272
  tb
272
273
  )
@@ -278,7 +279,7 @@ def install_crash_handlers(app: 'QApplication') -> None:
278
279
  tb = "".join(traceback.format_exception(args.exc_type, args.exc_value, args.exc_traceback))
279
280
  logging.error("Uncaught thread exception (%s):\n%s", args.thread.name, tb)
280
281
  _show_dialog(
281
- "Unhandled Thread Exception",
282
+ QCoreApplication.translate("CrashHandler", "Unhandled Thread Exception"),
282
283
  f"{args.exc_type.__name__}: {args.exc_value}",
283
284
  tb
284
285
  )