From 1d3c98be11d33fa937dfc3b0e51a25df918a21e5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 6 Oct 2026 09:35:46 +0200 Subject: [PATCH] Export und Import der Basemap-Stilvorlagen (Basis #101) dokumentiert Konzept 10 Abschnitt 5.3, Austauschformat in schnittstellen.md, Modulkarte und Testkatalog mit den neuen Tests. Co-Authored-By: Claude Opus 5.5 --- docs/architektur/modulkarte.md | 4 +-- docs/architektur/schnittstellen.md | 3 +- docs/konzept/10_basemap_legende.md | 12 ++++++- docs/tests/testkatalog.html | 52 +++++++++++++++++++++++------- docs/tests/testkatalog.md | 30 ++++++++++++----- 5 files changed, 77 insertions(+), 24 deletions(-) diff --git a/docs/architektur/modulkarte.md b/docs/architektur/modulkarte.md index 6633fbe..0942af2 100644 --- a/docs/architektur/modulkarte.md +++ b/docs/architektur/modulkarte.md @@ -18,7 +18,7 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi | `ui/base_dockwidget.py` | 172 | `BaseDockWidget`: Titel „LNO Sachsen \| “, Tabs aus Klassenattribut `tabs`, jeder Tab in einem Scroll-Bereich (`setWidget`, #104), ruft `cleanup()` der Tabs beim Schließen, setzt Toolbar-Action zurück | | `ui/tabs/settings_tab.py` | 158 | Tab „Projekteigenschaften“: Benutzer- und Projektfelder → Projektvariablen (`SettingsLogic`) | | `ui/tabs/print_tab.py` ⚠ | 730 | Tab „Druck“: Druckbereich, Maßstab, Format, Themen, Legende, Atlas, Basemap-Bereich; nutzt `print_logic` | -| `ui/widgets/basemap_bereich.py` | 433 | Einklappbarer Bereich „Basemap“ im Druck-Tab: Basemap hinzufügen und Thema wechseln (#100), Auswertebereich, Legende aktualisieren, Stilvorlagen | +| `ui/widgets/basemap_bereich.py` | 503 | Einklappbarer Bereich „Basemap“ im Druck-Tab: Basemap hinzufügen und Thema wechseln (#100), Auswertebereich, Legende aktualisieren, Stilvorlagen inkl. Export/Import (#101) | ### functions/ – Wrapper-Schicht (Qt/QGIS/OS mit Mock-Fallback) @@ -65,7 +65,7 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi | `modules/basemap_legende_layout.py` | 471 | Legendensymbole aus Projektlayer-Styles zusammensetzen (weiße Flächen mit Legendenrand, #92), leere Hilfslayer, Legendenelement „Legende Basemap“ schreiben und platzieren | | `modules/basemap_katalog.py` | 418 | Erzeugt/aktualisiert `data/basemap_legende.json` aus der basemap.de-Style-JSON (nur Standardbibliothek, eigenständig aufrufbar) | | `modules/basemap_stilkorrektur.py` | 99 | Darstellungsfehler des Basemap-Layers korrigieren: Punktlinien mit Strichlänge 0 sichtbar machen (#90) | -| `modules/basemap_stilvorlagen.py` | 188 | Lokale Stilvorlagen des Basemap-Layers (QML + JSON im QGIS-Profil, mit Thema), Standard in `QSettings` | +| `modules/basemap_stilvorlagen.py` | 313 | Lokale Stilvorlagen des Basemap-Layers (QML + JSON im QGIS-Profil, mit Thema), Standard in `QSettings`; Export als ZIP, Import von ZIP oder QML, Themenprüfung beim Laden (#101) | | `modules/basemap_themen.py` | 245 | Themen des Basemap-Layers (Farbe, Grau): Layer anlegen, an der Quell-URL erkennen, Thema wechseln, Prüfwert der Darstellung für ungespeicherte Änderungen (#100) | ### Sonstiges diff --git a/docs/architektur/schnittstellen.md b/docs/architektur/schnittstellen.md index b9a2c49..a376256 100644 --- a/docs/architektur/schnittstellen.md +++ b/docs/architektur/schnittstellen.md @@ -166,7 +166,8 @@ flowchart LR `python modules/basemap_katalog.py`; gehört zur Style-Version `bm_web_col` v2. - **Stilvorlagen:** lokal unter `/sn_basis/basemap_stile/`, Standard in `QSettings` `sn_basis/basemap_standardstil`. Die Begleit-JSON trägt seit #100 das Feld `thema` (Schlüssel aus - `basemap_themen.THEMEN`; fehlt bei älteren Vorlagen). + `basemap_themen.THEMEN`; fehlt bei älteren Vorlagen). Austauschformat seit #101: ZIP mit genau einer + `.qml` und optional `.json`; der Import nimmt auch eine reine QML-Datei an. - **Thema und Stil (Basis #100):** *Thema* = vom Dienst als Style-JSON gelieferte Darstellung (`farbe` → `bm_web_col.json`, `grau` → `bm_web_gry.json`); *Stil* = lokale Anpassung (Stilvorlage). Alle Themen nutzen dieselbe Kachel-URL `…/tiles/v2/bm_web_de_3857/{z}/{x}/{y}.pbf`; das Thema steht im Quellparameter `styleUrl`. diff --git a/docs/konzept/10_basemap_legende.md b/docs/konzept/10_basemap_legende.md index 14ab406..d233514 100644 --- a/docs/konzept/10_basemap_legende.md +++ b/docs/konzept/10_basemap_legende.md @@ -142,9 +142,19 @@ Ohne Basemap-Layer im Projekt ist der Bereich deaktiviert und zeigt „Kein Base - **Laden:** Rückfrage vor dem Überschreiben der aktuellen Darstellung. Danach Prüfung, ob die `styleName`s der Vorlage zum Layer passen (Farbe vs. Grau, neue Basemap-Version); bei Abweichung Hinweis mit Anzahl unbekannter Styles. Laden geschieht **nur über den Knopf**, nicht automatisch beim Öffnen eines Projekts. + Seit #101 zusätzlich: Passt das `thema` der Vorlage (Farbe/Grau) nicht zum Thema des Layers, folgt eine + Rückfrage. Ohne Thema in Vorlage oder Layer (ältere oder als QML importierte Vorlage) gibt es keine Rückfrage. - **Speichern unter …:** Name abfragen, vorhandene Variante nur nach Rückfrage überschreiben. +- **Exportieren … / Importieren … (#101):** Export schreibt die gewählte Variante als **eine ZIP-Datei** + (`.qml` + `.json`) zum Weitergeben per Mail oder Netzlaufwerk. Import nimmt eine solche ZIP-Datei + oder eine **reine QML-Datei** an (z. B. aus „Stil speichern“ in QGIS), schlägt den Anzeigenamen aus der + Begleitdatei bzw. dem Dateinamen vor und überschreibt eine gleichnamige Variante nur nach Rückfrage. Aus der + fremden Begleitdatei werden nur `erstellt`, `layer`, `stile`, `thema` und `legende_auswahl` übernommen, ergänzt + um `importiert` und `importiert_aus`; der Standard des anderen Rechners nicht. Geprüft wird, dass die QML eine + QGIS-Stildatei ist (`Testkatalog der sn_*-Plugins — was die Suite heute prüft, auf einen Blick.
Quelle: docs/tests/testkatalog.md
Baseline: docs/status/testbaseline.json (SHA-256 aeabc946a7f3)
-
732Testfälle
-
689grün
+
744Testfälle
+
701grün
35rot (Baseline)
-
80%mit Docstring
+
81%mit Docstring
60Testdateien
Verteilung je Paket
-
sn_basis43 Dateien · 478 Testfälle
+
sn_basis43 Dateien · 490 Testfälle
sn_verfahrensgebiet12 Dateien · 210 Testfälle
sn_plan415 Dateien · 44 Testfälle
@@ -147,9 +147,9 @@

sn_basis

-

Plattform-Plugin · Ordner Plugin_SN_Basis · 43 Testdateien · 478 Testfälle

+

Plattform-Plugin · Ordner Plugin_SN_Basis · 43 Testdateien · 490 Testfälle

- @@ -184,7 +184,7 @@ classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420; classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20; classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08; - classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
CloseEventTests
test_ruft_cleanup_aller_tabs_auf
Prüft, dass closeEvent cleanup() auf allen Tabs des Dock-Widgets aufruft.grün
CloseEventTests
test_ignoriert_tabs_ohne_cleanup
Prüft, dass ein Tab ohne cleanup()-Methode nicht zu einem Fehler führt.grün
CloseEventTests
test_fehler_in_cleanup_wird_abgefangen_und_andere_tabs_laufen_weiter
Prüft, dass ein Fehler in cleanup() eines Tabs nicht die übrigen Tabs verhindert.grün
CloseEventTests
test_setzt_toolbar_action_zurueck
Prüft, dass closeEvent die verknüpfte Toolbar-Action auf 'nicht gedrückt' zurücksetzt.grün
CloseEventTests
test_ohne_action_wird_nichts_zurueckgesetzt
Prüft, dass closeEvent ohne verknüpfte Toolbar-Action keine Ausnahme wirft.grün
ScrollbereichTests
test_jeder_tab_liegt_in_einem_scrollbereich
Prüft, dass BaseDockWidget jeden Tab in einen mitwachsenden Scroll-Bereich packt, damit ein langer Tab scrollt, statt das Fenster zu verlängern.grün
ScrollbereichTests
test_fachplugin_mit_eigenem_tabaufbau_bekommt_scrollbereich
Prüft, dass auch ein Fachplugin, das seine Tabs selbst aufbaut und per setWidget einsetzt (wie Plan41, Verfahrensgebiet), Scroll-Bereiche bekommt.grün
ScrollbereichTests
test_scrollbereich_wird_nicht_doppelt_angelegt
Prüft, dass ein Tab, der schon in einem Scroll-Bereich liegt, beim erneuten Einsetzen nicht ein zweites Mal verpackt wird.grün
ScrollbereichTests
test_setwidget_none_und_andere_widgets_bleiben_unveraendert
Prüft, dass setWidget(None) und Widgets ohne Tabs ohne Fehler und unverändert eingesetzt werden.grün
ScrollbereichTests
test_cleanup_erreicht_tabs_im_scrollbereich
Prüft, dass closeEvent cleanup() auch für Tabs aufruft, die in einem Scroll-Bereich liegen.grün

Tests für die Anbindung der Basemap-Legende an Druckablauf, Dialog und Druck-Tab (Basis #88):

TestMehrfachauswahl 1TestDruckanbindung 4TestBasemapBereich 10
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
CloseEventTests
test_ruft_cleanup_aller_tabs_auf
Prüft, dass closeEvent cleanup() auf allen Tabs des Dock-Widgets aufruft.grün
CloseEventTests
test_ignoriert_tabs_ohne_cleanup
Prüft, dass ein Tab ohne cleanup()-Methode nicht zu einem Fehler führt.grün
CloseEventTests
test_fehler_in_cleanup_wird_abgefangen_und_andere_tabs_laufen_weiter
Prüft, dass ein Fehler in cleanup() eines Tabs nicht die übrigen Tabs verhindert.grün
CloseEventTests
test_setzt_toolbar_action_zurueck
Prüft, dass closeEvent die verknüpfte Toolbar-Action auf 'nicht gedrückt' zurücksetzt.grün
CloseEventTests
test_ohne_action_wird_nichts_zurueckgesetzt
Prüft, dass closeEvent ohne verknüpfte Toolbar-Action keine Ausnahme wirft.grün
ScrollbereichTests
test_jeder_tab_liegt_in_einem_scrollbereich
Prüft, dass BaseDockWidget jeden Tab in einen mitwachsenden Scroll-Bereich packt, damit ein langer Tab scrollt, statt das Fenster zu verlängern.grün
ScrollbereichTests
test_fachplugin_mit_eigenem_tabaufbau_bekommt_scrollbereich
Prüft, dass auch ein Fachplugin, das seine Tabs selbst aufbaut und per setWidget einsetzt (wie Plan41, Verfahrensgebiet), Scroll-Bereiche bekommt.grün
ScrollbereichTests
test_scrollbereich_wird_nicht_doppelt_angelegt
Prüft, dass ein Tab, der schon in einem Scroll-Bereich liegt, beim erneuten Einsetzen nicht ein zweites Mal verpackt wird.grün
ScrollbereichTests
test_setwidget_none_und_andere_widgets_bleiben_unveraendert
Prüft, dass setWidget(None) und Widgets ohne Tabs ohne Fehler und unverändert eingesetzt werden.grün
ScrollbereichTests
test_cleanup_erreicht_tabs_im_scrollbereich
Prüft, dass closeEvent cleanup() auch für Tabs aufruft, die in einem Scroll-Bereich liegen.grün

Tests für die Anbindung der Basemap-Legende an Druckablauf, Dialog und Druck-Tab (Basis #88):

TestMehrfachauswahl 1TestDruckanbindung 4TestBasemapBereich 11TestStilvorlagenAustausch 5
flowchart TD
   root(["test_basemap_anbindung.py"])
   class root rootnode
   root --> g1["TestMehrfachauswahl (1)"]
@@ -196,7 +196,7 @@
   g2 --> t3("layout_wird_markiert_und_legende_erzeugt")
   g2 --> t4("fehler_der_basemap_legende_verhindert_die_vorlage_nicht")
   g2 --> t5("druck_tab_aktualisiert_basemap_bereich_falls_vorhanden")
-  root --> g3["TestBasemapBereich (10)"]
+  root --> g3["TestBasemapBereich (11)"]
   class g3 groupnode
   g3 --> t6("auswertebereich_wird_gespeichert")
   g3 --> t7("aktualisieren_ohne_vorlage_warnt")
@@ -208,6 +208,14 @@
   g3 --> t13("punktlinien_korrigieren_meldet_anzahl")
   g3 --> t14("punktlinien_ohne_basemap_layer_warnt")
   g3 --> t15("stil_speichern_ohne_basemap_layer_warnt")
+  g3 --> t16("stil_laden_bricht_bei_fremdem_thema_ab")
+  root --> g4["TestStilvorlagenAustausch (5)"]
+  class g4 groupnode
+  g4 --> t17("export_schreibt_gewaehlte_vorlage")
+  g4 --> t18("export_abgebrochen_oder_ohne_vorlage")
+  g4 --> t19("import_uebernimmt_datei_unter_gewaehltem_namen")
+  g4 --> t20("import_ersetzt_vorhandene_nur_nach_rueckfrage")
+  g4 --> t21("import_ungeeigneter_datei_warnt")
   class t1 ok
   class t2 ok
   class t3 ok
@@ -223,11 +231,17 @@
   class t13 ok
   class t14 ok
   class t15 ok
+  class t16 ok
+  class t17 ok
+  class t18 ok
+  class t19 ok
+  class t20 ok
+  class t21 ok
   classDef rootnode fill:#1f4038,stroke:#16302a,stroke-width:1px,color:#f4f1e8,font-weight:600;
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestMehrfachauswahl
test_mock_modus_liefert_vorauswahl_in_listenreihenfolge
Prüft, dass der Mehrfachauswahl-Dialog im Mock-Modus die vorausgewählten Schlüssel in Listenreihenfolge liefert.grün
TestDruckanbindung
test_basemap_legende_nur_fuer_38_und_41_und_bei_eingeschaltetem_schalter
Prüft, dass nur §-38- und §-41-Vorlagen eine Basemap-Legende bekommen und nur, wenn der Schalter im Druck-Tab an ist.grün
TestDruckanbindung
test_layout_wird_markiert_und_legende_erzeugt
Prüft, dass PrintLayout das Layout als Basemap-Nutzer kennzeichnet und die Basemap-Legende erzeugen lässt.grün
TestDruckanbindung
test_fehler_der_basemap_legende_verhindert_die_vorlage_nicht
Prüft, dass ein Fehler beim Erzeugen der Basemap-Legende nur als Warnung gemeldet wird und keine Ausnahme durchreicht.grün
TestDruckanbindung
test_druck_tab_aktualisiert_basemap_bereich_falls_vorhanden
Prüft, dass der Druck-Tab den Basemap-Bereich neu einliest und ohne Bereich nichts tut.grün
TestBasemapBereich
test_auswertebereich_wird_gespeichert
Prüft, dass die Wahl des Auswertebereichs in der Projektvariable landet.grün
TestBasemapBereich
test_aktualisieren_ohne_vorlage_warnt
Prüft, dass „Basemap-Legende aktualisieren“ ohne vorhandene Vorlage warnt und nichts auswertet.grün
TestBasemapBereich
test_aktualisieren_wertet_gewaehlte_vorlage_aus
Prüft, dass „Basemap-Legende aktualisieren“ die gewählte Vorlage auswertet und den Erfolg meldet.grün
TestBasemapBereich
test_stil_laden_uebernimmt_legendenauswahl
Prüft, dass das Laden einer Stilvorlage den Layerstil ersetzt und ihre Legendenauswahl in das Projekt übernimmt.grün
TestBasemapBereich
test_stil_laden_bricht_bei_fremder_vorlage_ab
Prüft, dass eine Vorlage mit unbekannten Styles nur nach Bestätigung geladen wird.grün
TestBasemapBereich
test_vorhandene_vorlage_wird_nur_nach_rueckfrage_ersetzt
Prüft, dass eine gleichnamige Stilvorlage ohne Bestätigung nicht überschrieben wird.grün
TestBasemapBereich
test_speichern_mit_aktueller_legendenauswahl
Prüft, dass eine neue Stilvorlage zusammen mit der aktuellen Legendenauswahl gespeichert wird.grün
TestBasemapBereich
test_punktlinien_korrigieren_meldet_anzahl
Prüft, dass „Punktlinien korrigieren“ den Basemap-Layer korrigiert und die Anzahl korrigierter Styles meldet.grün
TestBasemapBereich
test_punktlinien_ohne_basemap_layer_warnt
Prüft, dass ohne Basemap-Layer nichts korrigiert, sondern gewarnt wird.grün
TestBasemapBereich
test_stil_speichern_ohne_basemap_layer_warnt
Prüft, dass ohne Basemap-Layer keine Stilvorlage gespeichert, sondern gewarnt wird.grün

Tests für modules/basemap_kacheln.py – kachelweise Auswertung des Basemap-Layers (Basis #88).

TestSammleObjekte 4TestZoomUndStile 2
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestMehrfachauswahl
test_mock_modus_liefert_vorauswahl_in_listenreihenfolge
Prüft, dass der Mehrfachauswahl-Dialog im Mock-Modus die vorausgewählten Schlüssel in Listenreihenfolge liefert.grün
TestDruckanbindung
test_basemap_legende_nur_fuer_38_und_41_und_bei_eingeschaltetem_schalter
Prüft, dass nur §-38- und §-41-Vorlagen eine Basemap-Legende bekommen und nur, wenn der Schalter im Druck-Tab an ist.grün
TestDruckanbindung
test_layout_wird_markiert_und_legende_erzeugt
Prüft, dass PrintLayout das Layout als Basemap-Nutzer kennzeichnet und die Basemap-Legende erzeugen lässt.grün
TestDruckanbindung
test_fehler_der_basemap_legende_verhindert_die_vorlage_nicht
Prüft, dass ein Fehler beim Erzeugen der Basemap-Legende nur als Warnung gemeldet wird und keine Ausnahme durchreicht.grün
TestDruckanbindung
test_druck_tab_aktualisiert_basemap_bereich_falls_vorhanden
Prüft, dass der Druck-Tab den Basemap-Bereich neu einliest und ohne Bereich nichts tut.grün
TestBasemapBereich
test_auswertebereich_wird_gespeichert
Prüft, dass die Wahl des Auswertebereichs in der Projektvariable landet.grün
TestBasemapBereich
test_aktualisieren_ohne_vorlage_warnt
Prüft, dass „Basemap-Legende aktualisieren“ ohne vorhandene Vorlage warnt und nichts auswertet.grün
TestBasemapBereich
test_aktualisieren_wertet_gewaehlte_vorlage_aus
Prüft, dass „Basemap-Legende aktualisieren“ die gewählte Vorlage auswertet und den Erfolg meldet.grün
TestBasemapBereich
test_stil_laden_uebernimmt_legendenauswahl
Prüft, dass das Laden einer Stilvorlage den Layerstil ersetzt und ihre Legendenauswahl in das Projekt übernimmt.grün
TestBasemapBereich
test_stil_laden_bricht_bei_fremder_vorlage_ab
Prüft, dass eine Vorlage mit unbekannten Styles nur nach Bestätigung geladen wird.grün
TestBasemapBereich
test_vorhandene_vorlage_wird_nur_nach_rueckfrage_ersetzt
Prüft, dass eine gleichnamige Stilvorlage ohne Bestätigung nicht überschrieben wird.grün
TestBasemapBereich
test_speichern_mit_aktueller_legendenauswahl
Prüft, dass eine neue Stilvorlage zusammen mit der aktuellen Legendenauswahl gespeichert wird.grün
TestBasemapBereich
test_punktlinien_korrigieren_meldet_anzahl
Prüft, dass „Punktlinien korrigieren“ den Basemap-Layer korrigiert und die Anzahl korrigierter Styles meldet.grün
TestBasemapBereich
test_punktlinien_ohne_basemap_layer_warnt
Prüft, dass ohne Basemap-Layer nichts korrigiert, sondern gewarnt wird.grün
TestBasemapBereich
test_stil_speichern_ohne_basemap_layer_warnt
Prüft, dass ohne Basemap-Layer keine Stilvorlage gespeichert, sondern gewarnt wird.grün
TestBasemapBereich
test_stil_laden_bricht_bei_fremdem_thema_ab
Prüft, dass eine Vorlage eines anderen Themas (Grau auf Farbe) nur nach Bestätigung geladen wird.grün
TestStilvorlagenAustausch
test_export_schreibt_gewaehlte_vorlage
Prüft, dass „Exportieren …“ die gewählte Vorlage in die im Dateidialog gewählte Datei schreibt und den Pfad meldet.grün
TestStilvorlagenAustausch
test_export_abgebrochen_oder_ohne_vorlage
Prüft, dass ohne gewählte Vorlage oder bei abgebrochenem Dateidialog nichts exportiert wird.grün
TestStilvorlagenAustausch
test_import_uebernimmt_datei_unter_gewaehltem_namen
Prüft, dass „Importieren …“ den Namen aus der Datei vorschlägt, unter dem gewählten Namen importiert und die neue Vorlage auswählt.grün
TestStilvorlagenAustausch
test_import_ersetzt_vorhandene_nur_nach_rueckfrage
Prüft, dass ein Import eine gleichnamige Vorlage ohne Bestätigung nicht überschreibt.grün
TestStilvorlagenAustausch
test_import_ungeeigneter_datei_warnt
Prüft, dass eine ungeeignete Importdatei gemeldet wird, ohne nach einem Namen zu fragen oder etwas zu importieren.grün

Tests für modules/basemap_kacheln.py – kachelweise Auswertung des Basemap-Layers (Basis #88).

TestSammleObjekte 4TestZoomUndStile 2
flowchart TD
   root(["test_basemap_kacheln.py"])
   class root rootnode
   root --> g1["TestSammleObjekte (4)"]
@@ -435,7 +449,7 @@
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestMusterUndAusdruck
test_strichlaenge_null_im_festen_muster
Prüft, dass Strichlängen 0 (gerade Positionen) im Strichmuster ersetzt und Lücken der Länge 0 nicht verändert werden.grün
TestMusterUndAusdruck
test_strichlaenge_null_im_zoomabhaengigen_ausdruck
Prüft, dass jede Strichlänge 0 in den array(...)-Mustern des Konverter-Ausdrucks ersetzt wird und der übrige Ausdruck gleich bleibt.grün
TestLayerkorrektur
test_punktlinien_werden_korrigiert_andere_styles_nicht
Prüft, dass nur Styles mit Strichlänge 0 korrigiert werden – Muster und Ausdruck – und die Anzahl zurückkommt.grün
TestLayerkorrektur
test_zweiter_lauf_korrigiert_nichts
Prüft, dass ein zweiter Lauf keine Styles mehr korrigiert und nicht neu zeichnen lässt.grün
TestLayerkorrektur
test_nur_ausdruck_ohne_festes_muster
Prüft, dass auch ein Style korrigiert wird, dessen Strichlänge 0 nur im zoomabhängigen Ausdruck steht.grün
TestLayerkorrektur
test_layer_ohne_renderer
Prüft, dass ein Layer ohne Renderer 0 korrigierte Styles liefert.grün

Tests für modules/basemap_stilvorlagen.py – lokale Stilvorlagen des Basemap-Layers (Basis #88).

TestStilvorlagen 8
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestMusterUndAusdruck
test_strichlaenge_null_im_festen_muster
Prüft, dass Strichlängen 0 (gerade Positionen) im Strichmuster ersetzt und Lücken der Länge 0 nicht verändert werden.grün
TestMusterUndAusdruck
test_strichlaenge_null_im_zoomabhaengigen_ausdruck
Prüft, dass jede Strichlänge 0 in den array(...)-Mustern des Konverter-Ausdrucks ersetzt wird und der übrige Ausdruck gleich bleibt.grün
TestLayerkorrektur
test_punktlinien_werden_korrigiert_andere_styles_nicht
Prüft, dass nur Styles mit Strichlänge 0 korrigiert werden – Muster und Ausdruck – und die Anzahl zurückkommt.grün
TestLayerkorrektur
test_zweiter_lauf_korrigiert_nichts
Prüft, dass ein zweiter Lauf keine Styles mehr korrigiert und nicht neu zeichnen lässt.grün
TestLayerkorrektur
test_nur_ausdruck_ohne_festes_muster
Prüft, dass auch ein Style korrigiert wird, dessen Strichlänge 0 nur im zoomabhängigen Ausdruck steht.grün
TestLayerkorrektur
test_layer_ohne_renderer
Prüft, dass ein Layer ohne Renderer 0 korrigierte Styles liefert.grün

Tests für modules/basemap_stilvorlagen.py – lokale Stilvorlagen des Basemap-Layers (Basis #88),

TestStilvorlagen 8TestExportImport 6
flowchart TD
   root(["test_basemap_stilvorlagen.py"])
   class root rootnode
   root --> g1["TestStilvorlagen (8)"]
@@ -448,6 +462,14 @@
   g1 --> t6("standard_setzen_und_beim_loeschen_entfernen")
   g1 --> t7("fehlende_begleitdatei_wird_toleriert")
   g1 --> t8("ohne_ordner_leere_liste")
+  root --> g2["TestExportImport (6)"]
+  class g2 groupnode
+  g2 --> t9("export_und_import_uebertragen_vorlage_mit_begleitdaten")
+  g2 --> t10("export_einer_fehlenden_vorlage")
+  g2 --> t11("import_einer_reinen_qml_datei")
+  g2 --> t12("import_lehnt_ungeeignete_dateien_ab")
+  g2 --> t13("import_uebernimmt_nur_bekannte_begleitdaten")
+  g2 --> t14("thema_der_vorlage_passt_nicht_zum_layer")
   class t1 ok
   class t2 ok
   class t3 ok
@@ -456,11 +478,17 @@
   class t6 ok
   class t7 ok
   class t8 ok
+  class t9 ok
+  class t10 ok
+  class t11 ok
+  class t12 ok
+  class t13 ok
+  class t14 ok
   classDef rootnode fill:#1f4038,stroke:#16302a,stroke-width:1px,color:#f4f1e8,font-weight:600;
   classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
   classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
   classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
-  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestStilvorlagen
test_speichern_und_auflisten
Prüft, dass eine gespeicherte Vorlage mit Anzeigenamen, QML-Datei und Begleitdatei aufgelistet wird.grün
TestStilvorlagen
test_mehrere_varianten_alphabetisch
Prüft, dass mehrere Varianten nebeneinander bestehen und alphabetisch nach Anzeigename sortiert werden.grün
TestStilvorlagen
test_leerer_name_oder_fehler_beim_schreiben
Prüft, dass ein leerer Name und ein Schreibfehler von QGIS als ValueError gemeldet werden.grün
TestStilvorlagen
test_laden_setzt_stil_und_zeichnet_neu
Prüft, dass das Laden die QML-Datei der Vorlage in den Layer lädt und neu zeichnen lässt.grün
TestStilvorlagen
test_passung_meldet_fremde_styles
Prüft, dass Style-Namen der Vorlage gemeldet werden, die der Ziel-Layer nicht kennt.grün
TestStilvorlagen
test_standard_setzen_und_beim_loeschen_entfernen
Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt.grün
TestStilvorlagen
test_fehlende_begleitdatei_wird_toleriert
Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird.grün
TestStilvorlagen
test_ohne_ordner_leere_liste
Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt.grün

Tests für modules/basemap_themen.py und den Abschnitt „Basemap-Layer“ im Basemap-Bereich (Basis #100):

TestQuelleUndThema 4TestPruefwert 3TestLayerUndThemenwechsel 7TestStilvorlageMitThema 1TestAuswahlDialog 1TestBasemapHinzufuegen 5TestThemaWechseln 8TestZielLayer 1
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestStilvorlagen
test_speichern_und_auflisten
Prüft, dass eine gespeicherte Vorlage mit Anzeigenamen, QML-Datei und Begleitdatei aufgelistet wird.grün
TestStilvorlagen
test_mehrere_varianten_alphabetisch
Prüft, dass mehrere Varianten nebeneinander bestehen und alphabetisch nach Anzeigename sortiert werden.grün
TestStilvorlagen
test_leerer_name_oder_fehler_beim_schreiben
Prüft, dass ein leerer Name und ein Schreibfehler von QGIS als ValueError gemeldet werden.grün
TestStilvorlagen
test_laden_setzt_stil_und_zeichnet_neu
Prüft, dass das Laden die QML-Datei der Vorlage in den Layer lädt und neu zeichnen lässt.grün
TestStilvorlagen
test_passung_meldet_fremde_styles
Prüft, dass Style-Namen der Vorlage gemeldet werden, die der Ziel-Layer nicht kennt.grün
TestStilvorlagen
test_standard_setzen_und_beim_loeschen_entfernen
Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt.grün
TestStilvorlagen
test_fehlende_begleitdatei_wird_toleriert
Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird.grün
TestStilvorlagen
test_ohne_ordner_leere_liste
Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt.grün
TestExportImport
test_export_und_import_uebertragen_vorlage_mit_begleitdaten
Prüft, dass eine exportierte Vorlage auf einem anderen Rechner mit Anzeigename, Thema, Style-Namen und Legendenauswahl ankommt.grün
TestExportImport
test_export_einer_fehlenden_vorlage
Prüft, dass der Export einer nicht vorhandenen Vorlage als ValueError gemeldet wird und keine Datei entsteht.grün
TestExportImport
test_import_einer_reinen_qml_datei
Prüft, dass eine QML-Datei ohne Begleitdatei mit dem Dateinamen als Namensvorschlag und ohne Thema übernommen wird.grün
TestExportImport
test_import_lehnt_ungeeignete_dateien_ab
Prüft, dass Dateien ohne QGIS-Stil und ZIP-Dateien ohne genau eine QML-Datei abgelehnt werden, ohne etwas anzulegen.grün
TestExportImport
test_import_uebernimmt_nur_bekannte_begleitdaten
Prüft, dass ein Import unbekannte oder falsch typisierte Angaben der Begleitdatei verwirft und den gewählten Namen nutzt.grün
TestExportImport
test_thema_der_vorlage_passt_nicht_zum_layer
Prüft, dass ein abweichendes Thema der Vorlage gemeldet wird und ohne Thema in Vorlage oder Layer keine Meldung kommt.grün

Tests für modules/basemap_themen.py und den Abschnitt „Basemap-Layer“ im Basemap-Bereich (Basis #100):

TestQuelleUndThema 4TestPruefwert 3TestLayerUndThemenwechsel 7TestStilvorlageMitThema 1TestAuswahlDialog 1TestBasemapHinzufuegen 5TestThemaWechseln 8TestZielLayer 1
flowchart TD
   root(["test_basemap_themen.py"])
   class root rootnode
   root --> g1["TestQuelleUndThema (4)"]
diff --git a/docs/tests/testkatalog.md b/docs/tests/testkatalog.md
index 25e8d8c..3174fa7 100644
--- a/docs/tests/testkatalog.md
+++ b/docs/tests/testkatalog.md
@@ -9,17 +9,17 @@ selbst (Docstrings) und aus der Testbaseline.
 
 Stand der Baseline: `docs/status/testbaseline.json` (SHA-256 `aeabc946a7f3`)
 
-Gesamt: 3 Pakete, 60 Testdateien, 732 Testfälle – 689 grün, 35 rot (Baseline), 8 übersprungen.
-Mit Beschreibung (Docstring): 587 von 732 (80 %).
+Gesamt: 3 Pakete, 60 Testdateien, 744 Testfälle – 701 grün, 35 rot (Baseline), 8 übersprungen.
+Mit Beschreibung (Docstring): 599 von 744 (81 %).
 
 ## Zusammenfassung
 
 | Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung |
 | --- | ---: | ---: | ---: | ---: | ---: | ---: |
-| `sn_basis` | 43 | 478 | 478 | 0 | 0 | 478 von 478 (100 %) |
+| `sn_basis` | 43 | 490 | 490 | 0 | 0 | 490 von 490 (100 %) |
 | `sn_verfahrensgebiet` | 12 | 210 | 168 | 34 | 8 | 108 von 210 (51 %) |
 | `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) |
-| **Summe** | **60** | **732** | **689** | **35** | **8** | **587 von 732 (80 %)** |
+| **Summe** | **60** | **744** | **701** | **35** | **8** | **599 von 744 (81 %)** |
 
 ### Legende
 
@@ -31,7 +31,7 @@ Mit Beschreibung (Docstring): 587 von 732 (80 %).
 
 ## Paket `sn_basis`
 
-Plattform-Plugin, Ordner `Plugin_SN_Basis` – 43 Testdateien mit 478 Testfällen (478 grün, 0 rot, 0 übersprungen).
+Plattform-Plugin, Ordner `Plugin_SN_Basis` – 43 Testdateien mit 490 Testfällen (490 grün, 0 rot, 0 übersprungen).
 
 ### `Plugin_SN_Basis/tests/test_base_dockwidget.py`
 
@@ -63,7 +63,8 @@ Testgruppen:
 
 - `TestMehrfachauswahl` (1 Testfälle): — (Docstring fehlt)
 - `TestDruckanbindung` (4 Testfälle): — (Docstring fehlt)
-- `TestBasemapBereich` (10 Testfälle): — (Docstring fehlt)
+- `TestBasemapBereich` (11 Testfälle): — (Docstring fehlt)
+- `TestStilvorlagenAustausch` (5 Testfälle): — (Docstring fehlt)
 
 | Testfall | prüft | Status |
 | --- | --- | --- |
@@ -82,6 +83,12 @@ Testgruppen:
 | `TestBasemapBereich.test_punktlinien_korrigieren_meldet_anzahl` | Prüft, dass „Punktlinien korrigieren“ den Basemap-Layer korrigiert und die Anzahl korrigierter Styles meldet. | grün |
 | `TestBasemapBereich.test_punktlinien_ohne_basemap_layer_warnt` | Prüft, dass ohne Basemap-Layer nichts korrigiert, sondern gewarnt wird. | grün |
 | `TestBasemapBereich.test_stil_speichern_ohne_basemap_layer_warnt` | Prüft, dass ohne Basemap-Layer keine Stilvorlage gespeichert, sondern gewarnt wird. | grün |
+| `TestBasemapBereich.test_stil_laden_bricht_bei_fremdem_thema_ab` | Prüft, dass eine Vorlage eines anderen Themas (Grau auf Farbe) nur nach Bestätigung geladen wird. | grün |
+| `TestStilvorlagenAustausch.test_export_schreibt_gewaehlte_vorlage` | Prüft, dass „Exportieren …“ die gewählte Vorlage in die im Dateidialog gewählte Datei schreibt und den Pfad meldet. | grün |
+| `TestStilvorlagenAustausch.test_export_abgebrochen_oder_ohne_vorlage` | Prüft, dass ohne gewählte Vorlage oder bei abgebrochenem Dateidialog nichts exportiert wird. | grün |
+| `TestStilvorlagenAustausch.test_import_uebernimmt_datei_unter_gewaehltem_namen` | Prüft, dass „Importieren …“ den Namen aus der Datei vorschlägt, unter dem gewählten Namen importiert und die neue Vorlage auswählt. | grün |
+| `TestStilvorlagenAustausch.test_import_ersetzt_vorhandene_nur_nach_rueckfrage` | Prüft, dass ein Import eine gleichnamige Vorlage ohne Bestätigung nicht überschreibt. | grün |
+| `TestStilvorlagenAustausch.test_import_ungeeigneter_datei_warnt` | Prüft, dass eine ungeeignete Importdatei gemeldet wird, ohne nach einem Namen zu fragen oder etwas zu importieren. | grün |
 
 ### `Plugin_SN_Basis/tests/test_basemap_kacheln.py`
 
@@ -228,11 +235,12 @@ Testgruppen:
 
 ### `Plugin_SN_Basis/tests/test_basemap_stilvorlagen.py`
 
-Worum es in der Datei geht: Tests für modules/basemap_stilvorlagen.py – lokale Stilvorlagen des Basemap-Layers (Basis #88).
+Worum es in der Datei geht: Tests für modules/basemap_stilvorlagen.py – lokale Stilvorlagen des Basemap-Layers (Basis #88),
 
 Testgruppen:
 
 - `TestStilvorlagen` (8 Testfälle): — (Docstring fehlt)
+- `TestExportImport` (6 Testfälle): — (Docstring fehlt)
 
 | Testfall | prüft | Status |
 | --- | --- | --- |
@@ -244,6 +252,12 @@ Testgruppen:
 | `TestStilvorlagen.test_standard_setzen_und_beim_loeschen_entfernen` | Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt. | grün |
 | `TestStilvorlagen.test_fehlende_begleitdatei_wird_toleriert` | Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird. | grün |
 | `TestStilvorlagen.test_ohne_ordner_leere_liste` | Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt. | grün |
+| `TestExportImport.test_export_und_import_uebertragen_vorlage_mit_begleitdaten` | Prüft, dass eine exportierte Vorlage auf einem anderen Rechner mit Anzeigename, Thema, Style-Namen und Legendenauswahl ankommt. | grün |
+| `TestExportImport.test_export_einer_fehlenden_vorlage` | Prüft, dass der Export einer nicht vorhandenen Vorlage als ValueError gemeldet wird und keine Datei entsteht. | grün |
+| `TestExportImport.test_import_einer_reinen_qml_datei` | Prüft, dass eine QML-Datei ohne Begleitdatei mit dem Dateinamen als Namensvorschlag und ohne Thema übernommen wird. | grün |
+| `TestExportImport.test_import_lehnt_ungeeignete_dateien_ab` | Prüft, dass Dateien ohne QGIS-Stil und ZIP-Dateien ohne genau eine QML-Datei abgelehnt werden, ohne etwas anzulegen. | grün |
+| `TestExportImport.test_import_uebernimmt_nur_bekannte_begleitdaten` | Prüft, dass ein Import unbekannte oder falsch typisierte Angaben der Begleitdatei verwirft und den gewählten Namen nutzt. | grün |
+| `TestExportImport.test_thema_der_vorlage_passt_nicht_zum_layer` | Prüft, dass ein abweichendes Thema der Vorlage gemeldet wird und ohne Thema in Vorlage oder Layer keine Meldung kommt. | grün |
 
 ### `Plugin_SN_Basis/tests/test_basemap_themen.py`
 
@@ -1545,7 +1559,7 @@ Arbeitsliste: Diese Testfälle haben keinen Docstring; was sie fachlich prüfen,
 aus dem Quelltext erschließen. Jeder Eintrag braucht eine einzeilige Beschreibung im Testfall,
 dann verschwindet er hier von selbst.
 
-### `sn_basis` – 0 von 478 Testfällen ohne Beschreibung
+### `sn_basis` – 0 von 490 Testfällen ohne Beschreibung
 
 Keine Lücken.