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.
- setiastro/data/SASP_data.fits +0 -0
- setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +488 -0
- setiastro/data/catalogs/astrobin_filters.csv +890 -0
- setiastro/data/catalogs/astrobin_filters_page1_local.csv +51 -0
- setiastro/data/catalogs/cali2.csv +63 -0
- setiastro/data/catalogs/cali2color.csv +65 -0
- setiastro/data/catalogs/celestial_catalog - original.csv +16471 -0
- setiastro/data/catalogs/celestial_catalog.csv +24031 -0
- setiastro/data/catalogs/detected_stars.csv +24784 -0
- setiastro/data/catalogs/fits_header_data.csv +46 -0
- setiastro/data/catalogs/test.csv +8 -0
- setiastro/data/catalogs/updated_celestial_catalog.csv +16471 -0
- setiastro/images/Astro_Spikes.png +0 -0
- setiastro/images/Background_startup.jpg +0 -0
- setiastro/images/HRDiagram.png +0 -0
- setiastro/images/LExtract.png +0 -0
- setiastro/images/LInsert.png +0 -0
- setiastro/images/Oxygenation-atm-2.svg.png +0 -0
- setiastro/images/RGB080604.png +0 -0
- setiastro/images/abeicon.png +0 -0
- setiastro/images/aberration.png +0 -0
- setiastro/images/andromedatry.png +0 -0
- setiastro/images/andromedatry_satellited.png +0 -0
- setiastro/images/annotated.png +0 -0
- setiastro/images/aperture.png +0 -0
- setiastro/images/astrosuite.ico +0 -0
- setiastro/images/astrosuite.png +0 -0
- setiastro/images/astrosuitepro.icns +0 -0
- setiastro/images/astrosuitepro.ico +0 -0
- setiastro/images/astrosuitepro.png +0 -0
- setiastro/images/background.png +0 -0
- setiastro/images/background2.png +0 -0
- setiastro/images/benchmark.png +0 -0
- setiastro/images/big_moon_stabilizer_timeline.png +0 -0
- setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
- setiastro/images/blaster.png +0 -0
- setiastro/images/blink.png +0 -0
- setiastro/images/clahe.png +0 -0
- setiastro/images/collage.png +0 -0
- setiastro/images/colorwheel.png +0 -0
- setiastro/images/contsub.png +0 -0
- setiastro/images/convo.png +0 -0
- setiastro/images/copyslot.png +0 -0
- setiastro/images/cosmic.png +0 -0
- setiastro/images/cosmicsat.png +0 -0
- setiastro/images/crop1.png +0 -0
- setiastro/images/cropicon.png +0 -0
- setiastro/images/curves.png +0 -0
- setiastro/images/cvs.png +0 -0
- setiastro/images/debayer.png +0 -0
- setiastro/images/denoise_cnn_custom.png +0 -0
- setiastro/images/denoise_cnn_graph.png +0 -0
- setiastro/images/disk.png +0 -0
- setiastro/images/dse.png +0 -0
- setiastro/images/exoicon.png +0 -0
- setiastro/images/eye.png +0 -0
- setiastro/images/fliphorizontal.png +0 -0
- setiastro/images/flipvertical.png +0 -0
- setiastro/images/font.png +0 -0
- setiastro/images/freqsep.png +0 -0
- setiastro/images/functionbundle.png +0 -0
- setiastro/images/graxpert.png +0 -0
- setiastro/images/green.png +0 -0
- setiastro/images/gridicon.png +0 -0
- setiastro/images/halo.png +0 -0
- setiastro/images/hdr.png +0 -0
- setiastro/images/histogram.png +0 -0
- setiastro/images/hubble.png +0 -0
- setiastro/images/imagecombine.png +0 -0
- setiastro/images/invert.png +0 -0
- setiastro/images/isophote.png +0 -0
- setiastro/images/isophote_demo_figure.png +0 -0
- setiastro/images/isophote_demo_image.png +0 -0
- setiastro/images/isophote_demo_model.png +0 -0
- setiastro/images/isophote_demo_residual.png +0 -0
- setiastro/images/jwstpupil.png +0 -0
- setiastro/images/linearfit.png +0 -0
- setiastro/images/livestacking.png +0 -0
- setiastro/images/mask.png +0 -0
- setiastro/images/maskapply.png +0 -0
- setiastro/images/maskcreate.png +0 -0
- setiastro/images/maskremove.png +0 -0
- setiastro/images/morpho.png +0 -0
- setiastro/images/mosaic.png +0 -0
- setiastro/images/multiscale_decomp.png +0 -0
- setiastro/images/nbtorgb.png +0 -0
- setiastro/images/neutral.png +0 -0
- setiastro/images/nuke.png +0 -0
- setiastro/images/openfile.png +0 -0
- setiastro/images/pedestal.png +0 -0
- setiastro/images/pen.png +0 -0
- setiastro/images/pixelmath.png +0 -0
- setiastro/images/platesolve.png +0 -0
- setiastro/images/ppp.png +0 -0
- setiastro/images/pro.png +0 -0
- setiastro/images/project.png +0 -0
- setiastro/images/psf.png +0 -0
- setiastro/images/redo.png +0 -0
- setiastro/images/redoicon.png +0 -0
- setiastro/images/rescale.png +0 -0
- setiastro/images/rgbalign.png +0 -0
- setiastro/images/rgbcombo.png +0 -0
- setiastro/images/rgbextract.png +0 -0
- setiastro/images/rotate180.png +0 -0
- setiastro/images/rotatearbitrary.png +0 -0
- setiastro/images/rotateclockwise.png +0 -0
- setiastro/images/rotatecounterclockwise.png +0 -0
- setiastro/images/satellite.png +0 -0
- setiastro/images/script.png +0 -0
- setiastro/images/selectivecolor.png +0 -0
- setiastro/images/simbad.png +0 -0
- setiastro/images/slot0.png +0 -0
- setiastro/images/slot1.png +0 -0
- setiastro/images/slot2.png +0 -0
- setiastro/images/slot3.png +0 -0
- setiastro/images/slot4.png +0 -0
- setiastro/images/slot5.png +0 -0
- setiastro/images/slot6.png +0 -0
- setiastro/images/slot7.png +0 -0
- setiastro/images/slot8.png +0 -0
- setiastro/images/slot9.png +0 -0
- setiastro/images/spcc.png +0 -0
- setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
- setiastro/images/spinner.gif +0 -0
- setiastro/images/stacking.png +0 -0
- setiastro/images/staradd.png +0 -0
- setiastro/images/staralign.png +0 -0
- setiastro/images/starnet.png +0 -0
- setiastro/images/starregistration.png +0 -0
- setiastro/images/starspike.png +0 -0
- setiastro/images/starstretch.png +0 -0
- setiastro/images/statstretch.png +0 -0
- setiastro/images/supernova.png +0 -0
- setiastro/images/uhs.png +0 -0
- setiastro/images/undoicon.png +0 -0
- setiastro/images/upscale.png +0 -0
- setiastro/images/viewbundle.png +0 -0
- setiastro/images/whitebalance.png +0 -0
- setiastro/images/wimi_icon_256x256.png +0 -0
- setiastro/images/wimilogo.png +0 -0
- setiastro/images/wims.png +0 -0
- setiastro/images/wrench_icon.png +0 -0
- setiastro/images/xisfliberator.png +0 -0
- setiastro/qml/ResourceMonitor.qml +126 -0
- setiastro/saspro/__main__.py +228 -67
- setiastro/saspro/_generated/build_info.py +2 -1
- setiastro/saspro/abe.py +76 -25
- setiastro/saspro/aberration_ai.py +14 -14
- setiastro/saspro/add_stars.py +15 -12
- setiastro/saspro/astrobin_exporter.py +61 -58
- setiastro/saspro/astrospike_python.py +3 -1
- setiastro/saspro/autostretch.py +4 -2
- setiastro/saspro/backgroundneutral.py +65 -14
- setiastro/saspro/batch_convert.py +8 -5
- setiastro/saspro/batch_renamer.py +39 -36
- setiastro/saspro/blemish_blaster.py +15 -12
- setiastro/saspro/blink_comparator_pro.py +605 -379
- setiastro/saspro/cheat_sheet.py +62 -17
- setiastro/saspro/clahe.py +34 -8
- setiastro/saspro/comet_stacking.py +103 -38
- setiastro/saspro/common_tr.py +107 -0
- setiastro/saspro/continuum_subtract.py +7 -7
- setiastro/saspro/convo.py +12 -9
- setiastro/saspro/copyastro.py +3 -0
- setiastro/saspro/cosmicclarity.py +77 -52
- setiastro/saspro/crop_dialog_pro.py +80 -45
- setiastro/saspro/curve_editor_pro.py +51 -33
- setiastro/saspro/debayer.py +6 -3
- setiastro/saspro/doc_manager.py +49 -19
- setiastro/saspro/exoplanet_detector.py +11 -11
- setiastro/saspro/fitsmodifier.py +48 -44
- setiastro/saspro/fix_bom.py +32 -0
- setiastro/saspro/frequency_separation.py +18 -12
- setiastro/saspro/function_bundle.py +18 -16
- setiastro/saspro/generate_translations.py +3092 -0
- setiastro/saspro/ghs_dialog_pro.py +19 -16
- setiastro/saspro/graxpert.py +3 -0
- setiastro/saspro/gui/main_window.py +471 -126
- setiastro/saspro/gui/mixins/dock_mixin.py +123 -11
- setiastro/saspro/gui/mixins/file_mixin.py +25 -20
- setiastro/saspro/gui/mixins/geometry_mixin.py +115 -15
- setiastro/saspro/gui/mixins/header_mixin.py +6 -6
- setiastro/saspro/gui/mixins/mask_mixin.py +8 -8
- setiastro/saspro/gui/mixins/menu_mixin.py +62 -33
- setiastro/saspro/gui/mixins/toolbar_mixin.py +382 -226
- setiastro/saspro/gui/mixins/update_mixin.py +26 -26
- setiastro/saspro/gui/statistics_dialog.py +47 -0
- setiastro/saspro/halobgon.py +29 -3
- setiastro/saspro/header_viewer.py +21 -18
- setiastro/saspro/histogram.py +29 -26
- setiastro/saspro/history_explorer.py +2 -0
- setiastro/saspro/i18n.py +168 -0
- setiastro/saspro/image_combine.py +3 -0
- setiastro/saspro/image_peeker_pro.py +52 -44
- setiastro/saspro/imageops/stretch.py +5 -13
- setiastro/saspro/isophote.py +3 -0
- setiastro/saspro/legacy/numba_utils.py +64 -47
- setiastro/saspro/linear_fit.py +3 -0
- setiastro/saspro/live_stacking.py +13 -2
- setiastro/saspro/mask_creation.py +180 -22
- setiastro/saspro/mfdeconv.py +5 -0
- setiastro/saspro/morphology.py +38 -13
- setiastro/saspro/multiscale_decomp.py +713 -256
- setiastro/saspro/nbtorgb_stars.py +12 -2
- setiastro/saspro/numba_utils.py +149 -48
- setiastro/saspro/ops/scripts.py +77 -17
- setiastro/saspro/ops/settings.py +177 -100
- setiastro/saspro/perfect_palette_picker.py +25 -7
- setiastro/saspro/pixelmath.py +114 -110
- setiastro/saspro/plate_solver.py +118 -108
- setiastro/saspro/remove_green.py +24 -7
- setiastro/saspro/remove_stars.py +136 -162
- setiastro/saspro/remove_stars_preset.py +55 -13
- setiastro/saspro/resources.py +46 -15
- setiastro/saspro/rgb_combination.py +19 -18
- setiastro/saspro/rgbalign.py +11 -11
- setiastro/saspro/save_options.py +5 -4
- setiastro/saspro/selective_color.py +84 -25
- setiastro/saspro/sfcc.py +119 -72
- setiastro/saspro/shortcuts.py +345 -36
- setiastro/saspro/signature_insert.py +4 -1
- setiastro/saspro/stacking_suite.py +2066 -1119
- setiastro/saspro/star_alignment.py +291 -331
- setiastro/saspro/star_spikes.py +137 -53
- setiastro/saspro/star_stretch.py +47 -10
- setiastro/saspro/stat_stretch.py +52 -16
- setiastro/saspro/status_log_dock.py +1 -1
- setiastro/saspro/subwindow.py +97 -36
- setiastro/saspro/supernovaasteroidhunter.py +68 -61
- setiastro/saspro/swap_manager.py +77 -42
- setiastro/saspro/translations/all_source_strings.json +4726 -0
- setiastro/saspro/translations/ar_translations.py +4096 -0
- setiastro/saspro/translations/de_translations.py +3728 -0
- setiastro/saspro/translations/es_translations.py +4169 -0
- setiastro/saspro/translations/fr_translations.py +4090 -0
- setiastro/saspro/translations/hi_translations.py +3803 -0
- setiastro/saspro/translations/integrate_translations.py +271 -0
- setiastro/saspro/translations/it_translations.py +4728 -0
- setiastro/saspro/translations/ja_translations.py +3834 -0
- setiastro/saspro/translations/pt_translations.py +3847 -0
- setiastro/saspro/translations/ru_translations.py +3082 -0
- setiastro/saspro/translations/saspro_ar.qm +0 -0
- setiastro/saspro/translations/saspro_ar.ts +16019 -0
- setiastro/saspro/translations/saspro_de.qm +0 -0
- setiastro/saspro/translations/saspro_de.ts +14548 -0
- setiastro/saspro/translations/saspro_es.qm +0 -0
- setiastro/saspro/translations/saspro_es.ts +16202 -0
- setiastro/saspro/translations/saspro_fr.qm +0 -0
- setiastro/saspro/translations/saspro_fr.ts +15870 -0
- setiastro/saspro/translations/saspro_hi.qm +0 -0
- setiastro/saspro/translations/saspro_hi.ts +14855 -0
- setiastro/saspro/translations/saspro_it.qm +0 -0
- setiastro/saspro/translations/saspro_it.ts +19046 -0
- setiastro/saspro/translations/saspro_ja.qm +0 -0
- setiastro/saspro/translations/saspro_ja.ts +14980 -0
- setiastro/saspro/translations/saspro_pt.qm +0 -0
- setiastro/saspro/translations/saspro_pt.ts +15024 -0
- setiastro/saspro/translations/saspro_ru.qm +0 -0
- setiastro/saspro/translations/saspro_ru.ts +11835 -0
- setiastro/saspro/translations/saspro_sw.qm +0 -0
- setiastro/saspro/translations/saspro_sw.ts +15237 -0
- setiastro/saspro/translations/saspro_uk.qm +0 -0
- setiastro/saspro/translations/saspro_uk.ts +15248 -0
- setiastro/saspro/translations/saspro_zh.qm +0 -0
- setiastro/saspro/translations/saspro_zh.ts +15289 -0
- setiastro/saspro/translations/sw_translations.py +3897 -0
- setiastro/saspro/translations/uk_translations.py +3929 -0
- setiastro/saspro/translations/zh_translations.py +3910 -0
- setiastro/saspro/versioning.py +77 -0
- setiastro/saspro/view_bundle.py +20 -17
- setiastro/saspro/wavescale_hdr.py +54 -33
- setiastro/saspro/wavescale_hdr_preset.py +6 -5
- setiastro/saspro/wavescalede.py +54 -31
- setiastro/saspro/wavescalede_preset.py +9 -7
- setiastro/saspro/whitebalance.py +58 -22
- setiastro/saspro/widgets/common_utilities.py +12 -11
- setiastro/saspro/widgets/minigame/game.js +991 -0
- setiastro/saspro/widgets/minigame/index.html +53 -0
- setiastro/saspro/widgets/minigame/style.css +241 -0
- setiastro/saspro/widgets/preview_dialogs.py +8 -8
- setiastro/saspro/widgets/resource_monitor.py +263 -0
- setiastro/saspro/widgets/spinboxes.py +18 -0
- setiastro/saspro/widgets/wavelet_utils.py +52 -20
- setiastro/saspro/wimi.py +7996 -0
- setiastro/saspro/wims.py +578 -0
- setiastro/saspro/window_shelf.py +2 -2
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/METADATA +15 -3
- setiastrosuitepro-1.6.4.post1.dist-info/RECORD +368 -0
- setiastrosuitepro-1.6.0.dist-info/RECORD +0 -174
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/license.txt +0 -0
|
@@ -10,6 +10,9 @@ from PyQt6.QtCore import Qt, QTimer, QUrl
|
|
|
10
10
|
from PyQt6.QtGui import QAction, QActionGroup, QIcon, QKeySequence, QDesktopServices
|
|
11
11
|
from PyQt6.QtWidgets import QMenu, QToolButton
|
|
12
12
|
|
|
13
|
+
from PyQt6.QtCore import QElapsedTimer
|
|
14
|
+
|
|
15
|
+
|
|
13
16
|
if TYPE_CHECKING:
|
|
14
17
|
pass
|
|
15
18
|
|
|
@@ -20,7 +23,7 @@ from setiastro.saspro.resources import (
|
|
|
20
23
|
LInsert_path, rgbcombo_path, rgbextract_path, graxperticon_path,
|
|
21
24
|
cropicon_path, openfile_path, abeicon_path, undoicon_path, redoicon_path,
|
|
22
25
|
blastericon_path, hdr_path, invert_path, fliphorizontal_path,
|
|
23
|
-
flipvertical_path, rotateclockwise_path, rotatecounterclockwise_path,
|
|
26
|
+
flipvertical_path, rotateclockwise_path, rotatecounterclockwise_path,rotatearbitrary_path,
|
|
24
27
|
rotate180_path, maskcreate_path, maskapply_path, maskremove_path,
|
|
25
28
|
pixelmath_path, histogram_path, mosaic_path, rescale_path, staralign_path,
|
|
26
29
|
platesolve_path, psf_path, supernova_path, starregistration_path,
|
|
@@ -73,7 +76,8 @@ class ToolbarMixin:
|
|
|
73
76
|
|
|
74
77
|
def _init_toolbar(self):
|
|
75
78
|
# View toolbar (Undo / Redo / Display-Stretch)
|
|
76
|
-
tb = DraggableToolBar("View", self)
|
|
79
|
+
tb = DraggableToolBar(self.tr("View"), self)
|
|
80
|
+
tb.setObjectName("View")
|
|
77
81
|
tb.setSettingsKey("Toolbar/View")
|
|
78
82
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb)
|
|
79
83
|
|
|
@@ -144,23 +148,30 @@ class ToolbarMixin:
|
|
|
144
148
|
if isinstance(btn_fit, QToolButton):
|
|
145
149
|
fit_menu = QMenu(btn_fit)
|
|
146
150
|
|
|
147
|
-
|
|
148
|
-
self.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
# Use the existing action created in _create_actions()
|
|
152
|
+
fit_menu.addAction(self.act_auto_fit_resize)
|
|
153
|
+
|
|
154
|
+
# (Optional) make sure it reflects current flag at startup
|
|
155
|
+
self.act_auto_fit_resize.blockSignals(True)
|
|
156
|
+
try:
|
|
157
|
+
self.act_auto_fit_resize.setChecked(bool(self._auto_fit_on_resize))
|
|
158
|
+
finally:
|
|
159
|
+
self.act_auto_fit_resize.blockSignals(False)
|
|
151
160
|
|
|
152
161
|
btn_fit.setMenu(fit_menu)
|
|
153
162
|
btn_fit.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
|
|
154
163
|
|
|
155
|
-
# Same style concept as Display-Stretch
|
|
156
164
|
btn_fit.setStyleSheet("""
|
|
157
165
|
QToolButton { color: #dcdcdc; }
|
|
158
166
|
QToolButton:checked { color: #DAA520; font-weight: 600; }
|
|
159
167
|
""")
|
|
160
168
|
|
|
169
|
+
|
|
161
170
|
# Make sure the visual state matches the flag at startup
|
|
162
|
-
self._sync_fit_auto_visual()
|
|
163
171
|
self._restore_toolbar_order(tb, "Toolbar/View")
|
|
172
|
+
self._restore_toolbar_memberships() # (or keep your existing placement, but the bind must be AFTER it)
|
|
173
|
+
self._bind_view_toolbar_menus(tb)
|
|
174
|
+
self._sync_fit_auto_visual()
|
|
164
175
|
# Apply hidden state immediately after order restore (prevents flash)
|
|
165
176
|
try:
|
|
166
177
|
tb.apply_hidden_state()
|
|
@@ -168,7 +179,8 @@ class ToolbarMixin:
|
|
|
168
179
|
pass
|
|
169
180
|
|
|
170
181
|
# Functions toolbar
|
|
171
|
-
tb_fn = DraggableToolBar("Functions", self)
|
|
182
|
+
tb_fn = DraggableToolBar(self.tr("Functions"), self)
|
|
183
|
+
tb_fn.setObjectName("Functions")
|
|
172
184
|
tb_fn.setSettingsKey("Toolbar/Functions")
|
|
173
185
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_fn)
|
|
174
186
|
|
|
@@ -220,7 +232,8 @@ class ToolbarMixin:
|
|
|
220
232
|
except Exception:
|
|
221
233
|
pass
|
|
222
234
|
|
|
223
|
-
tbCosmic = DraggableToolBar("Cosmic Clarity", self)
|
|
235
|
+
tbCosmic = DraggableToolBar(self.tr("Cosmic Clarity"), self)
|
|
236
|
+
tbCosmic.setObjectName("Cosmic Clarity")
|
|
224
237
|
tbCosmic.setSettingsKey("Toolbar/Cosmic")
|
|
225
238
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tbCosmic)
|
|
226
239
|
|
|
@@ -234,7 +247,8 @@ class ToolbarMixin:
|
|
|
234
247
|
except Exception:
|
|
235
248
|
pass
|
|
236
249
|
|
|
237
|
-
tb_tl = DraggableToolBar("Tools", self)
|
|
250
|
+
tb_tl = DraggableToolBar(self.tr("Tools"), self)
|
|
251
|
+
tb_tl.setObjectName("Tools")
|
|
238
252
|
tb_tl.setSettingsKey("Toolbar/Tools")
|
|
239
253
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_tl)
|
|
240
254
|
|
|
@@ -253,7 +267,8 @@ class ToolbarMixin:
|
|
|
253
267
|
except Exception:
|
|
254
268
|
pass
|
|
255
269
|
|
|
256
|
-
tb_geom = DraggableToolBar("Geometry", self)
|
|
270
|
+
tb_geom = DraggableToolBar(self.tr("Geometry"), self)
|
|
271
|
+
tb_geom.setObjectName("Geometry")
|
|
257
272
|
tb_geom.setSettingsKey("Toolbar/Geometry")
|
|
258
273
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_geom)
|
|
259
274
|
|
|
@@ -265,6 +280,7 @@ class ToolbarMixin:
|
|
|
265
280
|
tb_geom.addAction(self.act_geom_rot_cw)
|
|
266
281
|
tb_geom.addAction(self.act_geom_rot_ccw)
|
|
267
282
|
tb_geom.addAction(self.act_geom_rot_180)
|
|
283
|
+
tb_geom.addAction(self.act_geom_rot_any)
|
|
268
284
|
tb_geom.addSeparator()
|
|
269
285
|
tb_geom.addAction(self.act_geom_rescale)
|
|
270
286
|
tb_geom.addSeparator()
|
|
@@ -276,7 +292,8 @@ class ToolbarMixin:
|
|
|
276
292
|
except Exception:
|
|
277
293
|
pass
|
|
278
294
|
|
|
279
|
-
tb_star = DraggableToolBar("Star Stuff", self)
|
|
295
|
+
tb_star = DraggableToolBar(self.tr("Star Stuff"), self)
|
|
296
|
+
tb_star.setObjectName("Star Stuff")
|
|
280
297
|
tb_star.setSettingsKey("Toolbar/StarStuff")
|
|
281
298
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_star)
|
|
282
299
|
|
|
@@ -301,7 +318,8 @@ class ToolbarMixin:
|
|
|
301
318
|
except Exception:
|
|
302
319
|
pass
|
|
303
320
|
|
|
304
|
-
tb_msk = DraggableToolBar("Masks", self)
|
|
321
|
+
tb_msk = DraggableToolBar(self.tr("Masks"), self)
|
|
322
|
+
tb_msk.setObjectName("Masks")
|
|
305
323
|
tb_msk.setSettingsKey("Toolbar/Masks")
|
|
306
324
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_msk)
|
|
307
325
|
|
|
@@ -315,7 +333,8 @@ class ToolbarMixin:
|
|
|
315
333
|
except Exception:
|
|
316
334
|
pass
|
|
317
335
|
|
|
318
|
-
tb_wim = DraggableToolBar("What's In My...", self)
|
|
336
|
+
tb_wim = DraggableToolBar(self.tr("What's In My..."), self)
|
|
337
|
+
tb_wim.setObjectName("What's In My...")
|
|
319
338
|
tb_wim.setSettingsKey("Toolbar/WhatsInMy")
|
|
320
339
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_wim)
|
|
321
340
|
|
|
@@ -328,7 +347,8 @@ class ToolbarMixin:
|
|
|
328
347
|
except Exception:
|
|
329
348
|
pass
|
|
330
349
|
|
|
331
|
-
tb_bundle = DraggableToolBar("Bundles", self)
|
|
350
|
+
tb_bundle = DraggableToolBar(self.tr("Bundles"), self)
|
|
351
|
+
tb_bundle.setObjectName("Bundles")
|
|
332
352
|
tb_bundle.setSettingsKey("Toolbar/Bundles")
|
|
333
353
|
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, tb_bundle)
|
|
334
354
|
|
|
@@ -352,74 +372,200 @@ class ToolbarMixin:
|
|
|
352
372
|
except Exception:
|
|
353
373
|
pass
|
|
354
374
|
|
|
375
|
+
self._rebind_view_dropdowns()
|
|
376
|
+
|
|
377
|
+
def _toolbar_containing_action(self, action: QAction):
|
|
378
|
+
from setiastro.saspro.shortcuts import DraggableToolBar
|
|
379
|
+
for tb in self.findChildren(DraggableToolBar):
|
|
380
|
+
if action in tb.actions():
|
|
381
|
+
return tb
|
|
382
|
+
return None
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _rebind_view_dropdowns(self):
|
|
386
|
+
"""
|
|
387
|
+
Rebind dropdown menus for Display-Stretch + Fit buttons
|
|
388
|
+
on whatever toolbar those actions currently live in.
|
|
389
|
+
Call this AFTER all restore/reorder/membership moves.
|
|
390
|
+
"""
|
|
391
|
+
# ---- Display-Stretch dropdown ----
|
|
392
|
+
tb = self._toolbar_containing_action(self.act_autostretch)
|
|
393
|
+
if tb:
|
|
394
|
+
btn = tb.widgetForAction(self.act_autostretch)
|
|
395
|
+
if isinstance(btn, QToolButton):
|
|
396
|
+
menu = QMenu(btn)
|
|
397
|
+
menu.addAction(self.act_stretch_linked)
|
|
398
|
+
menu.addAction(self.act_hardstretch)
|
|
399
|
+
|
|
400
|
+
menu.addSeparator()
|
|
401
|
+
menu.addAction(self.act_display_target)
|
|
402
|
+
menu.addAction(self.act_display_sigma)
|
|
403
|
+
|
|
404
|
+
presets = QMenu(self.tr("Presets"), menu)
|
|
405
|
+
a_norm = presets.addAction(self.tr("Normal (target 0.30, σ 5)"))
|
|
406
|
+
a_midy = presets.addAction(self.tr("Mid (target 0.40, σ 3)"))
|
|
407
|
+
a_hard = presets.addAction(self.tr("Hard (target 0.50, σ 2)"))
|
|
408
|
+
menu.addMenu(presets)
|
|
409
|
+
|
|
410
|
+
menu.addSeparator()
|
|
411
|
+
menu.addAction(self.act_bake_display_stretch)
|
|
412
|
+
|
|
413
|
+
def _apply_preset(t, s, also_enable=True):
|
|
414
|
+
self.settings.setValue("display/target", float(t))
|
|
415
|
+
self.settings.setValue("display/sigma", float(s))
|
|
416
|
+
sw = self.mdi.activeSubWindow()
|
|
417
|
+
if not sw:
|
|
418
|
+
return
|
|
419
|
+
view = sw.widget()
|
|
420
|
+
if hasattr(view, "set_autostretch_target"):
|
|
421
|
+
view.set_autostretch_target(float(t))
|
|
422
|
+
if hasattr(view, "set_autostretch_sigma"):
|
|
423
|
+
view.set_autostretch_sigma(float(s))
|
|
424
|
+
if also_enable and not getattr(view, "autostretch_enabled", False):
|
|
425
|
+
if hasattr(view, "set_autostretch"):
|
|
426
|
+
view.set_autostretch(True)
|
|
427
|
+
self._sync_autostretch_action(True)
|
|
428
|
+
|
|
429
|
+
a_norm.triggered.connect(lambda: _apply_preset(0.30, 5.0))
|
|
430
|
+
a_midy.triggered.connect(lambda: _apply_preset(0.40, 3.0))
|
|
431
|
+
a_hard.triggered.connect(lambda: _apply_preset(0.50, 2.0))
|
|
432
|
+
|
|
433
|
+
btn.setMenu(menu)
|
|
434
|
+
btn.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
|
|
435
|
+
|
|
436
|
+
# ---- Fit dropdown ----
|
|
437
|
+
tb_fit = self._toolbar_containing_action(self.act_zoom_fit)
|
|
438
|
+
if tb_fit:
|
|
439
|
+
btn_fit = tb_fit.widgetForAction(self.act_zoom_fit)
|
|
440
|
+
if isinstance(btn_fit, QToolButton):
|
|
441
|
+
fit_menu = QMenu(btn_fit)
|
|
442
|
+
fit_menu.addAction(self.act_auto_fit_resize) # use the real action
|
|
443
|
+
btn_fit.setMenu(fit_menu)
|
|
444
|
+
btn_fit.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def _bind_view_toolbar_menus(self, tb: DraggableToolBar):
|
|
448
|
+
# --- Display-Stretch menu ---
|
|
449
|
+
btn = tb.widgetForAction(self.act_autostretch)
|
|
450
|
+
if isinstance(btn, QToolButton):
|
|
451
|
+
menu = QMenu(btn)
|
|
452
|
+
menu.addAction(self.act_stretch_linked)
|
|
453
|
+
menu.addAction(self.act_hardstretch)
|
|
454
|
+
|
|
455
|
+
menu.addSeparator()
|
|
456
|
+
menu.addAction(self.act_display_target)
|
|
457
|
+
menu.addAction(self.act_display_sigma)
|
|
458
|
+
|
|
459
|
+
presets = QMenu(self.tr("Presets"), menu)
|
|
460
|
+
a_norm = presets.addAction(self.tr("Normal (target 0.30, σ 5)"))
|
|
461
|
+
a_midy = presets.addAction(self.tr("Mid (target 0.40, σ 3)"))
|
|
462
|
+
a_hard = presets.addAction(self.tr("Hard (target 0.50, σ 2)"))
|
|
463
|
+
menu.addMenu(presets)
|
|
464
|
+
menu.addSeparator()
|
|
465
|
+
menu.addAction(self.act_bake_display_stretch)
|
|
466
|
+
|
|
467
|
+
def _apply_preset(t, s, also_enable=True):
|
|
468
|
+
self.settings.setValue("display/target", float(t))
|
|
469
|
+
self.settings.setValue("display/sigma", float(s))
|
|
470
|
+
sw = self.mdi.activeSubWindow()
|
|
471
|
+
if not sw:
|
|
472
|
+
return
|
|
473
|
+
view = sw.widget()
|
|
474
|
+
if hasattr(view, "set_autostretch_target"):
|
|
475
|
+
view.set_autostretch_target(float(t))
|
|
476
|
+
if hasattr(view, "set_autostretch_sigma"):
|
|
477
|
+
view.set_autostretch_sigma(float(s))
|
|
478
|
+
if also_enable and not getattr(view, "autostretch_enabled", False):
|
|
479
|
+
if hasattr(view, "set_autostretch"):
|
|
480
|
+
view.set_autostretch(True)
|
|
481
|
+
self._sync_autostretch_action(True)
|
|
482
|
+
|
|
483
|
+
a_norm.triggered.connect(lambda: _apply_preset(0.30, 5.0))
|
|
484
|
+
a_midy.triggered.connect(lambda: _apply_preset(0.40, 3.0))
|
|
485
|
+
a_hard.triggered.connect(lambda: _apply_preset(0.50, 2.0))
|
|
486
|
+
|
|
487
|
+
btn.setMenu(menu)
|
|
488
|
+
btn.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
|
|
489
|
+
|
|
490
|
+
# --- Fit menu (Auto-fit checkbox) ---
|
|
491
|
+
btn_fit = tb.widgetForAction(self.act_zoom_fit)
|
|
492
|
+
if isinstance(btn_fit, QToolButton):
|
|
493
|
+
fit_menu = QMenu(btn_fit)
|
|
494
|
+
|
|
495
|
+
# IMPORTANT: use your existing action (don’t create a new one)
|
|
496
|
+
fit_menu.addAction(self.act_auto_fit_resize)
|
|
497
|
+
|
|
498
|
+
btn_fit.setMenu(fit_menu)
|
|
499
|
+
btn_fit.setPopupMode(QToolButton.ToolButtonPopupMode.MenuButtonPopup)
|
|
500
|
+
|
|
355
501
|
|
|
356
502
|
def _create_actions(self):
|
|
357
503
|
# File actions
|
|
358
|
-
self.act_open = QAction(QIcon(openfile_path), "Open...", self)
|
|
504
|
+
self.act_open = QAction(QIcon(openfile_path), self.tr("Open..."), self)
|
|
359
505
|
self.act_open.setIconVisibleInMenu(True)
|
|
360
506
|
self.act_open.setShortcut(QKeySequence.StandardKey.Open)
|
|
361
|
-
self.act_open.setStatusTip("Open image(s)")
|
|
507
|
+
self.act_open.setStatusTip(self.tr("Open image(s)"))
|
|
362
508
|
self.act_open.triggered.connect(self.open_files)
|
|
363
509
|
|
|
364
510
|
|
|
365
|
-
self.act_project_new = QAction("New Project", self)
|
|
366
|
-
self.act_project_save = QAction("Save Project...", self)
|
|
367
|
-
self.act_project_load = QAction("Load Project...", self)
|
|
511
|
+
self.act_project_new = QAction(self.tr("New Project"), self)
|
|
512
|
+
self.act_project_save = QAction(self.tr("Save Project..."), self)
|
|
513
|
+
self.act_project_load = QAction(self.tr("Load Project..."), self)
|
|
368
514
|
|
|
369
|
-
self.act_project_new.setStatusTip("Close all views and clear shortcuts")
|
|
370
|
-
self.act_project_save.setStatusTip("Save all views, histories, and shortcuts to a .sas file")
|
|
371
|
-
self.act_project_load.setStatusTip("Load a .sas project (views, histories, shortcuts)")
|
|
515
|
+
self.act_project_new.setStatusTip(self.tr("Close all views and clear shortcuts"))
|
|
516
|
+
self.act_project_save.setStatusTip(self.tr("Save all views, histories, and shortcuts to a .sas file"))
|
|
517
|
+
self.act_project_load.setStatusTip(self.tr("Load a .sas project (views, histories, shortcuts)"))
|
|
372
518
|
|
|
373
519
|
self.act_project_new.triggered.connect(self._new_project)
|
|
374
520
|
self.act_project_save.triggered.connect(self._save_project)
|
|
375
521
|
self.act_project_load.triggered.connect(self._load_project)
|
|
376
522
|
|
|
377
|
-
self.act_clear_views = QAction("Clear All Views", self)
|
|
378
|
-
self.act_clear_views.setStatusTip("Close all views and documents, keep desktop shortcuts")
|
|
523
|
+
self.act_clear_views = QAction(self.tr("Clear All Views"), self)
|
|
524
|
+
self.act_clear_views.setStatusTip(self.tr("Close all views and documents, keep desktop shortcuts"))
|
|
379
525
|
# optional shortcut (pick anything you like or omit)
|
|
380
526
|
# self.act_clear_views.setShortcut(QKeySequence("Ctrl+Shift+W"))
|
|
381
527
|
self.act_clear_views.triggered.connect(self._clear_views_keep_shortcuts)
|
|
382
528
|
|
|
383
|
-
self.act_save = QAction(QIcon(disk_path), "Save As...", self)
|
|
529
|
+
self.act_save = QAction(QIcon(disk_path), self.tr("Save As..."), self)
|
|
384
530
|
self.act_save.setIconVisibleInMenu(True)
|
|
385
531
|
self.act_save.setShortcut(QKeySequence.StandardKey.SaveAs)
|
|
386
|
-
self.act_save.setStatusTip("Save the active image")
|
|
532
|
+
self.act_save.setStatusTip(self.tr("Save the active image"))
|
|
387
533
|
self.act_save.triggered.connect(self.save_active)
|
|
388
534
|
|
|
389
|
-
self.act_exit = QAction("&Exit", self)
|
|
535
|
+
self.act_exit = QAction(self.tr("&Exit"), self)
|
|
390
536
|
self.act_exit.setShortcut(QKeySequence.StandardKey.Quit) # Cmd+Q / Ctrl+Q
|
|
391
537
|
# Make it appear under the app menu on macOS automatically:
|
|
392
538
|
self.act_exit.setMenuRole(QAction.MenuRole.QuitRole)
|
|
393
539
|
self.act_exit.triggered.connect(self._on_exit)
|
|
394
540
|
|
|
395
|
-
self.act_cascade = QAction("Cascade Views", self)
|
|
396
|
-
self.act_cascade.setStatusTip("Cascade all subwindows")
|
|
541
|
+
self.act_cascade = QAction(self.tr("Cascade Views"), self)
|
|
542
|
+
self.act_cascade.setStatusTip(self.tr("Cascade all subwindows"))
|
|
397
543
|
self.act_cascade.setShortcut(QKeySequence("Ctrl+Shift+C"))
|
|
398
544
|
self.act_cascade.triggered.connect(self._cascade_views)
|
|
399
545
|
|
|
400
|
-
self.act_tile = QAction("Tile Views", self)
|
|
401
|
-
self.act_tile.setStatusTip("Tile all subwindows")
|
|
546
|
+
self.act_tile = QAction(self.tr("Tile Views"), self)
|
|
547
|
+
self.act_tile.setStatusTip(self.tr("Tile all subwindows"))
|
|
402
548
|
self.act_tile.setShortcut(QKeySequence("Ctrl+Shift+T"))
|
|
403
549
|
self.act_tile.triggered.connect(self._tile_views)
|
|
404
550
|
|
|
405
|
-
self.act_tile_vert = QAction("Tile Vertically", self)
|
|
406
|
-
self.act_tile_vert.setStatusTip("Split the workspace into equal vertical columns")
|
|
551
|
+
self.act_tile_vert = QAction(self.tr("Tile Vertically"), self)
|
|
552
|
+
self.act_tile_vert.setStatusTip(self.tr("Split the workspace into equal vertical columns"))
|
|
407
553
|
self.act_tile_vert.triggered.connect(lambda: self._tile_views_direction("v"))
|
|
408
554
|
|
|
409
|
-
self.act_tile_horiz = QAction("Tile Horizontally", self)
|
|
410
|
-
self.act_tile_horiz.setStatusTip("Split the workspace into equal horizontal rows")
|
|
555
|
+
self.act_tile_horiz = QAction(self.tr("Tile Horizontally"), self)
|
|
556
|
+
self.act_tile_horiz.setStatusTip(self.tr("Split the workspace into equal horizontal rows"))
|
|
411
557
|
self.act_tile_horiz.triggered.connect(lambda: self._tile_views_direction("h"))
|
|
412
558
|
|
|
413
|
-
self.act_tile_grid = QAction("Smart Grid", self)
|
|
414
|
-
self.act_tile_grid.setStatusTip("Arrange subwindows in a near-square grid")
|
|
559
|
+
self.act_tile_grid = QAction(self.tr("Smart Grid"), self)
|
|
560
|
+
self.act_tile_grid.setStatusTip(self.tr("Arrange subwindows in a near-square grid"))
|
|
415
561
|
self.act_tile_grid.triggered.connect(self._tile_views_grid)
|
|
416
562
|
|
|
417
|
-
self.act_link_group = QAction("Link Pan/Zoom", self)
|
|
563
|
+
self.act_link_group = QAction(self.tr("Link Pan/Zoom"), self)
|
|
418
564
|
self.act_link_group.setCheckable(True) # checked when in any group
|
|
419
565
|
self.act_link_group.triggered.connect(self._cycle_group_for_active) # << add
|
|
420
566
|
|
|
421
|
-
self.act_undo = QAction(QIcon(undoicon_path), "Undo", self)
|
|
422
|
-
self.act_redo = QAction(QIcon(redoicon_path), "Redo", self)
|
|
567
|
+
self.act_undo = QAction(QIcon(undoicon_path), self.tr("Undo"), self)
|
|
568
|
+
self.act_redo = QAction(QIcon(redoicon_path), self.tr("Redo"), self)
|
|
423
569
|
self.act_undo.setShortcut(QKeySequence.StandardKey.Undo) # Ctrl+Z
|
|
424
570
|
self.act_redo.setShortcuts([QKeySequence.StandardKey.Redo, "Ctrl+Y"]) # Shift+Ctrl+Z / Ctrl+Y
|
|
425
571
|
self.act_undo.setIconVisibleInMenu(True)
|
|
@@ -428,34 +574,34 @@ class ToolbarMixin:
|
|
|
428
574
|
self.act_redo.triggered.connect(self._redo_active)
|
|
429
575
|
|
|
430
576
|
# View-ish action (toolbar toggle)
|
|
431
|
-
self.act_autostretch = QAction("Display-Stretch", self, checkable=True)
|
|
432
|
-
self.act_autostretch.setStatusTip("Toggle display auto-stretch for the active window")
|
|
577
|
+
self.act_autostretch = QAction(self.tr("Display-Stretch"), self, checkable=True)
|
|
578
|
+
self.act_autostretch.setStatusTip(self.tr("Toggle display auto-stretch for the active window"))
|
|
433
579
|
self.act_autostretch.setShortcut(QKeySequence("A")) # optional: mirror the view shortcut
|
|
434
580
|
self.act_autostretch.toggled.connect(self._toggle_autostretch)
|
|
435
581
|
|
|
436
|
-
self.act_hardstretch = QAction("Hard-Display-Stretch", self, checkable=True)
|
|
582
|
+
self.act_hardstretch = QAction(self.tr("Hard-Display-Stretch"), self, checkable=True)
|
|
437
583
|
self.addAction(self.act_hardstretch)
|
|
438
584
|
self.act_hardstretch.setShortcut(QKeySequence("H"))
|
|
439
|
-
self.act_hardstretch.setStatusTip("Toggle hard profile for Display-Stretch (H)")
|
|
585
|
+
self.act_hardstretch.setStatusTip(self.tr("Toggle hard profile for Display-Stretch (H)"))
|
|
440
586
|
|
|
441
587
|
# use toggled(bool), not triggered()
|
|
442
588
|
self.act_hardstretch.toggled.connect(self._set_hard_autostretch_from_action)
|
|
443
589
|
|
|
444
590
|
# NEW: Linked/Unlinked toggle (global default via QSettings, per-view runtime)
|
|
445
|
-
self.act_stretch_linked = QAction("Link RGB channels", self, checkable=True)
|
|
446
|
-
self.act_stretch_linked.setStatusTip("Apply the same stretch to all RGB channels")
|
|
591
|
+
self.act_stretch_linked = QAction(self.tr("Link RGB channels"), self, checkable=True)
|
|
592
|
+
self.act_stretch_linked.setStatusTip(self.tr("Apply the same stretch to all RGB channels"))
|
|
447
593
|
self.act_stretch_linked.setShortcut(QKeySequence("Ctrl+Shift+L"))
|
|
448
594
|
self.act_stretch_linked.setChecked(
|
|
449
595
|
self.settings.value("display/stretch_linked", False, type=bool)
|
|
450
596
|
)
|
|
451
597
|
self.act_stretch_linked.toggled.connect(self._set_linked_stretch_from_action)
|
|
452
598
|
|
|
453
|
-
self.act_display_target = QAction("Set Target Median...", self)
|
|
454
|
-
self.act_display_target.setStatusTip("Set the target median for Display-Stretch (e.g., 0.30)")
|
|
599
|
+
self.act_display_target = QAction(self.tr("Set Target Median..."), self)
|
|
600
|
+
self.act_display_target.setStatusTip(self.tr("Set the target median for Display-Stretch (e.g., 0.30)"))
|
|
455
601
|
self.act_display_target.triggered.connect(self._edit_display_target)
|
|
456
602
|
|
|
457
|
-
self.act_display_sigma = QAction("Set Sigma...", self)
|
|
458
|
-
self.act_display_sigma.setStatusTip("Set the sigma for Display-Stretch (e.g., 5.0)")
|
|
603
|
+
self.act_display_sigma = QAction(self.tr("Set Sigma..."), self)
|
|
604
|
+
self.act_display_sigma.setStatusTip(self.tr("Set the sigma for Display-Stretch (e.g., 5.0)"))
|
|
459
605
|
self.act_display_sigma.triggered.connect(self._edit_display_sigma)
|
|
460
606
|
|
|
461
607
|
# Defaults if not already present
|
|
@@ -464,9 +610,9 @@ class ToolbarMixin:
|
|
|
464
610
|
if self.settings.value("display/sigma", None) is None:
|
|
465
611
|
self.settings.setValue("display/sigma", 5.0)
|
|
466
612
|
|
|
467
|
-
self.act_bake_display_stretch = QAction("Make Display-Stretch Permanent", self)
|
|
613
|
+
self.act_bake_display_stretch = QAction(self.tr("Make Display-Stretch Permanent"), self)
|
|
468
614
|
self.act_bake_display_stretch.setStatusTip(
|
|
469
|
-
"Apply the current Display-Stretch to the image and add an undo step"
|
|
615
|
+
self.tr("Apply the current Display-Stretch to the image and add an undo step")
|
|
470
616
|
)
|
|
471
617
|
# choose any shortcut you like; avoid Ctrl+A etc
|
|
472
618
|
self.act_bake_display_stretch.setShortcut(QKeySequence("Shift+A"))
|
|
@@ -474,31 +620,31 @@ class ToolbarMixin:
|
|
|
474
620
|
|
|
475
621
|
# --- Zoom controls ---
|
|
476
622
|
# --- Zoom controls (themed icons) ---
|
|
477
|
-
self.act_zoom_out = QAction(QIcon.fromTheme("zoom-out"), "Zoom Out", self)
|
|
478
|
-
self.act_zoom_out.setStatusTip("Zoom out")
|
|
623
|
+
self.act_zoom_out = QAction(QIcon.fromTheme("zoom-out"), self.tr("Zoom Out"), self)
|
|
624
|
+
self.act_zoom_out.setStatusTip(self.tr("Zoom out"))
|
|
479
625
|
self.act_zoom_out.setShortcuts([QKeySequence("Ctrl+-")])
|
|
480
626
|
self.act_zoom_out.triggered.connect(lambda: self._zoom_step_active(-1))
|
|
481
627
|
|
|
482
|
-
self.act_zoom_in = QAction(QIcon.fromTheme("zoom-in"), "Zoom In", self)
|
|
483
|
-
self.act_zoom_in.setStatusTip("Zoom in")
|
|
628
|
+
self.act_zoom_in = QAction(QIcon.fromTheme("zoom-in"), self.tr("Zoom In"), self)
|
|
629
|
+
self.act_zoom_in.setStatusTip(self.tr("Zoom in"))
|
|
484
630
|
self.act_zoom_in.setShortcuts([
|
|
485
631
|
QKeySequence("Ctrl++"), # Ctrl + (Shift + = on many keyboards)
|
|
486
632
|
QKeySequence("Ctrl+="), # fallback
|
|
487
633
|
])
|
|
488
634
|
self.act_zoom_in.triggered.connect(lambda: self._zoom_step_active(+1))
|
|
489
635
|
|
|
490
|
-
self.act_zoom_1_1 = QAction(QIcon.fromTheme("zoom-original"), "1:1", self)
|
|
491
|
-
self.act_zoom_1_1.setStatusTip("Zoom to 100% (pixel-for-pixel)")
|
|
636
|
+
self.act_zoom_1_1 = QAction(QIcon.fromTheme("zoom-original"), self.tr("1:1"), self)
|
|
637
|
+
self.act_zoom_1_1.setStatusTip(self.tr("Zoom to 100% (pixel-for-pixel)"))
|
|
492
638
|
self.act_zoom_1_1.setShortcut(QKeySequence("Ctrl+1"))
|
|
493
639
|
self.act_zoom_1_1.triggered.connect(self._zoom_active_1_1)
|
|
494
640
|
|
|
495
|
-
self.act_zoom_fit = QAction(QIcon.fromTheme("zoom-fit-best"), "Fit", self)
|
|
496
|
-
self.act_zoom_fit.setStatusTip("Fit image to current window")
|
|
641
|
+
self.act_zoom_fit = QAction(QIcon.fromTheme("zoom-fit-best"), self.tr("Fit"), self)
|
|
642
|
+
self.act_zoom_fit.setStatusTip(self.tr("Fit image to current window"))
|
|
497
643
|
self.act_zoom_fit.setShortcut(QKeySequence("Ctrl+0"))
|
|
498
644
|
self.act_zoom_fit.triggered.connect(self._zoom_active_fit)
|
|
499
645
|
self.act_zoom_fit.setCheckable(True)
|
|
500
646
|
|
|
501
|
-
self.act_auto_fit_resize = QAction("Auto-fit on Resize", self)
|
|
647
|
+
self.act_auto_fit_resize = QAction(self.tr("Auto-fit on Resize"), self)
|
|
502
648
|
self.act_auto_fit_resize.setCheckable(True)
|
|
503
649
|
|
|
504
650
|
auto_on = self.settings.value("view/auto_fit_on_resize", False, type=bool)
|
|
@@ -509,102 +655,102 @@ class ToolbarMixin:
|
|
|
509
655
|
|
|
510
656
|
# View state copy/paste (optional quick commands)
|
|
511
657
|
self._copied_view_state = None
|
|
512
|
-
self.act_copy_view = QAction("Copy View (zoom/pan)", self)
|
|
513
|
-
self.act_paste_view = QAction("Paste View", self)
|
|
658
|
+
self.act_copy_view = QAction(self.tr("Copy View (zoom/pan)"), self)
|
|
659
|
+
self.act_paste_view = QAction(self.tr("Paste View"), self)
|
|
514
660
|
self.act_copy_view.setShortcut("Ctrl+Shift+C")
|
|
515
661
|
self.act_paste_view.setShortcut("Ctrl+Shift+V")
|
|
516
662
|
self.act_copy_view.triggered.connect(self._copy_active_view)
|
|
517
663
|
self.act_paste_view.triggered.connect(self._paste_active_view)
|
|
518
664
|
|
|
519
665
|
# Functions
|
|
520
|
-
self.act_crop = QAction(QIcon(cropicon_path), "Crop...", self)
|
|
521
|
-
self.act_crop.setStatusTip("Crop / rotate with handles")
|
|
666
|
+
self.act_crop = QAction(QIcon(cropicon_path), self.tr("Crop..."), self)
|
|
667
|
+
self.act_crop.setStatusTip(self.tr("Crop / rotate with handles"))
|
|
522
668
|
self.act_crop.setIconVisibleInMenu(True)
|
|
523
669
|
self.act_crop.triggered.connect(self._open_crop_dialog)
|
|
524
670
|
|
|
525
|
-
self.act_histogram = QAction(QIcon(histogram_path), "Histogram...", self)
|
|
526
|
-
self.act_histogram.setStatusTip("View histogram and basic stats for the active image")
|
|
671
|
+
self.act_histogram = QAction(QIcon(histogram_path), self.tr("Histogram..."), self)
|
|
672
|
+
self.act_histogram.setStatusTip(self.tr("View histogram and basic stats for the active image"))
|
|
527
673
|
self.act_histogram.setIconVisibleInMenu(True)
|
|
528
674
|
self.act_histogram.triggered.connect(self._open_histogram)
|
|
529
675
|
|
|
530
|
-
self.act_stat_stretch = QAction(QIcon(statstretch_path), "Statistical Stretch...", self)
|
|
531
|
-
self.act_stat_stretch.setStatusTip("Stretch the image using median/SD statistics")
|
|
676
|
+
self.act_stat_stretch = QAction(QIcon(statstretch_path), self.tr("Statistical Stretch..."), self)
|
|
677
|
+
self.act_stat_stretch.setStatusTip(self.tr("Stretch the image using median/SD statistics"))
|
|
532
678
|
self.act_stat_stretch.setIconVisibleInMenu(True)
|
|
533
679
|
self.act_stat_stretch.triggered.connect(self._open_statistical_stretch)
|
|
534
680
|
|
|
535
|
-
self.act_star_stretch = QAction(QIcon(starstretch_path), "Star Stretch...", self)
|
|
536
|
-
self.act_star_stretch.setStatusTip("Arcsinh star stretch with optional SCNR and color boost")
|
|
681
|
+
self.act_star_stretch = QAction(QIcon(starstretch_path), self.tr("Star Stretch..."), self)
|
|
682
|
+
self.act_star_stretch.setStatusTip(self.tr("Arcsinh star stretch with optional SCNR and color boost"))
|
|
537
683
|
self.act_star_stretch.setIconVisibleInMenu(True)
|
|
538
684
|
self.act_star_stretch.triggered.connect(self._open_star_stretch)
|
|
539
685
|
|
|
540
|
-
self.act_curves = QAction(QIcon(curves_path), "Curves Editor...", self)
|
|
541
|
-
self.act_curves.setStatusTip("Open the Curves Editor for the active image")
|
|
686
|
+
self.act_curves = QAction(QIcon(curves_path), self.tr("Curves Editor..."), self)
|
|
687
|
+
self.act_curves.setStatusTip(self.tr("Open the Curves Editor for the active image"))
|
|
542
688
|
self.act_curves.setIconVisibleInMenu(True)
|
|
543
689
|
self.act_curves.triggered.connect(self._open_curves_editor)
|
|
544
690
|
|
|
545
|
-
self.act_ghs = QAction(QIcon(uhs_path), "Hyperbolic Stretch...", self)
|
|
546
|
-
self.act_ghs.setStatusTip("Generalized hyperbolic stretch (
|
|
691
|
+
self.act_ghs = QAction(QIcon(uhs_path), self.tr("Hyperbolic Stretch..."), self)
|
|
692
|
+
self.act_ghs.setStatusTip(self.tr("Generalized hyperbolic stretch (α/beta/gamma, LP/HP, pivot)"))
|
|
547
693
|
self.act_ghs.setIconVisibleInMenu(True)
|
|
548
694
|
self.act_ghs.triggered.connect(self._open_hyperbolic)
|
|
549
695
|
|
|
550
|
-
self.act_abe = QAction(QIcon(abeicon_path), "ABE...", self)
|
|
551
|
-
self.act_abe.setStatusTip("Automatic Background Extraction")
|
|
696
|
+
self.act_abe = QAction(QIcon(abeicon_path), self.tr("ABE..."), self)
|
|
697
|
+
self.act_abe.setStatusTip(self.tr("Automatic Background Extraction"))
|
|
552
698
|
self.act_abe.setIconVisibleInMenu(True)
|
|
553
699
|
self.act_abe.triggered.connect(self._open_abe_tool)
|
|
554
700
|
|
|
555
|
-
self.act_graxpert = QAction(QIcon(graxperticon_path), "Remove Gradient (GraXpert)...", self)
|
|
701
|
+
self.act_graxpert = QAction(QIcon(graxperticon_path), self.tr("Remove Gradient (GraXpert)..."), self)
|
|
556
702
|
self.act_graxpert.setIconVisibleInMenu(True)
|
|
557
|
-
self.act_graxpert.setStatusTip("Run GraXpert background extraction on the active image")
|
|
703
|
+
self.act_graxpert.setStatusTip(self.tr("Run GraXpert background extraction on the active image"))
|
|
558
704
|
self.act_graxpert.triggered.connect(self._open_graxpert)
|
|
559
705
|
|
|
560
|
-
self.act_remove_stars = QAction(QIcon(starnet_path), "Remove Stars...", self)
|
|
706
|
+
self.act_remove_stars = QAction(QIcon(starnet_path), self.tr("Remove Stars..."), self)
|
|
561
707
|
self.act_remove_stars.setIconVisibleInMenu(True)
|
|
562
|
-
self.act_remove_stars.setStatusTip("Run star removal on the active image")
|
|
708
|
+
self.act_remove_stars.setStatusTip(self.tr("Run star removal on the active image"))
|
|
563
709
|
self.act_remove_stars.triggered.connect(lambda: self._remove_stars())
|
|
564
710
|
|
|
565
|
-
self.act_add_stars = QAction(QIcon(staradd_path), "Add Stars...", self)
|
|
566
|
-
self.act_add_stars.setStatusTip("Blend a starless view with a stars-only view")
|
|
711
|
+
self.act_add_stars = QAction(QIcon(staradd_path), self.tr("Add Stars..."), self)
|
|
712
|
+
self.act_add_stars.setStatusTip(self.tr("Blend a starless view with a stars-only view"))
|
|
567
713
|
self.act_add_stars.setIconVisibleInMenu(True)
|
|
568
714
|
self.act_add_stars.triggered.connect(lambda: self._add_stars())
|
|
569
715
|
|
|
570
|
-
self.act_pedestal = QAction(QIcon(pedestal_icon_path), "Remove Pedestal", self)
|
|
571
|
-
self.act_pedestal.setToolTip("Subtract per-channel minimum.\nClick: active view\nAlt+Drag: drop onto a view")
|
|
716
|
+
self.act_pedestal = QAction(QIcon(pedestal_icon_path), self.tr("Remove Pedestal"), self)
|
|
717
|
+
self.act_pedestal.setToolTip(self.tr("Subtract per-channel minimum.\nClick: active view\nAlt+Drag: drop onto a view"))
|
|
572
718
|
self.act_pedestal.setShortcut("Ctrl+P")
|
|
573
719
|
self.act_pedestal.triggered.connect(self._on_remove_pedestal)
|
|
574
720
|
|
|
575
|
-
self.act_linear_fit = QAction(QIcon(linearfit_path),"Linear Fit...", self)
|
|
721
|
+
self.act_linear_fit = QAction(QIcon(linearfit_path), self.tr("Linear Fit..."), self)
|
|
576
722
|
self.act_linear_fit.setIconVisibleInMenu(True)
|
|
577
|
-
self.act_linear_fit.setStatusTip("Match image levels using Linear Fit")
|
|
723
|
+
self.act_linear_fit.setStatusTip(self.tr("Match image levels using Linear Fit"))
|
|
578
724
|
# optional shortcut; change if you already use it elsewhere
|
|
579
725
|
self.act_linear_fit.setShortcut("Ctrl+L")
|
|
580
726
|
self.act_linear_fit.triggered.connect(self._open_linear_fit)
|
|
581
727
|
|
|
582
|
-
self.act_remove_green = QAction(QIcon(green_path), "Remove Green...", self)
|
|
583
|
-
self.act_remove_green.setToolTip("SCNR-style green channel removal.")
|
|
728
|
+
self.act_remove_green = QAction(QIcon(green_path), self.tr("Remove Green..."), self)
|
|
729
|
+
self.act_remove_green.setToolTip(self.tr("SCNR-style green channel removal."))
|
|
584
730
|
self.act_remove_green.setIconVisibleInMenu(True)
|
|
585
731
|
self.act_remove_green.triggered.connect(self._open_remove_green)
|
|
586
732
|
|
|
587
|
-
self.act_background_neutral = QAction(QIcon(neutral_path), "Background Neutralization...", self)
|
|
588
|
-
self.act_background_neutral.setStatusTip("Neutralize background color balance using a sampled region")
|
|
733
|
+
self.act_background_neutral = QAction(QIcon(neutral_path), self.tr("Background Neutralization..."), self)
|
|
734
|
+
self.act_background_neutral.setStatusTip(self.tr("Neutralize background color balance using a sampled region"))
|
|
589
735
|
self.act_background_neutral.setIconVisibleInMenu(True)
|
|
590
736
|
self.act_background_neutral.triggered.connect(self._open_background_neutral)
|
|
591
737
|
|
|
592
|
-
self.act_white_balance = QAction(QIcon(whitebalance_path), "White Balance...", self)
|
|
593
|
-
self.act_white_balance.setStatusTip("Apply white balance (Star-Based, Manual, or Auto)")
|
|
738
|
+
self.act_white_balance = QAction(QIcon(whitebalance_path), self.tr("White Balance..."), self)
|
|
739
|
+
self.act_white_balance.setStatusTip(self.tr("Apply white balance (Star-Based, Manual, or Auto)"))
|
|
594
740
|
self.act_white_balance.triggered.connect(self._open_white_balance)
|
|
595
741
|
|
|
596
|
-
self.act_sfcc = QAction(QIcon(spcc_icon_path), "Spectral Flux Color Calibration...", self)
|
|
742
|
+
self.act_sfcc = QAction(QIcon(spcc_icon_path), self.tr("Spectral Flux Color Calibration..."), self)
|
|
597
743
|
self.act_sfcc.setObjectName("sfcc")
|
|
598
|
-
self.act_sfcc.setToolTip("Open SFCC (Pickles + Filters + Sensor QE)")
|
|
744
|
+
self.act_sfcc.setToolTip(self.tr("Open SFCC (Pickles + Filters + Sensor QE)"))
|
|
599
745
|
self.act_sfcc.triggered.connect(self.SFCC_show)
|
|
600
746
|
|
|
601
|
-
self.act_convo = QAction(QIcon(convoicon_path), "Convolution / Deconvolution...", self)
|
|
747
|
+
self.act_convo = QAction(QIcon(convoicon_path), self.tr("Convolution / Deconvolution..."), self)
|
|
602
748
|
self.act_convo.setObjectName("convo_deconvo")
|
|
603
|
-
self.act_convo.setToolTip("Open Convolution / Deconvolution")
|
|
749
|
+
self.act_convo.setToolTip(self.tr("Open Convolution / Deconvolution"))
|
|
604
750
|
self.act_convo.triggered.connect(self.show_convo_deconvo)
|
|
605
751
|
|
|
606
|
-
self.act_multiscale_decomp = QAction(QIcon(multiscale_decomp_path), "Multiscale Decomposition...", self)
|
|
607
|
-
self.act_multiscale_decomp.setStatusTip("Multiscale detail/residual decomposition with per-layer controls")
|
|
752
|
+
self.act_multiscale_decomp = QAction(QIcon(multiscale_decomp_path), self.tr("Multiscale Decomposition..."), self)
|
|
753
|
+
self.act_multiscale_decomp.setStatusTip(self.tr("Multiscale detail/residual decomposition with per-layer controls"))
|
|
608
754
|
self.act_multiscale_decomp.setIconVisibleInMenu(True)
|
|
609
755
|
self.act_multiscale_decomp.triggered.connect(self._open_multiscale_decomp)
|
|
610
756
|
|
|
@@ -612,8 +758,8 @@ class ToolbarMixin:
|
|
|
612
758
|
|
|
613
759
|
|
|
614
760
|
# --- Extract Luminance main action ---
|
|
615
|
-
self.act_extract_luma = QAction(QIcon(LExtract_path), "Extract Luminance", self)
|
|
616
|
-
self.act_extract_luma.setStatusTip("Create a new mono document using the selected luminance method")
|
|
761
|
+
self.act_extract_luma = QAction(QIcon(LExtract_path), self.tr("Extract Luminance"), self)
|
|
762
|
+
self.act_extract_luma.setStatusTip(self.tr("Create a new mono document using the selected luminance method"))
|
|
617
763
|
self.act_extract_luma.setIconVisibleInMenu(True)
|
|
618
764
|
self.act_extract_luma.triggered.connect(lambda: self._extract_luminance(doc=None))
|
|
619
765
|
|
|
@@ -649,106 +795,112 @@ class ToolbarMixin:
|
|
|
649
795
|
|
|
650
796
|
self._luma_group.triggered.connect(_on_luma_pick)
|
|
651
797
|
|
|
652
|
-
self.act_recombine_luma = QAction(QIcon(LInsert_path), "Recombine Luminance...", self)
|
|
653
|
-
self.act_recombine_luma.setStatusTip("Replace the active image's luminance from another view")
|
|
798
|
+
self.act_recombine_luma = QAction(QIcon(LInsert_path), self.tr("Recombine Luminance..."), self)
|
|
799
|
+
self.act_recombine_luma.setStatusTip(self.tr("Replace the active image's luminance from another view"))
|
|
654
800
|
self.act_recombine_luma.setIconVisibleInMenu(True)
|
|
655
801
|
self.act_recombine_luma.triggered.connect(lambda: self._recombine_luminance_ui(target_doc=None))
|
|
656
802
|
|
|
657
|
-
self.act_rgb_extract = QAction(QIcon(rgbextract_path), "RGB Extract", self)
|
|
803
|
+
self.act_rgb_extract = QAction(QIcon(rgbextract_path), self.tr("RGB Extract"), self)
|
|
658
804
|
self.act_rgb_extract.setIconVisibleInMenu(True)
|
|
659
|
-
self.act_rgb_extract.setStatusTip("Extract R/G/B as three mono documents")
|
|
805
|
+
self.act_rgb_extract.setStatusTip(self.tr("Extract R/G/B as three mono documents"))
|
|
660
806
|
self.act_rgb_extract.triggered.connect(self._rgb_extract_active)
|
|
661
807
|
|
|
662
|
-
self.act_rgb_combine = QAction(QIcon(rgbcombo_path), "RGB Combination...", self)
|
|
808
|
+
self.act_rgb_combine = QAction(QIcon(rgbcombo_path), self.tr("RGB Combination..."), self)
|
|
663
809
|
self.act_rgb_combine.setIconVisibleInMenu(True)
|
|
664
|
-
self.act_rgb_combine.setStatusTip("Combine three mono images into RGB")
|
|
810
|
+
self.act_rgb_combine.setStatusTip(self.tr("Combine three mono images into RGB"))
|
|
665
811
|
self.act_rgb_combine.triggered.connect(self._open_rgb_combination)
|
|
666
812
|
|
|
667
|
-
self.act_blemish = QAction(QIcon(blastericon_path), "Blemish Blaster...", self)
|
|
813
|
+
self.act_blemish = QAction(QIcon(blastericon_path), self.tr("Blemish Blaster..."), self)
|
|
668
814
|
self.act_blemish.setIconVisibleInMenu(True)
|
|
669
|
-
self.act_blemish.setStatusTip("Interactive blemish removal on the active view")
|
|
815
|
+
self.act_blemish.setStatusTip(self.tr("Interactive blemish removal on the active view"))
|
|
670
816
|
self.act_blemish.triggered.connect(self._open_blemish_blaster)
|
|
671
817
|
|
|
672
|
-
self.act_wavescale_hdr = QAction(QIcon(hdr_path), "WaveScale HDR...", self)
|
|
673
|
-
self.act_wavescale_hdr.setStatusTip("Wave-scale HDR with luminance-masked starlet")
|
|
818
|
+
self.act_wavescale_hdr = QAction(QIcon(hdr_path), self.tr("WaveScale HDR..."), self)
|
|
819
|
+
self.act_wavescale_hdr.setStatusTip(self.tr("Wave-scale HDR with luminance-masked starlet"))
|
|
674
820
|
self.act_wavescale_hdr.setIconVisibleInMenu(True)
|
|
675
821
|
self.act_wavescale_hdr.triggered.connect(self._open_wavescale_hdr)
|
|
676
822
|
|
|
677
|
-
self.act_wavescale_de = QAction(QIcon(dse_icon_path), "WaveScale Dark Enhancer...", self)
|
|
678
|
-
self.act_wavescale_de.setStatusTip("Enhance faint/dark structures with wavelet-guided masking")
|
|
823
|
+
self.act_wavescale_de = QAction(QIcon(dse_icon_path), self.tr("WaveScale Dark Enhancer..."), self)
|
|
824
|
+
self.act_wavescale_de.setStatusTip(self.tr("Enhance faint/dark structures with wavelet-guided masking"))
|
|
679
825
|
self.act_wavescale_de.setIconVisibleInMenu(True)
|
|
680
826
|
self.act_wavescale_de.triggered.connect(self._open_wavescale_dark_enhance)
|
|
681
827
|
|
|
682
|
-
self.act_clahe = QAction(QIcon(clahe_path), "CLAHE...", self)
|
|
683
|
-
self.act_clahe.setStatusTip("Contrast Limited Adaptive Histogram Equalization")
|
|
828
|
+
self.act_clahe = QAction(QIcon(clahe_path), self.tr("CLAHE..."), self)
|
|
829
|
+
self.act_clahe.setStatusTip(self.tr("Contrast Limited Adaptive Histogram Equalization"))
|
|
684
830
|
self.act_clahe.setIconVisibleInMenu(True)
|
|
685
831
|
self.act_clahe.triggered.connect(self._open_clahe)
|
|
686
832
|
|
|
687
|
-
self.act_morphology = QAction(QIcon(morpho_path), "Morphological Operations...", self)
|
|
688
|
-
self.act_morphology.setStatusTip("Erosion, dilation, opening, and closing.")
|
|
833
|
+
self.act_morphology = QAction(QIcon(morpho_path), self.tr("Morphological Operations..."), self)
|
|
834
|
+
self.act_morphology.setStatusTip(self.tr("Erosion, dilation, opening, and closing."))
|
|
689
835
|
self.act_morphology.setIconVisibleInMenu(True)
|
|
690
836
|
self.act_morphology.triggered.connect(self._open_morphology)
|
|
691
837
|
|
|
692
|
-
self.act_pixelmath = QAction(QIcon(pixelmath_path), "Pixel Math...", self)
|
|
693
|
-
self.act_pixelmath.setStatusTip("Evaluate expressions using open view names")
|
|
838
|
+
self.act_pixelmath = QAction(QIcon(pixelmath_path), self.tr("Pixel Math..."), self)
|
|
839
|
+
self.act_pixelmath.setStatusTip(self.tr("Evaluate expressions using open view names"))
|
|
694
840
|
self.act_pixelmath.setIconVisibleInMenu(True)
|
|
695
841
|
self.act_pixelmath.triggered.connect(self._open_pixel_math)
|
|
696
842
|
|
|
697
|
-
self.act_signature = QAction(QIcon(signature_icon_path), "Signature / Insert...", self)
|
|
843
|
+
self.act_signature = QAction(QIcon(signature_icon_path), self.tr("Signature / Insert..."), self)
|
|
698
844
|
self.act_signature.setIconVisibleInMenu(True)
|
|
699
|
-
self.act_signature.setStatusTip("Add signatures/overlays and bake them into the active image")
|
|
845
|
+
self.act_signature.setStatusTip(self.tr("Add signatures/overlays and bake them into the active image"))
|
|
700
846
|
self.act_signature.triggered.connect(self._open_signature_insert)
|
|
701
847
|
|
|
702
|
-
self.act_halobgon = QAction(QIcon(halo_path), "Halo-B-Gon...", self)
|
|
848
|
+
self.act_halobgon = QAction(QIcon(halo_path), self.tr("Halo-B-Gon..."), self)
|
|
703
849
|
self.act_halobgon.setIconVisibleInMenu(True)
|
|
704
|
-
self.act_halobgon.setStatusTip("Remove those pesky halos around your stars")
|
|
850
|
+
self.act_halobgon.setStatusTip(self.tr("Remove those pesky halos around your stars"))
|
|
705
851
|
self.act_halobgon.triggered.connect(self._open_halo_b_gon)
|
|
706
852
|
|
|
707
|
-
self.act_image_combine = QAction(QIcon(imagecombine_path), "Image Combine...", self)
|
|
853
|
+
self.act_image_combine = QAction(QIcon(imagecombine_path), self.tr("Image Combine..."), self)
|
|
708
854
|
self.act_image_combine.setIconVisibleInMenu(True)
|
|
709
|
-
self.act_image_combine.setStatusTip("Blend two open images (replace A or create new)")
|
|
855
|
+
self.act_image_combine.setStatusTip(self.tr("Blend two open images (replace A or create new)"))
|
|
710
856
|
self.act_image_combine.triggered.connect(self._open_image_combine)
|
|
711
857
|
|
|
712
858
|
# --- Geometry ---
|
|
713
|
-
self.act_geom_invert = QAction(QIcon(invert_path), "Invert", self)
|
|
859
|
+
self.act_geom_invert = QAction(QIcon(invert_path), self.tr("Invert"), self)
|
|
714
860
|
self.act_geom_invert.setIconVisibleInMenu(True)
|
|
715
|
-
self.act_geom_invert.setStatusTip("Invert image colors")
|
|
861
|
+
self.act_geom_invert.setStatusTip(self.tr("Invert image colors"))
|
|
716
862
|
self.act_geom_invert.triggered.connect(self._exec_geom_invert)
|
|
717
863
|
|
|
718
|
-
self.act_geom_flip_h = QAction(QIcon(fliphorizontal_path), "Flip Horizontal", self)
|
|
864
|
+
self.act_geom_flip_h = QAction(QIcon(fliphorizontal_path), self.tr("Flip Horizontal"), self)
|
|
719
865
|
self.act_geom_flip_h.setIconVisibleInMenu(True)
|
|
720
|
-
self.act_geom_flip_h.setStatusTip("Flip image left<->right")
|
|
866
|
+
self.act_geom_flip_h.setStatusTip(self.tr("Flip image left<->right"))
|
|
721
867
|
self.act_geom_flip_h.triggered.connect(self._exec_geom_flip_h)
|
|
722
868
|
|
|
723
|
-
self.act_geom_flip_v = QAction(QIcon(flipvertical_path), "Flip Vertical", self)
|
|
869
|
+
self.act_geom_flip_v = QAction(QIcon(flipvertical_path), self.tr("Flip Vertical"), self)
|
|
724
870
|
self.act_geom_flip_v.setIconVisibleInMenu(True)
|
|
725
|
-
self.act_geom_flip_v.setStatusTip("Flip image top<->bottom")
|
|
871
|
+
self.act_geom_flip_v.setStatusTip(self.tr("Flip image top<->bottom"))
|
|
726
872
|
self.act_geom_flip_v.triggered.connect(self._exec_geom_flip_v)
|
|
727
873
|
|
|
728
|
-
self.act_geom_rot_cw = QAction(QIcon(rotateclockwise_path), "Rotate 90
|
|
874
|
+
self.act_geom_rot_cw = QAction(QIcon(rotateclockwise_path), self.tr("Rotate 90° Clockwise"), self)
|
|
729
875
|
self.act_geom_rot_cw.setIconVisibleInMenu(True)
|
|
730
|
-
self.act_geom_rot_cw.setStatusTip("Rotate image 90
|
|
876
|
+
self.act_geom_rot_cw.setStatusTip(self.tr("Rotate image 90° clockwise"))
|
|
731
877
|
self.act_geom_rot_cw.triggered.connect(self._exec_geom_rot_cw)
|
|
732
878
|
|
|
733
|
-
self.act_geom_rot_ccw = QAction(QIcon(rotatecounterclockwise_path), "Rotate 90
|
|
879
|
+
self.act_geom_rot_ccw = QAction(QIcon(rotatecounterclockwise_path), self.tr("Rotate 90° Counterclockwise"), self)
|
|
734
880
|
self.act_geom_rot_ccw.setIconVisibleInMenu(True)
|
|
735
|
-
self.act_geom_rot_ccw.setStatusTip("Rotate image 90
|
|
881
|
+
self.act_geom_rot_ccw.setStatusTip(self.tr("Rotate image 90° counterclockwise"))
|
|
736
882
|
self.act_geom_rot_ccw.triggered.connect(self._exec_geom_rot_ccw)
|
|
737
883
|
|
|
738
|
-
self.act_geom_rot_180 = QAction(QIcon(rotate180_path), "Rotate 180
|
|
884
|
+
self.act_geom_rot_180 = QAction(QIcon(rotate180_path), self.tr("Rotate 180°"), self)
|
|
739
885
|
self.act_geom_rot_180.setIconVisibleInMenu(True)
|
|
740
|
-
self.act_geom_rot_180.setStatusTip("Rotate image 180
|
|
886
|
+
self.act_geom_rot_180.setStatusTip(self.tr("Rotate image 180°"))
|
|
741
887
|
self.act_geom_rot_180.triggered.connect(self._exec_geom_rot_180)
|
|
742
888
|
|
|
743
|
-
self.
|
|
889
|
+
self.act_geom_rot_any = QAction(QIcon(rotatearbitrary_path), self.tr("Rotate..."), self)
|
|
890
|
+
self.act_geom_rot_any.setIconVisibleInMenu(True)
|
|
891
|
+
self.act_geom_rot_any.setStatusTip(self.tr("Rotate image by an arbitrary angle (degrees)"))
|
|
892
|
+
self.act_geom_rot_any.triggered.connect(self._exec_geom_rot_any)
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
self.act_geom_rescale = QAction(QIcon(rescale_path), self.tr("Rescale..."), self)
|
|
744
896
|
self.act_geom_rescale.setIconVisibleInMenu(True)
|
|
745
|
-
self.act_geom_rescale.setStatusTip("Rescale image by a factor")
|
|
897
|
+
self.act_geom_rescale.setStatusTip(self.tr("Rescale image by a factor"))
|
|
746
898
|
self.act_geom_rescale.triggered.connect(self._exec_geom_rescale)
|
|
747
899
|
|
|
748
|
-
self.act_debayer = QAction(QIcon(debayer_path), "Debayer...", self)
|
|
900
|
+
self.act_debayer = QAction(QIcon(debayer_path), self.tr("Debayer..."), self)
|
|
749
901
|
self.act_debayer.setObjectName("debayer")
|
|
750
902
|
self.act_debayer.setProperty("command_id", "debayer")
|
|
751
|
-
self.act_debayer.setStatusTip("Demosaic a Bayer-mosaic mono image to RGB")
|
|
903
|
+
self.act_debayer.setStatusTip(self.tr("Demosaic a Bayer-mosaic mono image to RGB"))
|
|
752
904
|
self.act_debayer.triggered.connect(self._open_debayer)
|
|
753
905
|
|
|
754
906
|
# (Optional example shortcuts; uncomment if you want)
|
|
@@ -772,8 +924,8 @@ class ToolbarMixin:
|
|
|
772
924
|
except Exception:
|
|
773
925
|
sat_icon = QIcon()
|
|
774
926
|
|
|
775
|
-
self.actCosmicUI = QAction(cosmic_icon, "Cosmic Clarity UI...", self)
|
|
776
|
-
self.actCosmicSat = QAction(sat_icon,
|
|
927
|
+
self.actCosmicUI = QAction(cosmic_icon, self.tr("Cosmic Clarity UI..."), self)
|
|
928
|
+
self.actCosmicSat = QAction(sat_icon, self.tr("Cosmic Clarity Satellite..."), self)
|
|
777
929
|
|
|
778
930
|
self.actCosmicUI.triggered.connect(self._open_cosmic_clarity_ui)
|
|
779
931
|
self.actCosmicSat.triggered.connect(self._open_cosmic_clarity_satellite)
|
|
@@ -781,207 +933,207 @@ class ToolbarMixin:
|
|
|
781
933
|
|
|
782
934
|
ab_icon = QIcon(aberration_path) # falls back if file missing
|
|
783
935
|
|
|
784
|
-
self.actAberrationAI = QAction(ab_icon, "Aberration Correction (AI)...", self)
|
|
936
|
+
self.actAberrationAI = QAction(ab_icon, self.tr("Aberration Correction (AI)..."), self)
|
|
785
937
|
self.actAberrationAI.triggered.connect(self._open_aberration_ai)
|
|
786
938
|
|
|
787
939
|
|
|
788
940
|
|
|
789
941
|
#Tools
|
|
790
|
-
self.act_blink = QAction(QIcon(blink_path), "Blink Comparator...", self)
|
|
791
|
-
self.act_blink.setStatusTip("Compare a stack of images by blinking")
|
|
942
|
+
self.act_blink = QAction(QIcon(blink_path), self.tr("Blink Comparator..."), self)
|
|
943
|
+
self.act_blink.setStatusTip(self.tr("Compare a stack of images by blinking"))
|
|
792
944
|
self.act_blink.triggered.connect(self._open_blink_tool)
|
|
793
945
|
|
|
794
|
-
self.act_ppp = QAction(QIcon(ppp_path), "Perfect Palette Picker...", self)
|
|
795
|
-
self.act_ppp.setStatusTip("Pick the perfect palette for your image")
|
|
946
|
+
self.act_ppp = QAction(QIcon(ppp_path), self.tr("Perfect Palette Picker..."), self)
|
|
947
|
+
self.act_ppp.setStatusTip(self.tr("Pick the perfect palette for your image"))
|
|
796
948
|
self.act_ppp.triggered.connect(self._open_ppp_tool)
|
|
797
949
|
|
|
798
|
-
self.act_nbtorgb = QAction(QIcon(nbtorgb_path), "NB->RGB Stars...", self)
|
|
799
|
-
self.act_nbtorgb.setStatusTip("Combine narrowband to RGB with optional OSC stars")
|
|
950
|
+
self.act_nbtorgb = QAction(QIcon(nbtorgb_path), self.tr("NB->RGB Stars..."), self)
|
|
951
|
+
self.act_nbtorgb.setStatusTip(self.tr("Combine narrowband to RGB with optional OSC stars"))
|
|
800
952
|
self.act_nbtorgb.setIconVisibleInMenu(True)
|
|
801
953
|
self.act_nbtorgb.triggered.connect(self._open_nbtorgb_tool)
|
|
802
954
|
|
|
803
|
-
self.act_selective_color = QAction(QIcon(selectivecolor_path), "Selective Color Correction...", self)
|
|
804
|
-
self.act_selective_color.setStatusTip("Adjust specific hue ranges with CMY/RGB controls")
|
|
955
|
+
self.act_selective_color = QAction(QIcon(selectivecolor_path), self.tr("Selective Color Correction..."), self)
|
|
956
|
+
self.act_selective_color.setStatusTip(self.tr("Adjust specific hue ranges with CMY/RGB controls"))
|
|
805
957
|
self.act_selective_color.triggered.connect(self._open_selective_color_tool)
|
|
806
958
|
|
|
807
959
|
# NEW: Frequency Separation
|
|
808
|
-
self.act_freqsep = QAction(QIcon(freqsep_path), "Frequency Separation...", self)
|
|
809
|
-
self.act_freqsep.setStatusTip("Split into LF/HF and enhance HF (scale, wavelet, denoise)")
|
|
960
|
+
self.act_freqsep = QAction(QIcon(freqsep_path), self.tr("Frequency Separation..."), self)
|
|
961
|
+
self.act_freqsep.setStatusTip(self.tr("Split into LF/HF and enhance HF (scale, wavelet, denoise)"))
|
|
810
962
|
self.act_freqsep.setIconVisibleInMenu(True)
|
|
811
963
|
self.act_freqsep.triggered.connect(self._open_freqsep_tool)
|
|
812
964
|
|
|
813
|
-
self.act_contsub = QAction(QIcon(contsub_path), "Continuum Subtract...", self)
|
|
814
|
-
self.act_contsub.setStatusTip("Continuum
|
|
965
|
+
self.act_contsub = QAction(QIcon(contsub_path), self.tr("Continuum Subtract..."), self)
|
|
966
|
+
self.act_contsub.setStatusTip(self.tr("Continuum Subtract (NB - scaled broadband)"))
|
|
815
967
|
self.act_contsub.setIconVisibleInMenu(True)
|
|
816
968
|
self.act_contsub.triggered.connect(self._open_contsub_tool)
|
|
817
969
|
|
|
818
970
|
# History
|
|
819
|
-
self.act_history_explorer = QAction("History Explorer...", self)
|
|
820
|
-
self.act_history_explorer.setStatusTip("Inspect and restore from the slot's history")
|
|
971
|
+
self.act_history_explorer = QAction(self.tr("History Explorer..."), self)
|
|
972
|
+
self.act_history_explorer.setStatusTip(self.tr("Inspect and restore from the slot's history"))
|
|
821
973
|
self.act_history_explorer.triggered.connect(self._open_history_explorer)
|
|
822
974
|
|
|
823
975
|
|
|
824
976
|
#STAR STUFF
|
|
825
|
-
self.act_image_peeker = QAction(QIcon(peeker_icon), "Image Peeker...", self)
|
|
977
|
+
self.act_image_peeker = QAction(QIcon(peeker_icon), self.tr("Image Peeker..."), self)
|
|
826
978
|
self.act_image_peeker.setIconVisibleInMenu(True)
|
|
827
|
-
self.act_image_peeker.setStatusTip("Image Inspector and Focal Plane Analysis")
|
|
979
|
+
self.act_image_peeker.setStatusTip(self.tr("Image Inspector and Focal Plane Analysis"))
|
|
828
980
|
self.act_image_peeker.triggered.connect(self._open_image_peeker)
|
|
829
981
|
|
|
830
|
-
self.act_psf_viewer = QAction(QIcon(psf_path), "PSF Viewer...", self)
|
|
982
|
+
self.act_psf_viewer = QAction(QIcon(psf_path), self.tr("PSF Viewer..."), self)
|
|
831
983
|
self.act_psf_viewer.setIconVisibleInMenu(True)
|
|
832
|
-
self.act_psf_viewer.setStatusTip("Inspect star PSF/HFR and flux histograms (SEP)")
|
|
984
|
+
self.act_psf_viewer.setStatusTip(self.tr("Inspect star PSF/HFR and flux histograms (SEP)"))
|
|
833
985
|
self.act_psf_viewer.triggered.connect(self._open_psf_viewer)
|
|
834
986
|
|
|
835
|
-
self.act_stacking_suite = QAction(QIcon(stacking_path), "Stacking Suite...", self)
|
|
987
|
+
self.act_stacking_suite = QAction(QIcon(stacking_path), self.tr("Stacking Suite..."), self)
|
|
836
988
|
self.act_stacking_suite.setIconVisibleInMenu(True)
|
|
837
|
-
self.act_stacking_suite.setStatusTip("Stacking! Darks, Flats, Lights, Calibration, Drizzle, and more!!")
|
|
989
|
+
self.act_stacking_suite.setStatusTip(self.tr("Stacking! Darks, Flats, Lights, Calibration, Drizzle, and more!!"))
|
|
838
990
|
self.act_stacking_suite.triggered.connect(self._open_stacking_suite)
|
|
839
991
|
|
|
840
|
-
self.act_live_stacking = QAction(QIcon(livestacking_path), "Live Stacking...", self)
|
|
992
|
+
self.act_live_stacking = QAction(QIcon(livestacking_path), self.tr("Live Stacking..."), self)
|
|
841
993
|
self.act_live_stacking.setIconVisibleInMenu(True)
|
|
842
|
-
self.act_live_stacking.setStatusTip("Live monitor and stack incoming frames")
|
|
994
|
+
self.act_live_stacking.setStatusTip(self.tr("Live monitor and stack incoming frames"))
|
|
843
995
|
self.act_live_stacking.triggered.connect(self._open_live_stacking)
|
|
844
996
|
|
|
845
|
-
self.act_plate_solve = QAction(QIcon(platesolve_path), "Plate Solver...", self)
|
|
997
|
+
self.act_plate_solve = QAction(QIcon(platesolve_path), self.tr("Plate Solver..."), self)
|
|
846
998
|
self.act_plate_solve.setIconVisibleInMenu(True)
|
|
847
|
-
self.act_plate_solve.setStatusTip("Solve WCS/SIP for the active image or a file")
|
|
999
|
+
self.act_plate_solve.setStatusTip(self.tr("Solve WCS/SIP for the active image or a file"))
|
|
848
1000
|
self.act_plate_solve.triggered.connect(self._open_plate_solver)
|
|
849
1001
|
|
|
850
|
-
self.act_star_align = QAction(QIcon(staralign_path), "Stellar Alignment...", self)
|
|
1002
|
+
self.act_star_align = QAction(QIcon(staralign_path), self.tr("Stellar Alignment..."), self)
|
|
851
1003
|
self.act_star_align.setIconVisibleInMenu(True)
|
|
852
|
-
self.act_star_align.setStatusTip("Align images via astroalign / triangles")
|
|
1004
|
+
self.act_star_align.setStatusTip(self.tr("Align images via astroalign / triangles"))
|
|
853
1005
|
self.act_star_align.triggered.connect(self._open_stellar_alignment)
|
|
854
1006
|
|
|
855
|
-
self.act_star_register = QAction(QIcon(starregistration_path), "Stellar Register...", self)
|
|
1007
|
+
self.act_star_register = QAction(QIcon(starregistration_path), self.tr("Stellar Register..."), self)
|
|
856
1008
|
self.act_star_register.setIconVisibleInMenu(True)
|
|
857
|
-
self.act_star_register.setStatusTip("Batch-align frames to a reference")
|
|
1009
|
+
self.act_star_register.setStatusTip(self.tr("Batch-align frames to a reference"))
|
|
858
1010
|
self.act_star_register.triggered.connect(self._open_stellar_registration)
|
|
859
1011
|
|
|
860
|
-
self.act_mosaic_master = QAction(QIcon(mosaic_path), "Mosaic Master...", self)
|
|
1012
|
+
self.act_mosaic_master = QAction(QIcon(mosaic_path), self.tr("Mosaic Master..."), self)
|
|
861
1013
|
self.act_mosaic_master.setIconVisibleInMenu(True)
|
|
862
|
-
self.act_mosaic_master.setStatusTip("Build mosaics from overlapping frames")
|
|
1014
|
+
self.act_mosaic_master.setStatusTip(self.tr("Build mosaics from overlapping frames"))
|
|
863
1015
|
self.act_mosaic_master.triggered.connect(self._open_mosaic_master)
|
|
864
1016
|
|
|
865
|
-
self.act_supernova_hunter = QAction(QIcon(supernova_path), "Supernova / Asteroid Hunter...", self)
|
|
1017
|
+
self.act_supernova_hunter = QAction(QIcon(supernova_path), self.tr("Supernova / Asteroid Hunter..."), self)
|
|
866
1018
|
self.act_supernova_hunter.setIconVisibleInMenu(True)
|
|
867
|
-
self.act_supernova_hunter.setStatusTip("Find transients/anomalies across frames")
|
|
1019
|
+
self.act_supernova_hunter.setStatusTip(self.tr("Find transients/anomalies across frames"))
|
|
868
1020
|
self.act_supernova_hunter.triggered.connect(self._open_supernova_hunter)
|
|
869
1021
|
|
|
870
|
-
self.act_star_spikes = QAction(QIcon(starspike_path), "Diffraction Spikes...", self)
|
|
1022
|
+
self.act_star_spikes = QAction(QIcon(starspike_path), self.tr("Diffraction Spikes..."), self)
|
|
871
1023
|
self.act_star_spikes.setIconVisibleInMenu(True)
|
|
872
|
-
self.act_star_spikes.setStatusTip("Add diffraction spikes to detected stars")
|
|
1024
|
+
self.act_star_spikes.setStatusTip(self.tr("Add diffraction spikes to detected stars"))
|
|
873
1025
|
self.act_star_spikes.triggered.connect(self._open_star_spikes)
|
|
874
1026
|
|
|
875
|
-
self.act_astrospike = QAction(QIcon(astrospike_path), "AstroSpike...", self)
|
|
1027
|
+
self.act_astrospike = QAction(QIcon(astrospike_path), self.tr("AstroSpike..."), self)
|
|
876
1028
|
self.act_astrospike.setIconVisibleInMenu(True)
|
|
877
|
-
self.act_astrospike.setStatusTip("Advanced diffraction spikes with halos, flares and rainbow effects")
|
|
1029
|
+
self.act_astrospike.setStatusTip(self.tr("Advanced diffraction spikes with halos, flares and rainbow effects"))
|
|
878
1030
|
self.act_astrospike.triggered.connect(self._open_astrospike)
|
|
879
1031
|
|
|
880
|
-
self.act_exo_detector = QAction(QIcon(exoicon_path), "Exoplanet Detector...", self)
|
|
1032
|
+
self.act_exo_detector = QAction(QIcon(exoicon_path), self.tr("Exoplanet Detector..."), self)
|
|
881
1033
|
self.act_exo_detector.setIconVisibleInMenu(True)
|
|
882
|
-
self.act_exo_detector.setStatusTip("Detect exoplanet transits from time-series subs")
|
|
1034
|
+
self.act_exo_detector.setStatusTip(self.tr("Detect exoplanet transits from time-series subs"))
|
|
883
1035
|
self.act_exo_detector.triggered.connect(self._open_exo_detector)
|
|
884
1036
|
|
|
885
|
-
self.act_isophote = QAction(QIcon(isophote_path), "GLIMR -- Isophote Modeler...", self)
|
|
1037
|
+
self.act_isophote = QAction(QIcon(isophote_path), self.tr("GLIMR -- Isophote Modeler..."), self)
|
|
886
1038
|
self.act_isophote.setIconVisibleInMenu(True)
|
|
887
|
-
self.act_isophote.setStatusTip("Fit galaxy isophotes and reveal residuals")
|
|
1039
|
+
self.act_isophote.setStatusTip(self.tr("Fit galaxy isophotes and reveal residuals"))
|
|
888
1040
|
self.act_isophote.triggered.connect(self._open_isophote)
|
|
889
1041
|
|
|
890
|
-
self.act_rgb_align = QAction(QIcon(rgbalign_path), "RGB Align...", self)
|
|
1042
|
+
self.act_rgb_align = QAction(QIcon(rgbalign_path), self.tr("RGB Align..."), self)
|
|
891
1043
|
self.act_rgb_align.setIconVisibleInMenu(True)
|
|
892
|
-
self.act_rgb_align.setStatusTip("Align R and B channels to G using astroalign (affine/homography/poly)")
|
|
1044
|
+
self.act_rgb_align.setStatusTip(self.tr("Align R and B channels to G using astroalign (affine/homography/poly)"))
|
|
893
1045
|
self.act_rgb_align.triggered.connect(self._open_rgb_align)
|
|
894
1046
|
|
|
895
|
-
self.act_whats_in_my_sky = QAction(QIcon(wims_path), "What's In My Sky...", self)
|
|
1047
|
+
self.act_whats_in_my_sky = QAction(QIcon(wims_path), self.tr("What's In My Sky..."), self)
|
|
896
1048
|
self.act_whats_in_my_sky.setIconVisibleInMenu(True)
|
|
897
|
-
self.act_whats_in_my_sky.setStatusTip("Plan targets by altitude, transit time, and lunar separation")
|
|
1049
|
+
self.act_whats_in_my_sky.setStatusTip(self.tr("Plan targets by altitude, transit time, and lunar separation"))
|
|
898
1050
|
self.act_whats_in_my_sky.triggered.connect(self._open_whats_in_my_sky)
|
|
899
1051
|
|
|
900
|
-
self.act_wimi = QAction(QIcon(wimi_path), "What's In My Image...", self)
|
|
1052
|
+
self.act_wimi = QAction(QIcon(wimi_path), self.tr("What's In My Image..."), self)
|
|
901
1053
|
self.act_wimi.setIconVisibleInMenu(True)
|
|
902
|
-
self.act_wimi.setStatusTip("Identify objects in a plate-solved frame")
|
|
1054
|
+
self.act_wimi.setStatusTip(self.tr("Identify objects in a plate-solved frame"))
|
|
903
1055
|
self.act_wimi.triggered.connect(self._open_wimi)
|
|
904
1056
|
|
|
905
1057
|
# --- Scripts actions ---
|
|
906
|
-
self.act_open_scripts_folder = QAction("Open Scripts Folder...", self)
|
|
907
|
-
self.act_open_scripts_folder.setStatusTip("Open the SASpro user scripts folder")
|
|
1058
|
+
self.act_open_scripts_folder = QAction(self.tr("Open Scripts Folder..."), self)
|
|
1059
|
+
self.act_open_scripts_folder.setStatusTip(self.tr("Open the SASpro user scripts folder"))
|
|
908
1060
|
self.act_open_scripts_folder.triggered.connect(self._open_scripts_folder)
|
|
909
1061
|
|
|
910
|
-
self.act_reload_scripts = QAction("Reload Scripts", self)
|
|
911
|
-
self.act_reload_scripts.setStatusTip("Rescan the scripts folder and reload .py files")
|
|
1062
|
+
self.act_reload_scripts = QAction(self.tr("Reload Scripts"), self)
|
|
1063
|
+
self.act_reload_scripts.setStatusTip(self.tr("Rescan the scripts folder and reload .py files"))
|
|
912
1064
|
self.act_reload_scripts.triggered.connect(self._reload_scripts)
|
|
913
1065
|
|
|
914
|
-
self.act_create_sample_script = QAction("Create Sample Scripts...", self)
|
|
915
|
-
self.act_create_sample_script.setStatusTip("Write a ready-to-edit sample script into the scripts folder")
|
|
1066
|
+
self.act_create_sample_script = QAction(self.tr("Create Sample Scripts..."), self)
|
|
1067
|
+
self.act_create_sample_script.setStatusTip(self.tr("Write a ready-to-edit sample script into the scripts folder"))
|
|
916
1068
|
self.act_create_sample_script.triggered.connect(self._create_sample_script)
|
|
917
1069
|
|
|
918
|
-
self.act_script_editor = QAction("Script Editor...", self)
|
|
919
|
-
self.act_script_editor.setStatusTip("Open the built-in script editor")
|
|
1070
|
+
self.act_script_editor = QAction(self.tr("Script Editor..."), self)
|
|
1071
|
+
self.act_script_editor.setStatusTip(self.tr("Open the built-in script editor"))
|
|
920
1072
|
self.act_script_editor.triggered.connect(self._show_script_editor)
|
|
921
1073
|
|
|
922
|
-
self.act_open_user_scripts_github = QAction("Open User Scripts (GitHub)...", self)
|
|
1074
|
+
self.act_open_user_scripts_github = QAction(self.tr("Open User Scripts (GitHub)..."), self)
|
|
923
1075
|
self.act_open_user_scripts_github.triggered.connect(self._open_user_scripts_github)
|
|
924
1076
|
|
|
925
|
-
self.act_open_scripts_discord = QAction("Open Scripts Forum (Discord)...", self)
|
|
1077
|
+
self.act_open_scripts_discord = QAction(self.tr("Open Scripts Forum (Discord)..."), self)
|
|
926
1078
|
self.act_open_scripts_discord.triggered.connect(self._open_scripts_discord_forum)
|
|
927
1079
|
|
|
928
1080
|
# --- FITS Header Modifier action ---
|
|
929
|
-
self.act_fits_modifier = QAction("FITS Header Modifier...", self)
|
|
1081
|
+
self.act_fits_modifier = QAction(self.tr("FITS Header Modifier..."), self)
|
|
930
1082
|
# self.act_fits_modifier.setIcon(QIcon(path_to_icon)) # (optional) icon goes here later
|
|
931
1083
|
self.act_fits_modifier.setIconVisibleInMenu(True)
|
|
932
|
-
self.act_fits_modifier.setStatusTip("View/Edit FITS headers")
|
|
1084
|
+
self.act_fits_modifier.setStatusTip(self.tr("View/Edit FITS headers"))
|
|
933
1085
|
self.act_fits_modifier.triggered.connect(self._open_fits_modifier)
|
|
934
1086
|
|
|
935
|
-
self.act_fits_batch_modifier = QAction("FITS Header Batch Modifier...", self)
|
|
1087
|
+
self.act_fits_batch_modifier = QAction(self.tr("FITS Header Batch Modifier..."), self)
|
|
936
1088
|
# self.act_fits_modifier.setIcon(QIcon(path_to_icon)) # (optional) icon goes here later
|
|
937
1089
|
self.act_fits_batch_modifier.setIconVisibleInMenu(True)
|
|
938
|
-
self.act_fits_batch_modifier.setStatusTip("Batch Modify FITS Headers")
|
|
1090
|
+
self.act_fits_batch_modifier.setStatusTip(self.tr("Batch Modify FITS Headers"))
|
|
939
1091
|
self.act_fits_batch_modifier.triggered.connect(self._open_fits_batch_modifier)
|
|
940
1092
|
|
|
941
|
-
self.act_batch_renamer = QAction("Batch Rename from FITS...", self)
|
|
1093
|
+
self.act_batch_renamer = QAction(self.tr("Batch Rename from FITS..."), self)
|
|
942
1094
|
# self.act_batch_renamer.setIcon(QIcon(batch_renamer_icon_path)) # (optional icon)
|
|
943
1095
|
self.act_batch_renamer.triggered.connect(self._open_batch_renamer)
|
|
944
1096
|
|
|
945
|
-
self.act_astrobin_exporter = QAction("AstroBin Exporter...", self)
|
|
1097
|
+
self.act_astrobin_exporter = QAction(self.tr("AstroBin Exporter..."), self)
|
|
946
1098
|
# self.act_astrobin_exporter.setIcon(QIcon(astrobin_icon_path)) # optional icon
|
|
947
1099
|
self.act_astrobin_exporter.triggered.connect(self._open_astrobin_exporter)
|
|
948
1100
|
|
|
949
|
-
self.act_batch_convert = QAction("Batch Converter...", self)
|
|
1101
|
+
self.act_batch_convert = QAction(self.tr("Batch Converter..."), self)
|
|
950
1102
|
# self.act_batch_convert.setIcon(QIcon("path/to/icon.svg")) # optional later
|
|
951
1103
|
self.act_batch_convert.triggered.connect(self._open_batch_convert)
|
|
952
1104
|
|
|
953
|
-
self.act_copy_astrometry = QAction("Copy Astrometric Solution...", self)
|
|
1105
|
+
self.act_copy_astrometry = QAction(self.tr("Copy Astrometric Solution..."), self)
|
|
954
1106
|
self.act_copy_astrometry.triggered.connect(self._open_copy_astrometry)
|
|
955
1107
|
|
|
956
1108
|
# Create Mask
|
|
957
|
-
self.act_create_mask = QAction(QIcon(maskcreate_path), "Create Mask...", self)
|
|
1109
|
+
self.act_create_mask = QAction(QIcon(maskcreate_path), self.tr("Create Mask..."), self)
|
|
958
1110
|
self.act_create_mask.setIconVisibleInMenu(True)
|
|
959
|
-
self.act_create_mask.setStatusTip("Create a mask from the active image")
|
|
1111
|
+
self.act_create_mask.setStatusTip(self.tr("Create a mask from the active image"))
|
|
960
1112
|
self.act_create_mask.triggered.connect(self._action_create_mask)
|
|
961
1113
|
|
|
962
1114
|
# --- Masks ---
|
|
963
|
-
self.act_apply_mask = QAction(QIcon(maskapply_path), "Apply Mask", self)
|
|
964
|
-
self.act_apply_mask.setStatusTip("Apply a mask document to the active image")
|
|
1115
|
+
self.act_apply_mask = QAction(QIcon(maskapply_path), self.tr("Apply Mask"), self)
|
|
1116
|
+
self.act_apply_mask.setStatusTip(self.tr("Apply a mask document to the active image"))
|
|
965
1117
|
self.act_apply_mask.triggered.connect(self._apply_mask_menu)
|
|
966
1118
|
|
|
967
|
-
self.act_remove_mask = QAction(QIcon(maskremove_path), "Remove Active Mask", self)
|
|
968
|
-
self.act_remove_mask.setStatusTip("Remove the active mask from the active image")
|
|
1119
|
+
self.act_remove_mask = QAction(QIcon(maskremove_path), self.tr("Remove Active Mask"), self)
|
|
1120
|
+
self.act_remove_mask.setStatusTip(self.tr("Remove the active mask from the active image"))
|
|
969
1121
|
self.act_remove_mask.triggered.connect(self._remove_mask_menu)
|
|
970
1122
|
|
|
971
|
-
self.act_show_mask = QAction("Show Mask Overlay", self)
|
|
972
|
-
self.act_hide_mask = QAction("Hide Mask Overlay", self)
|
|
1123
|
+
self.act_show_mask = QAction(self.tr("Show Mask Overlay"), self)
|
|
1124
|
+
self.act_hide_mask = QAction(self.tr("Hide Mask Overlay"), self)
|
|
973
1125
|
self.act_show_mask.triggered.connect(self._show_mask_overlay)
|
|
974
1126
|
self.act_hide_mask.triggered.connect(self._hide_mask_overlay)
|
|
975
1127
|
|
|
976
|
-
self.act_invert_mask = QAction("Invert Mask", self)
|
|
1128
|
+
self.act_invert_mask = QAction(self.tr("Invert Mask"), self)
|
|
977
1129
|
self.act_invert_mask.triggered.connect(self._invert_mask)
|
|
978
1130
|
self.act_invert_mask.setShortcut("Ctrl+Shift+I")
|
|
979
1131
|
|
|
980
|
-
self.act_check_updates = QAction("Check for Updates...", self)
|
|
1132
|
+
self.act_check_updates = QAction(self.tr("Check for Updates..."), self)
|
|
981
1133
|
self.act_check_updates.triggered.connect(self.check_for_updates_now)
|
|
982
1134
|
|
|
983
|
-
self.act_docs = QAction("Documentation...", self)
|
|
984
|
-
self.act_docs.setStatusTip("Open the Seti Astro Suite Pro online documentation")
|
|
1135
|
+
self.act_docs = QAction(self.tr("Documentation..."), self)
|
|
1136
|
+
self.act_docs.setStatusTip(self.tr("Open the Seti Astro Suite Pro online documentation"))
|
|
985
1137
|
self.act_docs.triggered.connect(
|
|
986
1138
|
lambda: QDesktopServices.openUrl(QUrl("https://github.com/setiastro/setiastrosuitepro/wiki"))
|
|
987
1139
|
)
|
|
@@ -994,12 +1146,12 @@ class ToolbarMixin:
|
|
|
994
1146
|
# Fallback works everywhere
|
|
995
1147
|
self.act_docs.setShortcut(QKeySequence("F1"))
|
|
996
1148
|
|
|
997
|
-
self.act_view_bundles = QAction(QIcon(viewbundles_path), "View Bundles...", self)
|
|
998
|
-
self.act_view_bundles.setStatusTip("Create bundles of views; drop shortcuts to apply to all")
|
|
1149
|
+
self.act_view_bundles = QAction(QIcon(viewbundles_path), self.tr("View Bundles..."), self)
|
|
1150
|
+
self.act_view_bundles.setStatusTip(self.tr("Create bundles of views; drop shortcuts to apply to all"))
|
|
999
1151
|
self.act_view_bundles.triggered.connect(self._open_view_bundles)
|
|
1000
1152
|
|
|
1001
|
-
self.act_function_bundles = QAction(QIcon(functionbundles_path), "Function Bundles...", self)
|
|
1002
|
-
self.act_function_bundles.setStatusTip("Create and run bundles of functions/shortcuts")
|
|
1153
|
+
self.act_function_bundles = QAction(QIcon(functionbundles_path), self.tr("Function Bundles..."), self)
|
|
1154
|
+
self.act_function_bundles.setStatusTip(self.tr("Create and run bundles of functions/shortcuts"))
|
|
1003
1155
|
self.act_function_bundles.triggered.connect(self._open_function_bundles)
|
|
1004
1156
|
|
|
1005
1157
|
# give each action a stable id and register
|
|
@@ -1063,6 +1215,7 @@ class ToolbarMixin:
|
|
|
1063
1215
|
reg("geom_rotate_clockwise", self.act_geom_rot_cw)
|
|
1064
1216
|
reg("geom_rotate_counterclockwise",self.act_geom_rot_ccw)
|
|
1065
1217
|
reg("geom_rotate_180", self.act_geom_rot_180)
|
|
1218
|
+
reg("geom_rotate_any", self.act_geom_rot_any)
|
|
1066
1219
|
reg("geom_rescale", self.act_geom_rescale)
|
|
1067
1220
|
reg("project_new", self.act_project_new)
|
|
1068
1221
|
reg("project_save", self.act_project_save)
|
|
@@ -1254,6 +1407,7 @@ class ToolbarMixin:
|
|
|
1254
1407
|
a.setStatusTip(tip)
|
|
1255
1408
|
a.setEnabled(False)
|
|
1256
1409
|
|
|
1410
|
+
|
|
1257
1411
|
def _sync_link_action_state(self):
|
|
1258
1412
|
g = self._current_group_of_active()
|
|
1259
1413
|
self.act_link_group.blockSignals(True)
|
|
@@ -1299,6 +1453,7 @@ class ToolbarMixin:
|
|
|
1299
1453
|
QTimer.singleShot(0, self.update_undo_redo_action_labels)
|
|
1300
1454
|
|
|
1301
1455
|
def _refresh_mask_action_states(self):
|
|
1456
|
+
|
|
1302
1457
|
active_doc = self._active_doc()
|
|
1303
1458
|
|
|
1304
1459
|
can_apply = bool(active_doc and self._list_candidate_mask_sources(exclude_doc=active_doc))
|
|
@@ -1322,3 +1477,4 @@ class ToolbarMixin:
|
|
|
1322
1477
|
if hasattr(self, "act_hide_mask"):
|
|
1323
1478
|
self.act_hide_mask.setEnabled(has_mask and overlay_on)
|
|
1324
1479
|
|
|
1480
|
+
|