From 6261b88fee11d0e613762c811ab0d46d94057fc2 Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 19 Mar 2026 16:32:01 +0100 Subject: [PATCH] Tab B und Tab B logic angelegt --- ui/dockwidget.py | 4 +- ui/tab_b_logic.py | 57 +++++++++++++++++++++++ ui/tab_b_ui.py | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 ui/tab_b_logic.py create mode 100644 ui/tab_b_ui.py diff --git a/ui/dockwidget.py b/ui/dockwidget.py index c004891..718be90 100644 --- a/ui/dockwidget.py +++ b/ui/dockwidget.py @@ -1,14 +1,14 @@ #sn_plan41/ui/dockwidget.py from sn_basis.ui.tabs.settings_tab import SettingsTab from sn_plan41.ui.tab_a_ui import TabA -#from sn_plan41.ui.tabs.tab_b import TabB +from sn_plan41.ui.tab_b_ui import TabB from sn_basis.ui.base_dockwidget import BaseDockWidget from sn_basis.functions.qt_wrapper import QTabWidget from sn_basis.functions.message_wrapper import error class DockWidget(BaseDockWidget): - tabs = [TabA, SettingsTab] + tabs = [TabA, TabB,SettingsTab] def __init__(self, parent=None, subtitle="", pruefmanager=None, data_grabber=None): super().__init__(parent, subtitle) diff --git a/ui/tab_b_logic.py b/ui/tab_b_logic.py new file mode 100644 index 0000000..7588e6f --- /dev/null +++ b/ui/tab_b_logic.py @@ -0,0 +1,57 @@ +""" +sn_plan41/ui/tab_b_logic.py – Fachlogik für Tab B (Druck) +""" +from __future__ import annotations +from sn_basis.functions.sys_wrapper import get_plugin_root, join_path, file_exists + +from typing import Any, Dict, List, Optional +from collections.abc import Mapping as _Mapping +import os +import datetime +import json +import tempfile + +from sn_basis.functions.qgiscore_wrapper import ( + QgsVectorFileWriter, + QgsVectorLayer, + QgsProject, + QgsGeometry, + QgsFeature, + QgsField, + QgsFeatureRequest, + QgsCoordinateReferenceSystem, + +) + +from sn_basis.functions.variable_wrapper import ( + get_variable, + set_variable, +) +from sn_basis.functions.ly_existence_wrapper import layer_exists +from sn_basis.functions.ly_metadata_wrapper import get_layer_type +from sn_basis.functions.qt_wrapper import QVariant +from sn_basis.functions.dialog_wrapper import create_progress_dialog +from sn_basis.functions.message_wrapper import info, warning, error + + +# Prüfer-Typen +from sn_basis.modules.Pruefmanager import Pruefmanager +from sn_basis.modules.linkpruefer import Linkpruefer +from sn_basis.modules.stilpruefer import Stilpruefer +from sn_basis.modules.Dateipruefer import Dateipruefer +from sn_basis.modules.layerpruefer import Layerpruefer +from sn_basis.modules.LayerLoader import LayerLoader +from sn_basis.modules.Datenschreiber import Datenschreiber + +from sn_basis.modules.pruef_ergebnis import pruef_ergebnis +from sn_basis.modules.DataGrabber import DataGrabber, SourceType, SourceDict +from sn_basis.modules.Datenabruf import Datenabruf + +class TabBLogic: + """ + Kapselt die Fachlogik von Tab B. + """ + + def __init__(self, pruefmanager: Pruefmanager) -> None: + self.pruefmanager = pruefmanager + \ No newline at end of file diff --git a/ui/tab_b_ui.py b/ui/tab_b_ui.py new file mode 100644 index 0000000..e706d25 --- /dev/null +++ b/ui/tab_b_ui.py @@ -0,0 +1,113 @@ +""" +sn_plan41/ui/tab_b_ui.py – UI für Tab B (Druck) +""" +from __future__ import annotations + +from typing import Optional + +from sn_basis.functions.qt_wrapper import ( + QWidget, + QVBoxLayout, + QLabel, + QPushButton, + QToolButton, + QFileDialog, + QMessageBox, + ToolButtonTextBesideIcon, + ArrowDown, + ArrowRight, + SizePolicyPreferred, + SizePolicyMaximum, + QComboBox, +) +from sn_basis.functions.qgisui_wrapper import QgsFileWidget, QgsMapLayerComboBox +from sn_basis.functions.qgiscore_wrapper import QgsProject, QgsMapLayerProxyModel +from sn_basis.functions.variable_wrapper import get_variable, set_variable +from sn_basis.modules.pruef_ergebnis import pruef_ergebnis + +# Services (werden von DockWidget injiziert) +from sn_basis.modules.Pruefmanager import Pruefmanager +from sn_basis.modules.DataGrabber import DataGrabber +from sn_basis.modules.Dateipruefer import Dateipruefer +from sn_plan41.ui.tab_b_logic import TabBLogic + +class TabB(QWidget): + """ + UI-Klasse für Tab B (Druck) des Plan41-Plugins. + + Zuständig für: + - Auswahl des Druckthemas + - Auswahl der Druckparameter + - Start der Vorlagenanlage (Druck über QGIS-Druckfunktion) + + Services (Pruefmanager, DataGrabber) werden zur Laufzeit vom DockWidget injiziert. + Alle fachlichen Prüfungen laufen über den zentralen Pruefmanager. + """ + + tab_title = "Druck" #: Tab-Titel für BaseDockWidget + + def __init__(self, parent: Optional[QWidget] = None): + """ + Initialisiert die UI-Struktur. + + Services werden später über :meth:`set_services` injiziert. + + :param parent: Parent-Widget (typischerweise DockWidget) + """ + super().__init__(parent) + + # Services (werden von DockWidget gesetzt) + self.pruefmanager: Optional[Pruefmanager] = None + + self.logic: Optional[TabBLogic] = None + + + + self._build_ui() + self._restore_state() + + def _build_ui(self) -> None: + """Erstellt die komplette UI-Hierarchie mit allen Gruppen.""" + main_layout = QVBoxLayout() + main_layout.setSpacing(4) + main_layout.setContentsMargins(4, 4, 4, 4) + + + # === 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.setFilters(QgsMapLayerProxyModel.VectorLayer) + self.layer_combo.layerChanged.connect(self._on_layer_changed) + main_layout.addWidget(self.layer_combo) + + def _restore_state(self) -> None: + """Stellt UI-State aus Projektvariablen/Persistenz wieder her.""" + + # === UI CALLBACKS === + def _toggle_group(self, checked: bool) -> None: + """Zeigt/verbirgt Verfahrens-DB-Gruppe.""" + self.group_button.setArrowType(ArrowDown if checked else ArrowRight) + self.group_content.setVisible(checked) + + def _toggle_optional(self, checked: bool) -> None: + """Zeigt/verbirgt optionale Linkliste.""" + self.optional_button.setArrowType(ArrowDown if checked else ArrowRight) + self.optional_content.setVisible(checked) + + def _on_layer_changed(self, layer) -> None: + """Persistiert Layer-Auswahl und registriert Verfahrensgebiet.""" + self._pufferlayer = layer + + if not layer: + return + + # UI-State speichern + set_variable("tab_b_layer_id", layer.id(), scope="project") + + # 🔹 NEU: Verfahrensgebiet explizit registrieren + if self.logic: + self.logic.save_verfahrensgebiet_layer(layer) +