Skip to content

Commit 4b60927

Browse files
authored
Merge branch 'main' into 14-lomakkeen-tuottaminen-templaatin-konfiguraatiosta
2 parents 840b18f + 161e3ba commit 4b60927

7 files changed

+158
-17
lines changed

arho_feature_template/core/feature_template_library.py

+84-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import logging
4+
from collections import defaultdict
45

56
from qgis.core import QgsFeature, QgsProject, QgsVectorLayer
67
from qgis.gui import QgsMapToolDigitizeFeature
@@ -81,15 +82,19 @@ def __init__(self) -> None:
8182
self.template_model = QStandardItemModel()
8283
self.template_dock.template_list.setModel(self.template_model)
8384

85+
# Set the selection mode to allow single selection
86+
self.template_dock.template_list.setSelectionMode(self.template_dock.template_list.SingleSelection)
87+
8488
self._read_library_configs()
8589

8690
self.template_dock.library_selection.addItems(self.get_library_names())
8791

88-
# Update template list when library selection changes
92+
# Update template tree when library selection changes
8993
self.template_dock.library_selection.currentIndexChanged.connect(
9094
lambda: self.set_active_library(self.template_dock.library_selection.currentText())
9195
)
92-
# Update template list when search text changes
96+
97+
# Update template tree when search text changes
9398
self.template_dock.search_box.valueChanged.connect(self.on_template_search_text_changed)
9499

95100
# Activate map tool when template is selected
@@ -101,11 +106,17 @@ def __init__(self) -> None:
101106

102107
def on_template_item_clicked(self, index):
103108
item = self.template_model.itemFromIndex(index)
109+
110+
# Do nothing if clicked item is a group
111+
if item.hasChildren():
112+
return
113+
104114
try:
105115
layer = get_layer_from_project(item.config.feature.layer)
106116
except (LayerNotFoundError, LayerNotVectorTypeError):
107117
logger.exception("Failed to activate template")
108118
return
119+
109120
self.active_template = item
110121
self.start_digitizing_for_layer(layer)
111122

@@ -114,16 +125,45 @@ def on_template_item_clicked(self, index):
114125
index, QItemSelectionModel.Select | QItemSelectionModel.Rows
115126
)
116127

117-
def on_template_search_text_changed(self, search_text: str):
128+
def on_template_search_text_changed(self, search_text: str) -> None:
129+
search_text = search_text.lower()
130+
118131
for row in range(self.template_model.rowCount()):
119-
item = self.template_model.item(row)
132+
group_item = self.template_model.item(row)
133+
group_visible = False
120134

121-
# If the search text is in the item's text, show the row
122-
if search_text in item.text().lower():
123-
self.template_dock.template_list.setRowHidden(row, False)
124-
else:
125-
# Otherwise, hide the row
126-
self.template_dock.template_list.setRowHidden(row, True)
135+
for child_row in range(group_item.rowCount()):
136+
child_item = group_item.child(child_row)
137+
138+
if child_item.hasChildren():
139+
subgroup_visible = False
140+
141+
for template_row in range(child_item.rowCount()):
142+
template_item = child_item.child(template_row)
143+
matches = search_text in template_item.text().lower()
144+
template_item.setEnabled(matches)
145+
146+
if matches:
147+
subgroup_visible = True
148+
149+
child_item.setEnabled(subgroup_visible)
150+
group_visible = group_visible or subgroup_visible
151+
152+
index = self.template_model.indexFromItem(child_item)
153+
self.template_dock.template_list.setExpanded(index, subgroup_visible)
154+
155+
else:
156+
template_item = child_item
157+
matches = search_text in template_item.text().lower()
158+
template_item.setEnabled(matches)
159+
160+
if matches:
161+
group_visible = True
162+
163+
group_item.setEnabled(group_visible)
164+
165+
index = self.template_model.indexFromItem(group_item)
166+
self.template_dock.template_list.setExpanded(index, group_visible)
127167

128168
def start_digitizing_for_layer(self, layer: QgsVectorLayer) -> None:
129169
self.digitize_map_tool.clean()
@@ -163,10 +203,41 @@ def get_library_names(self) -> list[str]:
163203
def set_active_library(self, library_name: str) -> None:
164204
self.template_model.clear()
165205

206+
grouped_templates: defaultdict[str, defaultdict[str, list[FeatureTemplate]]] = defaultdict(
207+
lambda: defaultdict(list)
208+
)
209+
210+
# Group templates by 'group' and 'sub_group'
166211
for template in self.library_configs[library_name].templates:
167-
item = TemplateItem(template)
168-
item.setEditable(False)
169-
self.template_model.appendRow(item)
212+
group = getattr(template, "group", None) or "Ryhmittelemättömät"
213+
sub_group = getattr(template, "sub_group", None)
214+
if sub_group:
215+
grouped_templates[group][sub_group].append(template)
216+
else:
217+
grouped_templates[group][""].append(template)
218+
219+
for group_name, sub_group_dict in grouped_templates.items():
220+
group_item = QStandardItem(group_name)
221+
group_item.setEditable(False)
222+
223+
for sub_group_name, templates in sub_group_dict.items():
224+
if sub_group_name:
225+
sub_group_item = QStandardItem(sub_group_name)
226+
sub_group_item.setEditable(False)
227+
group_item.appendRow(sub_group_item)
228+
target_item = sub_group_item
229+
else:
230+
# If template has no sub_group set, list it directly under group
231+
target_item = group_item
232+
233+
for template in templates:
234+
template_item = TemplateItem(template)
235+
template_item.setEditable(False)
236+
target_item.appendRow(template_item)
237+
238+
self.template_model.appendRow(group_item)
239+
240+
self.template_dock.template_list.expandAll()
170241

171242
def _read_library_configs(self) -> None:
172243
for config_file in library_config_files():

arho_feature_template/core/template_library_config.py

+8
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,17 @@ class TemplateLibraryMeta:
5353
"""Describes the metadata of a template library"""
5454

5555
name: str
56+
group: str | None
57+
sub_group: str | None
5658
description: str | None
5759
version: str | None
5860

5961
@classmethod
6062
def from_dict(cls, data: dict) -> TemplateLibraryMeta:
6163
return cls(
6264
name=data["name"],
65+
group=data.get("group"),
66+
sub_group=data.get("sub_group"),
6367
description=data.get("description"),
6468
version=data.get("version"),
6569
)
@@ -70,13 +74,17 @@ class FeatureTemplate:
7074
"""Describes a feature template that can include nested features"""
7175

7276
name: str
77+
group: str | None
78+
sub_group: str | None
7379
description: str | None
7480
feature: Feature
7581

7682
@classmethod
7783
def from_dict(cls, data: dict) -> FeatureTemplate:
7884
return cls(
7985
name=data["name"],
86+
group=data.get("group"),
87+
sub_group=data.get("sub_group"),
8088
description=data.get("description"),
8189
feature=Feature.from_dict(data["feature"]),
8290
)

arho_feature_template/gui/load_plan_dialog.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ def __init__(self, parent, connections):
5656

5757
self.planTableView.setSelectionMode(QTableView.SingleSelection)
5858
self.planTableView.setSelectionBehavior(QTableView.SelectRows)
59-
self.planTableView.selectionModel().selectionChanged.connect(self.on_selection_changed)
6059

6160
self.model = QStandardItemModel()
6261
self.model.setColumnCount(5)
@@ -75,6 +74,7 @@ def __init__(self, parent, connections):
7574
self.filterProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
7675

7776
self.planTableView.setModel(self.filterProxyModel)
77+
self.planTableView.selectionModel().selectionChanged.connect(self.on_selection_changed)
7878

7979
def load_plans(self):
8080
self.model.removeRows(0, self.model.rowCount())

arho_feature_template/gui/template_dock.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
if TYPE_CHECKING:
88
from qgis.gui import QgsFilterLineEdit
9-
from qgis.PyQt.QtWidgets import QComboBox, QLabel, QListView
9+
from qgis.PyQt.QtWidgets import QComboBox, QLabel, QTreeView
1010

1111
ui_path = resources.files(__package__) / "template_dock.ui"
1212
DockClass, _ = uic.loadUiType(ui_path)
@@ -15,7 +15,8 @@
1515
class TemplateLibraryDock(QgsDockWidget, DockClass): # type: ignore
1616
library_selection: "QComboBox"
1717
search_box: "QgsFilterLineEdit"
18-
template_list: "QListView"
18+
# template_list: "QListView"
19+
template_list: "QTreeView"
1920
txt_tip: "QLabel"
2021

2122
def __init__(self):

arho_feature_template/gui/template_dock.ui

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<widget class="QgsFilterLineEdit" name="search_box"/>
4141
</item>
4242
<item>
43-
<widget class="QListView" name="template_list"/>
43+
<widget class="QTreeView" name="template_list"/>
4444
</item>
4545
<item>
4646
<widget class="QLabel" name="txt_tip">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
version: 1
2+
meta:
3+
name: Asemakaavan kaavamääräykset
4+
version: "1.0"
5+
templates:
6+
- name: Simppeli kaavakohde
7+
group: Osa-alue
8+
sub_group: Alue
9+
description: Kaavakohde ilman kikkareita
10+
feature:
11+
layer: land_use_area
12+
attributes:
13+
- attribute: name
14+
- attribute: type_of_underground_id
15+
default: 1
16+
17+
- name: Asuin-, liike- ja toimistorakennusten alue
18+
group: Aluevaraus
19+
sub_group: Alue
20+
description: Alueella kuvataan ...
21+
feature:
22+
layer: land_use_area
23+
attributes:
24+
- attribute: name
25+
- attribute: type_of_underground_id
26+
default: 1
27+
child_features:
28+
- layer: plan_requlation_group
29+
attributes:
30+
- attribute: name
31+
default: Asuin-, liike- ja toimistorakennusten alue
32+
allow_user_input: false
33+
child_features:
34+
- layer: plan_requlation
35+
attributes:
36+
- attribute: type_of_plan_regulation_id
37+
default: asumisenAlue
38+
hidden: true
39+
child_features:
40+
- layer: additional_information_of_plan_regulation
41+
attributes:
42+
- attribute: type_of_additional_information_id
43+
default: paakayttotarkoitus
44+
hidden: true
45+
46+
- name: Ryhmätön simppeli kaavakohde
47+
description: Kaavakohde ilman kikkareita
48+
feature:
49+
layer: other_area
50+
attributes:
51+
- attribute: name
52+
- attribute: type_of_underground_id
53+
default: 1

arho_feature_template/resources/template_libraries/schema/template_library.schema.json

+8
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@
9090
"description": "The name of the template",
9191
"type": "string"
9292
},
93+
"group": {
94+
"description": "The group of the template",
95+
"type": "string"
96+
},
97+
"sub_group": {
98+
"description": "The geometry type of the template",
99+
"type": "string"
100+
},
93101
"description": {
94102
"description": "The description of the template",
95103
"type": "string"

0 commit comments

Comments
 (0)