""" sn_basis/functions/qgisui_wrapper.py – zentrale QGIS-UI-Abstraktion """ from __future__ import annotations from typing import Any, List, Type from sn_basis.functions.qt_wrapper import QDockWidget from sn_basis.functions.qgiscore_wrapper import QgsProject, QGIS_AVAILABLE iface: Any QGIS_UI_AVAILABLE = False QgsFileWidget: Type[Any] QgsMapLayerComboBox: Type[Any] # --------------------------------------------------------- # iface + QGIS-Widgets initialisieren (QGIS oder Mock) # --------------------------------------------------------- try: from qgis.utils import iface as _iface from qgis.gui import ( QgsFileWidget as _QgsFileWidget, QgsMapLayerComboBox as _QgsMapLayerComboBox, ) iface = _iface QgsFileWidget = _QgsFileWidget QgsMapLayerComboBox = _QgsMapLayerComboBox QGIS_UI_AVAILABLE = True except Exception: QGIS_UI_AVAILABLE = False class _MockSignal: def __init__(self): self._callbacks: list[Any] = [] def connect(self, callback): self._callbacks.append(callback) def emit(self, *args, **kwargs): for cb in list(self._callbacks): cb(*args, **kwargs) class _MockMessageBar: def pushMessage(self, title, text, level=0, duration=5): return { "title": title, "text": text, "level": level, "duration": duration, } class _MockIface: def messageBar(self): return _MockMessageBar() def mainWindow(self): return None def addDockWidget(self, *args, **kwargs): pass def removeDockWidget(self, *args, **kwargs): pass def addToolBar(self, *args, **kwargs): pass def removeToolBar(self, *args, **kwargs): pass iface = _MockIface() class _MockQgsFileWidget: GetFile = 0 def __init__(self, *args, **kwargs): self._path = "" self.fileChanged = _MockSignal() def setStorageMode(self, *args, **kwargs): pass def setFilter(self, *args, **kwargs): pass def setFilePath(self, path: str): self._path = path self.fileChanged.emit(path) def filePath(self) -> str: return self._path class _MockQgsMapLayerComboBox: def __init__(self, *args, **kwargs): self.layerChanged = _MockSignal() self._layer = None self._count = 0 def setFilters(self, *args, **kwargs): pass def setLayer(self, layer): self._layer = layer self.layerChanged.emit(layer) def count(self) -> int: return self._count def setCurrentIndex(self, idx: int): pass QgsFileWidget = _MockQgsFileWidget QgsMapLayerComboBox = _MockQgsMapLayerComboBox # --------------------------------------------------------- # Main Window # --------------------------------------------------------- def get_main_window(): try: return iface.mainWindow() except Exception: return None # --------------------------------------------------------- # Dock-Handling # --------------------------------------------------------- def add_dock_widget(area, dock: Any) -> None: try: iface.addDockWidget(area, dock) except Exception: pass def remove_dock_widget(dock: Any) -> None: try: iface.removeDockWidget(dock) except Exception: pass def find_dock_widgets() -> List[Any]: main_window = get_main_window() if not main_window: return [] try: return main_window.findChildren(QDockWidget) except Exception: return [] # --------------------------------------------------------- # Menü-Handling # --------------------------------------------------------- def add_menu(menu): main_window = iface.mainWindow() if not main_window: return # Nur echte Qt-Menüs an Qt übergeben if hasattr(menu, "menuAction"): main_window.menuBar().addMenu(menu) def remove_menu(menu): main_window = iface.mainWindow() if not main_window: return if hasattr(menu, "menuAction"): main_window.menuBar().removeAction(menu.menuAction()) # --------------------------------------------------------- # Toolbar-Handling # --------------------------------------------------------- def add_toolbar(toolbar: Any) -> None: try: iface.addToolBar(toolbar) except Exception: pass def remove_toolbar(toolbar: Any) -> None: try: iface.removeToolBar(toolbar) except Exception: pass # --------------------------------------------------------- # Layer zum Projekt hinzufügen # --------------------------------------------------------- def add_layer_to_project(layer: Any) -> bool: """ Fügt einen Layer dem aktuellen QGIS-Projekt hinzu. Diese Funktion kapselt den Zugriff auf ``QgsProject.instance().addMapLayer`` und dient als zentrale Abstraktion für alle Stellen, die Layer dynamisch ins Projekt einfügen möchten (z.B. Pufferlayer im Datenabruf). Verhalten --------- - Wenn QGIS verfügbar ist und der Layer gültig ist, wird er dem Projekt hinzugefügt und ``True`` zurückgegeben. - Wenn QGIS nicht verfügbar ist oder der Layer ungültig ist, wird ``False`` zurückgegeben. - Im Mock-Modus wird kein Layer hinzugefügt, aber ``True`` zurückgegeben, damit Tests ohne QGIS nicht fehlschlagen. Parameters ---------- layer: Ein QGIS-Layer (typischerweise ``QgsVectorLayer``), der dem Projekt hinzugefügt werden soll. Returns ------- bool ``True`` bei Erfolg oder im Mock-Modus, sonst ``False``. """ if layer is None: return False # Mock-Modus: Erfolg simulieren if not QGIS_AVAILABLE: return True try: project = QgsProject.instance() project.addMapLayer(layer) return True except Exception: return False