Skip to content

Commit f2c6db1

Browse files
Mtk112LKajan
authored andcommittedOct 29, 2024
Convert template listing into a tree view.
Change QListView to QTreeView. Added optional group attribute to templates.
1 parent d549451 commit f2c6db1

File tree

6 files changed

+116
-16
lines changed

6 files changed

+116
-16
lines changed
 

‎arho_feature_template/core/feature_template_library.py

+53-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,29 @@ 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
134+
135+
for child_row in range(group_item.rowCount()):
136+
template_item = group_item.child(child_row)
137+
matches = search_text in template_item.text().lower()
138+
template_item.setEnabled(matches)
139+
group_item.setChild(child_row, template_item)
120140

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)
141+
if matches:
142+
group_visible = True
143+
144+
# Show or hide the group based on child matches
145+
group_item.setEnabled(group_visible)
146+
147+
index = self.template_model.indexFromItem(group_item)
148+
self.template_dock.template_list.setExpanded(index, group_visible)
149+
150+
self.template_model.setItem(row, group_item)
127151

128152
def start_digitizing_for_layer(self, layer: QgsVectorLayer) -> None:
129153
self.digitize_map_tool.clean()
@@ -163,10 +187,26 @@ def get_library_names(self) -> list[str]:
163187
def set_active_library(self, library_name: str) -> None:
164188
self.template_model.clear()
165189

190+
# Group templates by their 'group' attribute, defaulting to "Ryhmittelemättömät" for ungrouped templates
191+
grouped_templates = defaultdict(list)
166192
for template in self.library_configs[library_name].templates:
167-
item = TemplateItem(template)
168-
item.setEditable(False)
169-
self.template_model.appendRow(item)
193+
group = getattr(template, "group", None)
194+
if not group:
195+
group = "Ryhmittelemättömät"
196+
grouped_templates[group].append(template)
197+
198+
for group_name, templates in grouped_templates.items():
199+
group_item = QStandardItem(group_name)
200+
group_item.setEditable(False)
201+
202+
for template in templates:
203+
template_item = TemplateItem(template)
204+
template_item.setEditable(False)
205+
group_item.appendRow(template_item)
206+
207+
self.template_model.appendRow(group_item)
208+
209+
self.template_dock.template_list.expandAll()
170210

171211
def _read_library_configs(self) -> None:
172212
for config_file in library_config_files():

‎arho_feature_template/core/template_library_config.py

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

5555
name: str
56+
group: str | None
5657
description: str | None
5758
version: str | None
5859

5960
@classmethod
6061
def from_dict(cls, data: dict) -> TemplateLibraryMeta:
6162
return cls(
6263
name=data["name"],
64+
group=data.get("group"),
6365
description=data.get("description"),
6466
version=data.get("version"),
6567
)
@@ -70,13 +72,15 @@ class FeatureTemplate:
7072
"""Describes a feature template that can include nested features"""
7173

7274
name: str
75+
group: str | None
7376
description: str | None
7477
feature: Feature
7578

7679
@classmethod
7780
def from_dict(cls, data: dict) -> FeatureTemplate:
7881
return cls(
7982
name=data["name"],
83+
group=data.get("group"),
8084
description=data.get("description"),
8185
feature=Feature.from_dict(data["feature"]),
8286
)

‎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,51 @@
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+
description: Kaavakohde ilman kikkareita
9+
feature:
10+
layer: land_use_area
11+
attributes:
12+
- attribute: name
13+
- attribute: type_of_underground_id
14+
default: 1
15+
16+
- name: Asuin-, liike- ja toimistorakennusten alue
17+
group: Aluevaraus
18+
description: Alueella kuvataan ...
19+
feature:
20+
layer: land_use_area
21+
attributes:
22+
- attribute: name
23+
- attribute: type_of_underground_id
24+
default: 1
25+
child_features:
26+
- layer: plan_requlation_group
27+
attributes:
28+
- attribute: name
29+
default: Asuin-, liike- ja toimistorakennusten alue
30+
allow_user_input: false
31+
child_features:
32+
- layer: plan_requlation
33+
attributes:
34+
- attribute: type_of_plan_regulation_id
35+
default: asumisenAlue
36+
hidden: true
37+
child_features:
38+
- layer: additional_information_of_plan_regulation
39+
attributes:
40+
- attribute: type_of_additional_information_id
41+
default: paakayttotarkoitus
42+
hidden: true
43+
44+
- name: Ryhmätön simppeli kaavakohde
45+
description: Kaavakohde ilman kikkareita
46+
feature:
47+
layer: other_area
48+
attributes:
49+
- attribute: name
50+
- attribute: type_of_underground_id
51+
default: 1

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

+4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
"description": "The name of the template",
9191
"type": "string"
9292
},
93+
"group": {
94+
"description": "The group of the template",
95+
"type": "string"
96+
},
9397
"description": {
9498
"description": "The description of the template",
9599
"type": "string"

0 commit comments

Comments
 (0)
Please sign in to comment.