2026-04-20 14:33:13 +02:00
|
|
|
|
"""sn_verfahrensgebiet/ui/tabs/working_tab.py – Bearbeitungs-Tab.
|
|
|
|
|
|
Verwaltet die Verfahrensgebiet-Abgrenzung und ALKIS-Integration.
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
2026-03-06 10:11:17 +01:00
|
|
|
|
from sn_basis.functions.qt_wrapper import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QMessageBox
|
|
|
|
|
|
from sn_basis.functions.qt_wrapper import Qt
|
|
|
|
|
|
from sn_basis.functions import Qgis, QgsProject #QgsMessageLog
|
2026-03-27 11:19:07 +01:00
|
|
|
|
from sn_basis.functions.qgisui_wrapper import QgsMapLayerComboBox
|
|
|
|
|
|
from sn_basis.functions.qgiscore_wrapper import QgsMapLayerProxyModel
|
|
|
|
|
|
from sn_basis.functions.verfahrensgebiet_manager import get_verfahrensgebiet_layer_id, set_verfahrensgebiet_layer_id
|
2025-11-18 16:10:58 +01:00
|
|
|
|
from qgis.utils import iface
|
|
|
|
|
|
|
|
|
|
|
|
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import verfahrensgebiet_alkis, LoadStatus
|
2026-03-06 10:11:17 +01:00
|
|
|
|
from sn_basis.functions.message_wrapper import success, info, warning, error
|
|
|
|
|
|
from sn_basis.functions.ly_style_wrapper import apply_style
|
2025-11-18 16:10:58 +01:00
|
|
|
|
|
|
|
|
|
|
class WorkingTab(QWidget):
|
2026-04-20 14:33:13 +02:00
|
|
|
|
"""Tab für die Verfahrensgebiet-Bearbeitung und Verwaltung.
|
|
|
|
|
|
|
|
|
|
|
|
Attributes:
|
|
|
|
|
|
tab_title: Anzeigetitel des Tabs ("Bearbeitung")
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
tab_title = "Bearbeitung"
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
2026-04-20 14:33:13 +02:00
|
|
|
|
"""Initialisiert den Working-Tab mit Verfahrensgebiet-Verwaltung.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
parent: Übergeordnetes Widget
|
|
|
|
|
|
"""
|
2025-11-18 16:10:58 +01:00
|
|
|
|
super().__init__(parent)
|
|
|
|
|
|
|
|
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
|
|
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
|
|
|
|
|
|
|
|
|
|
# Abschnitt 1: Verfahrensgebiet
|
|
|
|
|
|
row_verf_header = QHBoxLayout()
|
|
|
|
|
|
lbl_verf = QLabel("<b>Verfahrensgebiet</b>")
|
|
|
|
|
|
self.haken_verf = self._haken_label()
|
|
|
|
|
|
row_verf_header.addWidget(lbl_verf)
|
|
|
|
|
|
row_verf_header.addWidget(self.haken_verf)
|
|
|
|
|
|
row_verf_header.addStretch()
|
|
|
|
|
|
layout.addLayout(row_verf_header)
|
|
|
|
|
|
|
|
|
|
|
|
row_verf_buttons = QHBoxLayout()
|
|
|
|
|
|
self.btn_verf_alkis = QPushButton("Aus ALKIS laden")
|
|
|
|
|
|
self.btn_verf_shape = QPushButton("Aus Shape laden")
|
|
|
|
|
|
row_verf_buttons.addWidget(self.btn_verf_alkis)
|
|
|
|
|
|
row_verf_buttons.addWidget(self.btn_verf_shape)
|
|
|
|
|
|
layout.addLayout(row_verf_buttons)
|
|
|
|
|
|
|
2026-03-27 11:19:07 +01:00
|
|
|
|
# Abschnitt 1b: Verfahrensgebiet-Layer auswählen
|
|
|
|
|
|
row_layer_label = QHBoxLayout()
|
|
|
|
|
|
lbl_layer = QLabel("Oder: Verfahrensgebiet-Layer auswählen")
|
|
|
|
|
|
lbl_layer.setStyleSheet("font-style: italic; color: gray; margin-top: 8px;")
|
|
|
|
|
|
row_layer_label.addWidget(lbl_layer)
|
|
|
|
|
|
row_layer_label.addStretch()
|
|
|
|
|
|
layout.addLayout(row_layer_label)
|
|
|
|
|
|
|
|
|
|
|
|
self.verf_layer_combo = QgsMapLayerComboBox(self)
|
|
|
|
|
|
self.verf_layer_combo.setFilters(QgsMapLayerProxyModel.VectorLayer)
|
|
|
|
|
|
self.verf_layer_combo.setToolTip("Wähle den Verfahrensgebiet-Layer, oder lasse es leer für Automatik")
|
|
|
|
|
|
self.verf_layer_combo.layerChanged.connect(self._on_verf_layer_changed)
|
|
|
|
|
|
layout.addWidget(self.verf_layer_combo)
|
|
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
# Abschnitt 2: Flurstücke (Platzhalter für spätere Implementierung)
|
2026-03-27 11:19:07 +01:00
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
row_flurst_header = QHBoxLayout()
|
|
|
|
|
|
lbl_flurst = QLabel("<b>Flurstücke</b>")
|
|
|
|
|
|
self.haken_flurst = self._haken_label()
|
|
|
|
|
|
row_flurst_header.addWidget(lbl_flurst)
|
|
|
|
|
|
row_flurst_header.addWidget(self.haken_flurst)
|
|
|
|
|
|
row_flurst_header.addStretch()
|
|
|
|
|
|
layout.addLayout(row_flurst_header)
|
|
|
|
|
|
|
|
|
|
|
|
row_flurst_buttons = QHBoxLayout()
|
|
|
|
|
|
self.btn_flurst_alkis = QPushButton("Aus ALKIS laden")
|
|
|
|
|
|
self.btn_flurst_shape = QPushButton("Aus Shape laden")
|
|
|
|
|
|
row_flurst_buttons.addWidget(self.btn_flurst_alkis)
|
|
|
|
|
|
row_flurst_buttons.addWidget(self.btn_flurst_shape)
|
|
|
|
|
|
layout.addLayout(row_flurst_buttons)
|
|
|
|
|
|
|
|
|
|
|
|
layout.addStretch()
|
|
|
|
|
|
self.setLayout(layout)
|
|
|
|
|
|
|
|
|
|
|
|
# Signale verbinden
|
|
|
|
|
|
self.btn_verf_alkis.clicked.connect(self.handle_verf_alkis)
|
|
|
|
|
|
# self.btn_verf_shape.clicked.connect(self.handle_verf_shape)
|
|
|
|
|
|
# self.btn_flurst_alkis.clicked.connect(self.handle_flurst_alkis)
|
|
|
|
|
|
# self.btn_flurst_shape.clicked.connect(self.handle_flurst_shape)
|
|
|
|
|
|
|
2026-03-27 11:19:07 +01:00
|
|
|
|
# Beim Init: aktuelle Verfahrensgebiet-Layer-ID laden und im Dropdown anzeigen
|
|
|
|
|
|
self._restore_verf_layer_selection()
|
|
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
def handle_verf_alkis(self):
|
|
|
|
|
|
self._set_busy(self.btn_verf_alkis, True)
|
|
|
|
|
|
try:
|
|
|
|
|
|
layer, status = verfahrensgebiet_alkis(self)
|
|
|
|
|
|
if not layer or not layer.isValid():
|
2026-04-08 14:36:39 +02:00
|
|
|
|
set_verfahrensgebiet_layer_id("")
|
2025-11-18 16:10:58 +01:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if status in (LoadStatus.FIRST, LoadStatus.RELOAD):
|
|
|
|
|
|
# Gemeinsame Logik für erstmaliges und erneutes Laden
|
|
|
|
|
|
QgsProject.instance().addMapLayer(layer)
|
|
|
|
|
|
iface.mapCanvas().setExtent(layer.extent())
|
2026-03-06 10:11:17 +01:00
|
|
|
|
#iface.mapCanvas().refresh()
|
2026-04-08 14:36:39 +02:00
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
apply_style(layer, "verfahrensgebiet.qml")
|
2026-03-06 10:11:17 +01:00
|
|
|
|
iface.mapCanvas().refresh()
|
2025-11-18 16:10:58 +01:00
|
|
|
|
self.setze_haken(self.haken_verf, True)
|
|
|
|
|
|
|
2026-04-08 14:36:39 +02:00
|
|
|
|
# Dropdown + Variable explizit synchronisieren.
|
|
|
|
|
|
self.verf_layer_combo.setLayer(layer)
|
|
|
|
|
|
self._on_verf_layer_changed(layer)
|
|
|
|
|
|
|
2025-11-18 16:10:58 +01:00
|
|
|
|
# Unterschied nur in der Meldung
|
|
|
|
|
|
msg = "erstmalig geladen" if status == LoadStatus.FIRST else "neu geladen"
|
|
|
|
|
|
success("Verfahrensgebiet", f"Layer wurde {msg}.", duration=5)
|
|
|
|
|
|
|
|
|
|
|
|
elif status == LoadStatus.KEEP:
|
2026-04-08 14:36:39 +02:00
|
|
|
|
self.verf_layer_combo.setLayer(layer)
|
|
|
|
|
|
self._on_verf_layer_changed(layer)
|
2025-11-18 16:10:58 +01:00
|
|
|
|
info("Verfahrensgebiet", "Vorhandener Layer wurde behalten.", duration=4)
|
|
|
|
|
|
|
|
|
|
|
|
elif status == LoadStatus.NONE:
|
2026-04-08 14:36:39 +02:00
|
|
|
|
self._on_verf_layer_changed(None)
|
2025-11-18 16:10:58 +01:00
|
|
|
|
warning("Verfahrensgebiet", "Layer konnte nicht geladen werden.", duration=None)
|
|
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
self._set_busy(self.btn_verf_alkis, False)
|
|
|
|
|
|
|
|
|
|
|
|
def _set_busy(self, button: QPushButton, busy: bool):
|
|
|
|
|
|
button.setEnabled(not busy)
|
|
|
|
|
|
if busy:
|
|
|
|
|
|
button.setText("Lade ...")
|
|
|
|
|
|
else:
|
|
|
|
|
|
button.setText("Aus ALKIS laden")
|
|
|
|
|
|
|
|
|
|
|
|
def _haken_label(self) -> QLabel:
|
|
|
|
|
|
label = QLabel()
|
|
|
|
|
|
label.setFixedSize(20, 20)
|
|
|
|
|
|
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
|
|
|
|
label.setText("") # Start ohne Haken
|
|
|
|
|
|
return label
|
|
|
|
|
|
|
|
|
|
|
|
def setze_haken(self, label: QLabel, aktiv: bool):
|
|
|
|
|
|
"""Zeigt oder entfernt den grünen Haken (Unicode), ohne Theme-Icons."""
|
|
|
|
|
|
if aktiv:
|
|
|
|
|
|
label.setText("✓")
|
|
|
|
|
|
label.setStyleSheet("color: #2ea043; font-weight: bold;")
|
|
|
|
|
|
else:
|
|
|
|
|
|
label.setText("")
|
|
|
|
|
|
label.setStyleSheet("")
|
|
|
|
|
|
|
2026-03-27 11:19:07 +01:00
|
|
|
|
def _on_verf_layer_changed(self, layer) -> None:
|
|
|
|
|
|
"""Callback: Nutzer hat einen anderen Layer im Dropdown gewählt."""
|
|
|
|
|
|
if layer and layer.isValid():
|
|
|
|
|
|
# Speichere die Layer-ID in der zentralen Variable
|
|
|
|
|
|
set_verfahrensgebiet_layer_id(layer.id())
|
|
|
|
|
|
else:
|
|
|
|
|
|
# Layer is None oder invalid; leere die Variable
|
|
|
|
|
|
set_verfahrensgebiet_layer_id("")
|
|
|
|
|
|
|
|
|
|
|
|
def _restore_verf_layer_selection(self) -> None:
|
|
|
|
|
|
"""Beim Tab-Init: Lade die zuletzt gespeicherte Verfahrensgebiet-Layer-ID."""
|
|
|
|
|
|
layer_id = get_verfahrensgebiet_layer_id()
|
|
|
|
|
|
if layer_id:
|
|
|
|
|
|
# Versuche, den Layer im Projekt zu finden
|
|
|
|
|
|
try:
|
|
|
|
|
|
project = QgsProject.instance()
|
|
|
|
|
|
layer = project.mapLayer(layer_id)
|
|
|
|
|
|
if layer and layer.isValid():
|
|
|
|
|
|
self.verf_layer_combo.setLayer(layer)
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
pass
|