setiastrosuitepro 1.6.1__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/__init__.py +2 -0
- 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/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/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/saspro/__init__.py +20 -0
- setiastro/saspro/__main__.py +809 -0
- setiastro/saspro/_generated/__init__.py +7 -0
- setiastro/saspro/_generated/build_info.py +2 -0
- setiastro/saspro/abe.py +1295 -0
- setiastro/saspro/abe_preset.py +196 -0
- setiastro/saspro/aberration_ai.py +694 -0
- setiastro/saspro/aberration_ai_preset.py +224 -0
- setiastro/saspro/accel_installer.py +218 -0
- setiastro/saspro/accel_workers.py +30 -0
- setiastro/saspro/add_stars.py +621 -0
- setiastro/saspro/astrobin_exporter.py +1007 -0
- setiastro/saspro/astrospike.py +153 -0
- setiastro/saspro/astrospike_python.py +1839 -0
- setiastro/saspro/autostretch.py +196 -0
- setiastro/saspro/backgroundneutral.py +560 -0
- setiastro/saspro/batch_convert.py +325 -0
- setiastro/saspro/batch_renamer.py +519 -0
- setiastro/saspro/blemish_blaster.py +488 -0
- setiastro/saspro/blink_comparator_pro.py +2926 -0
- setiastro/saspro/bundles.py +61 -0
- setiastro/saspro/bundles_dock.py +114 -0
- setiastro/saspro/cheat_sheet.py +178 -0
- setiastro/saspro/clahe.py +342 -0
- setiastro/saspro/comet_stacking.py +1377 -0
- setiastro/saspro/common_tr.py +107 -0
- setiastro/saspro/config.py +38 -0
- setiastro/saspro/config_bootstrap.py +40 -0
- setiastro/saspro/config_manager.py +316 -0
- setiastro/saspro/continuum_subtract.py +1617 -0
- setiastro/saspro/convo.py +1397 -0
- setiastro/saspro/convo_preset.py +414 -0
- setiastro/saspro/copyastro.py +187 -0
- setiastro/saspro/cosmicclarity.py +1564 -0
- setiastro/saspro/cosmicclarity_preset.py +407 -0
- setiastro/saspro/crop_dialog_pro.py +956 -0
- setiastro/saspro/crop_preset.py +189 -0
- setiastro/saspro/curve_editor_pro.py +2544 -0
- setiastro/saspro/curves_preset.py +375 -0
- setiastro/saspro/debayer.py +670 -0
- setiastro/saspro/debug_utils.py +29 -0
- setiastro/saspro/dnd_mime.py +35 -0
- setiastro/saspro/doc_manager.py +2641 -0
- setiastro/saspro/exoplanet_detector.py +2166 -0
- setiastro/saspro/file_utils.py +284 -0
- setiastro/saspro/fitsmodifier.py +745 -0
- setiastro/saspro/fix_bom.py +32 -0
- setiastro/saspro/free_torch_memory.py +48 -0
- setiastro/saspro/frequency_separation.py +1343 -0
- setiastro/saspro/function_bundle.py +1594 -0
- setiastro/saspro/generate_translations.py +2378 -0
- setiastro/saspro/ghs_dialog_pro.py +660 -0
- setiastro/saspro/ghs_preset.py +284 -0
- setiastro/saspro/graxpert.py +634 -0
- setiastro/saspro/graxpert_preset.py +287 -0
- setiastro/saspro/gui/__init__.py +0 -0
- setiastro/saspro/gui/main_window.py +8567 -0
- setiastro/saspro/gui/mixins/__init__.py +33 -0
- setiastro/saspro/gui/mixins/dock_mixin.py +263 -0
- setiastro/saspro/gui/mixins/file_mixin.py +443 -0
- setiastro/saspro/gui/mixins/geometry_mixin.py +403 -0
- setiastro/saspro/gui/mixins/header_mixin.py +441 -0
- setiastro/saspro/gui/mixins/mask_mixin.py +421 -0
- setiastro/saspro/gui/mixins/menu_mixin.py +361 -0
- setiastro/saspro/gui/mixins/theme_mixin.py +367 -0
- setiastro/saspro/gui/mixins/toolbar_mixin.py +1457 -0
- setiastro/saspro/gui/mixins/update_mixin.py +309 -0
- setiastro/saspro/gui/mixins/view_mixin.py +435 -0
- setiastro/saspro/halobgon.py +462 -0
- setiastro/saspro/header_viewer.py +448 -0
- setiastro/saspro/headless_utils.py +88 -0
- setiastro/saspro/histogram.py +753 -0
- setiastro/saspro/history_explorer.py +939 -0
- setiastro/saspro/i18n.py +156 -0
- setiastro/saspro/image_combine.py +414 -0
- setiastro/saspro/image_peeker_pro.py +1601 -0
- setiastro/saspro/imageops/__init__.py +37 -0
- setiastro/saspro/imageops/mdi_snap.py +292 -0
- setiastro/saspro/imageops/scnr.py +36 -0
- setiastro/saspro/imageops/starbasedwhitebalance.py +210 -0
- setiastro/saspro/imageops/stretch.py +244 -0
- setiastro/saspro/isophote.py +1179 -0
- setiastro/saspro/layers.py +208 -0
- setiastro/saspro/layers_dock.py +714 -0
- setiastro/saspro/lazy_imports.py +193 -0
- setiastro/saspro/legacy/__init__.py +2 -0
- setiastro/saspro/legacy/image_manager.py +2226 -0
- setiastro/saspro/legacy/numba_utils.py +3659 -0
- setiastro/saspro/legacy/xisf.py +1071 -0
- setiastro/saspro/linear_fit.py +534 -0
- setiastro/saspro/live_stacking.py +1830 -0
- setiastro/saspro/log_bus.py +5 -0
- setiastro/saspro/logging_config.py +460 -0
- setiastro/saspro/luminancerecombine.py +309 -0
- setiastro/saspro/main_helpers.py +201 -0
- setiastro/saspro/mask_creation.py +928 -0
- setiastro/saspro/masks_core.py +56 -0
- setiastro/saspro/mdi_widgets.py +353 -0
- setiastro/saspro/memory_utils.py +666 -0
- setiastro/saspro/metadata_patcher.py +75 -0
- setiastro/saspro/mfdeconv.py +3826 -0
- setiastro/saspro/mfdeconv_earlystop.py +71 -0
- setiastro/saspro/mfdeconvcudnn.py +3263 -0
- setiastro/saspro/mfdeconvsport.py +2382 -0
- setiastro/saspro/minorbodycatalog.py +567 -0
- setiastro/saspro/morphology.py +382 -0
- setiastro/saspro/multiscale_decomp.py +1290 -0
- setiastro/saspro/nbtorgb_stars.py +531 -0
- setiastro/saspro/numba_utils.py +3044 -0
- setiastro/saspro/numba_warmup.py +141 -0
- setiastro/saspro/ops/__init__.py +9 -0
- setiastro/saspro/ops/command_help_dialog.py +623 -0
- setiastro/saspro/ops/command_runner.py +217 -0
- setiastro/saspro/ops/commands.py +1594 -0
- setiastro/saspro/ops/script_editor.py +1102 -0
- setiastro/saspro/ops/scripts.py +1413 -0
- setiastro/saspro/ops/settings.py +679 -0
- setiastro/saspro/parallel_utils.py +554 -0
- setiastro/saspro/pedestal.py +121 -0
- setiastro/saspro/perfect_palette_picker.py +1070 -0
- setiastro/saspro/pipeline.py +110 -0
- setiastro/saspro/pixelmath.py +1600 -0
- setiastro/saspro/plate_solver.py +2444 -0
- setiastro/saspro/project_io.py +797 -0
- setiastro/saspro/psf_utils.py +136 -0
- setiastro/saspro/psf_viewer.py +549 -0
- setiastro/saspro/pyi_rthook_astroquery.py +95 -0
- setiastro/saspro/remove_green.py +314 -0
- setiastro/saspro/remove_stars.py +1625 -0
- setiastro/saspro/remove_stars_preset.py +404 -0
- setiastro/saspro/resources.py +477 -0
- setiastro/saspro/rgb_combination.py +207 -0
- setiastro/saspro/rgb_extract.py +19 -0
- setiastro/saspro/rgbalign.py +723 -0
- setiastro/saspro/runtime_imports.py +7 -0
- setiastro/saspro/runtime_torch.py +754 -0
- setiastro/saspro/save_options.py +72 -0
- setiastro/saspro/selective_color.py +1552 -0
- setiastro/saspro/sfcc.py +1430 -0
- setiastro/saspro/shortcuts.py +3043 -0
- setiastro/saspro/signature_insert.py +1099 -0
- setiastro/saspro/stacking_suite.py +18181 -0
- setiastro/saspro/star_alignment.py +7420 -0
- setiastro/saspro/star_alignment_preset.py +329 -0
- setiastro/saspro/star_metrics.py +49 -0
- setiastro/saspro/star_spikes.py +681 -0
- setiastro/saspro/star_stretch.py +470 -0
- setiastro/saspro/stat_stretch.py +506 -0
- setiastro/saspro/status_log_dock.py +78 -0
- setiastro/saspro/subwindow.py +3267 -0
- setiastro/saspro/supernovaasteroidhunter.py +1716 -0
- setiastro/saspro/swap_manager.py +99 -0
- setiastro/saspro/torch_backend.py +89 -0
- setiastro/saspro/torch_rejection.py +434 -0
- setiastro/saspro/translations/de_translations.py +3733 -0
- setiastro/saspro/translations/es_translations.py +3923 -0
- setiastro/saspro/translations/fr_translations.py +3842 -0
- setiastro/saspro/translations/integrate_translations.py +234 -0
- setiastro/saspro/translations/it_translations.py +3662 -0
- setiastro/saspro/translations/ja_translations.py +3585 -0
- setiastro/saspro/translations/pt_translations.py +3853 -0
- setiastro/saspro/translations/saspro_de.qm +0 -0
- setiastro/saspro/translations/saspro_de.ts +253 -0
- setiastro/saspro/translations/saspro_es.qm +0 -0
- setiastro/saspro/translations/saspro_es.ts +12520 -0
- setiastro/saspro/translations/saspro_fr.qm +0 -0
- setiastro/saspro/translations/saspro_fr.ts +12514 -0
- setiastro/saspro/translations/saspro_it.qm +0 -0
- setiastro/saspro/translations/saspro_it.ts +12520 -0
- setiastro/saspro/translations/saspro_ja.qm +0 -0
- setiastro/saspro/translations/saspro_ja.ts +257 -0
- setiastro/saspro/translations/saspro_pt.qm +0 -0
- setiastro/saspro/translations/saspro_pt.ts +257 -0
- setiastro/saspro/translations/saspro_zh.qm +0 -0
- setiastro/saspro/translations/saspro_zh.ts +12520 -0
- setiastro/saspro/translations/zh_translations.py +3659 -0
- setiastro/saspro/versioning.py +71 -0
- setiastro/saspro/view_bundle.py +1555 -0
- setiastro/saspro/wavescale_hdr.py +624 -0
- setiastro/saspro/wavescale_hdr_preset.py +101 -0
- setiastro/saspro/wavescalede.py +658 -0
- setiastro/saspro/wavescalede_preset.py +230 -0
- setiastro/saspro/wcs_update.py +374 -0
- setiastro/saspro/whitebalance.py +456 -0
- setiastro/saspro/widgets/__init__.py +48 -0
- setiastro/saspro/widgets/common_utilities.py +306 -0
- setiastro/saspro/widgets/graphics_views.py +122 -0
- setiastro/saspro/widgets/image_utils.py +518 -0
- setiastro/saspro/widgets/preview_dialogs.py +280 -0
- setiastro/saspro/widgets/spinboxes.py +275 -0
- setiastro/saspro/widgets/themed_buttons.py +13 -0
- setiastro/saspro/widgets/wavelet_utils.py +299 -0
- setiastro/saspro/window_shelf.py +185 -0
- setiastro/saspro/xisf.py +1123 -0
- setiastrosuitepro-1.6.1.dist-info/METADATA +267 -0
- setiastrosuitepro-1.6.1.dist-info/RECORD +342 -0
- setiastrosuitepro-1.6.1.dist-info/WHEEL +4 -0
- setiastrosuitepro-1.6.1.dist-info/entry_points.txt +6 -0
- setiastrosuitepro-1.6.1.dist-info/licenses/LICENSE +674 -0
- setiastrosuitepro-1.6.1.dist-info/licenses/license.txt +2580 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# pro/gui/mixins/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
GUI Mixins for AstroSuiteProMainWindow.
|
|
4
|
+
|
|
5
|
+
This package contains modular mixins that separate different aspects of the main window
|
|
6
|
+
into logical, maintainable components.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from .dock_mixin import DockMixin
|
|
11
|
+
from .menu_mixin import MenuMixin
|
|
12
|
+
from .toolbar_mixin import ToolbarMixin
|
|
13
|
+
from .file_mixin import FileMixin
|
|
14
|
+
from .theme_mixin import ThemeMixin
|
|
15
|
+
from .geometry_mixin import GeometryMixin
|
|
16
|
+
from .view_mixin import ViewMixin
|
|
17
|
+
from .header_mixin import HeaderMixin
|
|
18
|
+
from .mask_mixin import MaskMixin
|
|
19
|
+
from .update_mixin import UpdateMixin
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"DockMixin",
|
|
23
|
+
"MenuMixin",
|
|
24
|
+
"ToolbarMixin",
|
|
25
|
+
"FileMixin",
|
|
26
|
+
"ThemeMixin",
|
|
27
|
+
"GeometryMixin",
|
|
28
|
+
"ViewMixin",
|
|
29
|
+
"HeaderMixin",
|
|
30
|
+
"MaskMixin",
|
|
31
|
+
"UpdateMixin",
|
|
32
|
+
]
|
|
33
|
+
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# pro/gui/mixins/dock_mixin.py
|
|
2
|
+
"""
|
|
3
|
+
Dock management mixin for AstroSuiteProMainWindow.
|
|
4
|
+
|
|
5
|
+
This mixin contains all dock-related functionality: initialization,
|
|
6
|
+
visibility management, and registration in menus.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from PyQt6.QtCore import Qt, QTimer
|
|
12
|
+
from PyQt6.QtWidgets import (
|
|
13
|
+
QDockWidget, QPlainTextEdit, QTreeWidget, QTreeWidgetItem,
|
|
14
|
+
QVBoxLayout, QWidget, QTextEdit, QListWidget, QListWidgetItem,
|
|
15
|
+
QAbstractItemView, QApplication
|
|
16
|
+
)
|
|
17
|
+
from PyQt6.QtGui import QTextCursor
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from PyQt6.QtWidgets import QAction
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DockMixin:
|
|
24
|
+
"""
|
|
25
|
+
Mixin for dock widget management.
|
|
26
|
+
|
|
27
|
+
Provides methods for creating, managing, and synchronizing dock widgets
|
|
28
|
+
in the main window.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def _init_log_dock(self):
|
|
32
|
+
"""Initialize the system log dock widget."""
|
|
33
|
+
self.log_dock = QDockWidget(self.tr("System Log"), self)
|
|
34
|
+
self.log_dock.setObjectName("LogDock")
|
|
35
|
+
self.log_dock.setAllowedAreas(
|
|
36
|
+
Qt.DockWidgetArea.BottomDockWidgetArea
|
|
37
|
+
| Qt.DockWidgetArea.TopDockWidgetArea
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
self.log_text = QPlainTextEdit(self.log_dock)
|
|
41
|
+
self.log_text.setReadOnly(True)
|
|
42
|
+
self.log_text.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap)
|
|
43
|
+
self.log_dock.setWidget(self.log_text)
|
|
44
|
+
|
|
45
|
+
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.log_dock)
|
|
46
|
+
|
|
47
|
+
self.act_toggle_log = self.log_dock.toggleViewAction()
|
|
48
|
+
self.act_toggle_log.setText(self.tr("Show System Log Panel"))
|
|
49
|
+
|
|
50
|
+
def _append_log_text(self, text: str):
|
|
51
|
+
"""Append text to the system log dock."""
|
|
52
|
+
if not text:
|
|
53
|
+
return
|
|
54
|
+
# Append to the bottom and keep view scrolled
|
|
55
|
+
cursor = self.log_text.textCursor()
|
|
56
|
+
cursor.movePosition(QTextCursor.MoveOperation.End)
|
|
57
|
+
cursor.insertText(text)
|
|
58
|
+
self.log_text.setTextCursor(cursor)
|
|
59
|
+
self.log_text.ensureCursorVisible()
|
|
60
|
+
|
|
61
|
+
def _hook_stdout_stderr(self):
|
|
62
|
+
"""Hook stdout/stderr to redirect to the system log dock."""
|
|
63
|
+
import sys
|
|
64
|
+
from setiastro.saspro.mdi_widgets import QtLogStream
|
|
65
|
+
|
|
66
|
+
# Remember original streams so we still print to real console.
|
|
67
|
+
self._orig_stdout = sys.stdout
|
|
68
|
+
self._orig_stderr = sys.stderr
|
|
69
|
+
|
|
70
|
+
self._qt_stdout = QtLogStream(self._orig_stdout, self)
|
|
71
|
+
self._qt_stderr = QtLogStream(self._orig_stderr, self)
|
|
72
|
+
|
|
73
|
+
self._qt_stdout.text_emitted.connect(self._append_log_text)
|
|
74
|
+
self._qt_stderr.text_emitted.connect(self._append_log_text)
|
|
75
|
+
|
|
76
|
+
sys.stdout = self._qt_stdout
|
|
77
|
+
sys.stderr = self._qt_stderr
|
|
78
|
+
|
|
79
|
+
def _register_dock_in_view_menu(self, dock: QDockWidget, action: QAction | None = None):
|
|
80
|
+
"""
|
|
81
|
+
Register a dock widget's toggle action in the View → Panels menu.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
dock: The QDockWidget to register
|
|
85
|
+
action: Optional custom action (if None, uses dock.toggleViewAction())
|
|
86
|
+
"""
|
|
87
|
+
if not hasattr(self, "_view_panels_menu"):
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
if action is None:
|
|
91
|
+
action = dock.toggleViewAction()
|
|
92
|
+
|
|
93
|
+
self._view_panels_menu.addAction(action)
|
|
94
|
+
|
|
95
|
+
def _remove_dock_from_view_menu(self, action: QAction):
|
|
96
|
+
"""
|
|
97
|
+
Remove a dock's toggle action from the View → Panels menu.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
action: The action to remove
|
|
101
|
+
"""
|
|
102
|
+
if not hasattr(self, "_view_panels_menu"):
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
self._view_panels_menu.removeAction(action)
|
|
106
|
+
|
|
107
|
+
def _init_explorer_dock(self):
|
|
108
|
+
self.explorer = QListWidget()
|
|
109
|
+
# Enter/Return or single-activation: focus if open, else open
|
|
110
|
+
self.explorer.itemActivated.connect(self._activate_or_open_from_explorer)
|
|
111
|
+
# Double-click: same behavior
|
|
112
|
+
self.explorer.itemDoubleClicked.connect(self._activate_or_open_from_explorer)
|
|
113
|
+
|
|
114
|
+
dock = QDockWidget(self.tr("Explorer"), self)
|
|
115
|
+
dock.setWidget(self.explorer)
|
|
116
|
+
dock.setObjectName("ExplorerDock")
|
|
117
|
+
self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, dock)
|
|
118
|
+
|
|
119
|
+
def _init_console_dock(self):
|
|
120
|
+
self.console = QListWidget()
|
|
121
|
+
|
|
122
|
+
# Allow multi-row selection so Select All actually highlights everything
|
|
123
|
+
self.console.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
|
124
|
+
|
|
125
|
+
# Right-click context menu
|
|
126
|
+
self.console.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
|
127
|
+
self.console.customContextMenuRequested.connect(self._on_console_context_menu)
|
|
128
|
+
|
|
129
|
+
dock = QDockWidget(self.tr("Console / Status"), self)
|
|
130
|
+
dock.setWidget(self.console)
|
|
131
|
+
dock.setObjectName("ConsoleDock")
|
|
132
|
+
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, dock)
|
|
133
|
+
|
|
134
|
+
def _init_status_log_dock(self):
|
|
135
|
+
from setiastro.saspro.status_log_dock import StatusLogDock
|
|
136
|
+
from setiastro.saspro.log_bus import LogBus
|
|
137
|
+
|
|
138
|
+
# Create the dock
|
|
139
|
+
self.status_log_dock = StatusLogDock(self) # your dock widget class
|
|
140
|
+
self.status_log_dock.setObjectName("StatusLogDock") # stable name for restoreState/menu
|
|
141
|
+
self.status_log_dock.setAllowedAreas(
|
|
142
|
+
Qt.DockWidgetArea.LeftDockWidgetArea
|
|
143
|
+
| Qt.DockWidgetArea.RightDockWidgetArea
|
|
144
|
+
| Qt.DockWidgetArea.BottomDockWidgetArea
|
|
145
|
+
| Qt.DockWidgetArea.TopDockWidgetArea
|
|
146
|
+
)
|
|
147
|
+
# Default area (will be overridden by restoreState if present)
|
|
148
|
+
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.status_log_dock)
|
|
149
|
+
|
|
150
|
+
# Expose the dock globally so dialogs can show/raise it
|
|
151
|
+
app = QApplication.instance()
|
|
152
|
+
app._sasd_status_console = self.status_log_dock
|
|
153
|
+
|
|
154
|
+
# Ensure a global log bus and wire bus -> dock (queued; thread-safe)
|
|
155
|
+
if not hasattr(app, "_sasd_log_bus"):
|
|
156
|
+
app._sasd_log_bus = LogBus()
|
|
157
|
+
app._sasd_log_bus.posted.connect(
|
|
158
|
+
self.status_log_dock.append_line,
|
|
159
|
+
type=Qt.ConnectionType.QueuedConnection
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# First-run placement (only if no prior saved layout)
|
|
163
|
+
self._first_place_status_log_if_needed()
|
|
164
|
+
|
|
165
|
+
def _init_layers_dock(self):
|
|
166
|
+
from setiastro.saspro.layers_dock import LayersDock
|
|
167
|
+
|
|
168
|
+
self.layers_dock = LayersDock(self)
|
|
169
|
+
self.layers_dock.setObjectName("LayersDock")
|
|
170
|
+
# put it on the right, *below* header viewer if you dock that at right too
|
|
171
|
+
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.layers_dock)
|
|
172
|
+
# ensure the header viewer sits above, layers below
|
|
173
|
+
try:
|
|
174
|
+
self.splitDockWidget(self.header_dock, self.layers_dock, Qt.Orientation.Vertical)
|
|
175
|
+
except Exception:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
def _init_header_viewer_dock(self):
|
|
179
|
+
from setiastro.saspro.header_viewer import HeaderViewerDock
|
|
180
|
+
|
|
181
|
+
self.header_viewer = HeaderViewerDock(self)
|
|
182
|
+
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.header_viewer)
|
|
183
|
+
|
|
184
|
+
# Bind the dock to DocManager so it tracks the ACTIVE subwindow only.
|
|
185
|
+
# Make sure self.doc_manager.set_mdi_area(mdi) was already called.
|
|
186
|
+
self.header_viewer.attach_doc_manager(self.doc_manager)
|
|
187
|
+
|
|
188
|
+
# Optional: keep it strictly active-only (default). Flip to True to restore hover-follow behavior.
|
|
189
|
+
# self.header_viewer.set_follow_hover(False)
|
|
190
|
+
|
|
191
|
+
# Seed once with whatever is currently active.
|
|
192
|
+
try:
|
|
193
|
+
self.header_viewer.set_document(self.doc_manager.get_active_document())
|
|
194
|
+
except Exception:
|
|
195
|
+
pass
|
|
196
|
+
|
|
197
|
+
# ⌠Remove this old line; it let random mouse-over updates hijack the dock:
|
|
198
|
+
# self.currentDocumentChanged.disconnect(self.header_viewer.set_document) # if previously connected
|
|
199
|
+
# (If you prefer to keep the signal for explicit tab switches, it's fine to leave
|
|
200
|
+
# it connected--the dock's new guard will ignore non-active/hover docs.)
|
|
201
|
+
|
|
202
|
+
def _populate_view_panels_menu(self):
|
|
203
|
+
"""Rebuild 'View Panels' with all current dock widgets (ordered nicely)."""
|
|
204
|
+
menu = self._ensure_view_panels_menu()
|
|
205
|
+
menu.clear()
|
|
206
|
+
self._view_panels_actions = {}
|
|
207
|
+
|
|
208
|
+
# Collect every QDockWidget that exists right now
|
|
209
|
+
docks: list[QDockWidget] = self.findChildren(QDockWidget)
|
|
210
|
+
|
|
211
|
+
# Friendly ordering for common ones; others follow alphabetically.
|
|
212
|
+
order_hint = {
|
|
213
|
+
"Explorer": 10,
|
|
214
|
+
"Console / Status": 20,
|
|
215
|
+
"Header Viewer": 30,
|
|
216
|
+
"Layers": 40,
|
|
217
|
+
"Window Shelf": 50,
|
|
218
|
+
"Command Search": 60,
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
def key_fn(d: QDockWidget):
|
|
222
|
+
t = d.windowTitle()
|
|
223
|
+
return (order_hint.get(t, 1000), t.lower())
|
|
224
|
+
|
|
225
|
+
for dock in sorted(docks, key=key_fn):
|
|
226
|
+
self._register_dock_in_view_menu(dock)
|
|
227
|
+
|
|
228
|
+
def _add_doc_to_explorer(self, doc):
|
|
229
|
+
base = self._normalize_base_doc(doc)
|
|
230
|
+
|
|
231
|
+
# de-dupe by identity on base
|
|
232
|
+
for i in range(self.explorer.count()):
|
|
233
|
+
it = self.explorer.item(i)
|
|
234
|
+
if it.data(Qt.ItemDataRole.UserRole) is base:
|
|
235
|
+
# refresh text in case dims/name changed
|
|
236
|
+
it.setText(self._format_explorer_title(base))
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
item = QListWidgetItem(self._format_explorer_title(base))
|
|
240
|
+
item.setData(Qt.ItemDataRole.UserRole, base)
|
|
241
|
+
fp = (base.metadata or {}).get("file_path")
|
|
242
|
+
if fp:
|
|
243
|
+
item.setToolTip(fp)
|
|
244
|
+
self.explorer.addItem(item)
|
|
245
|
+
|
|
246
|
+
# keep row label in sync with edits/resizes/renames
|
|
247
|
+
try:
|
|
248
|
+
base.changed.connect(lambda *_: self._update_explorer_item_for_doc(base))
|
|
249
|
+
except Exception:
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
def _remove_doc_from_explorer(self, doc):
|
|
253
|
+
"""
|
|
254
|
+
Remove either the exact doc or its base (handles ROI proxies).
|
|
255
|
+
"""
|
|
256
|
+
base = self._normalize_base_doc(doc)
|
|
257
|
+
for i in range(self.explorer.count()):
|
|
258
|
+
it = self.explorer.item(i)
|
|
259
|
+
d = it.data(Qt.ItemDataRole.UserRole)
|
|
260
|
+
if d is doc or d is base:
|
|
261
|
+
self.explorer.takeItem(i)
|
|
262
|
+
break
|
|
263
|
+
|