""" sn_plan41/ui/tab_a_logic.py – Fachlogik für Tab A (Daten) """ from __future__ import annotations from typing import Any, Dict, List, Optional from collections.abc import Mapping as _Mapping import os from sn_basis.functions.qgiscore_wrapper import ( QgsVectorFileWriter, QgsVectorLayer, QgsProject, ) from sn_basis.functions.variable_wrapper import ( get_variable, set_variable, ) from sn_basis.functions.sys_wrapper import file_exists from sn_basis.functions.ly_existence_wrapper import layer_exists from sn_basis.functions.ly_metadata_wrapper import get_layer_type # Prüfer-Typen from sn_basis.modules.Pruefmanager import Pruefmanager from sn_basis.modules.linkpruefer import Linkpruefer from sn_basis.modules.stilpruefer import Stilpruefer Row = Dict[str, Any] DataDict = Dict[str, List[Row]] class TabALogic: """ Kapselt die Fachlogik von Tab A. Verfahrens-DB wird **nicht** bei Pfad-Auswahl, sondern erst beim ersten Layer-Schreiben angelegt (alte Logik). """ def __init__(self, pruefmanager: Pruefmanager, link_pruefer: Linkpruefer, stil_pruefer: Stilpruefer) -> None: self.pruefmanager = pruefmanager self.link_pruefer = link_pruefer self.stil_pruefer = stil_pruefer # ------------------------------- # Verfahrens-Datenbank (Pfad-Management) # ------------------------------- def load_verfahrens_db(self) -> Optional[str]: """Lädt den gespeicherten Verfahrens-DB-Pfad (Datei muss nicht existieren).""" path = get_variable("verfahrens_db", scope="project") return path or None def set_verfahrens_db(self, path: Optional[str]) -> None: """Speichert den Verfahrens-DB-Pfad (Datei wird später angelegt).""" if path: set_variable("verfahrens_db", path, scope="project") else: set_variable("verfahrens_db", "", scope="project") # ------------------------------- # Layer → Verfahrens-DB schreiben (alte Logik!) # ------------------------------- def write_layer_to_verfahrens_db( self, source_layer: QgsVectorLayer, zielpfad: str, layer_name: str, ) -> bool: """ Schreibt einen Layer in die Verfahrens-DB. Legt GPKG **bei Bedarf neu an** (wie puffer_setzen im alten Code). Args: source_layer: Layer zum Exportieren (z.B. aus DataGrabber) zielpfad: Vom Dateiprüfer geprüfter Ziel-GPKG-Pfad layer_name: Name des Layers in der GPKG Returns: True wenn erfolgreich """ if not zielpfad or not source_layer or not source_layer.isValid(): return False # Optionen wie im alten puffer_setzen opts = QgsVectorFileWriter.SaveVectorOptions() opts.driverName = "GPKG" opts.fileEncoding = "UTF-8" opts.layerName = layer_name # Alte Logik: bei neuem Pfad komplett neue GPKG, sonst Layer überschreiben if not os.path.exists(zielpfad): opts.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile else: opts.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer transform_context = QgsProject.instance().transformContext() error = QgsVectorFileWriter.writeAsVectorFormatV3( source_layer, zielpfad, transform_context, opts, ) if error != QgsVectorFileWriter.NoError: print(f"Fehler beim Schreiben nach {zielpfad}: {error}") return False # Pfad jetzt auch als "Verfahrens-DB" merken self.set_verfahrens_db(zielpfad) return True # ------------------------------- # Lokale Linkliste # ------------------------------- def load_linkliste(self) -> Optional[str]: path = get_variable("linkliste", scope="project") if path and file_exists(path): return path return None def set_linkliste(self, path: Optional[str]) -> None: if path: set_variable("linkliste", path, scope="project") else: set_variable("linkliste", "", scope="project") # ------------------------------- # Verfahrensgebiet-Layer # ------------------------------- def save_verfahrensgebiet_layer(self, layer) -> None: if layer is None: set_variable("verfahrensgebiet_layer", "", scope="project") return if not hasattr(layer, "id") or not callable(layer.id): set_variable("verfahrensgebiet_layer", "", scope="project") return try: layer_id = layer.id() except Exception: set_variable("verfahrensgebiet_layer", "", scope="project") return if not layer_id: set_variable("verfahrensgebiet_layer", "", scope="project") return set_variable("verfahrensgebiet_layer", layer_id, scope="project") def load_verfahrensgebiet_layer_id(self) -> Optional[str]: value = get_variable("verfahrensgebiet_layer", scope="project") return value or None def is_valid_verfahrensgebiet_layer(self, layer) -> bool: if not layer_exists(layer): return False layer_type = get_layer_type(layer) return layer_type == "vector"