From 8e4031a88485a4455f776c0ae2d5bcbbb464a9e7 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 8 Apr 2026 13:56:58 +0200 Subject: [PATCH] Legende an Hauptkarte des Layouts angebunden --- functions/qgiscore_wrapper.py | 40 ++++++++++++----- modules/print_layout.py | 20 +-------- tests/test_print_layout.py | 85 +++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 30 deletions(-) create mode 100644 tests/test_print_layout.py diff --git a/functions/qgiscore_wrapper.py b/functions/qgiscore_wrapper.py index ca654f4..2ece68e 100644 --- a/functions/qgiscore_wrapper.py +++ b/functions/qgiscore_wrapper.py @@ -174,6 +174,7 @@ except Exception: self.project = project self._name = "" self._page = _MockQgsLayoutPage() + self.items: list[Any] = [] def initializeDefaults(self) -> None: pass @@ -188,7 +189,7 @@ except Exception: return self._page def addLayoutItem(self, item: Any) -> None: - pass + self.items.append(item) class _MockQgsLayoutPage: def setPageSize(self, size: Any) -> None: @@ -201,15 +202,21 @@ except Exception: class _MockQgsLayoutItemMap: def __init__(self, layout: Any): self.layout = layout + self.item_id = "" + self.extent = None + self.scale = None + self.follow_visibility_preset = False + self.follow_visibility_preset_name = "" + self.keep_layer_set = False def setId(self, item_id: str) -> None: - pass + self.item_id = item_id def setExtent(self, extent: Any) -> None: - pass + self.extent = extent def setScale(self, scale: float) -> None: - pass + self.scale = scale def attemptMove(self, point: Any) -> None: pass @@ -218,10 +225,13 @@ except Exception: pass def setFollowVisibilityPreset(self, active: bool) -> None: - pass + self.follow_visibility_preset = active def setFollowVisibilityPresetName(self, name: str) -> None: - pass + self.follow_visibility_preset_name = name + + def setKeepLayerSet(self, enabled: bool) -> None: + self.keep_layer_set = enabled class _MockQgsLayoutItemLabel: ModeHtml = 1 @@ -271,24 +281,30 @@ except Exception: def __init__(self, layout: Any): self.layout = layout self._model = _MockLegendModel() + self.item_id = "" + self.object_name = "" + self.linked_map = None + self.auto_update_model = None + self.legend_filter_by_map_enabled = None + self.title = "" def setId(self, item_id: str) -> None: - pass + self.item_id = item_id def setObjectName(self, name: str) -> None: - pass + self.object_name = name def setLinkedMap(self, map_item: Any) -> None: - pass + self.linked_map = map_item def setAutoUpdateModel(self, enabled: bool) -> None: - pass + self.auto_update_model = enabled def setLegendFilterByMapEnabled(self, enabled: bool) -> None: - pass + self.legend_filter_by_map_enabled = enabled def setTitle(self, title: str) -> None: - pass + self.title = title def setReferencePoint(self, point: Any) -> None: pass diff --git a/modules/print_layout.py b/modules/print_layout.py index b4cf731..049a279 100644 --- a/modules/print_layout.py +++ b/modules/print_layout.py @@ -494,30 +494,14 @@ class PrintLayout: set_auto_update_model = getattr(legend, "setAutoUpdateModel", None) if callable(set_auto_update_model): try: - set_auto_update_model(False) + set_auto_update_model(True) except Exception: pass set_filter_by_map = getattr(legend, "setLegendFilterByMapEnabled", None) if callable(set_filter_by_map): try: - set_filter_by_map(False) - except Exception: - pass - - model_method = getattr(legend, "model", None) - if callable(model_method): - try: - model = model_method() - root_group_method = getattr(model, "rootGroup", None) - root_group = root_group_method() if callable(root_group_method) else None - clear = getattr(root_group, "clear", None) - if callable(clear): - clear() - add_layer = getattr(root_group, "addLayer", None) - if callable(add_layer): - for layer in self._resolve_visible_map_layers(linked_map): - add_layer(layer) + set_filter_by_map(True) except Exception: pass diff --git a/tests/test_print_layout.py b/tests/test_print_layout.py new file mode 100644 index 0000000..7fd307b --- /dev/null +++ b/tests/test_print_layout.py @@ -0,0 +1,85 @@ +import unittest +from unittest.mock import patch + +from sn_basis.functions.qgiscore_wrapper import ( + QgsLayoutItemLegend, + QgsLayoutItemMap, + QgsPrintLayout, + QgsProject, +) +from sn_basis.modules.print_layout import PrintLayout + + +class _FakeExtent: + def isNull(self) -> bool: + return False + + +class TestPrintLayout(unittest.TestCase): + + def test_create_legend_item_links_map_and_enables_map_filtering(self): + project = QgsProject.instance() + print_layout = PrintLayout(project=project) + layout = QgsPrintLayout(project) + linked_map = QgsLayoutItemMap(layout) + + legend = print_layout._create_legend_item( + layout, + "legende", + linked_map, + 10.0, + 20.0, + width_mm=50.0, + height_mm=30.0, + ) + + self.assertIs(legend.linked_map, linked_map) + self.assertTrue(legend.auto_update_model) + self.assertTrue(legend.legend_filter_by_map_enabled) + + def test_create_legend_item_does_not_copy_project_layers_into_legend_model(self): + project = QgsProject.instance() + print_layout = PrintLayout(project=project) + layout = QgsPrintLayout(project) + linked_map = QgsLayoutItemMap(layout) + + legend = print_layout._create_legend_item( + layout, + "legende", + linked_map, + 10.0, + 20.0, + ) + + root_group = legend.model().rootGroup() + self.assertEqual(root_group.layers, []) + + @patch("sn_basis.modules.print_layout.open_layout_designer") + def test_create_single_page_layout_keeps_legend_linked_to_hauptkarte_and_theme(self, _mock_open_designer): + project = QgsProject.instance() + print_layout = PrintLayout(project=project) + + layout = print_layout.create_single_page_layout( + name="Testlayout", + page_width_mm=420.0, + page_height_mm=297.0, + map_width_mm=200.0, + map_height_mm=150.0, + extent=_FakeExtent(), + plotmassstab=5000.0, + thema="Thema A", + ) + + hauptkarte = next(item for item in layout.items if isinstance(item, QgsLayoutItemMap)) + legende = next(item for item in layout.items if isinstance(item, QgsLayoutItemLegend)) + + self.assertTrue(hauptkarte.follow_visibility_preset) + self.assertEqual(hauptkarte.follow_visibility_preset_name, "Thema A") + self.assertTrue(hauptkarte.keep_layer_set) + self.assertIs(legende.linked_map, hauptkarte) + self.assertTrue(legende.auto_update_model) + self.assertTrue(legende.legend_filter_by_map_enabled) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file