diff --git a/changelog.txt b/changelog.txt index 41aaad1..1011734 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,4 @@ +- Bezeichner-Bereinigung (Layernamen) um Bindestrich ergänzt und in eine zentrale Funktion `sanitize_bezeichner` (`functions/text_wrapper.py`) ausgelagert, damit Umlaute/Sonderzeichen nicht mehr pro Aufrufstelle vergessen werden (#42) - Landkreis-Dropdown (statt Freitext) in den Projekteigenschaften ergänzt, inkl. Landkreiskennzahl als eigene Projektvariable - Landkreisliste liegt jetzt als JSON (sn_basis/data/landkreise.json) statt hartcodiert vor, damit auch andere Module und Nicht-Entwickler sie pflegen können - Auswahldialog für mehrere BauRaumOderBodenordnungsrecht-Treffer auf Mehrfachauswahl umgestellt (mehrere Objekte gemeinsam laden/verschmelzen) diff --git a/functions/__init__.py b/functions/__init__.py index 485334a..9180e6a 100644 --- a/functions/__init__.py +++ b/functions/__init__.py @@ -22,6 +22,7 @@ from .ly_metadata_wrapper import ( from .ly_style_wrapper import apply_style from .dialog_wrapper import ask_yes_no, ask_overwrite_append_cancel_custom, ask_ergaenzen_entfernen_ersetzen_abbrechen, ask_detailpruefung_oder_vg_laden from .laenderkennung import get_laenderkennung, LAENDERKENNUNGEN +from .text_wrapper import sanitize_bezeichner from .message_wrapper import ( _get_message_bar, diff --git a/functions/text_wrapper.py b/functions/text_wrapper.py new file mode 100644 index 0000000..03e93a4 --- /dev/null +++ b/functions/text_wrapper.py @@ -0,0 +1,28 @@ +""" +sn_basis/functions/text_wrapper.py – Bezeichner-Hilfsfunktionen. + +Zentrale Stelle, um Freitext (z. B. ein Thema oder ein Schriftfeldinhalt) in einen +technischen Bezeichner (Layername, Dateiname) umzuwandeln. Nicht pro Aufrufstelle +ein eigenes Regex schreiben – Umlaute, Unterstrich und Bindestrich werden hier an +einer Stelle gepflegt (siehe docs/wissen/fallstricke.md, Issue Plugin_SN_Basis #42). +""" + +import re + +# Buchstaben, Ziffern, deutsche Umlaute/ß, Unterstrich und Bindestrich gelten immer +# als zulässig. Wurde in der Vergangenheit wiederholt vergessen, wenn ein neues +# Regex direkt im Aufrufer entstand statt diese Funktion zu nutzen. +_BEZEICHNER_ERLAUBT = r"A-Za-z0-9_\-ÄäÖöÜüß" + + +def sanitize_bezeichner(text: str, ersatz: str = "_") -> str: + """Wandelt `text` in einen technischen Bezeichner um. + + Alle Zeichen außerhalb von Buchstaben/Ziffern/Umlauten/ß/Unterstrich/Bindestrich + werden durch `ersatz` ersetzt, anschließend werden führende und folgende + Vorkommen von `ersatz` entfernt. Gedacht für Layer- und Dateinamen – nicht für + Freitext in Schriftfeldern oder der Legende, wo auch andere Zeichen sichtbar + bleiben sollen. + """ + bereinigt = re.sub(rf"[^{_BEZEICHNER_ERLAUBT}]+", ersatz, text) + return bereinigt.strip(ersatz) diff --git a/modules/Datenschreiber.py b/modules/Datenschreiber.py index aa91308..b25551b 100644 --- a/modules/Datenschreiber.py +++ b/modules/Datenschreiber.py @@ -30,13 +30,13 @@ from __future__ import annotations from typing import Any, Dict, List, Optional import os import json -import re import datetime import sqlite3 from sn_basis.functions import qgiscore_wrapper as qgiscore from sn_basis.functions.os_wrapper import normalize_path, is_absolute_path from sn_basis.functions.sys_wrapper import get_plugin_root, join_path, file_exists +from sn_basis.functions.text_wrapper import sanitize_bezeichner from sn_basis.modules.pruef_ergebnis import pruef_ergebnis @@ -209,7 +209,7 @@ class Datenschreiber: continue layer_name_raw = thema or str(ident) - layer_name = re.sub(r"[^A-Za-z0-9_ÄäÖöÜüß]+", "_", layer_name_raw).strip("_") + layer_name = sanitize_bezeichner(layer_name_raw) if not layer_name: layer_name = f"layer_{ident}" diff --git a/modules/print_layout.py b/modules/print_layout.py index 2fe01f7..3ed2aa7 100644 --- a/modules/print_layout.py +++ b/modules/print_layout.py @@ -45,7 +45,7 @@ MM = QgsUnitTypes.LayoutMillimeters class PrintLayout: - """Erzeugt ein QGIS-Einzelblatt-Layout fuer den Druck.""" + """Erzeugt ein QGIS-Einzelblatt-Layout für den Druck.""" _FRAME_STROKE_WIDTH_MM = 0.5 _LEGEND_WIDTH_MM = 180.0 @@ -340,7 +340,7 @@ class PrintLayout: ("[% @sn_landkreise_proj %]", 16.0, -48.0, 171.0, 4.0, "Format_1", "Landkreis"), ("[% @sn_kartenname %]", 16.0, -32.0, 137.0, 12.0, "Format_3", "Kartenname"), ("Gefertigt: ", 16.0, -23.0, 81.0, 4.0, "Format_1", "Gefertigt"), - ("Geprueft: ", 101.0, -23.0, 81.0, 4.0, "Format_1", "Geprüft"), + ("Geprüft: ", 101.0, -23.0, 81.0, 4.0, "Format_1", "Geprüft"), ( "Maßstab: 1 : [%round(map_get(item_variables('Hauptkarte'),'map_scale'),0)%]", 16.0, diff --git a/modules/print_layout_baufreigabe.py b/modules/print_layout_baufreigabe.py index 05c32f0..e0b3153 100644 --- a/modules/print_layout_baufreigabe.py +++ b/modules/print_layout_baufreigabe.py @@ -1,9 +1,9 @@ """ -sn_basis/modules/print_layout_baufreigabe.py - Layout-Erstellung fuer Baufreigabe-Vorlagen. +sn_basis/modules/print_layout_baufreigabe.py - Layout-Erstellung für 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. +Baufreigabe-Layouts verwenden immer feste DIN A3/A4 Seitengrößen im Querformat, +ein 120 mm breites Kartenschild (statt 180 mm) und erben die Standard-Logik +für Hauptkarte, Quellenangabe und Legende vom PrintLayout. Atlas-Integration erfolgt nach Layouterstellung durch externe Konfiguration in der PrintLogic. @@ -32,7 +32,7 @@ MM = QgsUnitTypes.LayoutMillimeters class PrintLayoutBaufreigabe(PrintLayout): - """Erzeugt QGIS-Einzelblatt-Layouts mit fester DIN A3/A4 Querformat-Groesse und 80mm Kartenschild.""" + """Erzeugt QGIS-Einzelblatt-Layouts mit fester DIN A3/A4 Querformat-Größe und 80mm Kartenschild.""" _FRAME_STROKE_WIDTH_MM = 0.5 _KARTENSCHILD_WIDTH_MM = 80.0 @@ -41,7 +41,7 @@ class PrintLayoutBaufreigabe(PrintLayout): _GRID_INTERVAL_MAP_UNITS = 500.0 # DIN-Formate: nur A3 und A4 im Querformat - _DIN_A3_LANDSCAPE = (420, 297) # Breite x Hoehe (Querformat) + _DIN_A3_LANDSCAPE = (420, 297) # Breite x Höhe (Querformat) _DIN_A4_LANDSCAPE = (297, 210) # Querformat _TEXT_FORMAT_TEMPLATES = { @@ -99,25 +99,25 @@ class PrintLayoutBaufreigabe(PrintLayout): fit_extent_to_map: bool = True, atlas_driven: bool = True, ) -> Any: - """Erstellt ein Baufreigabe-Layout mit fester DIN A3/A4 Querformat-Groesse. + """Erstellt ein Baufreigabe-Layout mit fester DIN A3/A4 Querformat-Größe. Args: name: Name des Layouts din_format: "DIN A3" oder "DIN A4" map_width_mm: Breite der Hauptkarte - map_height_mm: Hoehe der Hauptkarte + map_height_mm: Höhe der Hauptkarte extent: QgsRectangle der Kartenausdehnung - plotmassstab: Plotmassstab (z.B. 5000 fuer 1:5000) + plotmassstab: Plotmaßstab (z.B. 5000 für 1:5000) thema: Name des Visibility-Presets (optional) - fit_extent_to_map: Extent bei Bedarf auf das Karten-Seitenverhaeltnis erweitern + fit_extent_to_map: Extent bei Bedarf auf das Karten-Seitenverhältnis erweitern Returns: - QgsPrintLayout objektInstance (wird im Layout-Dialog geoeffnet) + QgsPrintLayout objektInstance (wird im Layout-Dialog geöffnet) Raises: - ValueError: Falls Name bereits existiert oder Format ungueltig ist + ValueError: Falls Name bereits existiert oder Format ungültig ist """ - # Seitenformat auswaehlen (nur A3/A4 im Querformat) + # Seitenformat auswählen (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": @@ -266,9 +266,9 @@ class PrintLayoutBaufreigabe(PrintLayout): map_top_mm: float, map_height_mm: float, ) -> None: - """Erstellt Legende, Quellenangabe und Kartenschild fuer Baufreigabe-Layout. + """Erstellt Legende, Quellenangabe und Kartenschild für Baufreigabe-Layout. - Angepasst fuer 80mm Kartenschild statt 180mm. + Angepasst für 80mm Kartenschild statt 180mm. """ if self._current_layout is None: raise RuntimeError("Kein Layout aktiv.") @@ -279,7 +279,7 @@ class PrintLayoutBaufreigabe(PrintLayout): kartenfenster_untere_rechte_ecke_mm[1] + rel_y_mm, ) - # Legende: 80mm Breite, hoehe adaptive wie Standard + # Legende: 80mm Breite, Höhe adaptiv 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 diff --git a/modules/print_logic.py b/modules/print_logic.py index 74a74b4..3fbd51b 100644 --- a/modules/print_logic.py +++ b/modules/print_logic.py @@ -1,5 +1,5 @@ """ -sn_basis/modules/print_logic.py - Fachlogik fuer den Druck-Tab (nur Einzelblatt). +sn_basis/modules/print_logic.py - Fachlogik für den Druck-Tab (nur Einzelblatt). """ from __future__ import annotations @@ -16,7 +16,7 @@ from sn_basis.modules.print_layout_baufreigabe import PrintLayoutBaufreigabe class AtlasConfig(TypedDict, total=False): - """Strukturierte Konfiguration fuer Atlas-Optionen. + """Strukturierte Konfiguration für Atlas-Optionen. Alle Felder sind optional (total=False) und haben vordefinierte Standartwerte. """ @@ -113,7 +113,7 @@ STANDARD_A4_LANDSCAPE_H_MM = 210.0 class PrintLogic: - """Kapselt die Fachlogik fuer den Druck-Tab (ohne Atlas).""" + """Kapselt die Fachlogik für den Druck-Tab (ohne Atlas).""" def __init__(self, pruefmanager: Pruefmanager) -> None: self.pruefmanager = pruefmanager @@ -125,8 +125,8 @@ class PrintLogic: def _show_target_size_too_small(self) -> dict: self.pruefmanager.zeige_hinweis( - "Zielgroesse zu klein", - "Die gewaehlte Zielgroesse reicht fuer den Einzelblatt-Druck nicht aus.", + "Zielgröße zu klein", + "Die gewählte Zielgröße reicht für den Einzelblatt-Druck nicht aus.", ) return self._failed_result() @@ -348,13 +348,13 @@ class PrintLogic: if int(cast(Any, selected_count())) == 0: self.pruefmanager.zeige_hinweis( "Atlas Layer erstellen", - "Auf dem Layer sind keine Features ausgewaehlt.", + "Auf dem Layer sind keine Features ausgewählt.", ) return None, "" except Exception: pass - # Bestehenden Atlaslayer loeschen (optional Wiederverwedung) + # Bestehenden Atlaslayer löschen (optional Wiederverwendung) existing_atlas = self._get_existing_layer_by_name("Atlaslayer") if existing_atlas is not None: try: @@ -367,7 +367,7 @@ class PrintLogic: if qgs_vector_layer is None: self.pruefmanager.zeige_hinweis( "Atlas Layer erstellen", - "QgsVectorLayer ist nicht verfuegbar.", + "QgsVectorLayer ist nicht verfügbar.", ) return None, "" @@ -392,7 +392,7 @@ class PrintLogic: ) return None, "" - # Ausgewaehlte Features kopieren + # Ausgewählte Features kopieren try: get_selected = getattr(source_layer, "selectedFeatures", None) if not callable(get_selected): @@ -400,15 +400,15 @@ class PrintLogic: selected_features = list(cast(Any, get_selected())) if not selected_features: - raise Exception("Keine Features ausgewaehlt") + raise Exception("Keine Features ausgewählt") qgs_feature = self._import_qgis_symbol("qgis.core", "QgsFeature") if qgs_feature is None: - raise Exception("QgsFeature Symbol nicht verfuegbar") + raise Exception("QgsFeature Symbol nicht verfügbar") data_provider = getattr(atlas_layer, "dataProvider", lambda: None)() if data_provider is None: - raise Exception("dataProvider nicht verfuegbar") + raise Exception("dataProvider nicht verfügbar") new_features = [] for source_feature in selected_features: @@ -470,7 +470,7 @@ class PrintLogic: layout_name: str = "", atlas_config: AtlasConfig | None = None, ) -> bool: - """Konfiguriert den Atlas fuer ein Baufreigabe-Layout mit erweiterten Optionen. + """Konfiguriert den Atlas für 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 @@ -483,7 +483,7 @@ class PrintLogic: 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.") + self.pruefmanager.zeige_hinweis("Atlas konfigurieren", "Layout Manager nicht verfügbar.") return False if not layout_name: @@ -672,7 +672,7 @@ class PrintLogic: if map_canvas is None: self.pruefmanager.zeige_hinweis( "Druckrechteck", - "Das Kartenfenster ist nicht verfuegbar.", + "Das Kartenfenster ist nicht verfügbar.", ) return False @@ -684,7 +684,7 @@ class PrintLogic: if None in (qgs_geometry, qgs_rectangle, qgs_wkb_types, qgs_map_tool_emit_point, qgs_rubber_band): self.pruefmanager.zeige_hinweis( "Druckrechteck", - "Die Rechteck-Erfassung ist in dieser QGIS-Umgebung nicht verfuegbar.", + "Die Rechteck-Erfassung ist in dieser QGIS-Umgebung nicht verfügbar.", ) return False @@ -736,13 +736,13 @@ class PrintLogic: if width <= 0 or height <= 0: logic.pruefmanager.zeige_hinweis( "Druckrechteck", - "Das gezeichnete Rechteck ist ungueltig.", + "Das gezeichnete Rechteck ist ungültig.", ) else: if logic._store_druckrechteck(layer, rectangle): logic.pruefmanager.zeige_hinweis( "Druckrechteck", - "Das Druckrechteck wurde uebernommen.", + "Das Druckrechteck wurde übernommen.", ) try: self.rubber_band.reset(polygon_geometry) @@ -920,7 +920,7 @@ class PrintLogic: if extent is None: self.pruefmanager.zeige_hinweis( "Druckbereich", - "Das aktuelle Kartenfenster liefert keine gueltige Ausdehnung.", + "Das aktuelle Kartenfenster liefert keine gültige Ausdehnung.", ) return None, None return extent, None @@ -931,7 +931,7 @@ class PrintLogic: if extent is None: self.pruefmanager.zeige_hinweis( "Druckbereich", - "Auf dem aktuellen Layer sind keine gueltigen Objekte ausgewaehlt.", + "Auf dem aktuellen Layer sind keine gültigen Objekte ausgewählt.", ) return None, None return self._buffer_extent(extent, plotmassstab), None @@ -948,7 +948,7 @@ class PrintLogic: if not ergebnis.ok: self.pruefmanager.zeige_hinweis( "Verfahrensgebiets-Layer angeben", - "Kein gueltiger Verfahrensgebiets-Layer gefunden. Bitte Layerauswahl im jeweiligen Plugin setzen.", + "Kein gültiger Verfahrensgebiets-Layer gefunden. Bitte Layerauswahl im jeweiligen Plugin setzen.", ) return None, None @@ -1001,12 +1001,12 @@ class PrintLogic: required_map_height_mm: float, max_format: str = "DIN A3", ) -> tuple[str, float, float, float, float, bool]: - """Waehlt fuer Baufreigabe ein Blatt im Querformat. + """Wählt für Baufreigabe ein Blatt im Querformat. Args: - required_map_width_mm: benoetigte Breite der Hauptkarte in mm - required_map_height_mm: benoetigte Hoehe der Hauptkarte in mm - max_format: maximale Blattgroesse, standardmaessig DIN A3 + required_map_width_mm: benötigte Breite der Hauptkarte in mm + required_map_height_mm: benötigte Höhe der Hauptkarte in mm + max_format: maximale Blattgröße, standardmäßig DIN A3 Returns: (din_format, page_width_mm, page_height_mm, map_w_mm, map_h_mm, fallback_applied) @@ -1029,8 +1029,8 @@ class PrintLogic: if map_w >= required_map_width_mm and map_h >= required_map_height_mm: return din_format, page_w, page_h, map_w, map_h, False - # Wenn der gewuenschte Ausschnitt nicht passt, verwende das maximal erlaubte Blatt - # und erweitere die Hauptkarte auf die verfuegbare Kartenflaeche (zentriert per fit_extent_to_map). + # Wenn der gewünschte Ausschnitt nicht passt, verwende das maximal erlaubte Blatt + # und erweitere die Hauptkarte auf die verfügbare Kartenfläche (zentriert per fit_extent_to_map). din_format, page_w, page_h = limited_candidates[-1] map_w = max(page_w - BAUFREIGABE_LAYOUT_FIXBREITE_MM, 50.0) map_h = max(page_h - BAUFREIGABE_LAYOUT_FIXHOEHE_MM, 50.0) @@ -1059,7 +1059,7 @@ class PrintLogic: return map_width_mm + fixed_width_mm, map_height_mm + fixed_height_mm def _get_required_map_dimensions_mm(self, extent: Any, plotmassstab: float) -> tuple[float, float]: - """Berechnet die benoetigte Kartenfenstergroesse in mm fuer Extent und Massstab.""" + """Berechnet die benötigte Kartenfenstergröße in mm für Extent und Maßstab.""" if extent is None or not isinstance(plotmassstab, (int, float)) or plotmassstab <= 0: return 0.0, 0.0 @@ -1077,7 +1077,7 @@ class PrintLogic: required_map_height_mm: float, max_format: str, ) -> tuple[float, float, float, float] | None: - """Waehlt das kleinste passende DIN-Blatt fuer das Standardlayout.""" + """Wählt das kleinste passende DIN-Blatt für das Standardlayout.""" try: max_index = DIN_AUTO_REIHENFOLGE.index(max_format) except ValueError: @@ -1170,7 +1170,7 @@ class PrintLogic: resolved_layer = layer or self._resolve_layer_from_project() if kartenname_auswahl not in (KARTENNAME_38, KARTENNAME_41, KARTENNAME_BAUFREIGABE): - self.pruefmanager.zeige_hinweis("Kartennamen waehlen", "Kartennamen waehlen") + self.pruefmanager.zeige_hinweis("Kartennamen wählen", "Kartennamen wählen") return self._failed_result() if massstab_auswahl == MASSSTAB_WIE_KARTENFENSTER: @@ -1191,7 +1191,7 @@ class PrintLogic: massstab_zahl = float(PLOTMASSSTAB_BY_AUSWAHL.get(massstab_auswahl, 0)) if massstab_zahl <= 0: - self.pruefmanager.zeige_hinweis("Massstab fehlt", "Kein gueltiger Massstab angegeben.") + self.pruefmanager.zeige_hinweis("Maßstab fehlt", "Kein gültiger Maßstab angegeben.") return self._failed_result() extent, layer_for_extent = self._resolve_extent(resolved_layer, druckbereich_auswahl, massstab_zahl) @@ -1262,7 +1262,7 @@ class PrintLogic: vorlage_name = (vorlage_name or "").strip() or kartenname - # Atlas-Status vorab bestimmen, damit er sowohl an create_ als auch configure_ uebergeben wird. + # Atlas-Status vorab bestimmen, damit er sowohl an create_ als auch configure_ übergeben wird. atlas_raw_bf = get_variable(ATLAS_ERZEUGEN_UI_VAR, scope="project") atlas_erzeugen_bf = self._is_enabled_flag(atlas_raw_bf) @@ -1283,7 +1283,7 @@ class PrintLogic: atlas_driven=atlas_erzeugen_bf, ) else: - # Standard-Layout: dynamische Groessenanpassung + # Standard-Layout: dynamische Größenanpassung PrintLayout().create_single_page_layout( name=vorlage_name, page_width_mm=auto_page_w, diff --git a/tests/test_text_wrapper.py b/tests/test_text_wrapper.py new file mode 100644 index 0000000..ed917da --- /dev/null +++ b/tests/test_text_wrapper.py @@ -0,0 +1,43 @@ +"""sn_basis/tests/test_text_wrapper.py + +Unit-Tests für :mod:`sn_basis.functions.text_wrapper`. +""" + +import unittest + +from sn_basis.functions.text_wrapper import sanitize_bezeichner + + +class TestSanitizeBezeichner(unittest.TestCase): + def test_umlaute_bleiben_erhalten(self): + """Prüft, dass Umlaute und ß nicht durch den Ersatz entfernt werden.""" + self.assertEqual(sanitize_bezeichner("Grünfläche"), "Grünfläche") + self.assertEqual(sanitize_bezeichner("Straße"), "Straße") + + def test_bindestrich_bleibt_erhalten(self): + """Prüft, dass ein Bindestrich im Bezeichner erhalten bleibt (Issue #42).""" + self.assertEqual(sanitize_bezeichner("Wege-Plan"), "Wege-Plan") + + def test_unterstrich_bleibt_erhalten(self): + """Prüft, dass ein Unterstrich im Bezeichner erhalten bleibt.""" + self.assertEqual(sanitize_bezeichner("thema_flur_1"), "thema_flur_1") + + def test_leerzeichen_wird_durch_ersatz_zusammengefasst(self): + """Prüft, dass Leerzeichen (kein zulässiges Zeichen) zu einem Ersatzzeichen werden.""" + self.assertEqual(sanitize_bezeichner("Flurstücke Gemarkung"), "Flurstücke_Gemarkung") + + def test_fuehrender_und_folgender_ersatz_wird_entfernt(self): + """Prüft, dass ein Ersatzzeichen am Anfang oder Ende des Ergebnisses entfernt wird.""" + self.assertEqual(sanitize_bezeichner("!Thema!"), "Thema") + + def test_eigenes_ersatzzeichen_wird_verwendet(self): + """Prüft, dass ein abweichendes Ersatzzeichen anstelle von Unterstrich genutzt wird.""" + self.assertEqual(sanitize_bezeichner("a b", ersatz="-"), "a-b") + + def test_nur_unzulaessige_zeichen_ergibt_leeren_string(self): + """Prüft, dass ein Bezeichner ganz aus unzulässigen Zeichen zu einem leeren String wird.""" + self.assertEqual(sanitize_bezeichner("!!!"), "") + + +if __name__ == "__main__": + unittest.main() diff --git a/ui/tabs/print_tab.py b/ui/tabs/print_tab.py index 953500e..4446c80 100644 --- a/ui/tabs/print_tab.py +++ b/ui/tabs/print_tab.py @@ -1,5 +1,5 @@ """ -sn_basis/ui/tabs/print_tab.py - Zentraler Druck-Tab fuer sn-Plugins. +sn_basis/ui/tabs/print_tab.py - Zentraler Druck-Tab für sn-Plugins. """ from __future__ import annotations @@ -41,7 +41,7 @@ from sn_basis.modules.print_logic import ( KARTENNAME_VAR = "tab_b_kartenname" -KARTENNAME_PLACEHOLDER = "Kartenname waehlen" +KARTENNAME_PLACEHOLDER = "Kartenname wählen" KARTENNAME_38 = "§38" KARTENNAME_41 = "§41" KARTENNAME_BAUFREIGABE = "Anlage zur Baufreigabe" @@ -59,7 +59,7 @@ DRUCKBEREICH_OPTIONEN = [ class PrintTab(QWidget): - """UI-Klasse fuer den zentralen Druck-Tab.""" + """UI-Klasse für den zentralen Druck-Tab.""" tab_title = "Druck" @@ -130,7 +130,7 @@ class PrintTab(QWidget): self._kartenname_combo = kartenname_combo main_layout.addWidget(kartenname_combo) - massstab_label = QLabel("Massstab") + massstab_label = QLabel("Maßstab") massstab_label.setStyleSheet("font-weight: bold; margin-top: 6px;") main_layout.addWidget(massstab_label) @@ -152,7 +152,7 @@ class PrintTab(QWidget): self._thema_combo = thema_combo main_layout.addWidget(thema_combo) - zielgroesse_label = QLabel("max. Blattgroesse") + zielgroesse_label = QLabel("max. Blattgröße") zielgroesse_label.setStyleSheet("font-weight: bold; margin-top: 6px;") main_layout.addWidget(zielgroesse_label) @@ -610,7 +610,7 @@ class PrintTab(QWidget): return None def _on_atlas_layer_changed(self, layer_or_name: Any) -> None: - """Speichert den ausgewaehlten Atlas-Layer als Layer-ID in Projektvariablen.""" + """Speichert den ausgewählten Atlas-Layer als Layer-ID in Projektvariablen.""" if layer_or_name is None or layer_or_name == "": set_variable("sn_abdeckungslayer", "", scope="project") return @@ -639,10 +639,10 @@ class PrintTab(QWidget): pass def _on_auswahl_as_atlas_clicked(self) -> None: - """Handler fuer Button 'Auswahl als Atlas anlegen'. - + """Handler für Button 'Auswahl als Atlas anlegen'. + Erstellt einen neuen Layer 'Atlaslayer' aus der aktuellen Feature-Auswahl - und traegt ihn ins Atlas-Dropdown ein. + und trägt ihn ins Atlas-Dropdown ein. """ if not self.logic or not self.pruefmanager: return @@ -673,11 +673,11 @@ class PrintTab(QWidget): except Exception: pass - # Fallback nur fuer Mock/klassische ComboBox + # Fallback nur für Mock/klassische ComboBox self._populate_atlas_layer_combo() def _populate_atlas_layer_combo(self) -> None: - """Fallback-Befuellung, falls kein echtes QgsMapLayerComboBox Verhalten verfuegbar ist.""" + """Fallback-Befüllung, falls kein echtes QgsMapLayerComboBox Verhalten verfügbar ist.""" if not self._atlas_layer_combo: return