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
setiastro/saspro/__main__.py
CHANGED
|
@@ -11,6 +11,7 @@ called via the `main()` function when invoked as an entry point.
|
|
|
11
11
|
|
|
12
12
|
import sys
|
|
13
13
|
import os
|
|
14
|
+
from PyQt6.QtCore import QCoreApplication
|
|
14
15
|
|
|
15
16
|
# ---- Linux Qt stability guard (must run BEFORE any PyQt6 import) ----
|
|
16
17
|
# Default behavior: DO NOT override Wayland.
|
|
@@ -34,6 +35,11 @@ _app = None
|
|
|
34
35
|
# Flag to track if splash was initialized
|
|
35
36
|
_splash_initialized = False
|
|
36
37
|
|
|
38
|
+
from setiastro.saspro.versioning import get_app_version
|
|
39
|
+
_EARLY_VERSION = get_app_version("setiastrosuitepro")
|
|
40
|
+
|
|
41
|
+
VERSION = _EARLY_VERSION
|
|
42
|
+
|
|
37
43
|
def _init_splash():
|
|
38
44
|
"""Initialize the splash screen. Safe to call multiple times."""
|
|
39
45
|
global _splash, _app, _splash_initialized
|
|
@@ -43,7 +49,8 @@ def _init_splash():
|
|
|
43
49
|
|
|
44
50
|
# Minimal imports for splash screen
|
|
45
51
|
from PyQt6.QtWidgets import QApplication, QWidget
|
|
46
|
-
from PyQt6.QtCore import Qt, QCoreApplication, QRect
|
|
52
|
+
from PyQt6.QtCore import Qt, QCoreApplication, QRect, QPropertyAnimation, QEasingCurve
|
|
53
|
+
import time
|
|
47
54
|
from PyQt6.QtGui import QGuiApplication, QIcon, QPixmap, QColor, QPainter, QFont, QLinearGradient
|
|
48
55
|
|
|
49
56
|
|
|
@@ -81,28 +88,37 @@ def _init_splash():
|
|
|
81
88
|
except Exception:
|
|
82
89
|
pass
|
|
83
90
|
|
|
91
|
+
# Determine icon paths early
|
|
84
92
|
# Determine icon paths early
|
|
85
93
|
def _find_icon_path():
|
|
86
|
-
"""
|
|
94
|
+
"""Legacy fallback if resources import fails."""
|
|
87
95
|
if hasattr(sys, '_MEIPASS'):
|
|
88
96
|
base = sys._MEIPASS
|
|
89
97
|
else:
|
|
90
|
-
# When running from package, try to find images directory
|
|
91
98
|
try:
|
|
92
99
|
import setiastro
|
|
93
100
|
package_dir = os.path.dirname(os.path.abspath(setiastro.__file__))
|
|
94
|
-
# Check if images/ exists at package root level (for pip-installed packages)
|
|
95
101
|
package_parent = os.path.dirname(package_dir)
|
|
96
102
|
images_dir_installed = os.path.join(package_parent, 'images')
|
|
97
103
|
if os.path.exists(images_dir_installed):
|
|
98
104
|
base = package_parent
|
|
99
105
|
else:
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
base = os.path.dirname(
|
|
107
|
+
os.path.dirname(
|
|
108
|
+
os.path.dirname(
|
|
109
|
+
os.path.dirname(os.path.abspath(__file__))
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
)
|
|
102
113
|
except (ImportError, AttributeError):
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
114
|
+
base = os.path.dirname(
|
|
115
|
+
os.path.dirname(
|
|
116
|
+
os.path.dirname(
|
|
117
|
+
os.path.dirname(os.path.abspath(__file__))
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
)
|
|
121
|
+
|
|
106
122
|
candidates = [
|
|
107
123
|
os.path.join(base, "images", "astrosuitepro.png"),
|
|
108
124
|
os.path.join(base, "images", "astrosuitepro.ico"),
|
|
@@ -112,9 +128,25 @@ def _init_splash():
|
|
|
112
128
|
for p in candidates:
|
|
113
129
|
if os.path.exists(p):
|
|
114
130
|
return p
|
|
115
|
-
return
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
return "" # nothing found
|
|
132
|
+
|
|
133
|
+
# NEW: Prefer centralized resources resolver
|
|
134
|
+
try:
|
|
135
|
+
from setiastro.saspro.resources import icon_path, background_startup_path
|
|
136
|
+
_early_icon_path = icon_path
|
|
137
|
+
if not os.path.exists(_early_icon_path):
|
|
138
|
+
# fall back to legacy search if for some reason this is missing
|
|
139
|
+
_early_icon_path = _find_icon_path()
|
|
140
|
+
|
|
141
|
+
# Load startup background path
|
|
142
|
+
_startup_bg_path = background_startup_path
|
|
143
|
+
if not os.path.exists(_startup_bg_path):
|
|
144
|
+
_startup_bg_path = None
|
|
145
|
+
|
|
146
|
+
except Exception:
|
|
147
|
+
_early_icon_path = _find_icon_path()
|
|
148
|
+
_startup_bg_path = None
|
|
149
|
+
|
|
118
150
|
|
|
119
151
|
# =========================================================================
|
|
120
152
|
# PhotoshopStyleSplash - Custom splash screen widget
|
|
@@ -125,9 +157,9 @@ def _init_splash():
|
|
|
125
157
|
"""
|
|
126
158
|
def __init__(self, logo_path: str):
|
|
127
159
|
super().__init__()
|
|
128
|
-
self._version =
|
|
160
|
+
self._version = _EARLY_VERSION
|
|
129
161
|
self._build = ""
|
|
130
|
-
self.current_message = "Starting..."
|
|
162
|
+
self.current_message = QCoreApplication.translate("Splash", "Starting...")
|
|
131
163
|
self.progress_value = 0
|
|
132
164
|
|
|
133
165
|
# Window setup
|
|
@@ -155,6 +187,11 @@ def _init_splash():
|
|
|
155
187
|
# Load and scale logo
|
|
156
188
|
self.logo_pixmap = self._load_logo(logo_path)
|
|
157
189
|
|
|
190
|
+
# Load background image
|
|
191
|
+
self.bg_image_pixmap = QPixmap()
|
|
192
|
+
if _startup_bg_path:
|
|
193
|
+
self.bg_image_pixmap = QPixmap(_startup_bg_path)
|
|
194
|
+
|
|
158
195
|
# Fonts
|
|
159
196
|
self.title_font = QFont("Segoe UI", 28, QFont.Weight.Bold)
|
|
160
197
|
self.subtitle_font = QFont("Segoe UI", 11)
|
|
@@ -193,15 +230,42 @@ def _init_splash():
|
|
|
193
230
|
_app.processEvents()
|
|
194
231
|
|
|
195
232
|
def setProgress(self, value: int):
|
|
196
|
-
"""Update progress (0-100)."""
|
|
197
|
-
|
|
233
|
+
"""Update progress (0-100) with smooth animation."""
|
|
234
|
+
target = max(0, min(100, value))
|
|
235
|
+
start = self.progress_value
|
|
236
|
+
|
|
237
|
+
# If jumping backwards or small change, just set it
|
|
238
|
+
if target <= start or (target - start) < 1:
|
|
239
|
+
self.progress_value = target
|
|
240
|
+
self.repaint()
|
|
241
|
+
if _app: _app.processEvents()
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
# Animate forward
|
|
245
|
+
steps = 15 # number of frames for the slide
|
|
246
|
+
# We want the total slide to take ~100-150ms max to feel responsive but smooth
|
|
247
|
+
dt = 0.005 # 5ms per frame
|
|
248
|
+
|
|
249
|
+
for i in range(1, steps + 1):
|
|
250
|
+
# Ease out interpolator
|
|
251
|
+
t = i / steps
|
|
252
|
+
# Quadratic ease out: f(t) = -t*(t-2)
|
|
253
|
+
factor = -t * (t - 2)
|
|
254
|
+
|
|
255
|
+
cur = start + (target - start) * factor
|
|
256
|
+
self.progress_value = cur
|
|
257
|
+
self.repaint()
|
|
258
|
+
if _app: _app.processEvents()
|
|
259
|
+
time.sleep(dt)
|
|
260
|
+
|
|
261
|
+
self.progress_value = target
|
|
198
262
|
self.repaint()
|
|
199
263
|
if _app:
|
|
200
264
|
_app.processEvents()
|
|
201
265
|
|
|
202
266
|
def setBuildInfo(self, version: str, build: str):
|
|
203
267
|
"""Update version and build info once available."""
|
|
204
|
-
self._version =
|
|
268
|
+
self._version = _EARLY_VERSION
|
|
205
269
|
self._build = build
|
|
206
270
|
self.repaint()
|
|
207
271
|
|
|
@@ -220,6 +284,45 @@ def _init_splash():
|
|
|
220
284
|
gradient.setColorAt(1.0, QColor(10, 10, 20))
|
|
221
285
|
painter.fillRect(0, 0, w, h, gradient)
|
|
222
286
|
|
|
287
|
+
# --- Background Image (Centered with Fade Out) ---
|
|
288
|
+
if not self.bg_image_pixmap.isNull():
|
|
289
|
+
# Create a temporary pixmap to handle the masking
|
|
290
|
+
temp = QPixmap(w, h)
|
|
291
|
+
temp.fill(Qt.GlobalColor.transparent)
|
|
292
|
+
|
|
293
|
+
ptmp = QPainter(temp)
|
|
294
|
+
ptmp.setRenderHint(QPainter.RenderHint.Antialiasing)
|
|
295
|
+
ptmp.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
|
|
296
|
+
|
|
297
|
+
# Scale image to cover the entire splash screen
|
|
298
|
+
scaled = self.bg_image_pixmap.scaled(
|
|
299
|
+
w, h,
|
|
300
|
+
Qt.AspectRatioMode.KeepAspectRatioByExpanding,
|
|
301
|
+
Qt.TransformationMode.SmoothTransformation
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Center the image
|
|
305
|
+
sx = (w - scaled.width()) // 2
|
|
306
|
+
sy = (h - scaled.height()) // 2
|
|
307
|
+
ptmp.drawPixmap(sx, sy, scaled)
|
|
308
|
+
|
|
309
|
+
# Apply Fade Out Mask (Gradient Alpha)
|
|
310
|
+
ptmp.setCompositionMode(QPainter.CompositionMode.CompositionMode_DestinationIn)
|
|
311
|
+
fade_gradient = QLinearGradient(0, 0, 0, h)
|
|
312
|
+
# Keep top half fully visible (subject to global opacity)
|
|
313
|
+
fade_gradient.setColorAt(0.0, QColor(0, 0, 0, 255))
|
|
314
|
+
fade_gradient.setColorAt(0.5, QColor(0, 0, 0, 255))
|
|
315
|
+
# Fade out completely at the bottom
|
|
316
|
+
fade_gradient.setColorAt(1.0, QColor(0, 0, 0, 0))
|
|
317
|
+
ptmp.fillRect(0, 0, w, h, fade_gradient)
|
|
318
|
+
ptmp.end()
|
|
319
|
+
|
|
320
|
+
# Draw combined result with 50% opacity
|
|
321
|
+
painter.save()
|
|
322
|
+
painter.setOpacity(0.25)
|
|
323
|
+
painter.drawPixmap(0, 0, temp)
|
|
324
|
+
painter.restore()
|
|
325
|
+
|
|
223
326
|
# --- Subtle border ---
|
|
224
327
|
painter.setPen(QColor(60, 60, 80))
|
|
225
328
|
painter.drawRect(0, 0, w - 1, h - 1)
|
|
@@ -239,14 +342,14 @@ def _init_splash():
|
|
|
239
342
|
# --- Subtitle with version ---
|
|
240
343
|
painter.setFont(self.subtitle_font)
|
|
241
344
|
painter.setPen(QColor(180, 180, 200))
|
|
242
|
-
subtitle_text =
|
|
345
|
+
subtitle_text = QCoreApplication.translate("Splash", "Version {0}").format(self._version)
|
|
243
346
|
|
|
244
347
|
if self._build:
|
|
245
348
|
if self._build == "dev":
|
|
246
349
|
# No build_info → running from source checkout
|
|
247
|
-
subtitle_text += " • Running locally from source code"
|
|
350
|
+
subtitle_text += QCoreApplication.translate("Splash", " • Running locally from source code")
|
|
248
351
|
else:
|
|
249
|
-
subtitle_text +=
|
|
352
|
+
subtitle_text += QCoreApplication.translate("Splash", " • Build {0}").format(self._build)
|
|
250
353
|
|
|
251
354
|
subtitle_rect = QRect(0, 270, w, 25)
|
|
252
355
|
painter.drawText(subtitle_rect, Qt.AlignmentFlag.AlignCenter, subtitle_text)
|
|
@@ -290,20 +393,59 @@ def _init_splash():
|
|
|
290
393
|
self.hide()
|
|
291
394
|
self.close()
|
|
292
395
|
self.deleteLater()
|
|
396
|
+
|
|
397
|
+
def start_fade_out(self):
|
|
398
|
+
"""Smoothly fade out the splash screen."""
|
|
399
|
+
self._anim = QPropertyAnimation(self, b"windowOpacity")
|
|
400
|
+
self._anim.setDuration(1000)
|
|
401
|
+
self._anim.setStartValue(1.0)
|
|
402
|
+
self._anim.setEndValue(0.0)
|
|
403
|
+
self._anim.setEasingCurve(QEasingCurve.Type.OutQuad)
|
|
404
|
+
self._anim.finished.connect(self.finish)
|
|
405
|
+
self._anim.start()
|
|
293
406
|
|
|
407
|
+
def start_fade_in(self):
|
|
408
|
+
"""Smoothly fade in the splash screen."""
|
|
409
|
+
self.setWindowOpacity(0.0)
|
|
410
|
+
self._anim = QPropertyAnimation(self, b"windowOpacity")
|
|
411
|
+
self._anim.setDuration(800)
|
|
412
|
+
self._anim.setStartValue(0.0)
|
|
413
|
+
self._anim.setEndValue(1.0)
|
|
414
|
+
self._anim.setEasingCurve(QEasingCurve.Type.InQuad)
|
|
415
|
+
self._anim.start()
|
|
416
|
+
|
|
294
417
|
# --- Show splash IMMEDIATELY ---
|
|
295
418
|
_splash = _EarlySplash(_early_icon_path)
|
|
419
|
+
_splash.start_fade_in()
|
|
296
420
|
_splash.show()
|
|
297
|
-
|
|
421
|
+
|
|
422
|
+
# Block briefly to allow fade-in to progress smoothly before heavy imports start
|
|
423
|
+
# We use a busy loop with processEvents to keep the UI responsive during fade
|
|
424
|
+
t_start = time.time()
|
|
425
|
+
while time.time() - t_start < 0.85: # slightly longer than animation
|
|
426
|
+
_app.processEvents()
|
|
427
|
+
if _splash.windowOpacity() >= 0.99:
|
|
428
|
+
break
|
|
429
|
+
time.sleep(0.01)
|
|
430
|
+
|
|
431
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Initializing Python runtime..."))
|
|
298
432
|
_splash.setProgress(2)
|
|
299
433
|
_app.processEvents()
|
|
300
434
|
|
|
435
|
+
# Load translation BEFORE any other widgets are created
|
|
436
|
+
try:
|
|
437
|
+
from setiastro.saspro.i18n import load_language, get_translations_dir
|
|
438
|
+
ok = load_language(app=_app)
|
|
439
|
+
except Exception as e:
|
|
440
|
+
print("i18n load failed:", repr(e))
|
|
441
|
+
|
|
442
|
+
|
|
301
443
|
_splash_initialized = True
|
|
302
444
|
|
|
303
445
|
|
|
304
|
-
# Initialize splash
|
|
305
|
-
|
|
306
|
-
|
|
446
|
+
# Initialize splash immediately before any heavy imports
|
|
447
|
+
# This ensures the splash is visible while PyTorch, NumPy, etc. are loading
|
|
448
|
+
_init_splash()
|
|
307
449
|
|
|
308
450
|
|
|
309
451
|
# =============================================================================
|
|
@@ -317,7 +459,7 @@ def _update_splash(msg: str, progress: int):
|
|
|
317
459
|
_splash.setMessage(msg)
|
|
318
460
|
_splash.setProgress(progress)
|
|
319
461
|
|
|
320
|
-
_update_splash("Loading PyTorch runtime...", 5)
|
|
462
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading PyTorch runtime..."), 5)
|
|
321
463
|
|
|
322
464
|
from setiastro.saspro.runtime_torch import (
|
|
323
465
|
add_runtime_to_sys_path,
|
|
@@ -329,7 +471,7 @@ add_runtime_to_sys_path(status_cb=lambda *_: None)
|
|
|
329
471
|
_ban_shadow_torch_paths(status_cb=lambda *_: None)
|
|
330
472
|
_purge_bad_torch_from_sysmodules(status_cb=lambda *_: None)
|
|
331
473
|
|
|
332
|
-
_update_splash("Loading standard libraries...", 10)
|
|
474
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading standard libraries..."), 10)
|
|
333
475
|
|
|
334
476
|
# ----------------------------------------
|
|
335
477
|
# Standard library imports (consolidated)
|
|
@@ -358,18 +500,18 @@ from pathlib import Path
|
|
|
358
500
|
from typing import Dict, List, Optional, Set, Tuple
|
|
359
501
|
from urllib.parse import quote, quote_plus
|
|
360
502
|
|
|
361
|
-
_update_splash("Loading NumPy...", 15)
|
|
503
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading NumPy..."), 15)
|
|
362
504
|
|
|
363
505
|
# ----------------------------------------
|
|
364
506
|
# Third-party imports
|
|
365
507
|
# ----------------------------------------
|
|
366
508
|
import numpy as np
|
|
367
509
|
|
|
368
|
-
_update_splash("Loading image libraries...", 20)
|
|
510
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading image libraries..."), 20)
|
|
369
511
|
from tifffile import imwrite
|
|
370
512
|
from setiastro.saspro.xisf import XISF
|
|
371
513
|
|
|
372
|
-
_update_splash("Configuring matplotlib...", 25)
|
|
514
|
+
_update_splash(QCoreApplication.translate("Splash", "Configuring matplotlib..."), 25)
|
|
373
515
|
from setiastro.saspro.config_bootstrap import ensure_mpl_config_dir
|
|
374
516
|
_MPL_CFG_DIR = ensure_mpl_config_dir()
|
|
375
517
|
|
|
@@ -440,7 +582,7 @@ def get_lightkurve():
|
|
|
440
582
|
return _lightkurve_module if _lightkurve_module else None
|
|
441
583
|
# --- End lazy imports ---
|
|
442
584
|
|
|
443
|
-
_update_splash("Loading UI utilities...", 30)
|
|
585
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading UI utilities..."), 30)
|
|
444
586
|
|
|
445
587
|
# Shared UI utilities (avoiding code duplication)
|
|
446
588
|
from setiastro.saspro.widgets.common_utilities import (
|
|
@@ -451,7 +593,7 @@ from setiastro.saspro.widgets.common_utilities import (
|
|
|
451
593
|
install_crash_handlers,
|
|
452
594
|
)
|
|
453
595
|
|
|
454
|
-
_update_splash("Loading reproject library...", 35)
|
|
596
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading reproject library..."), 35)
|
|
455
597
|
|
|
456
598
|
# Reproject for WCS-based alignment
|
|
457
599
|
try:
|
|
@@ -459,7 +601,7 @@ try:
|
|
|
459
601
|
except ImportError:
|
|
460
602
|
reproject_interp = None # fallback if not installed
|
|
461
603
|
|
|
462
|
-
_update_splash("Loading OpenCV...", 40)
|
|
604
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading OpenCV..."), 40)
|
|
463
605
|
|
|
464
606
|
# OpenCV for transform estimation & warping
|
|
465
607
|
try:
|
|
@@ -469,7 +611,7 @@ except ImportError:
|
|
|
469
611
|
OPENCV_AVAILABLE = False
|
|
470
612
|
|
|
471
613
|
|
|
472
|
-
_update_splash("Loading PyQt6 components...", 45)
|
|
614
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading PyQt6 components..."), 45)
|
|
473
615
|
|
|
474
616
|
#################################
|
|
475
617
|
# PyQt6 Imports
|
|
@@ -487,7 +629,8 @@ from PyQt6.QtGui import (QPixmap, QColor, QIcon, QKeySequence, QShortcut, QGuiAp
|
|
|
487
629
|
)
|
|
488
630
|
|
|
489
631
|
# ----- QtCore -----
|
|
490
|
-
from PyQt6.QtCore import (Qt, pyqtSignal, QCoreApplication, QTimer, QSize, QSignalBlocker, QModelIndex, QThread, QUrl, QSettings, QEvent, QByteArray, QObject
|
|
632
|
+
from PyQt6.QtCore import (Qt, pyqtSignal, QCoreApplication, QTimer, QSize, QSignalBlocker, QModelIndex, QThread, QUrl, QSettings, QEvent, QByteArray, QObject,
|
|
633
|
+
QPropertyAnimation, QEasingCurve
|
|
491
634
|
)
|
|
492
635
|
|
|
493
636
|
from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
|
@@ -500,14 +643,8 @@ except Exception:
|
|
|
500
643
|
BUILD_TIMESTAMP = "dev"
|
|
501
644
|
|
|
502
645
|
|
|
503
|
-
try:
|
|
504
|
-
from importlib.metadata import version as _get_version
|
|
505
|
-
VERSION = _get_version("setiastrosuitepro")
|
|
506
|
-
except Exception:
|
|
507
|
-
# Fallback if package not installed (e.g. running from source without install)
|
|
508
|
-
VERSION = "1.6.0-dev"
|
|
509
646
|
|
|
510
|
-
_update_splash("Loading resources...", 50)
|
|
647
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading resources..."), 50)
|
|
511
648
|
|
|
512
649
|
# Icon paths are now centralized in setiastro.saspro.resources module
|
|
513
650
|
from setiastro.saspro.resources import (
|
|
@@ -536,7 +673,7 @@ from setiastro.saspro.resources import (
|
|
|
536
673
|
)
|
|
537
674
|
|
|
538
675
|
|
|
539
|
-
_update_splash("Configuring Qt message handler...", 55)
|
|
676
|
+
_update_splash(QCoreApplication.translate("Splash", "Configuring Qt message handler..."), 55)
|
|
540
677
|
|
|
541
678
|
from PyQt6.QtCore import qInstallMessageHandler, QtMsgType
|
|
542
679
|
|
|
@@ -552,7 +689,7 @@ def _qt_msg_handler(mode, ctx, msg):
|
|
|
552
689
|
|
|
553
690
|
qInstallMessageHandler(_qt_msg_handler)
|
|
554
691
|
|
|
555
|
-
_update_splash("Loading MDI widgets...", 60)
|
|
692
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading MDI widgets..."), 60)
|
|
556
693
|
|
|
557
694
|
# MDI widgets imported from setiastro.saspro.mdi_widgets
|
|
558
695
|
from setiastro.saspro.mdi_widgets import (
|
|
@@ -582,11 +719,11 @@ from setiastro.saspro.file_utils import (
|
|
|
582
719
|
WIN_RESERVED_NAMES as _WIN_RESERVED,
|
|
583
720
|
)
|
|
584
721
|
|
|
585
|
-
_update_splash("Loading main window module...", 65)
|
|
722
|
+
_update_splash(QCoreApplication.translate("Splash", "Loading main window module..."), 65)
|
|
586
723
|
|
|
587
724
|
from setiastro.saspro.gui.main_window import AstroSuiteProMainWindow
|
|
588
725
|
|
|
589
|
-
_update_splash("Modules loaded, finalizing...", 70)
|
|
726
|
+
_update_splash(QCoreApplication.translate("Splash", "Modules loaded, finalizing..."), 70)
|
|
590
727
|
|
|
591
728
|
|
|
592
729
|
def main():
|
|
@@ -607,7 +744,7 @@ def main():
|
|
|
607
744
|
# Update splash with build info now that we have VERSION and BUILD_TIMESTAMP
|
|
608
745
|
if _splash:
|
|
609
746
|
_splash.setBuildInfo(VERSION, BUILD_TIMESTAMP)
|
|
610
|
-
_splash.setMessage("Setting up logging...")
|
|
747
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Setting up logging..."))
|
|
611
748
|
_splash.setProgress(72)
|
|
612
749
|
|
|
613
750
|
# --- Logging (catch unhandled exceptions to a file) ---
|
|
@@ -674,14 +811,14 @@ def main():
|
|
|
674
811
|
|
|
675
812
|
# Setup crash handlers and app icon
|
|
676
813
|
if _splash:
|
|
677
|
-
_splash.setMessage("Installing crash handlers...")
|
|
814
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Installing crash handlers..."))
|
|
678
815
|
_splash.setProgress(75)
|
|
679
816
|
install_crash_handlers(_app)
|
|
680
817
|
_app.setWindowIcon(QIcon(windowslogo_path if os.path.exists(windowslogo_path) else icon_path))
|
|
681
818
|
|
|
682
819
|
# --- Windows exe / multiprocessing friendly ---
|
|
683
820
|
if _splash:
|
|
684
|
-
_splash.setMessage("Configuring multiprocessing...")
|
|
821
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Configuring multiprocessing..."))
|
|
685
822
|
_splash.setProgress(78)
|
|
686
823
|
try:
|
|
687
824
|
multiprocessing.freeze_support()
|
|
@@ -695,23 +832,23 @@ def main():
|
|
|
695
832
|
|
|
696
833
|
try:
|
|
697
834
|
if _splash:
|
|
698
|
-
_splash.setMessage("Loading image manager...")
|
|
835
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Loading image manager..."))
|
|
699
836
|
_splash.setProgress(80)
|
|
700
837
|
from setiastro.saspro.legacy.image_manager import ImageManager
|
|
701
838
|
|
|
702
839
|
if _splash:
|
|
703
|
-
_splash.setMessage("Suppressing warnings...")
|
|
840
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Suppressing warnings..."))
|
|
704
841
|
_splash.setProgress(82)
|
|
705
842
|
from matplotlib import MatplotlibDeprecationWarning
|
|
706
843
|
warnings.filterwarnings("ignore", category=MatplotlibDeprecationWarning)
|
|
707
844
|
|
|
708
845
|
if _splash:
|
|
709
|
-
_splash.setMessage("Creating image manager...")
|
|
846
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Creating image manager..."))
|
|
710
847
|
_splash.setProgress(85)
|
|
711
848
|
imgr = ImageManager(max_slots=100)
|
|
712
849
|
|
|
713
850
|
if _splash:
|
|
714
|
-
_splash.setMessage("Building main window...")
|
|
851
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Building main window..."))
|
|
715
852
|
_splash.setProgress(90)
|
|
716
853
|
win = AstroSuiteProMainWindow(
|
|
717
854
|
image_manager=imgr,
|
|
@@ -720,9 +857,35 @@ def main():
|
|
|
720
857
|
)
|
|
721
858
|
|
|
722
859
|
if _splash:
|
|
723
|
-
_splash.setMessage("Showing main window...")
|
|
860
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Showing main window..."))
|
|
724
861
|
_splash.setProgress(95)
|
|
862
|
+
|
|
863
|
+
# --- Smooth Transition: App Fade In + Splash Fade Out ---
|
|
864
|
+
# MITIGATION: Prevent "White Flash" on startup
|
|
865
|
+
# 1. Force a dark background immediately so if opacity lags, it's dark not white
|
|
866
|
+
win.setStyleSheet("QMainWindow { background-color: #0F0F19; }")
|
|
867
|
+
# 2. Ensure native window handle exists so setWindowOpacity works immediately
|
|
868
|
+
win.winId()
|
|
869
|
+
# 3. Set opacity to 0
|
|
870
|
+
win.setWindowOpacity(0.0)
|
|
871
|
+
|
|
725
872
|
win.show()
|
|
873
|
+
|
|
874
|
+
# 1. Animate Main Window Fade In
|
|
875
|
+
anim_app = QPropertyAnimation(win, b"windowOpacity")
|
|
876
|
+
anim_app.setDuration(1200)
|
|
877
|
+
anim_app.setStartValue(0.0)
|
|
878
|
+
anim_app.setEndValue(1.0)
|
|
879
|
+
anim_app.setEasingCurve(QEasingCurve.Type.OutQuad)
|
|
880
|
+
|
|
881
|
+
# Cleanup temp stylesheet upon completion to avoid interfering with ThemeMixin
|
|
882
|
+
def _on_fade_in_finished():
|
|
883
|
+
win.setStyleSheet("")
|
|
884
|
+
if hasattr(win, "on_fade_in_complete"):
|
|
885
|
+
win.on_fade_in_complete()
|
|
886
|
+
|
|
887
|
+
anim_app.finished.connect(_on_fade_in_finished)
|
|
888
|
+
anim_app.start()
|
|
726
889
|
|
|
727
890
|
# Start background Numba warmup after UI is visible
|
|
728
891
|
try:
|
|
@@ -732,22 +895,20 @@ def main():
|
|
|
732
895
|
pass # Non-critical if warmup fails
|
|
733
896
|
|
|
734
897
|
if _splash:
|
|
735
|
-
_splash.setMessage("Ready!")
|
|
898
|
+
_splash.setMessage(QCoreApplication.translate("Splash", "Ready!"))
|
|
736
899
|
_splash.setProgress(100)
|
|
737
900
|
_app.processEvents()
|
|
738
901
|
|
|
739
|
-
# Small delay to
|
|
902
|
+
# Small delay to ensure "Ready!" is seen briefly before fade starts
|
|
740
903
|
import time
|
|
741
|
-
time.sleep(0.
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
#
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
_splash.close()
|
|
750
|
-
_splash.deleteLater()
|
|
904
|
+
time.sleep(0.1)
|
|
905
|
+
|
|
906
|
+
# 2. Animate Splash Fade Out
|
|
907
|
+
# Note: We do NOT use finish() directly here. The animation calls it when done.
|
|
908
|
+
_splash.start_fade_out()
|
|
909
|
+
|
|
910
|
+
# NOTE: We keep a reference to _splash (global) so it doesn't get GC'd during animation.
|
|
911
|
+
# It will deleteLater() itself.
|
|
751
912
|
|
|
752
913
|
if BUILD_TIMESTAMP == "dev":
|
|
753
914
|
build_label = "running from local source code"
|
|
@@ -770,8 +931,8 @@ def main():
|
|
|
770
931
|
logging.error("Unhandled exception occurred\n%s", tb)
|
|
771
932
|
msg = QMessageBox(None)
|
|
772
933
|
msg.setIcon(QMessageBox.Icon.Critical)
|
|
773
|
-
msg.setWindowTitle("Application Error")
|
|
774
|
-
msg.setText("An unexpected error occurred.")
|
|
934
|
+
msg.setWindowTitle(QCoreApplication.translate("Main", "Application Error"))
|
|
935
|
+
msg.setText(QCoreApplication.translate("Main", "An unexpected error occurred."))
|
|
775
936
|
msg.setInformativeText(tb.splitlines()[-1] if tb else "See details.")
|
|
776
937
|
msg.setDetailedText(tb)
|
|
777
938
|
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
|