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
@@ -35,7 +35,7 @@ class BatchRenamerDialog(QDialog):
35
35
  """
36
36
  def __init__(self, parent=None):
37
37
  super().__init__(parent)
38
- self.setWindowTitle("Batch Rename from FITS")
38
+ self.setWindowTitle(self.tr("Batch Rename from FITS"))
39
39
  self.settings = QSettings()
40
40
  self.files: list[str] = []
41
41
  self.headers: dict[str, fits.Header] = {}
@@ -46,6 +46,9 @@ class BatchRenamerDialog(QDialog):
46
46
  self.setWindowFlag(Qt.WindowType.WindowTitleHint, True)
47
47
  self.setWindowFlag(Qt.WindowType.WindowMinMaxButtonsHint, True)
48
48
  self.setWindowFlag(Qt.WindowType.WindowContextHelpButtonHint, False)
49
+ self.setWindowFlag(Qt.WindowType.Window, True)
50
+ self.setWindowModality(Qt.WindowModality.NonModal)
51
+ self.setModal(False)
49
52
  self.setSizeGripEnabled(True)
50
53
 
51
54
  self._build_ui()
@@ -58,37 +61,37 @@ class BatchRenamerDialog(QDialog):
58
61
  # Top: source and destination
59
62
  io_row = QHBoxLayout()
60
63
  self.src_edit = QLineEdit(self)
61
- self.src_edit.setPlaceholderText("Select a folder or add files…")
62
- btn_scan = QPushButton("Scan Folder…", self); btn_scan.clicked.connect(self._scan_folder)
63
- btn_add = QPushButton("Add Files…", self); btn_add.clicked.connect(self._add_files)
64
- btn_clear = QPushButton("Clear Selections", self); btn_clear.clicked.connect(self._clear_selection)
65
- io_row.addWidget(QLabel("Source:"))
64
+ self.src_edit.setPlaceholderText(self.tr("Select a folder or add files…"))
65
+ btn_scan = QPushButton(self.tr("Scan Folder…"), self); btn_scan.clicked.connect(self._scan_folder)
66
+ btn_add = QPushButton(self.tr("Add Files…"), self); btn_add.clicked.connect(self._add_files)
67
+ btn_clear = QPushButton(self.tr("Clear Selections"), self); btn_clear.clicked.connect(self._clear_selection)
68
+ io_row.addWidget(QLabel(self.tr("Source:")))
66
69
  io_row.addWidget(self.src_edit, 1)
67
70
  io_row.addWidget(btn_scan)
68
71
  io_row.addWidget(btn_add)
69
72
  io_row.addWidget(btn_clear)
70
73
 
71
74
  self.dest_edit = QLineEdit(self)
72
- self.dest_edit.setPlaceholderText("(optional) Rename into this folder; leave empty to rename in place")
73
- btn_dest = QPushButton("Browse…", self); btn_dest.clicked.connect(self._pick_dest)
75
+ self.dest_edit.setPlaceholderText(self.tr("(optional) Rename into this folder; leave empty to rename in place"))
76
+ btn_dest = QPushButton(self.tr("Browse…"), self); btn_dest.clicked.connect(self._pick_dest)
74
77
  io_row2 = QHBoxLayout()
75
- io_row2.addWidget(QLabel("Destination:"))
78
+ io_row2.addWidget(QLabel(self.tr("Destination:")))
76
79
  io_row2.addWidget(self.dest_edit, 1)
77
80
  io_row2.addWidget(btn_dest)
78
81
 
79
82
  root.addLayout(io_row); root.addLayout(io_row2)
80
83
 
81
84
  # Middle: template & options
82
- pat_box = QGroupBox("Filename pattern")
85
+ pat_box = QGroupBox(self.tr("Filename pattern"))
83
86
  pat_lay = QHBoxLayout(pat_box)
84
87
 
85
88
  self.pattern_edit = QLineEdit(self)
86
- self.pattern_edit.setPlaceholderText("e.g. LIGHT_{FILTER}_{EXPOSURE:.0f}s_{DATE-OBS:%Y%m%d}_{#03}.{ext}")
89
+ self.pattern_edit.setPlaceholderText(self.tr("e.g. LIGHT_{FILTER}_{EXPOSURE:.0f}s_{DATE-OBS:%Y%m%d}_{#03}.{ext}"))
87
90
  self.pattern_edit.textChanged.connect(self._refresh_preview)
88
91
 
89
- self.lower_cb = QCheckBox("lowercase", self); self.lower_cb.toggled.connect(self._refresh_preview)
90
- self.slug_cb = QCheckBox("spaces→_", self); self.slug_cb.toggled.connect(self._refresh_preview)
91
- self.keep_ext_cb = QCheckBox("append .{ext} if missing", self); self.keep_ext_cb.setChecked(True)
92
+ self.lower_cb = QCheckBox(self.tr("lowercase"), self); self.lower_cb.toggled.connect(self._refresh_preview)
93
+ self.slug_cb = QCheckBox(self.tr("spaces→_"), self); self.slug_cb.toggled.connect(self._refresh_preview)
94
+ self.keep_ext_cb = QCheckBox(self.tr("append .{ext} if missing"), self); self.keep_ext_cb.setChecked(True)
92
95
  self.index_start = QSpinBox(self); self.index_start.setRange(0, 999999); self.index_start.setValue(1)
93
96
  self.index_start.valueChanged.connect(self._refresh_preview)
94
97
 
@@ -96,18 +99,18 @@ class BatchRenamerDialog(QDialog):
96
99
  self.token_combo.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContents)
97
100
  self.token_combo.setMinimumContentsLength(12)
98
101
  self.token_combo.setEditable(False)
99
- self.token_combo.setToolTip("Insert token")
102
+ self.token_combo.setToolTip(self.tr("Insert token"))
100
103
  self.token_combo.activated.connect(
101
104
  lambda idx: self._insert_token(self.token_combo.itemText(idx))
102
105
  )
103
106
 
104
- insert_btn = QPushButton("Insert", self)
107
+ insert_btn = QPushButton(self.tr("Insert"), self)
105
108
  insert_btn.clicked.connect(lambda: self._insert_token(self.token_combo.currentText()))
106
109
 
107
- pat_lay.addWidget(QLabel("Template:")); pat_lay.addWidget(self.pattern_edit, 1)
110
+ pat_lay.addWidget(QLabel(self.tr("Template:"))); pat_lay.addWidget(self.pattern_edit, 1)
108
111
  pat_lay.addWidget(self.token_combo); pat_lay.addWidget(insert_btn)
109
112
  pat_lay.addWidget(self.lower_cb); pat_lay.addWidget(self.slug_cb)
110
- pat_lay.addWidget(QLabel("Index start:")); pat_lay.addWidget(self.index_start)
113
+ pat_lay.addWidget(QLabel(self.tr("Index start:"))); pat_lay.addWidget(self.index_start)
111
114
  pat_lay.addWidget(self.keep_ext_cb)
112
115
 
113
116
  root.addWidget(pat_box)
@@ -120,14 +123,14 @@ class BatchRenamerDialog(QDialog):
120
123
  left.setFixedWidth(180)
121
124
  self.keys_list = QListWidget(self)
122
125
  self.keys_list.itemDoubleClicked.connect(self._insert_key_from_list)
123
- lyt.addWidget(QLabel("Available FITS keywords (double-click to insert):"))
126
+ lyt.addWidget(QLabel(self.tr("Available FITS keywords (double-click to insert):")))
124
127
  lyt.addWidget(self.keys_list, 1)
125
128
  split.addWidget(left)
126
129
 
127
130
  # Table
128
131
  right = QWidget(self); rlyt = QVBoxLayout(right)
129
132
  self.table = QTableWidget(self); self.table.setColumnCount(4)
130
- self.table.setHorizontalHeaderLabels(["Old path", "→", "New name", "Status"])
133
+ self.table.setHorizontalHeaderLabels([self.tr("Old path"), "→", self.tr("New name"), self.tr("Status")])
131
134
  self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
132
135
  self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
133
136
  self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
@@ -138,7 +141,7 @@ class BatchRenamerDialog(QDialog):
138
141
  self.table.setTextElideMode(Qt.TextElideMode.ElideMiddle) # PyQt6
139
142
  except AttributeError:
140
143
  pass
141
- rlyt.addWidget(QLabel("Preview"))
144
+ rlyt.addWidget(QLabel(self.tr("Preview")))
142
145
  rlyt.addWidget(self.table, 1)
143
146
  split.addWidget(right)
144
147
  split.setSizes([250, 700])
@@ -150,8 +153,8 @@ class BatchRenamerDialog(QDialog):
150
153
 
151
154
  # Buttons
152
155
  btns = QDialogButtonBox(self)
153
- self.btn_preview = btns.addButton("Preview", QDialogButtonBox.ButtonRole.ActionRole)
154
- self.btn_rename = btns.addButton("Rename", QDialogButtonBox.ButtonRole.AcceptRole)
156
+ self.btn_preview = btns.addButton(self.tr("Preview"), QDialogButtonBox.ButtonRole.ActionRole)
157
+ self.btn_rename = btns.addButton(self.tr("Rename"), QDialogButtonBox.ButtonRole.AcceptRole)
155
158
  self.btn_close = btns.addButton(QDialogButtonBox.StandardButton.Close)
156
159
  self.btn_preview.clicked.connect(self._refresh_preview)
157
160
  self.btn_rename.clicked.connect(self._do_rename)
@@ -189,7 +192,7 @@ class BatchRenamerDialog(QDialog):
189
192
  # ---------- file loading ----------
190
193
  def _scan_folder(self):
191
194
  start = self.src_edit.text().strip()
192
- path = QFileDialog.getExistingDirectory(self, "Select Folder", start or "")
195
+ path = QFileDialog.getExistingDirectory(self, self.tr("Select Folder"), start or "")
193
196
  if not path: return
194
197
  self.src_edit.setText(path)
195
198
  self._scan_existing(path)
@@ -207,7 +210,7 @@ class BatchRenamerDialog(QDialog):
207
210
  def _add_files(self):
208
211
  start = self.src_edit.text().strip() or ""
209
212
  files, _ = QFileDialog.getOpenFileNames(
210
- self, "Add FITS files", start, "FITS files (*.fit *.fits *.fts *.fz);;All files (*)"
213
+ self, self.tr("Add FITS files"), start, self.tr("FITS files (*.fit *.fits *.fts *.fz);;All files (*)")
211
214
  )
212
215
  if not files: return
213
216
  new = sorted(set(self.files) | set(files))
@@ -237,7 +240,7 @@ class BatchRenamerDialog(QDialog):
237
240
 
238
241
  def _pick_dest(self):
239
242
  start = self.dest_edit.text().strip() or self.src_edit.text().strip()
240
- d = QFileDialog.getExistingDirectory(self, "Choose Destination Folder", start or "")
243
+ d = QFileDialog.getExistingDirectory(self, self.tr("Choose Destination Folder"), start or "")
241
244
  if not d: return
242
245
  self.dest_edit.setText(d)
243
246
  self._save_settings()
@@ -342,9 +345,9 @@ class BatchRenamerDialog(QDialog):
342
345
  self.table.item(r, 2).setText(new)
343
346
  status = ""
344
347
  conflict = (count > 1)
345
- if conflict: status = "name collision"
346
- elif os.path.exists(new): status = "will overwrite"
347
- else: status = "ok"
348
+ if conflict: status = self.tr("name collision")
349
+ elif os.path.exists(new): status = self.tr("will overwrite")
350
+ else: status = self.tr("ok")
348
351
  it = QTableWidgetItem(status)
349
352
  if conflict or status == "will overwrite":
350
353
  it.setForeground(Qt.GlobalColor.red)
@@ -361,8 +364,8 @@ class BatchRenamerDialog(QDialog):
361
364
  for t in targets: counts[t] += 1
362
365
  collisions = [t for t,c in counts.items() if c > 1]
363
366
  if collisions:
364
- QMessageBox.warning(self, "Collisions",
365
- "Two or more files would map to the same name. Adjust your pattern.")
367
+ QMessageBox.warning(self, self.tr("Collisions"),
368
+ self.tr("Two or more files would map to the same name. Adjust your pattern."))
366
369
  return
367
370
 
368
371
  failures = []
@@ -374,17 +377,17 @@ class BatchRenamerDialog(QDialog):
374
377
  os.makedirs(os.path.dirname(newp), exist_ok=True)
375
378
  try:
376
379
  shutil.move(oldp, newp)
377
- self.table.item(r, 3).setText("renamed")
380
+ self.table.item(r, 3).setText(self.tr("renamed"))
378
381
  except Exception as e:
379
- self.table.item(r, 3).setText(f"ERROR: {e}")
382
+ self.table.item(r, 3).setText(self.tr("ERROR: {0}").format(e))
380
383
  self.table.item(r, 3).setForeground(Qt.GlobalColor.red)
381
384
  failures.append((oldp, str(e)))
382
385
 
383
386
  if failures:
384
- QMessageBox.warning(self, "Done with errors",
385
- f"Some files could not be renamed ({len(failures)} errors).")
387
+ QMessageBox.warning(self, self.tr("Done with errors"),
388
+ self.tr("Some files could not be renamed ({0} errors).").format(len(failures)))
386
389
  else:
387
- QMessageBox.information(self, "Done", "All files renamed.")
390
+ QMessageBox.information(self, self.tr("Done"), self.tr("All files renamed."))
388
391
  self._save_settings()
389
392
  src = self.src_edit.text().strip()
390
393
  if src and not self.dest_edit.text().strip():
@@ -154,7 +154,10 @@ class BlemishBlasterDialogPro(QDialog):
154
154
  """
155
155
  def __init__(self, parent, doc):
156
156
  super().__init__(parent)
157
- self.setWindowTitle("Blemish Blaster")
157
+ self.setWindowTitle(self.tr("Blemish Blaster"))
158
+ self.setWindowFlag(Qt.WindowType.Window, True)
159
+ self.setWindowModality(Qt.WindowModality.NonModal)
160
+ self.setModal(False)
158
161
  self.setMinimumSize(900, 650)
159
162
 
160
163
  self._doc = doc
@@ -214,19 +217,19 @@ class BlemishBlasterDialogPro(QDialog):
214
217
 
215
218
 
216
219
  # ── Controls
217
- ctrls = QGroupBox("Controls")
220
+ ctrls = QGroupBox(self.tr("Controls"))
218
221
  form = QFormLayout(ctrls)
219
222
 
220
223
  # existing sliders
221
224
  self.s_radius = QSlider(Qt.Orientation.Horizontal); self.s_radius.setRange(1, 900); self.s_radius.setValue(12)
222
225
  self.s_feather = QSlider(Qt.Orientation.Horizontal); self.s_feather.setRange(0, 100); self.s_feather.setValue(50)
223
226
  self.s_opacity = QSlider(Qt.Orientation.Horizontal); self.s_opacity.setRange(0, 100); self.s_opacity.setValue(100)
224
- form.addRow("Radius:", self.s_radius)
225
- form.addRow("Feather:", self.s_feather)
226
- form.addRow("Opacity:", self.s_opacity)
227
+ form.addRow(self.tr("Radius:"), self.s_radius)
228
+ form.addRow(self.tr("Feather:"), self.s_feather)
229
+ form.addRow(self.tr("Opacity:"), self.s_opacity)
227
230
 
228
231
  # --- PREVIEW AUTOSTRETCH (display only) ---
229
- self.cb_autostretch = QCheckBox("Auto-stretch preview")
232
+ self.cb_autostretch = QCheckBox(self.tr("Auto-stretch preview"))
230
233
  self.cb_autostretch.setChecked(True)
231
234
  form.addRow(self.cb_autostretch)
232
235
 
@@ -235,9 +238,9 @@ class BlemishBlasterDialogPro(QDialog):
235
238
  self.s_target_median.setSingleStep(0.01)
236
239
  self.s_target_median.setDecimals(3)
237
240
  self.s_target_median.setValue(0.25)
238
- form.addRow("Target median:", self.s_target_median)
241
+ form.addRow(self.tr("Target median:"), self.s_target_median)
239
242
 
240
- self.cb_linked = QCheckBox("Linked color channels")
243
+ self.cb_linked = QCheckBox(self.tr("Linked color channels"))
241
244
  self.cb_linked.setChecked(True)
242
245
  form.addRow(self.cb_linked)
243
246
 
@@ -252,10 +255,10 @@ class BlemishBlasterDialogPro(QDialog):
252
255
  # buttons / layout (unchanged)
253
256
  bb = QHBoxLayout()
254
257
 
255
- self.btn_undo = QPushButton("Undo")
256
- self.btn_redo = QPushButton("Redo")
257
- self.btn_apply = QPushButton("Apply to Document")
258
- self.btn_close = QPushButton("Close")
258
+ self.btn_undo = QPushButton(self.tr("Undo"))
259
+ self.btn_redo = QPushButton(self.tr("Redo"))
260
+ self.btn_apply = QPushButton(self.tr("Apply to Document"))
261
+ self.btn_close = QPushButton(self.tr("Close"))
259
262
 
260
263
  self.btn_undo.setEnabled(False)
261
264
  self.btn_redo.setEnabled(False)