Files
Plugin_SN_Plan41/ui/tab_a_ui.py

309 lines
9.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
sn_plan41/ui/tab_a_ui.py UI für Tab A (Daten)
"""
from typing import Optional
from sn_basis.functions.qt_wrapper import ( # type: ignore
QWidget,
QVBoxLayout,
QLabel,
QPushButton,
QToolButton,
QFileDialog,
QMessageBox,
QTabWidget,
ToolButtonTextBesideIcon,
ArrowDown,
ArrowRight,
SizePolicyPreferred,
SizePolicyMaximum,
)
from sn_basis.functions.qgisui_wrapper import ( # type: ignore
QgsFileWidget,
QgsMapLayerComboBox,
add_dock_widget,
)
from sn_basis.functions.qgiscore_wrapper import ( # type: ignore
QgsProject,
QgsMapLayerProxyModel,
)
from sn_basis.functions.message_wrapper import ( # type: ignore
info,
warning,
error,
)
from sn_basis.functions.dialog_wrapper import ask_yes_no # type: ignore
from sn_basis.functions.sys_wrapper import file_exists # type: ignore
from sn_plan41.ui.tab_a_logic import TabALogic # type: ignore
class TabA(QWidget):
"""
UI-Klasse für Tab A (Daten).
Enthält ausschließlich UI-Code und delegiert Logik an TabALogic.
"""
def __init__(self, parent=None, build_ui: bool=True):
super().__init__(parent)
self.parent=parent
self.tab_title="Daten"
self.logic = TabALogic()
self.verfahrens_db: Optional[str] = None
self.lokale_linkliste: Optional[str] = None
if build_ui:
self._build_ui()
self._restore_state()
# ---------------------------------------------------------
# UI-Aufbau
# ---------------------------------------------------------
def _build_ui(self) -> None:
main_layout = QVBoxLayout()
main_layout.setSpacing(4)
main_layout.setContentsMargins(4, 4, 4, 4)
# -------------------------------
# Verfahrens-Datenbank
# -------------------------------
self.group_button = QToolButton()
self.group_button.setText("Verfahrens-Datenbank")
self.group_button.setCheckable(True)
self.group_button.setChecked(True)
self.group_button.setToolButtonStyle(ToolButtonTextBesideIcon)
self.group_button.setArrowType(ArrowDown)
self.group_button.setStyleSheet("font-weight: bold;")
self.group_button.toggled.connect(self._toggle_group)
main_layout.addWidget(self.group_button)
self.group_content = QWidget()
self.group_content.setSizePolicy(SizePolicyPreferred, SizePolicyMaximum)
group_layout = QVBoxLayout()
group_layout.setSpacing(2)
group_layout.setContentsMargins(10, 4, 4, 4)
group_layout.addWidget(QLabel("bestehende Datei auswählen"))
self.file_widget = QgsFileWidget()
self.file_widget.setStorageMode(QgsFileWidget.GetFile)
self.file_widget.setFilter("Geopackage (*.gpkg)")
self.file_widget.fileChanged.connect(self._on_verfahrens_db_changed)
group_layout.addWidget(self.file_widget)
group_layout.addWidget(QLabel("-oder-"))
self.btn_new = QPushButton("Neue Verfahrens-DB anlegen")
self.btn_new.clicked.connect(self._create_new_gpkg)
group_layout.addWidget(self.btn_new)
self.group_content.setLayout(group_layout)
main_layout.addWidget(self.group_content)
# -------------------------------
# Optionale Linkliste
# -------------------------------
self.optional_button = QToolButton()
self.optional_button.setText("Optional: Lokale Linkliste")
self.optional_button.setCheckable(True)
self.optional_button.setChecked(False)
self.optional_button.setToolButtonStyle(ToolButtonTextBesideIcon)
self.optional_button.setArrowType(ArrowRight)
self.optional_button.setStyleSheet("font-weight: bold; margin-top: 6px;")
self.optional_button.toggled.connect(self._toggle_optional)
main_layout.addWidget(self.optional_button)
self.optional_content = QWidget()
self.optional_content.setSizePolicy(SizePolicyPreferred, SizePolicyMaximum)
optional_layout = QVBoxLayout()
optional_layout.setSpacing(2)
optional_layout.setContentsMargins(10, 4, 4, 20)
optional_layout.addWidget(QLabel("(frei lassen für globale Linkliste)"))
self.linkliste_widget = QgsFileWidget()
self.linkliste_widget.setStorageMode(QgsFileWidget.GetFile)
self.linkliste_widget.setFilter("Excelliste (*.xlsx)")
self.linkliste_widget.fileChanged.connect(self._on_linkliste_changed)
optional_layout.addWidget(self.linkliste_widget)
self.optional_content.setLayout(optional_layout)
self.optional_content.setVisible(False)
main_layout.addWidget(self.optional_content)
# -------------------------------
# Layer-Auswahl
# -------------------------------
layer_label = QLabel("Verfahrensgebiet-Layer auswählen")
layer_label.setStyleSheet("font-weight: bold; margin-top: 6px;")
main_layout.addWidget(layer_label)
self.layer_combo = QgsMapLayerComboBox()
self.layer_combo.setSizePolicy(SizePolicyPreferred, SizePolicyMaximum)
self.layer_combo.setFilters(QgsMapLayerProxyModel.VectorLayer)
self.layer_combo.layerChanged.connect(self._on_layer_changed)
main_layout.addWidget(self.layer_combo)
main_layout.addStretch(1)
self.setLayout(main_layout)
# ---------------------------------------------------------
# State Restore
# ---------------------------------------------------------
def _restore_state(self) -> None:
db = self.logic.load_verfahrens_db()
if db:
self.verfahrens_db = db
self.file_widget.setFilePath(db)
self._update_group_color()
link = self.logic.load_linkliste()
if link:
self.lokale_linkliste = link
self.linkliste_widget.setFilePath(link)
layer_id = self.logic.load_verfahrensgebiet_layer_id()
if layer_id:
layer = QgsProject.instance().mapLayer(layer_id)
if layer:
self.layer_combo.setLayer(layer)
# ---------------------------------------------------------
# UI-Callbacks
# ---------------------------------------------------------
def _toggle_group(self, checked: bool):
"""
Klappt den Gruppenbereich ein oder aus.
"""
if not hasattr(self, "group_button"):
return
self.group_button.setArrowType(
ArrowDown if checked else ArrowRight
)
self.group_content.setVisible(checked)
def _toggle_optional(self, checked: bool):
"""
Klappt den optionalen Bereich ein oder aus.
"""
if not hasattr(self, "optional_button"):
return
self.group_button.setArrowType(
ArrowDown if checked else ArrowRight
)
self.optional_content.setVisible(checked)
def _on_verfahrens_db_changed(self, path: str) -> None:
if not path:
self.verfahrens_db = None
self.logic.set_verfahrens_db(None)
self._update_group_color()
return
if not path.lower().endswith(".gpkg"):
path += ".gpkg"
self.file_widget.setFilePath(path)
if not file_exists(path):
warning("Datei nicht gefunden", f"Die Datei existiert nicht:\n{path}")
self.file_widget.setFilePath("")
return
self.verfahrens_db = path
self.logic.set_verfahrens_db(path)
self._update_group_color()
def _on_linkliste_changed(self, path: str) -> None:
if not path:
self.lokale_linkliste = None
self.logic.set_linkliste(None)
return
if not path.lower().endswith(".xlsx"):
path += ".xlsx"
self.linkliste_widget.setFilePath(path)
if not file_exists(path):
warning("Datei nicht gefunden", f"Die Datei existiert nicht:\n{path}")
self.linkliste_widget.setFilePath("")
return
self.lokale_linkliste = path
self.logic.set_linkliste(path)
def _on_layer_changed(self, layer) -> None:
self.logic.save_verfahrensgebiet_layer(layer)
def _create_new_gpkg(self) -> None:
file_path, _ = QFileDialog.getSaveFileName(
self,
"Neue Verfahrens-Datenbank anlegen",
"",
"Geopackage (*.gpkg)",
)
if not file_path:
return
if not file_path.lower().endswith(".gpkg"):
file_path += ".gpkg"
if file_exists(file_path):
overwrite = ask_yes_no(
"Datei existiert bereits",
f"Die Datei existiert bereits:\n\n{file_path}\n\nSoll sie überschrieben werden?",
default=False,
parent=self,
)
if not overwrite:
return
if not self.logic.create_new_verfahrens_db(file_path):
error("Fehler", "Die Datei konnte nicht angelegt werden.")
return
self.verfahrens_db = file_path
self.file_widget.setFilePath(file_path)
self._update_group_color()
info("Projekt-DB angelegt", f"Neue Projekt-Datenbank wurde angelegt:\n{file_path}")
# ---------------------------------------------------------
# UI-Helfer
# ---------------------------------------------------------
def _update_group_color(self):
"""
Aktualisiert die Darstellung der Gruppenüberschrift.
"""
if not hasattr(self, "group_button"):
return
if self.verfahrens_db:
self.group_button.setStyleSheet("font-weight: bold;")
else:
self.group_button.setStyleSheet("")