1
1
from __future__ import annotations
2
2
3
3
import logging
4
+ from collections import defaultdict
4
5
5
6
from qgis .core import QgsFeature , QgsProject , QgsVectorLayer
6
7
from qgis .gui import QgsMapToolDigitizeFeature
@@ -81,15 +82,19 @@ def __init__(self) -> None:
81
82
self .template_model = QStandardItemModel ()
82
83
self .template_dock .template_list .setModel (self .template_model )
83
84
85
+ # Set the selection mode to allow single selection
86
+ self .template_dock .template_list .setSelectionMode (self .template_dock .template_list .SingleSelection )
87
+
84
88
self ._read_library_configs ()
85
89
86
90
self .template_dock .library_selection .addItems (self .get_library_names ())
87
91
88
- # Update template list when library selection changes
92
+ # Update template tree when library selection changes
89
93
self .template_dock .library_selection .currentIndexChanged .connect (
90
94
lambda : self .set_active_library (self .template_dock .library_selection .currentText ())
91
95
)
92
- # Update template list when search text changes
96
+
97
+ # Update template tree when search text changes
93
98
self .template_dock .search_box .valueChanged .connect (self .on_template_search_text_changed )
94
99
95
100
# Activate map tool when template is selected
@@ -101,11 +106,17 @@ def __init__(self) -> None:
101
106
102
107
def on_template_item_clicked (self , index ):
103
108
item = self .template_model .itemFromIndex (index )
109
+
110
+ # Do nothing if clicked item is a group
111
+ if item .hasChildren ():
112
+ return
113
+
104
114
try :
105
115
layer = get_layer_from_project (item .config .feature .layer )
106
116
except (LayerNotFoundError , LayerNotVectorTypeError ):
107
117
logger .exception ("Failed to activate template" )
108
118
return
119
+
109
120
self .active_template = item
110
121
self .start_digitizing_for_layer (layer )
111
122
@@ -114,16 +125,45 @@ def on_template_item_clicked(self, index):
114
125
index , QItemSelectionModel .Select | QItemSelectionModel .Rows
115
126
)
116
127
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
+
118
131
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
120
134
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 )
127
167
128
168
def start_digitizing_for_layer (self , layer : QgsVectorLayer ) -> None :
129
169
self .digitize_map_tool .clean ()
@@ -163,10 +203,41 @@ def get_library_names(self) -> list[str]:
163
203
def set_active_library (self , library_name : str ) -> None :
164
204
self .template_model .clear ()
165
205
206
+ grouped_templates : defaultdict [str , defaultdict [str , list [FeatureTemplate ]]] = defaultdict (
207
+ lambda : defaultdict (list )
208
+ )
209
+
210
+ # Group templates by 'group' and 'sub_group'
166
211
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 ()
170
241
171
242
def _read_library_configs (self ) -> None :
172
243
for config_file in library_config_files ():
0 commit comments