forked from AG_QGIS/Plugin_SN_Basis
Anpassung an den Wrappern für sn_plan41
This commit is contained in:
@@ -1,20 +1,31 @@
|
||||
# sn_basis/functions/ly_existence_wrapper.py
|
||||
|
||||
def layer_exists(layer) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Layer-Objekt existiert (nicht None).
|
||||
"""
|
||||
return layer is not None
|
||||
|
||||
|
||||
def layer_is_valid(layer) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Layer gültig ist (QGIS-konform).
|
||||
"""
|
||||
if layer is None:
|
||||
return False
|
||||
|
||||
is_valid_flag = getattr(layer, "is_valid", None)
|
||||
if is_valid_flag is not None:
|
||||
is_valid = getattr(layer, "isValid", None)
|
||||
if callable(is_valid):
|
||||
try:
|
||||
return bool(is_valid_flag)
|
||||
return bool(is_valid())
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
try:
|
||||
is_valid = getattr(layer, "isValid", None)
|
||||
if callable(is_valid):
|
||||
return bool(is_valid())
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
def layer_is_usable(layer) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Layer existiert und gültig ist.
|
||||
"""
|
||||
return layer_exists(layer) and layer_is_valid(layer)
|
||||
|
||||
@@ -1,48 +1,57 @@
|
||||
# sn_basis/functions/ly_geometry_wrapper.py
|
||||
|
||||
def get_layer_geometry_type(layer) -> str:
|
||||
if layer is None:
|
||||
return "None"
|
||||
from typing import Optional
|
||||
|
||||
geometry_type = getattr(layer, "geometry_type", None)
|
||||
if geometry_type is not None:
|
||||
return str(geometry_type)
|
||||
|
||||
GEOM_NONE = None
|
||||
GEOM_POINT = "Point"
|
||||
GEOM_LINE = "LineString"
|
||||
GEOM_POLYGON = "Polygon"
|
||||
|
||||
|
||||
def get_layer_geometry_type(layer) -> Optional[str]:
|
||||
"""
|
||||
Gibt den Geometrietyp eines Layers zurück.
|
||||
|
||||
Rückgabewerte:
|
||||
- "Point"
|
||||
- "LineString"
|
||||
- "Polygon"
|
||||
- None (nicht räumlich / ungültig / unbekannt)
|
||||
"""
|
||||
if layer is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
if callable(getattr(layer, "isSpatial", None)) and not layer.isSpatial():
|
||||
return "None"
|
||||
is_spatial = getattr(layer, "isSpatial", None)
|
||||
if callable(is_spatial) and not is_spatial():
|
||||
return None
|
||||
|
||||
gtype = getattr(layer, "geometryType", None)
|
||||
if callable(gtype):
|
||||
value = gtype()
|
||||
if not isinstance(value, int):
|
||||
return "None"
|
||||
|
||||
return {
|
||||
0: "Point",
|
||||
1: "LineString",
|
||||
2: "Polygon",
|
||||
}.get(value, "None")
|
||||
if value == 0:
|
||||
return GEOM_POINT
|
||||
if value == 1:
|
||||
return GEOM_LINE
|
||||
if value == 2:
|
||||
return GEOM_POLYGON
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return "None"
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_layer_feature_count(layer) -> int:
|
||||
"""
|
||||
Gibt die Anzahl der Features eines Layers zurück.
|
||||
"""
|
||||
if layer is None:
|
||||
return 0
|
||||
|
||||
count = getattr(layer, "feature_count", None)
|
||||
if count is not None:
|
||||
if isinstance(count, int):
|
||||
return count
|
||||
return 0
|
||||
|
||||
try:
|
||||
if callable(getattr(layer, "isSpatial", None)) and not layer.isSpatial():
|
||||
is_spatial = getattr(layer, "isSpatial", None)
|
||||
if callable(is_spatial) and not is_spatial():
|
||||
return 0
|
||||
|
||||
fc = getattr(layer, "featureCount", None)
|
||||
@@ -54,4 +63,3 @@ def get_layer_feature_count(layer) -> int:
|
||||
pass
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
# layer/metadata.py
|
||||
# sn_basis/functions/ly_metadata_wrapper.py
|
||||
|
||||
def get_layer_type(layer) -> str:
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
LAYER_TYPE_VECTOR = "vector"
|
||||
LAYER_TYPE_TABLE = "table"
|
||||
|
||||
|
||||
def get_layer_type(layer) -> Optional[str]:
|
||||
"""
|
||||
Gibt den Layer-Typ zurück.
|
||||
|
||||
Rückgabewerte:
|
||||
- "vector"
|
||||
- "table"
|
||||
- None (unbekannt / nicht bestimmbar)
|
||||
"""
|
||||
if layer is None:
|
||||
return "unknown"
|
||||
|
||||
layer_type = getattr(layer, "layer_type", None)
|
||||
if layer_type is not None:
|
||||
return str(layer_type)
|
||||
return None
|
||||
|
||||
try:
|
||||
if callable(getattr(layer, "isSpatial", None)):
|
||||
return "vector" if layer.isSpatial() else "table"
|
||||
is_spatial = getattr(layer, "isSpatial", None)
|
||||
if callable(is_spatial):
|
||||
return LAYER_TYPE_VECTOR if is_spatial() else LAYER_TYPE_TABLE
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return "unknown"
|
||||
return None
|
||||
|
||||
|
||||
def get_layer_crs(layer) -> str:
|
||||
def get_layer_crs(layer) -> Optional[str]:
|
||||
"""
|
||||
Gibt das CRS als AuthID zurück (z. B. 'EPSG:25833').
|
||||
"""
|
||||
if layer is None:
|
||||
return "None"
|
||||
|
||||
crs = getattr(layer, "crs", None)
|
||||
if crs is not None and not callable(crs):
|
||||
if isinstance(crs, str):
|
||||
return crs
|
||||
return "None"
|
||||
return None
|
||||
|
||||
try:
|
||||
crs_obj = layer.crs()
|
||||
authid = getattr(crs_obj, "authid", None)
|
||||
crs = layer.crs()
|
||||
authid = getattr(crs, "authid", None)
|
||||
if callable(authid):
|
||||
value = authid()
|
||||
if isinstance(value, str):
|
||||
@@ -37,49 +46,47 @@ def get_layer_crs(layer) -> str:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return "None"
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def get_layer_fields(layer) -> list[str]:
|
||||
def get_layer_fields(layer) -> List[str]:
|
||||
"""
|
||||
Gibt die Feldnamen eines Layers zurück.
|
||||
"""
|
||||
if layer is None:
|
||||
return []
|
||||
|
||||
fields = getattr(layer, "fields", None)
|
||||
if fields is not None and not callable(fields):
|
||||
return list(fields)
|
||||
|
||||
try:
|
||||
f = layer.fields()
|
||||
if callable(getattr(f, "names", None)):
|
||||
return list(f.names())
|
||||
return list(f)
|
||||
return list(layer.fields().names())
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
def get_layer_source(layer) -> str:
|
||||
if layer is None:
|
||||
return "None"
|
||||
|
||||
source = getattr(layer, "source", None)
|
||||
if source is not None and not callable(source):
|
||||
return str(source)
|
||||
def get_layer_source(layer) -> Optional[str]:
|
||||
"""
|
||||
Gibt die Datenquelle eines Layers zurück.
|
||||
"""
|
||||
if layer is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
return layer.source() or "None"
|
||||
value = layer.source()
|
||||
if isinstance(value, str) and value:
|
||||
return value
|
||||
except Exception:
|
||||
return "None"
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def is_layer_editable(layer) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Layer editierbar ist.
|
||||
"""
|
||||
if layer is None:
|
||||
return False
|
||||
|
||||
editable = getattr(layer, "editable", None)
|
||||
if editable is not None:
|
||||
return bool(editable)
|
||||
|
||||
try:
|
||||
is_editable = getattr(layer, "isEditable", None)
|
||||
if callable(is_editable):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# layer/style.py
|
||||
# sn_basis/functions/ly_style_wrapper.py
|
||||
|
||||
from sn_basis.functions.ly_existence_wrapper import layer_exists
|
||||
from sn_basis.functions.sys_wrapper import (
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# sn_basis/functions/ly_visibility_wrapper.py
|
||||
|
||||
def is_layer_visible(layer) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Layer im Layer-Tree sichtbar ist.
|
||||
"""
|
||||
if layer is None:
|
||||
return False
|
||||
|
||||
visible = getattr(layer, "visible", None)
|
||||
if visible is not None:
|
||||
return bool(visible)
|
||||
|
||||
try:
|
||||
is_visible = getattr(layer, "isVisible", None)
|
||||
if callable(is_visible):
|
||||
return bool(is_visible())
|
||||
node = getattr(layer, "treeLayer", None)
|
||||
if callable(node):
|
||||
tree_node = node()
|
||||
is_visible = getattr(tree_node, "isVisible", None)
|
||||
if callable(is_visible):
|
||||
return bool(is_visible())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -19,21 +21,20 @@ def is_layer_visible(layer) -> bool:
|
||||
|
||||
|
||||
def set_layer_visible(layer, visible: bool) -> bool:
|
||||
"""
|
||||
Setzt die Sichtbarkeit eines Layers im Layer-Tree.
|
||||
"""
|
||||
if layer is None:
|
||||
return False
|
||||
|
||||
try:
|
||||
if hasattr(layer, "visible"):
|
||||
layer.visible = bool(visible)
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
node = getattr(layer, "treeLayer", lambda: None)()
|
||||
if node and callable(getattr(node, "setItemVisibilityChecked", None)):
|
||||
node.setItemVisibilityChecked(bool(visible))
|
||||
return True
|
||||
node = getattr(layer, "treeLayer", None)
|
||||
if callable(node):
|
||||
tree_node = node()
|
||||
setter = getattr(tree_node, "setItemVisibilityChecked", None)
|
||||
if callable(setter):
|
||||
setter(bool(visible))
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ QgsProject: Type[Any]
|
||||
QgsVectorLayer: Type[Any]
|
||||
QgsNetworkAccessManager: Type[Any]
|
||||
Qgis: Type[Any]
|
||||
QgsMapLayerProxyModel: Type[Any]
|
||||
|
||||
QGIS_AVAILABLE = False
|
||||
|
||||
@@ -31,12 +32,14 @@ try:
|
||||
QgsVectorLayer as _QgsVectorLayer,
|
||||
QgsNetworkAccessManager as _QgsNetworkAccessManager,
|
||||
Qgis as _Qgis,
|
||||
QgsMapLayerProxyModel as _QgsMaplLayerProxyModel
|
||||
)
|
||||
|
||||
QgsProject = _QgsProject
|
||||
QgsVectorLayer = _QgsVectorLayer
|
||||
QgsNetworkAccessManager = _QgsNetworkAccessManager
|
||||
Qgis = _Qgis
|
||||
QgsMapLayerProxyModel=_QgsMaplLayerProxyModel
|
||||
|
||||
QGIS_AVAILABLE = True
|
||||
|
||||
@@ -94,6 +97,20 @@ except Exception:
|
||||
|
||||
Qgis = _MockQgis
|
||||
|
||||
class _MockQgsMapLayerProxyModel:
|
||||
# Layer-Typen (entsprechen QGIS-Konstanten)
|
||||
NoLayer = 0
|
||||
VectorLayer = 1
|
||||
RasterLayer = 2
|
||||
PluginLayer = 3
|
||||
MeshLayer = 4
|
||||
VectorTileLayer = 5
|
||||
PointCloudLayer = 6
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
QgsMapLayerProxyModel = _MockQgsMapLayerProxyModel
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Netzwerk
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
sn_basis/functions/qgisui_wrapper.py – zentrale QGIS-UI-Abstraktion
|
||||
"""
|
||||
|
||||
from typing import Any, List
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, List, Type
|
||||
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QDockWidget
|
||||
|
||||
@@ -10,18 +13,39 @@ from sn_basis.functions.qt_wrapper import QDockWidget
|
||||
iface: Any
|
||||
QGIS_UI_AVAILABLE = False
|
||||
|
||||
QgsFileWidget: Type[Any]
|
||||
QgsMapLayerComboBox: Type[Any]
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# iface initialisieren (QGIS oder Mock)
|
||||
# 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):
|
||||
@@ -53,6 +77,48 @@ except Exception:
|
||||
|
||||
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
|
||||
@@ -108,8 +174,6 @@ def add_menu(menu):
|
||||
main_window.menuBar().addMenu(menu)
|
||||
|
||||
|
||||
|
||||
|
||||
def remove_menu(menu):
|
||||
main_window = iface.mainWindow()
|
||||
if not main_window:
|
||||
@@ -119,9 +183,6 @@ def remove_menu(menu):
|
||||
main_window.menuBar().removeAction(menu.menuAction())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Toolbar-Handling
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@@ -29,8 +29,9 @@ QMenu: Type[Any]
|
||||
QToolBar: Type[Any]
|
||||
QActionGroup: Type[Any]
|
||||
QTabWidget: type
|
||||
|
||||
|
||||
QToolButton: Type[Any]
|
||||
QSizePolicy: Type[Any]
|
||||
Qt: Type[Any]
|
||||
|
||||
YES: Optional[Any] = None
|
||||
NO: Optional[Any] = None
|
||||
@@ -65,6 +66,9 @@ try:
|
||||
QActionGroup as _QActionGroup,# type: ignore
|
||||
QDockWidget as _QDockWidget,# type: ignore
|
||||
QTabWidget as _QTabWidget,# type: ignore
|
||||
QToolButton as _QToolButton,#type:ignore
|
||||
QSizePolicy as _QSizePolicy,#type:ignore
|
||||
|
||||
)
|
||||
|
||||
|
||||
@@ -73,6 +77,7 @@ try:
|
||||
QEventLoop as _QEventLoop,# type: ignore
|
||||
QUrl as _QUrl,# type: ignore
|
||||
QCoreApplication as _QCoreApplication,# type: ignore
|
||||
Qt as _Qt#type:ignore
|
||||
)
|
||||
from qgis.PyQt.QtNetwork import ( # type: ignore
|
||||
QNetworkRequest as _QNetworkRequest,# type: ignore
|
||||
@@ -86,6 +91,7 @@ try:
|
||||
QNetworkRequest = _QNetworkRequest
|
||||
QNetworkReply = _QNetworkReply
|
||||
QCoreApplication = _QCoreApplication
|
||||
Qt=_Qt
|
||||
QDockWidget = _QDockWidget
|
||||
QWidget = _QWidget
|
||||
QGridLayout = _QGridLayout
|
||||
@@ -99,13 +105,37 @@ try:
|
||||
QToolBar = _QToolBar
|
||||
QActionGroup = _QActionGroup
|
||||
QTabWidget = _QTabWidget
|
||||
|
||||
|
||||
QToolButton=_QToolButton
|
||||
QSizePolicy=_QSizePolicy
|
||||
|
||||
YES = QMessageBox.StandardButton.Yes
|
||||
NO = QMessageBox.StandardButton.No
|
||||
CANCEL = QMessageBox.StandardButton.Cancel
|
||||
ICON_QUESTION = QMessageBox.Icon.Question
|
||||
# ---------------------------------------------------------
|
||||
# Qt6 Enum-Aliase (vereinheitlicht)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
ToolButtonTextBesideIcon = Qt.ToolButtonStyle.ToolButtonTextBesideIcon
|
||||
ArrowDown = Qt.ArrowType.DownArrow
|
||||
ArrowRight = Qt.ArrowType.RightArrow
|
||||
# QSizePolicy Enum-Aliase (Qt6)
|
||||
SizePolicyPreferred = QSizePolicy.Policy.Preferred
|
||||
SizePolicyMaximum = QSizePolicy.Policy.Maximum
|
||||
# ---------------------------------------------------------
|
||||
# QDockWidget Feature-Aliase (Qt6)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
DockWidgetMovable = QDockWidget.DockWidgetFeature.DockWidgetMovable
|
||||
DockWidgetFloatable = QDockWidget.DockWidgetFeature.DockWidgetFloatable
|
||||
DockWidgetClosable = QDockWidget.DockWidgetFeature.DockWidgetClosable
|
||||
# ---------------------------------------------------------
|
||||
# Dock-Area-Aliase (Qt6)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
DockAreaLeft = Qt.DockWidgetArea.LeftDockWidgetArea
|
||||
DockAreaRight = Qt.DockWidgetArea.RightDockWidgetArea
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -134,12 +164,14 @@ except Exception:
|
||||
QActionGroup as _QActionGroup,
|
||||
QDockWidget as _QDockWidget,
|
||||
QTabWidget as _QTabWidget,
|
||||
|
||||
QToolButton as _QToolButton,
|
||||
QSizePolicy as _QSizePolicy,
|
||||
)
|
||||
from PyQt5.QtCore import (
|
||||
QEventLoop as _QEventLoop,
|
||||
QUrl as _QUrl,
|
||||
QCoreApplication as _QCoreApplication,
|
||||
Qt as _Qt,
|
||||
)
|
||||
from PyQt5.QtNetwork import (
|
||||
QNetworkRequest as _QNetworkRequest,
|
||||
@@ -153,6 +185,7 @@ except Exception:
|
||||
QNetworkRequest = _QNetworkRequest
|
||||
QNetworkReply = _QNetworkReply
|
||||
QCoreApplication = _QCoreApplication
|
||||
Qt=_Qt
|
||||
QDockWidget = _QDockWidget
|
||||
|
||||
|
||||
@@ -168,8 +201,8 @@ except Exception:
|
||||
QToolBar = _QToolBar
|
||||
QActionGroup = _QActionGroup
|
||||
QTabWidget = _QTabWidget
|
||||
|
||||
|
||||
QToolButton=_QToolButton
|
||||
QSizePolicy=_QSizePolicy
|
||||
|
||||
YES = QMessageBox.Yes
|
||||
NO = QMessageBox.No
|
||||
@@ -177,6 +210,30 @@ except Exception:
|
||||
ICON_QUESTION = QMessageBox.Question
|
||||
|
||||
QT_VERSION = 5
|
||||
# ---------------------------------------------------------
|
||||
# Qt5 Enum-Aliase (vereinheitlicht)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
ToolButtonTextBesideIcon = Qt.ToolButtonTextBesideIcon
|
||||
ArrowDown = Qt.DownArrow
|
||||
ArrowRight = Qt.RightArrow
|
||||
# QSizePolicy Enum-Aliase (Qt5)
|
||||
SizePolicyPreferred = QSizePolicy.Preferred
|
||||
SizePolicyMaximum = QSizePolicy.Maximum
|
||||
# ---------------------------------------------------------
|
||||
# QDockWidget Feature-Aliase (Qt5)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
DockWidgetMovable = QDockWidget.DockWidgetMovable
|
||||
DockWidgetFloatable = QDockWidget.DockWidgetFloatable
|
||||
DockWidgetClosable = QDockWidget.DockWidgetClosable
|
||||
# ---------------------------------------------------------
|
||||
# Dock-Area-Aliase (Qt5)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
DockAreaLeft = Qt.LeftDockWidgetArea
|
||||
DockAreaRight = Qt.RightDockWidgetArea
|
||||
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
return dialog.exec_()
|
||||
@@ -257,15 +314,26 @@ except Exception:
|
||||
pass
|
||||
|
||||
class _MockLayout:
|
||||
def addWidget(self, *args, **kwargs):
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._widgets = []
|
||||
|
||||
def addLayout(self, *args, **kwargs):
|
||||
def addWidget(self, widget):
|
||||
self._widgets.append(widget)
|
||||
|
||||
def addLayout(self, layout):
|
||||
pass
|
||||
|
||||
def addStretch(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def setSpacing(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def setContentsMargins(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class _MockLabel:
|
||||
def __init__(self, text: str = ""):
|
||||
self._text = text
|
||||
@@ -296,7 +364,18 @@ except Exception:
|
||||
pass
|
||||
|
||||
QCoreApplication = _MockQCoreApplication
|
||||
class _MockQt:
|
||||
# ToolButtonStyle
|
||||
ToolButtonTextBesideIcon = 0
|
||||
|
||||
# ArrowType
|
||||
ArrowDown = 1
|
||||
ArrowRight = 2
|
||||
|
||||
Qt=_MockQt
|
||||
ToolButtonTextBesideIcon = Qt.ToolButtonTextBesideIcon
|
||||
ArrowDown = Qt.ArrowDown
|
||||
ArrowRight = Qt.ArrowRight
|
||||
|
||||
class _MockQDockWidget(_MockWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -380,6 +459,54 @@ except Exception:
|
||||
QToolBar = _MockToolBar
|
||||
QActionGroup = _MockActionGroup
|
||||
|
||||
class _MockToolButton(_MockWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._checked = False
|
||||
self.toggled = lambda *a, **k: None
|
||||
|
||||
def setText(self, text: str) -> None:
|
||||
pass
|
||||
|
||||
def setCheckable(self, value: bool) -> None:
|
||||
pass
|
||||
|
||||
def setChecked(self, value: bool) -> None:
|
||||
self._checked = value
|
||||
|
||||
def setToolButtonStyle(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def setArrowType(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def setStyleSheet(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
QToolButton=_MockToolButton
|
||||
|
||||
class _MockQSizePolicy:
|
||||
# horizontale Policies
|
||||
Fixed = 0
|
||||
Minimum = 1
|
||||
Maximum = 2
|
||||
Preferred = 3
|
||||
Expanding = 4
|
||||
MinimumExpanding = 5
|
||||
Ignored = 6
|
||||
|
||||
# vertikale Policies (Qt nutzt dieselben Werte)
|
||||
def __init__(self, horizontal=None, vertical=None):
|
||||
self.horizontal = horizontal
|
||||
self.vertical = vertical
|
||||
QSizePolicy=_MockQSizePolicy
|
||||
SizePolicyPreferred = QSizePolicy.Preferred
|
||||
SizePolicyMaximum = QSizePolicy.Maximum
|
||||
DockWidgetMovable = 1
|
||||
DockWidgetFloatable = 2
|
||||
DockWidgetClosable = 4
|
||||
DockAreaLeft = 1
|
||||
DockAreaRight = 2
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
return YES
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
variable_wrapper.py – QGIS-Variablen-Abstraktion
|
||||
sn_basis/functions/variable_wrapper.py – QGIS-Variablen-Abstraktion
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
@@ -5,7 +5,7 @@ Verwendet sys_wrapper und gibt pruef_ergebnis an den Pruefmanager zurück.
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from sn_basis.functions import (
|
||||
from sn_basis.functions.sys_wrapper import (
|
||||
join_path,
|
||||
file_exists,
|
||||
)
|
||||
|
||||
3
pyrightconfig.json
Normal file
3
pyrightconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extraPaths": ["."]
|
||||
}
|
||||
@@ -6,6 +6,17 @@ Basis-Dockwidget für alle LNO-Module.
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QDockWidget, QTabWidget
|
||||
from sn_basis.functions.message_wrapper import warning, error
|
||||
from sn_basis.functions.qt_wrapper import (
|
||||
QDockWidget,
|
||||
QTabWidget,
|
||||
Qt,
|
||||
DockWidgetMovable,
|
||||
DockWidgetFloatable,
|
||||
DockWidgetClosable,
|
||||
DockAreaLeft,
|
||||
DockAreaRight,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class BaseDockWidget(QDockWidget):
|
||||
@@ -23,6 +34,19 @@ class BaseDockWidget(QDockWidget):
|
||||
|
||||
def __init__(self, parent=None, subtitle=""):
|
||||
super().__init__(parent)
|
||||
# -----------------------------------------------------
|
||||
# Dock-Konfiguration (WICHTIG)
|
||||
# -----------------------------------------------------
|
||||
self.setFeatures(
|
||||
DockWidgetMovable
|
||||
| DockWidgetFloatable
|
||||
| DockWidgetClosable
|
||||
)
|
||||
|
||||
self.setAllowedAreas(
|
||||
DockAreaLeft
|
||||
| DockAreaRight
|
||||
)
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Titel setzen
|
||||
|
||||
@@ -5,7 +5,7 @@ Verwaltet das Anzeigen und Ersetzen von DockWidgets.
|
||||
Stellt sicher, dass immer nur ein sn_basis-Dock gleichzeitig sichtbar ist.
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
from sn_basis.functions import (
|
||||
add_dock_widget,
|
||||
@@ -14,6 +14,9 @@ from sn_basis.functions import (
|
||||
warning,
|
||||
error,
|
||||
)
|
||||
from sn_basis.functions.qt_wrapper import (
|
||||
DockAreaRight,
|
||||
)
|
||||
|
||||
|
||||
class DockManager:
|
||||
@@ -24,22 +27,34 @@ class DockManager:
|
||||
dock_prefix = "sn_dock_"
|
||||
|
||||
@classmethod
|
||||
def show(cls, dock_widget: Any, area=None) -> None:
|
||||
def show(cls, dock_widget: Any, area: Optional[Any] = None) -> None:
|
||||
"""
|
||||
Zeigt ein DockWidget an und entfernt vorher alle anderen
|
||||
sn_basis-Docks (erkennbar am Prefix 'sn_dock_').
|
||||
"""
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Default-Dock-Area (wrapper-konform)
|
||||
# -----------------------------------------------------
|
||||
if area is None:
|
||||
area = DockAreaRight
|
||||
|
||||
if dock_widget is None:
|
||||
error("Dock konnte nicht angezeigt werden", "Dock-Widget ist None.")
|
||||
return
|
||||
|
||||
try:
|
||||
# -------------------------------------------------
|
||||
# Sicherstellen, dass das Dock einen Namen hat
|
||||
# -------------------------------------------------
|
||||
if not dock_widget.objectName():
|
||||
dock_widget.setObjectName(f"{cls.dock_prefix}{id(dock_widget)}")
|
||||
dock_widget.setObjectName(
|
||||
f"{cls.dock_prefix}{id(dock_widget)}"
|
||||
)
|
||||
|
||||
# -------------------------------------------------
|
||||
# Vorhandene Plugin-Docks entfernen
|
||||
# -------------------------------------------------
|
||||
try:
|
||||
for widget in find_dock_widgets():
|
||||
if (
|
||||
@@ -54,7 +69,9 @@ class DockManager:
|
||||
str(e),
|
||||
)
|
||||
|
||||
# -------------------------------------------------
|
||||
# Neues Dock anzeigen
|
||||
# -------------------------------------------------
|
||||
try:
|
||||
add_dock_widget(area, dock_widget)
|
||||
dock_widget.show()
|
||||
@@ -66,4 +83,3 @@ class DockManager:
|
||||
|
||||
except Exception as e:
|
||||
error("DockManager-Fehler", str(e))
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ class Navigation:
|
||||
test_action = QAction("TEST ACTION", main_window)
|
||||
self.menu.addAction(test_action)
|
||||
self.toolbar.addAction(test_action)
|
||||
|
||||
self.plugin_group = QActionGroup(main_window)
|
||||
self.plugin_group.setExclusive(True)
|
||||
|
||||
|
||||
# -----------------------------------------------------
|
||||
|
||||
@@ -8,7 +8,7 @@ from sn_basis.functions.qt_wrapper import QDockWidget, QTabWidget
|
||||
from sn_basis.functions.message_wrapper import warning, error
|
||||
|
||||
|
||||
class BaseDockWidget(QDockWidget):
|
||||
class SettingsTab(QDockWidget):
|
||||
"""
|
||||
Basis-Dockwidget für alle LNO-Module.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user