neues Layout "Baufreigabe" hinzugefügt
This commit is contained in:
+20
-2
@@ -46,7 +46,7 @@ class Dateipruefer:
|
||||
standarddatei: Optional[str] = None,
|
||||
temporaer_erlaubt: bool = False,
|
||||
*,
|
||||
verfahrens_db_modus: bool = True, # 🆕 Verfahrens-DB-spezifische Logik
|
||||
verfahrens_db_modus: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
Parameters
|
||||
@@ -90,6 +90,8 @@ class Dateipruefer:
|
||||
|
||||
def _pfad(self, relativer_pfad: str) -> Path:
|
||||
"""Erzeugt OS-unabhängigen Pfad relativ zum Basisverzeichnis."""
|
||||
if relativer_pfad.startswith(("/", "\\")):
|
||||
return Path(relativer_pfad)
|
||||
return join_path(self.basis_pfad, relativer_pfad)
|
||||
|
||||
|
||||
@@ -152,6 +154,22 @@ class Dateipruefer:
|
||||
#Excel-dateien erkennen
|
||||
dateityp = self.erkenne_dateityp(pfad)
|
||||
|
||||
if not self.verfahrens_db_modus:
|
||||
if not file_exists(pfad):
|
||||
return pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung=f"Datei '{self.pfad}' wurde nicht gefunden.",
|
||||
aktion="datei_nicht_gefunden",
|
||||
kontext=pfad,
|
||||
)
|
||||
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
meldung="Datei ist gültig.",
|
||||
aktion="ok",
|
||||
kontext=pfad,
|
||||
)
|
||||
|
||||
if dateityp == "excel":
|
||||
if not file_exists(pfad):
|
||||
return pruef_ergebnis(
|
||||
@@ -176,7 +194,7 @@ class Dateipruefer:
|
||||
)
|
||||
|
||||
# 🆕 2.c: Ungültiger GPKG-Pfad?
|
||||
if not self.verfahrens_db_modus or not self._ist_gueltiger_gpkg_pfad(pfad):
|
||||
if not self._ist_gueltiger_gpkg_pfad(pfad):
|
||||
return pruef_ergebnis(
|
||||
ok=False,
|
||||
meldung=f"Der Pfad '{self.pfad}' ist kein gültiger GPKG-Pfad.",
|
||||
|
||||
+15
-30
@@ -6,8 +6,8 @@ from __future__ import annotations
|
||||
from typing import Optional, Any
|
||||
|
||||
from sn_basis.functions import ask_yes_no, info, warning, error, ask_overwrite_append_cancel_custom
|
||||
from sn_basis.functions.ly_visibility_wrapper import set_layer_visible
|
||||
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion
|
||||
print("DEBUG: Pruefmanager DATEI GELADEN:", __file__)
|
||||
|
||||
class Pruefmanager:
|
||||
def __init__(self, ui_modus: str = "qgis", parent: Optional[Any] = None) -> None:
|
||||
@@ -146,10 +146,7 @@ class Pruefmanager:
|
||||
# ------------------------------------------------------------------
|
||||
def _handle_basic_decision(self, ergebnis: pruef_ergebnis) -> pruef_ergebnis:
|
||||
"""Basis-Entscheidung für einfache Ja/Nein-Fragen."""
|
||||
print(f"DEBUG _handle_basic_decision: aktion='{ergebnis.aktion}', ui_modus='{self.ui_modus}'")
|
||||
|
||||
if self.ui_modus != "qgis":
|
||||
print("DEBUG: Nicht QGIS → ergebnis unverändert")
|
||||
return ergebnis
|
||||
|
||||
title_map = {
|
||||
@@ -163,27 +160,32 @@ class Pruefmanager:
|
||||
meldung = ergebnis.meldung or ""
|
||||
|
||||
try:
|
||||
print(f"DEBUG ask_yes_no: title='{title}', meldung='{meldung[:50]}...'")
|
||||
yes = ask_yes_no(title, meldung, default=False, parent=self.parent)
|
||||
print(f"DEBUG ask_yes_no: yes={yes}")
|
||||
except Exception as e:
|
||||
print(f"DEBUG ask_yes_no Exception: {e}")
|
||||
except Exception:
|
||||
return ergebnis
|
||||
|
||||
if not yes:
|
||||
print("DEBUG: Nutzer sagte Nein → ok=False")
|
||||
return ergebnis
|
||||
|
||||
# Nutzer sagte Ja
|
||||
if ergebnis.aktion == "temporaer_erlaubt":
|
||||
print("DEBUG: temporaer_erlaubt bestätigt → ok=True")
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
aktion="temporaer_erlaubt",
|
||||
aktion="temporaer_erzeugen",
|
||||
kontext=ergebnis.kontext
|
||||
)
|
||||
|
||||
print("DEBUG: Andere Aktion bestätigt → ok=True, aktion='ok'")
|
||||
if ergebnis.aktion == "layer_unsichtbar":
|
||||
try:
|
||||
set_layer_visible(ergebnis.kontext, True)
|
||||
except Exception:
|
||||
return ergebnis
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
aktion="ok",
|
||||
kontext=ergebnis.kontext,
|
||||
)
|
||||
|
||||
return pruef_ergebnis(
|
||||
ok=True,
|
||||
aktion="ok",
|
||||
@@ -194,48 +196,31 @@ class Pruefmanager:
|
||||
# Hauptlogik: verarbeite() (KORRIGIERT!)
|
||||
# ------------------------------------------------------------------
|
||||
def verarbeite(self, ergebnis: pruef_ergebnis) -> pruef_ergebnis:
|
||||
print("🔥 verarbeite() START")
|
||||
print("DEBUG Pruefmanager:", ergebnis.ok, ergebnis.aktion)
|
||||
print("DEBUG ergebnis.aktion TYPE:", type(ergebnis.aktion), repr(ergebnis.aktion))
|
||||
|
||||
# 1. Erfolg → direkt weiter
|
||||
print("🔍 Schritt 1: Prüfe ergebnis.ok =", ergebnis.ok)
|
||||
if ergebnis.ok:
|
||||
print("✅ Schritt 1: ok=True → return")
|
||||
return ergebnis
|
||||
|
||||
# 2. VERFAHRENS-DB: Bestehende Datei
|
||||
print("🔍 Schritt 2: Prüfe datei_existiert =", ergebnis.aktion == "datei_existiert")
|
||||
if ergebnis.aktion == "datei_existiert":
|
||||
print("✅ Schritt 2: _handle_datei_existiert")
|
||||
return self._handle_datei_existiert(ergebnis)
|
||||
|
||||
# 3. Basis interaktive Aktionen
|
||||
print("🔍 Schritt 3: Definiere interactive_actions")
|
||||
interactive_actions = {
|
||||
"leereingabe_erlaubt",
|
||||
"standarddatei_vorschlagen",
|
||||
"temporaer_erlaubt",
|
||||
"layer_unsichtbar",
|
||||
}
|
||||
print("DEBUG interactive_actions:", repr(interactive_actions))
|
||||
print("DEBUG ergebnis.aktion in interactive_actions?", ergebnis.aktion in interactive_actions)
|
||||
|
||||
if ergebnis.aktion in interactive_actions:
|
||||
print("✅ Schritt 3: Interaktive Aktion → _handle_basic_decision")
|
||||
decision = self._handle_basic_decision(ergebnis)
|
||||
print(f"DEBUG: _handle_basic_decision Ergebnis: ok={decision.ok}, aktion='{decision.aktion}'")
|
||||
return decision
|
||||
return self._handle_basic_decision(ergebnis)
|
||||
|
||||
# 4. Fehler behandeln
|
||||
print("❌ Schritt 4: FEHLER BEHANDELN")
|
||||
self.report_error(
|
||||
thema=ergebnis.aktion or "pruefung",
|
||||
meldung=ergebnis.meldung or "",
|
||||
aktion=ergebnis.aktion,
|
||||
kontext=ergebnis.kontext,
|
||||
)
|
||||
print("🔥 verarbeite() ENDE mit ok=False")
|
||||
return ergebnis
|
||||
|
||||
def _ask_use_or_replace_pufferlayer(self) -> str:
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
"""
|
||||
sn_basis/modules/print_layout_baufreigabe.py - Layout-Erstellung fuer Baufreigabe-Vorlagen.
|
||||
|
||||
Baufreigabe-Layouts verwenden immer feste DIN A3/A4 Seitengroessen im Querformat,
|
||||
ein 120 mm breites Kartenschild (statt 180 mm) und erbenerben die Standard-Logik
|
||||
fuer Hauptkarte, Quellenangabe und Legende vom PrintLayout.
|
||||
|
||||
Atlas-Integration erfolgt nach Layouterstellung durch externe Konfiguration
|
||||
in der PrintLogic.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QFont
|
||||
from sn_basis.functions.qgiscore_wrapper import (
|
||||
QgsLayoutItem,
|
||||
QgsLayoutItemLabel,
|
||||
QgsLayoutItemLegend,
|
||||
QgsLayoutItemMap,
|
||||
QgsLayoutPoint,
|
||||
QgsLayoutSize,
|
||||
QgsPrintLayout,
|
||||
QgsProject,
|
||||
QgsUnitTypes,
|
||||
)
|
||||
from sn_basis.functions.qgisui_wrapper import open_layout_designer
|
||||
from sn_basis.modules.print_layout import PrintLayout
|
||||
|
||||
|
||||
MM = QgsUnitTypes.LayoutMillimeters
|
||||
|
||||
|
||||
class PrintLayoutBaufreigabe(PrintLayout):
|
||||
"""Erzeugt QGIS-Einzelblatt-Layouts mit fester DIN A3/A4 Querformat-Groesse und 120mm Kartenschild."""
|
||||
|
||||
_FRAME_STROKE_WIDTH_MM = 0.5
|
||||
_KARTENSCHILD_WIDTH_MM = 120.0 # Unterschied zu StandardLayout: 120mm statt 180mm
|
||||
_KARTENSCHILD_HEIGHT_MM = 92.0
|
||||
_GRID_INTERVAL_MAP_UNITS = 500.0
|
||||
|
||||
# DIN-Formate: nur A3 und A4 im Querformat
|
||||
_DIN_A3_LANDSCAPE = (420, 297) # Breite x Hoehe (Querformat)
|
||||
_DIN_A4_LANDSCAPE = (297, 210) # Querformat
|
||||
|
||||
_TEXT_FORMAT_TEMPLATES = {
|
||||
"Format_1": {"font_family": "Arial", "font_size": 11, "font_style": "normal"},
|
||||
"Format_2": {"font_family": "Arial", "font_size": 13, "font_style": "bold"},
|
||||
"Format_3": {"font_family": "Arial", "font_size": 16, "font_style": "bold"},
|
||||
}
|
||||
|
||||
_OBJECT_TEMPLATES = {
|
||||
"hauptkarte": {"id": "Hauptkarte", "object_name": "Hauptkarte"},
|
||||
"quellenangabe": {
|
||||
"id": "Quellenangabe",
|
||||
"object_name": "Quellenangabe",
|
||||
"size_mm": (120.0, 100.0), # Breite angepasst auf 120mm Kartenschild
|
||||
"format": "Format_1",
|
||||
},
|
||||
"textfeld": {
|
||||
"id": "Textfeld",
|
||||
"object_name": "Textfeld",
|
||||
"size_mm": (60.0, 8.0),
|
||||
"format": "Format_1",
|
||||
"html_mode": True,
|
||||
"text": "",
|
||||
},
|
||||
"legende": {
|
||||
"id": "Legende",
|
||||
"object_name": "Legende",
|
||||
"size_mm": (120.0, 60.0), # Breite angepasst auf 120mm Kartenschild
|
||||
},
|
||||
}
|
||||
|
||||
_QUELLENANGABE_TEXT = (
|
||||
"Quelle Geobasisdaten: GeoSN, "
|
||||
"<a href=\"https://www.govdata.de/dl-de/by-2-0\">dl-de/by-2-0</a><br>"
|
||||
"Quelle Fachdaten: Darstellung auf der Grundlage von Daten und mit Erlaubnis des "
|
||||
"Saechsischen Landesamtes fuer Umwelt, Landwirtschaft und Geologie<br>"
|
||||
"Basemap:"
|
||||
"© GeoBasis-DE / <a href=\"https://www.bkg.bund.de\">BKG</a> ([%year($now)%]) "
|
||||
"<a href=\"https://creativecommons.org/licences/by/4.0/\">CC BY 4.0</a> "
|
||||
"mit teilweise angepasster Signatur<br>"
|
||||
)
|
||||
|
||||
def __init__(self, project: Any | None = None) -> None:
|
||||
super().__init__(project)
|
||||
|
||||
def create_baufreigabe_layout(
|
||||
self,
|
||||
name: str,
|
||||
din_format: str,
|
||||
map_width_mm: float,
|
||||
map_height_mm: float,
|
||||
extent: Any,
|
||||
plotmassstab: float,
|
||||
thema: str = "",
|
||||
fit_extent_to_map: bool = True,
|
||||
) -> Any:
|
||||
"""Erstellt ein Baufreigabe-Layout mit fester DIN A3/A4 Querformat-Groesse.
|
||||
|
||||
Args:
|
||||
name: Name des Layouts
|
||||
din_format: "DIN A3" oder "DIN A4"
|
||||
map_width_mm: Breite der Hauptkarte
|
||||
map_height_mm: Hoehe der Hauptkarte
|
||||
extent: QgsRectangle der Kartenausdehnung
|
||||
plotmassstab: Plotmassstab (z.B. 5000 fuer 1:5000)
|
||||
thema: Name des Visibility-Presets (optional)
|
||||
fit_extent_to_map: Ob das Extent an die Kartengroe angepasst wird
|
||||
|
||||
Returns:
|
||||
QgsPrintLayout objektInstance (wird im Layout-Dialog geoeffnet)
|
||||
|
||||
Raises:
|
||||
ValueError: Falls Name bereits existiert oder Format ungueltig ist
|
||||
"""
|
||||
# Seitenformat auswaehlen (nur A3/A4 im Querformat)
|
||||
if din_format == "DIN A3":
|
||||
page_width_mm, page_height_mm = self._DIN_A3_LANDSCAPE
|
||||
elif din_format == "DIN A4":
|
||||
page_width_mm, page_height_mm = self._DIN_A4_LANDSCAPE
|
||||
else:
|
||||
raise ValueError(f"Baufreigabe: Format {din_format} ist nicht unterstuetzt. Nur DIN A3/A4 Querformat.")
|
||||
|
||||
layout_manager = self.project.layoutManager()
|
||||
existing_layout = layout_manager.layoutByName(name)
|
||||
if existing_layout is not None:
|
||||
raise ValueError(f"Eine Vorlage mit der Bezeichnung '{name}' existiert bereits.")
|
||||
|
||||
layout = QgsPrintLayout(self.project)
|
||||
layout.initializeDefaults()
|
||||
layout.setName(name)
|
||||
self._current_layout = layout
|
||||
|
||||
page = layout.pageCollection().page(0)
|
||||
page.setPageSize(QgsLayoutSize(page_width_mm, page_height_mm, MM))
|
||||
|
||||
map_left_mm = 10.0
|
||||
map_top_mm = 10.0
|
||||
map_right_mm = map_left_mm + map_width_mm
|
||||
map_bottom_mm = map_top_mm + map_height_mm
|
||||
kartenfenster_untere_rechte_ecke_mm = (map_right_mm, map_bottom_mm)
|
||||
|
||||
hauptkarte = self._create_map_item(
|
||||
layout,
|
||||
"hauptkarte",
|
||||
map_left_mm,
|
||||
map_top_mm,
|
||||
map_width_mm,
|
||||
map_height_mm,
|
||||
)
|
||||
|
||||
fitted_extent = extent
|
||||
if fit_extent_to_map:
|
||||
fitted_extent = self._fit_extent_to_map_item(extent, map_width_mm, map_height_mm)
|
||||
if fitted_extent is not None and hasattr(fitted_extent, "isNull") and callable(fitted_extent.isNull) and not fitted_extent.isNull():
|
||||
try:
|
||||
hauptkarte.setExtent(fitted_extent)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(plotmassstab, (int, float)) and math.isfinite(plotmassstab) and plotmassstab > 0:
|
||||
try:
|
||||
hauptkarte.setScale(plotmassstab)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_frame_enabled = getattr(hauptkarte, "setFrameEnabled", None)
|
||||
if callable(set_frame_enabled):
|
||||
try:
|
||||
set_frame_enabled(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_frame_stroke_width = getattr(hauptkarte, "setFrameStrokeWidth", None)
|
||||
if callable(set_frame_stroke_width):
|
||||
try:
|
||||
self._set_item_frame_stroke_width(hauptkarte, self._FRAME_STROKE_WIDTH_MM)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if thema and thema != "aktuell":
|
||||
follow_theme = getattr(hauptkarte, "setFollowVisibilityPreset", None)
|
||||
set_theme_name = getattr(hauptkarte, "setFollowVisibilityPresetName", None)
|
||||
if callable(follow_theme):
|
||||
try:
|
||||
follow_theme(True)
|
||||
except Exception:
|
||||
pass
|
||||
if callable(set_theme_name):
|
||||
try:
|
||||
set_theme_name(thema)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_keep_layer_set = getattr(hauptkarte, "setKeepLayerSet", None)
|
||||
if callable(set_keep_layer_set):
|
||||
try:
|
||||
set_keep_layer_set(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_refresh_strategy = getattr(hauptkarte, "setRefreshStrategy", None)
|
||||
if callable(set_refresh_strategy):
|
||||
refresh_cache = (
|
||||
getattr(hauptkarte, "RefreshLaterOnly", None)
|
||||
or getattr(hauptkarte, "RefreshWhenRequested", None)
|
||||
or 0
|
||||
)
|
||||
try:
|
||||
set_refresh_strategy(refresh_cache)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self._configure_hauptkarte_grids(hauptkarte)
|
||||
|
||||
self._setup_layout_objects_baufreigabe(
|
||||
kartenfenster_untere_rechte_ecke_mm,
|
||||
hauptkarte,
|
||||
map_top_mm,
|
||||
map_height_mm,
|
||||
)
|
||||
|
||||
layout_manager.addLayout(layout)
|
||||
self._current_layout = None
|
||||
open_layout_designer(layout)
|
||||
return layout
|
||||
|
||||
def _setup_layout_objects_baufreigabe(
|
||||
self,
|
||||
kartenfenster_untere_rechte_ecke_mm: tuple,
|
||||
hauptkarte: Any,
|
||||
map_top_mm: float,
|
||||
map_height_mm: float,
|
||||
) -> None:
|
||||
"""Erstellt Legende, Quellenangabe und Kartenschild fuer Baufreigabe-Layout.
|
||||
|
||||
Angepasst fuer 120mm Kartenschild statt 180mm, mit proportional skalierten Textfeldern.
|
||||
"""
|
||||
if self._current_layout is None:
|
||||
raise RuntimeError("Kein Layout aktiv.")
|
||||
|
||||
def _coords_rel_untere_rechte_ecke(rel_x_mm: float, rel_y_mm: float) -> tuple[float, float]:
|
||||
return (
|
||||
kartenfenster_untere_rechte_ecke_mm[0] + rel_x_mm,
|
||||
kartenfenster_untere_rechte_ecke_mm[1] + rel_y_mm,
|
||||
)
|
||||
|
||||
# Legende: 120mm Breite (angepasst), hoehe adaptive wie Standard
|
||||
legende_x = kartenfenster_untere_rechte_ecke_mm[0] + 10.0
|
||||
legende_height_mm = max(map_height_mm - 122.0, 20.0)
|
||||
legende_y = map_top_mm
|
||||
legende = self._create_legend_item(
|
||||
self._current_layout,
|
||||
"legende",
|
||||
hauptkarte,
|
||||
legende_x,
|
||||
legende_y,
|
||||
width_mm=self._KARTENSCHILD_WIDTH_MM,
|
||||
height_mm=legende_height_mm,
|
||||
object_name="Legende",
|
||||
)
|
||||
|
||||
legende_hoehe_mm = self._configure_legend_size(
|
||||
legende,
|
||||
width_limit_mm=self._KARTENSCHILD_WIDTH_MM,
|
||||
column_count=1,
|
||||
equal_column_width=False,
|
||||
)
|
||||
|
||||
# Quellenangabe: 120mm Breite
|
||||
quellenangabe_x, quellenangabe_y = _coords_rel_untere_rechte_ecke(10.0, -102.0)
|
||||
quellenangabe_hoehe_mm = 20.0
|
||||
quellenangabe_obere_y = quellenangabe_y - quellenangabe_hoehe_mm
|
||||
legende_untere_y = legende_y + legende_hoehe_mm
|
||||
|
||||
if legende_untere_y > quellenangabe_obere_y:
|
||||
self._configure_legend_size(
|
||||
legende,
|
||||
width_limit_mm=self._KARTENSCHILD_WIDTH_MM,
|
||||
column_count=2,
|
||||
equal_column_width=True,
|
||||
)
|
||||
|
||||
self.add_text_label(
|
||||
self._QUELLENANGABE_TEXT,
|
||||
quellenangabe_x,
|
||||
quellenangabe_y,
|
||||
width_mm=self._KARTENSCHILD_WIDTH_MM,
|
||||
height_mm=20.0,
|
||||
text_format="Format_1",
|
||||
html_mode=True,
|
||||
expression_enabled=True,
|
||||
object_name="Quellenangabe",
|
||||
)
|
||||
|
||||
# Kartenschild: 120mm Breite (angepasst)
|
||||
kartenschild_x, kartenschild_y = _coords_rel_untere_rechte_ecke(10.0, 0.0)
|
||||
self._create_rectangle_box_item(
|
||||
self._current_layout,
|
||||
"Kartenschild",
|
||||
kartenschild_x,
|
||||
kartenschild_y,
|
||||
self._KARTENSCHILD_WIDTH_MM,
|
||||
self._KARTENSCHILD_HEIGHT_MM,
|
||||
stroke_width_mm=self._FRAME_STROKE_WIDTH_MM,
|
||||
)
|
||||
|
||||
# Kartenschild-Linien: 6 Trennlinien (Positionen gleich)
|
||||
kartenschild_line_x, _ = _coords_rel_untere_rechte_ecke(10.0, 0.0)
|
||||
kartenschild_line_offsets_y = (-10.0, -20.0, -30.0, -46.0, -62.0, -82.0)
|
||||
for index, offset_y in enumerate(kartenschild_line_offsets_y, start=1):
|
||||
_, line_y = _coords_rel_untere_rechte_ecke(0.0, offset_y)
|
||||
self._create_rectangle_box_item(
|
||||
self._current_layout,
|
||||
f"Kartenschild_Linie_{index}",
|
||||
kartenschild_line_x,
|
||||
line_y,
|
||||
self._KARTENSCHILD_WIDTH_MM,
|
||||
0.0,
|
||||
stroke_width_mm=0.1,
|
||||
)
|
||||
|
||||
# Textfelder im Kartenschild: proportional skaliert auf 120mm
|
||||
# Skalierungsfaktor: 120/180 = 0.667 fuer horizontale Abstaende/Breiten
|
||||
scale_x = self._KARTENSCHILD_WIDTH_MM / 180.0
|
||||
base_x = 16.0 * scale_x # ~10.7mm statt 16mm
|
||||
label_width_scaled = 101.0 * scale_x # ~67.3mm statt 101mm
|
||||
|
||||
labels = [
|
||||
("[% @sn_amt %]", base_x, -84.0, label_width_scaled, 4.0, "Format_1", "Herausgeber"),
|
||||
("[% @sn_bezeichnung %]", base_x, -75.0, label_width_scaled, 4.0, "Format_1", "Bezeichnung_Flurbereinigung"),
|
||||
("[% @sn_name %]", base_x, -64.0, label_width_scaled, 5.0, "Format_2", "Name_Flurbereinigung"),
|
||||
("[% @sn_gemeinden %]", base_x, -56.0, label_width_scaled, 4.0, "Format_1", "Stadt_Gemeinde"),
|
||||
("[% @sn_landkreise_proj %]", base_x, -48.0, label_width_scaled, 4.0, "Format_1", "Landkreis"),
|
||||
("[% @sn_kartenname %]", base_x, -32.0, label_width_scaled - 30, 12.0, "Format_3", "Kartenname"),
|
||||
("Gefertigt: ", base_x, -23.0, 40.0 * scale_x, 4.0, "Format_1", "Gefertigt"),
|
||||
("Geprueft: ", base_x + 40.0 * scale_x + 5.0, -23.0, 40.0 * scale_x, 4.0, "Format_1", "Geprueft"),
|
||||
(
|
||||
"Massstab: 1 : [%round(map_get(item_variables('Hauptkarte'),'map_scale'),0)%]",
|
||||
base_x,
|
||||
-13.0,
|
||||
40.0 * scale_x,
|
||||
4.0,
|
||||
"Format_1",
|
||||
"Massstab",
|
||||
),
|
||||
("Ausgabedatum: [%format_date(now(), 'dd.MM.yyyy')%]", base_x + 40.0 * scale_x + 5.0, -13.0, 40.0 * scale_x, 4.0, "Format_1", "Ausgabedatum"),
|
||||
("Aktenzeichen: ", base_x, -3.0, label_width_scaled, 4.0, "Format_1", "Aktenzeichen"),
|
||||
]
|
||||
|
||||
for text, rx, ry, w, h, fmt, obj_name in labels:
|
||||
x, y = _coords_rel_untere_rechte_ecke(rx, ry)
|
||||
self.add_text_label(
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
width_mm=w,
|
||||
height_mm=h,
|
||||
text_format=fmt,
|
||||
expression_enabled=True,
|
||||
object_name=obj_name,
|
||||
)
|
||||
+379
-13
@@ -4,7 +4,7 @@ sn_basis/modules/print_logic.py - Fachlogik fuer den Druck-Tab (nur Einzelblatt)
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
from typing import Any, cast
|
||||
from typing import Any, cast, TypedDict
|
||||
|
||||
from sn_basis.functions.qgiscore_wrapper import QgsProject, get_layer_extent
|
||||
from sn_basis.functions.qgisui_wrapper import iface
|
||||
@@ -12,6 +12,48 @@ from sn_basis.functions.variable_wrapper import get_variable, set_variable
|
||||
from sn_basis.modules.layerpruefer import Layerpruefer
|
||||
from sn_basis.modules.Pruefmanager import Pruefmanager
|
||||
from sn_basis.modules.print_layout import PrintLayout
|
||||
from sn_basis.modules.print_layout_baufreigabe import PrintLayoutBaufreigabe
|
||||
|
||||
|
||||
class AtlasConfig(TypedDict, total=False):
|
||||
"""Strukturierte Konfiguration fuer Atlas-Optionen.
|
||||
|
||||
Alle Felder sind optional (total=False) und haben vordefinierte Standartwerte.
|
||||
"""
|
||||
# Basis-Konfiguration
|
||||
enabled: bool # Atlas aktivieren (Standard: True nach Coverage-Layer-Setzung)
|
||||
page_name_expression: str # QGIS Expression für Seitennamen (z.B. "@atlas_featurenumber")
|
||||
|
||||
# Filterung
|
||||
filter_features: bool # Features filtern? (Standard: False)
|
||||
filter_expression: str # QGIS Expression für Feature-Filter
|
||||
|
||||
# Sortierung
|
||||
sort_features: bool # Features sortieren? (Standard: False)
|
||||
sort_expression: str # QGIS Expression/Feldname zum Sortieren
|
||||
sort_ascending: bool # Aufsteigend sortieren? (Standard: True)
|
||||
|
||||
# Rendering
|
||||
hide_coverage: bool # Coverage-Layer in Layout verstecken? (Standard: False)
|
||||
limit_render_to_current_feature: bool # Rendering auf aktuelles Feature limitieren (QGIS 4.0+, Standard: False)
|
||||
|
||||
# Metadaten
|
||||
description: str # Beschreibung der Atlas-Konfiguration
|
||||
|
||||
|
||||
# Vordefinierte Standardkonfigurationen für Baufreigabe
|
||||
ATLAS_CONFIG_BAUFREIGABE_DEFAULT: AtlasConfig = {
|
||||
"enabled": True,
|
||||
"page_name_expression": "@atlas_featurenumber",
|
||||
"filter_features": False,
|
||||
"filter_expression": "",
|
||||
"sort_features": False,
|
||||
"sort_expression": "",
|
||||
"sort_ascending": True,
|
||||
"hide_coverage": False,
|
||||
"limit_render_to_current_feature": False,
|
||||
"description": "Baufreigabe Atlas mit Standardkonfiguration",
|
||||
}
|
||||
|
||||
|
||||
KARTENNAME_VAR = "kartenname"
|
||||
@@ -25,6 +67,7 @@ DRUCKRECHTECK_LAYER_NAME = "Druckrechteck"
|
||||
|
||||
KARTENNAME_38 = "§38"
|
||||
KARTENNAME_41 = "§41"
|
||||
KARTENNAME_BAUFREIGABE = "Anlage zur Baufreigabe"
|
||||
MASSSTAB_WIE_KARTENFENSTER = "Wie Kartenfenster"
|
||||
THEMA_WIE_KARTENFENSTER = "wie kartenfenster"
|
||||
|
||||
@@ -35,6 +78,7 @@ DRUCKBEREICH_RECHTECK = "Rechteck"
|
||||
KARTENNAME_BY_AUSWAHL = {
|
||||
KARTENNAME_38: "Planungsübersicht §38 FlurbG",
|
||||
KARTENNAME_41: "Karte zum Plan über die gemeinschaftlichen und öffentlichen Anlagen (§ 41 FlurbG)",
|
||||
KARTENNAME_BAUFREIGABE: "Anlage zur Baufreigabe",
|
||||
}
|
||||
|
||||
PLOTMASSSTAB_BY_AUSWAHL = {
|
||||
@@ -253,6 +297,269 @@ class PrintLogic:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def create_atlas_layer_from_selection(self, source_layer: object | None = None) -> tuple[object | None, str]:
|
||||
"""Erstellt einen neuen Layer 'Atlaslayer' aus der Auswahl des Quell-Layers.
|
||||
|
||||
Args:
|
||||
source_layer: Der Layer mit der Auswahl (wenn None, wird aktiver Layer verwendet)
|
||||
|
||||
Returns:
|
||||
(created_layer, layer_id) oder (None, "") bei Fehler
|
||||
"""
|
||||
# Source-Layer bestimmen
|
||||
if source_layer is None:
|
||||
source_layer = self._resolve_active_layer()
|
||||
if source_layer is None:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
"Kein Layer mit Auswahl gefunden.",
|
||||
)
|
||||
return None, ""
|
||||
|
||||
# Pruefen ob Auswahl vorhanden ist
|
||||
selected_count = getattr(source_layer, "selectedFeatureCount", None)
|
||||
if callable(selected_count):
|
||||
try:
|
||||
if int(cast(Any, selected_count())) == 0:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
"Auf dem Layer sind keine Features ausgewaehlt.",
|
||||
)
|
||||
return None, ""
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Bestehenden Atlaslayer loeschen (optional Wiederverwedung)
|
||||
existing_atlas = self._get_existing_layer_by_name("Atlaslayer")
|
||||
if existing_atlas is not None:
|
||||
try:
|
||||
QgsProject.instance().removeMapLayer(existing_atlas)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Neuen Memory-Layer mit Geometrie-Type des Quell-Layers erstellen
|
||||
qgs_vector_layer = self._import_qgis_symbol("qgis.core", "QgsVectorLayer")
|
||||
if qgs_vector_layer is None:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
"QgsVectorLayer ist nicht verfuegbar.",
|
||||
)
|
||||
return None, ""
|
||||
|
||||
# CRS vom Quell-Layer übernehmen
|
||||
crs_authid = "EPSG:25832"
|
||||
try:
|
||||
source_crs = getattr(source_layer, "crs", lambda: None)()
|
||||
if source_crs is not None:
|
||||
crs_authid_method = getattr(source_crs, "authid", lambda: None)
|
||||
if callable(crs_authid_method):
|
||||
crs_authid = crs_authid_method() or crs_authid
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Geometrie-Type vom Quell-Layer bestimmen (vereinfacht: Polygon für Atlas)
|
||||
# TODO: Intelligentere Bestimmung des Geometrie-Types
|
||||
atlas_layer = qgs_vector_layer(f"Polygon?crs={crs_authid}", "Atlaslayer", "memory")
|
||||
if not atlas_layer or not getattr(atlas_layer, "isValid", lambda: False)():
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
"Der Atlaslayer konnte nicht erstellt werden.",
|
||||
)
|
||||
return None, ""
|
||||
|
||||
# Ausgewaehlte Features kopieren
|
||||
try:
|
||||
get_selected = getattr(source_layer, "selectedFeatures", None)
|
||||
if not callable(get_selected):
|
||||
raise Exception("selectedFeatures ist nicht aufrufbar")
|
||||
|
||||
selected_features = list(cast(Any, get_selected()))
|
||||
if not selected_features:
|
||||
raise Exception("Keine Features ausgewaehlt")
|
||||
|
||||
qgs_feature = self._import_qgis_symbol("qgis.core", "QgsFeature")
|
||||
if qgs_feature is None:
|
||||
raise Exception("QgsFeature Symbol nicht verfuegbar")
|
||||
|
||||
data_provider = getattr(atlas_layer, "dataProvider", lambda: None)()
|
||||
if data_provider is None:
|
||||
raise Exception("dataProvider nicht verfuegbar")
|
||||
|
||||
new_features = []
|
||||
for source_feature in selected_features:
|
||||
geometry = getattr(source_feature, "geometry", lambda: None)()
|
||||
if geometry is None:
|
||||
continue
|
||||
new_feature = qgs_feature()
|
||||
set_geometry = getattr(new_feature, "setGeometry", None)
|
||||
if callable(set_geometry):
|
||||
try:
|
||||
set_geometry(geometry)
|
||||
new_features.append(new_feature)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if new_features:
|
||||
add_features = getattr(data_provider, "addFeatures", None)
|
||||
if callable(add_features):
|
||||
add_features(new_features)
|
||||
|
||||
update_fields = getattr(atlas_layer, "updateFields", None)
|
||||
if callable(update_fields):
|
||||
update_fields()
|
||||
|
||||
update_extents = getattr(atlas_layer, "updateExtents", None)
|
||||
if callable(update_extents):
|
||||
update_extents()
|
||||
|
||||
except Exception as exc:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
f"Fehler beim Kopieren der Features: {exc}",
|
||||
)
|
||||
return None, ""
|
||||
|
||||
# Layer ins Projekt aufnehmen
|
||||
try:
|
||||
QgsProject.instance().addMapLayer(atlas_layer)
|
||||
except Exception:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
"Der Layer konnte nicht ins Projekt aufgenommen werden.",
|
||||
)
|
||||
return None, ""
|
||||
|
||||
# Layer-ID speichern
|
||||
layer_id = getattr(atlas_layer, "id", lambda: "")() or ""
|
||||
set_variable("sn_abdeckungslayer", layer_id, scope="project")
|
||||
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas Layer erstellen",
|
||||
f"Atlas Layer 'Atlaslayer' erfolgreich erstellt.",
|
||||
)
|
||||
|
||||
return atlas_layer, layer_id
|
||||
|
||||
def configure_atlas_for_baufreigabe_layout(
|
||||
self,
|
||||
layout_name: str = "",
|
||||
atlas_config: AtlasConfig | None = None,
|
||||
) -> bool:
|
||||
"""Konfiguriert den Atlas fuer ein Baufreigabe-Layout mit erweiterten Optionen.
|
||||
|
||||
Wird nach erfolgreicher Baufreigabe-Layout-Erstellung aufgerufen.
|
||||
Setzt den Coverage-Layer (aus sn_abdeckungslayer Variable) und konfiguriert den Atlas
|
||||
mit allen Optionen aus der AtlasConfig.
|
||||
"""
|
||||
try:
|
||||
if atlas_config is None:
|
||||
atlas_config = ATLAS_CONFIG_BAUFREIGABE_DEFAULT
|
||||
|
||||
project = QgsProject.instance()
|
||||
layout_manager = getattr(project, "layoutManager", lambda: None)()
|
||||
if layout_manager is None:
|
||||
self.pruefmanager.zeige_hinweis("Atlas konfigurieren", "Layout Manager nicht verfuegbar.")
|
||||
return False
|
||||
|
||||
if not layout_name:
|
||||
layouts_fn = getattr(layout_manager, "layouts", None)
|
||||
if not callable(layouts_fn):
|
||||
return False
|
||||
try:
|
||||
layout_list = layouts_fn()
|
||||
if not layout_list:
|
||||
return False
|
||||
layout = layout_list[-1]
|
||||
except Exception:
|
||||
return False
|
||||
else:
|
||||
layout_by_name = getattr(layout_manager, "layoutByName", None)
|
||||
if not callable(layout_by_name):
|
||||
return False
|
||||
layout = layout_by_name(layout_name)
|
||||
if layout is None:
|
||||
return False
|
||||
|
||||
atlas = getattr(layout, "atlas", lambda: None)()
|
||||
if atlas is None:
|
||||
return False
|
||||
|
||||
coverage_layer_id = get_variable("sn_abdeckungslayer", scope="project") or ""
|
||||
if not coverage_layer_id:
|
||||
return True
|
||||
|
||||
coverage_layer = project.mapLayer(coverage_layer_id)
|
||||
if coverage_layer is None:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas konfigurieren",
|
||||
f"Atlas-Layer mit ID '{coverage_layer_id}' nicht gefunden.",
|
||||
)
|
||||
return False
|
||||
|
||||
set_coverage = getattr(atlas, "setCoverageLayer", None)
|
||||
if callable(set_coverage):
|
||||
set_coverage(coverage_layer)
|
||||
|
||||
page_name_expr = atlas_config.get("page_name_expression", "")
|
||||
if page_name_expr:
|
||||
set_page_name = getattr(atlas, "setPageNameExpression", None)
|
||||
if callable(set_page_name):
|
||||
set_page_name(page_name_expr)
|
||||
|
||||
if atlas_config.get("filter_features", False):
|
||||
set_filter_features = getattr(atlas, "setFilterFeatures", None)
|
||||
if callable(set_filter_features):
|
||||
set_filter_features(True)
|
||||
filter_expr = atlas_config.get("filter_expression", "")
|
||||
if filter_expr:
|
||||
set_filter_expr = getattr(atlas, "setFilterExpression", None)
|
||||
if callable(set_filter_expr):
|
||||
set_filter_expr(filter_expr)
|
||||
|
||||
if atlas_config.get("sort_features", False):
|
||||
set_sort_features = getattr(atlas, "setSortFeatures", None)
|
||||
if callable(set_sort_features):
|
||||
set_sort_features(True)
|
||||
sort_expr = atlas_config.get("sort_expression", "")
|
||||
if sort_expr:
|
||||
set_sort_expr = getattr(atlas, "setSortExpression", None)
|
||||
if callable(set_sort_expr):
|
||||
set_sort_expr(sort_expr)
|
||||
set_sort_asc = getattr(atlas, "setSortAscending", None)
|
||||
if callable(set_sort_asc):
|
||||
set_sort_asc(atlas_config.get("sort_ascending", True))
|
||||
|
||||
set_hide_coverage = getattr(atlas, "setHideCoverage", None)
|
||||
if callable(set_hide_coverage):
|
||||
set_hide_coverage(atlas_config.get("hide_coverage", False))
|
||||
|
||||
set_limit_render = getattr(atlas, "setLimitCoverageLayerRenderToCurrentFeature", None)
|
||||
if callable(set_limit_render):
|
||||
try:
|
||||
set_limit_render(atlas_config.get("limit_render_to_current_feature", False))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
num_features = 0
|
||||
update_features = getattr(atlas, "updateFeatures", None)
|
||||
if callable(update_features):
|
||||
try:
|
||||
num_features = update_features() or 0
|
||||
except Exception:
|
||||
num_features = 0
|
||||
|
||||
set_enabled = getattr(atlas, "setEnabled", None)
|
||||
if callable(set_enabled):
|
||||
set_enabled(atlas_config.get("enabled", True))
|
||||
return True
|
||||
|
||||
except Exception as exc:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlas konfigurieren",
|
||||
f"Fehler beim Konfigurieren des Atlas: {exc}",
|
||||
)
|
||||
return False
|
||||
|
||||
def _store_druckrechteck(self, layer: object, rectangle: Any) -> bool:
|
||||
qgs_feature = self._import_qgis_symbol("qgis.core", "QgsFeature")
|
||||
qgs_geometry = self._import_qgis_symbol("qgis.core", "QgsGeometry")
|
||||
@@ -579,6 +886,43 @@ class PrintLogic:
|
||||
auswahl = DRUCKBEREICH_VERFAHRENSGEBIET
|
||||
set_variable(DRUCKBEREICH_VAR, auswahl, scope="project")
|
||||
|
||||
def _get_baufreigabe_page_dimensions(
|
||||
self,
|
||||
kartenbild_w: float,
|
||||
kartenbild_h: float,
|
||||
zielgroesse: str,
|
||||
) -> tuple[str, float, float, float, float]:
|
||||
"""Berechnet Seitenformat und verfuegbare Kartenfenster fuer Baufreigabe.
|
||||
|
||||
Args:
|
||||
kartenbild_w: Berechnete Kartenbild-Breite aus Extent/Massstab
|
||||
kartenbild_h: Berechnete Kartenbild-Hoehe aus Extent/Massstab
|
||||
zielgroesse: "DIN A3" oder "DIN A4" (wird zu Querformat konvertiert)
|
||||
|
||||
Returns:
|
||||
(din_format, page_width_mm, page_height_mm, adjusted_map_w, adjusted_map_h)
|
||||
"""
|
||||
# Nur A3/A4 im Querformat fuer Baufreigabe
|
||||
if zielgroesse == "DIN A3":
|
||||
din_format = "DIN A3"
|
||||
page_w, page_h = 420.0, 297.0
|
||||
else:
|
||||
din_format = "DIN A4"
|
||||
page_w, page_h = 297.0, 210.0
|
||||
|
||||
# Verfuegbare Flaeche fuer Kartenbild: Seite - Kartenschild und Maerchen
|
||||
kartenschild_w = 120.0
|
||||
kartenschild_h = 92.0
|
||||
margin = 10.0
|
||||
|
||||
avail_w = page_w - 2 * margin - kartenschild_w - margin
|
||||
avail_h = page_h - 2 * margin - kartenschild_h - margin
|
||||
|
||||
adjusted_map_w = min(kartenbild_w, avail_w)
|
||||
adjusted_map_h = min(kartenbild_h, avail_h)
|
||||
|
||||
return din_format, page_w, page_h, adjusted_map_w, adjusted_map_h
|
||||
|
||||
def druckvorlage_anlegen(
|
||||
self,
|
||||
layer: object | None,
|
||||
@@ -590,7 +934,7 @@ class PrintLogic:
|
||||
) -> dict:
|
||||
resolved_layer = layer or self._resolve_layer_from_project()
|
||||
|
||||
if kartenname_auswahl not in (KARTENNAME_38, KARTENNAME_41):
|
||||
if kartenname_auswahl not in (KARTENNAME_38, KARTENNAME_41, KARTENNAME_BAUFREIGABE):
|
||||
self.pruefmanager.zeige_hinweis("Kartennamen waehlen", "Kartennamen waehlen")
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
@@ -671,18 +1015,36 @@ class PrintLogic:
|
||||
|
||||
vorlage_name = (vorlage_name or "").strip() or kartenname
|
||||
|
||||
# Verzweigung: Baufreigabe vs. Standard-Layout
|
||||
try:
|
||||
PrintLayout().create_single_page_layout(
|
||||
name=vorlage_name,
|
||||
page_width_mm=ziel_w,
|
||||
page_height_mm=ziel_h,
|
||||
map_width_mm=kartenbild_w,
|
||||
map_height_mm=kartenbild_h,
|
||||
extent=extent,
|
||||
plotmassstab=massstab_zahl,
|
||||
thema=thema,
|
||||
fit_extent_to_map=(druckbereich_auswahl != DRUCKBEREICH_VERFAHRENSGEBIET),
|
||||
)
|
||||
if kartenname_auswahl == KARTENNAME_BAUFREIGABE:
|
||||
# Baufreigabe: feste DIN A3/A4 Querformat-Logik mit 120mm Kartenschild
|
||||
din_format, page_w, page_h, map_w, map_h = self._get_baufreigabe_page_dimensions(
|
||||
kartenbild_w, kartenbild_h, zielgroesse
|
||||
)
|
||||
PrintLayoutBaufreigabe().create_baufreigabe_layout(
|
||||
name=vorlage_name if vorlage_name != kartenname else "Baufreigabe",
|
||||
din_format=din_format,
|
||||
map_width_mm=map_w,
|
||||
map_height_mm=map_h,
|
||||
extent=extent,
|
||||
plotmassstab=massstab_zahl,
|
||||
thema=thema,
|
||||
fit_extent_to_map=(druckbereich_auswahl != DRUCKBEREICH_VERFAHRENSGEBIET),
|
||||
)
|
||||
else:
|
||||
# Standard-Layout: dynamische Groessenanpassung
|
||||
PrintLayout().create_single_page_layout(
|
||||
name=vorlage_name,
|
||||
page_width_mm=ziel_w,
|
||||
page_height_mm=ziel_h,
|
||||
map_width_mm=kartenbild_w,
|
||||
map_height_mm=kartenbild_h,
|
||||
extent=extent,
|
||||
plotmassstab=massstab_zahl,
|
||||
thema=thema,
|
||||
fit_extent_to_map=(druckbereich_auswahl != DRUCKBEREICH_VERFAHRENSGEBIET),
|
||||
)
|
||||
except ValueError as exc:
|
||||
self.pruefmanager.zeige_hinweis("Vorlage anlegen", str(exc))
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
@@ -693,4 +1055,8 @@ class PrintLogic:
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
# Nach erfolgreicher Layout-Erstellung: Atlas konfigurieren (falls Baufreigabe)
|
||||
if kartenname_auswahl == KARTENNAME_BAUFREIGABE:
|
||||
self.configure_atlas_for_baufreigabe_layout()
|
||||
|
||||
return {"ok": True, "switch_to_tab_a": False, "atlas_seiten": 1}
|
||||
|
||||
@@ -5,6 +5,7 @@ Die Anwendung erfolgt später über eine Aktion.
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from sn_basis.functions.os_wrapper import is_absolute_path
|
||||
from sn_basis.functions.sys_wrapper import get_plugin_root, file_exists, join_path
|
||||
@@ -43,7 +44,7 @@ class Stilpruefer:
|
||||
|
||||
pfad = str(stil_pfad)
|
||||
|
||||
if not is_absolute_path(pfad):
|
||||
if not is_absolute_path(pfad) and not pfad.startswith(("/", "\\")):
|
||||
plugin_root = get_plugin_root()
|
||||
pfad = str(join_path(plugin_root, "sn_plan41", "assets", pfad))
|
||||
|
||||
@@ -55,7 +56,7 @@ class Stilpruefer:
|
||||
ok=False,
|
||||
meldung=f"Die Stil-Datei '{stil_pfad}' wurde nicht gefunden.",
|
||||
aktion="datei_nicht_gefunden",
|
||||
kontext=pfad,
|
||||
kontext=Path(pfad),
|
||||
)
|
||||
|
||||
# -----------------------------------------------------
|
||||
@@ -66,7 +67,7 @@ class Stilpruefer:
|
||||
ok=False,
|
||||
meldung="Die Stil-Datei muss die Endung '.qml' haben.",
|
||||
aktion="falsche_endung",
|
||||
kontext=pfad,
|
||||
kontext=Path(pfad),
|
||||
)
|
||||
|
||||
# -----------------------------------------------------
|
||||
@@ -76,5 +77,5 @@ class Stilpruefer:
|
||||
ok=True,
|
||||
meldung="Stil-Datei ist gültig.",
|
||||
aktion="stil_anwendbar",
|
||||
kontext=pfad,
|
||||
kontext=Path(pfad),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user