Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

29 templatelistan muuttaminen puumaiseksi #49

Merged
merged 3 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 84 additions & 13 deletions arho_feature_template/core/feature_template_library.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import logging
from collections import defaultdict

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

# Set the selection mode to allow single selection
self.template_dock.template_list.setSelectionMode(self.template_dock.template_list.SingleSelection)

self._read_library_configs()

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

# Update template list when library selection changes
# Update template tree when library selection changes
self.template_dock.library_selection.currentIndexChanged.connect(
lambda: self.set_active_library(self.template_dock.library_selection.currentText())
)
# Update template list when search text changes

# Update template tree when search text changes
self.template_dock.search_box.valueChanged.connect(self.on_template_search_text_changed)

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

def on_template_item_clicked(self, index):
item = self.template_model.itemFromIndex(index)

# Do nothing if clicked item is a group
if item.hasChildren():
return

try:
layer = get_layer_from_project(item.config.feature.layer)
except (LayerNotFoundError, LayerNotVectorTypeError):
logger.exception("Failed to activate template")
return

self.active_template = item
self.start_digitizing_for_layer(layer)

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

def on_template_search_text_changed(self, search_text: str):
def on_template_search_text_changed(self, search_text: str) -> None:
search_text = search_text.lower()

for row in range(self.template_model.rowCount()):
item = self.template_model.item(row)
group_item = self.template_model.item(row)
group_visible = False

# If the search text is in the item's text, show the row
if search_text in item.text().lower():
self.template_dock.template_list.setRowHidden(row, False)
else:
# Otherwise, hide the row
self.template_dock.template_list.setRowHidden(row, True)
for child_row in range(group_item.rowCount()):
child_item = group_item.child(child_row)

if child_item.hasChildren():
subgroup_visible = False

for template_row in range(child_item.rowCount()):
template_item = child_item.child(template_row)
matches = search_text in template_item.text().lower()
template_item.setEnabled(matches)

if matches:
subgroup_visible = True

child_item.setEnabled(subgroup_visible)
group_visible = group_visible or subgroup_visible

index = self.template_model.indexFromItem(child_item)
self.template_dock.template_list.setExpanded(index, subgroup_visible)

else:
template_item = child_item
matches = search_text in template_item.text().lower()
template_item.setEnabled(matches)

if matches:
group_visible = True

group_item.setEnabled(group_visible)

index = self.template_model.indexFromItem(group_item)
self.template_dock.template_list.setExpanded(index, group_visible)

def start_digitizing_for_layer(self, layer: QgsVectorLayer) -> None:
self.digitize_map_tool.clean()
Expand Down Expand Up @@ -163,10 +203,41 @@ def get_library_names(self) -> list[str]:
def set_active_library(self, library_name: str) -> None:
self.template_model.clear()

grouped_templates: defaultdict[str, defaultdict[str, list[FeatureTemplate]]] = defaultdict(
lambda: defaultdict(list)
)

# Group templates by 'group' and 'sub_group'
for template in self.library_configs[library_name].templates:
item = TemplateItem(template)
item.setEditable(False)
self.template_model.appendRow(item)
group = getattr(template, "group", None) or "Ryhmittelemättömät"
sub_group = getattr(template, "sub_group", None)
if sub_group:
grouped_templates[group][sub_group].append(template)
else:
grouped_templates[group][""].append(template)

for group_name, sub_group_dict in grouped_templates.items():
group_item = QStandardItem(group_name)
group_item.setEditable(False)

for sub_group_name, templates in sub_group_dict.items():
if sub_group_name:
sub_group_item = QStandardItem(sub_group_name)
sub_group_item.setEditable(False)
group_item.appendRow(sub_group_item)
target_item = sub_group_item
else:
# If template has no sub_group set, list it directly under group
target_item = group_item

for template in templates:
template_item = TemplateItem(template)
template_item.setEditable(False)
target_item.appendRow(template_item)

self.template_model.appendRow(group_item)

self.template_dock.template_list.expandAll()

def _read_library_configs(self) -> None:
for config_file in library_config_files():
Expand Down
8 changes: 8 additions & 0 deletions arho_feature_template/core/template_library_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ class TemplateLibraryMeta:
"""Describes the metadata of a template library"""

name: str
group: str | None
sub_group: str | None
description: str | None
version: str | None

@classmethod
def from_dict(cls, data: dict) -> TemplateLibraryMeta:
return cls(
name=data["name"],
group=data.get("group"),
sub_group=data.get("sub_group"),
description=data.get("description"),
version=data.get("version"),
)
Expand All @@ -70,13 +74,17 @@ class FeatureTemplate:
"""Describes a feature template that can include nested features"""

name: str
group: str | None
sub_group: str | None
description: str | None
feature: Feature

@classmethod
def from_dict(cls, data: dict) -> FeatureTemplate:
return cls(
name=data["name"],
group=data.get("group"),
sub_group=data.get("sub_group"),
description=data.get("description"),
feature=Feature.from_dict(data["feature"]),
)
Expand Down
5 changes: 3 additions & 2 deletions arho_feature_template/gui/template_dock.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

if TYPE_CHECKING:
from qgis.gui import QgsFilterLineEdit
from qgis.PyQt.QtWidgets import QComboBox, QLabel, QListView
from qgis.PyQt.QtWidgets import QComboBox, QLabel, QTreeView

ui_path = resources.files(__package__) / "template_dock.ui"
DockClass, _ = uic.loadUiType(ui_path)
Expand All @@ -15,7 +15,8 @@
class TemplateLibraryDock(QgsDockWidget, DockClass): # type: ignore
library_selection: "QComboBox"
search_box: "QgsFilterLineEdit"
template_list: "QListView"
# template_list: "QListView"
template_list: "QTreeView"
txt_tip: "QLabel"

def __init__(self):
Expand Down
2 changes: 1 addition & 1 deletion arho_feature_template/gui/template_dock.ui
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<widget class="QgsFilterLineEdit" name="search_box"/>
</item>
<item>
<widget class="QListView" name="template_list"/>
<widget class="QTreeView" name="template_list"/>
</item>
<item>
<widget class="QLabel" name="txt_tip">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: 1
meta:
name: Asemakaavan kaavamääräykset
version: "1.0"
templates:
- name: Simppeli kaavakohde
group: Osa-alue
sub_group: Alue
description: Kaavakohde ilman kikkareita
feature:
layer: land_use_area
attributes:
- attribute: name
- attribute: type_of_underground_id
default: 1

- name: Asuin-, liike- ja toimistorakennusten alue
group: Aluevaraus
sub_group: Alue
description: Alueella kuvataan ...
feature:
layer: land_use_area
attributes:
- attribute: name
- attribute: type_of_underground_id
default: 1
child_features:
- layer: plan_requlation_group
attributes:
- attribute: name
default: Asuin-, liike- ja toimistorakennusten alue
allow_user_input: false
child_features:
- layer: plan_requlation
attributes:
- attribute: type_of_plan_regulation_id
default: asumisenAlue
hidden: true
child_features:
- layer: additional_information_of_plan_regulation
attributes:
- attribute: type_of_additional_information_id
default: paakayttotarkoitus
hidden: true

- name: Ryhmätön simppeli kaavakohde
description: Kaavakohde ilman kikkareita
feature:
layer: other_area
attributes:
- attribute: name
- attribute: type_of_underground_id
default: 1
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@
"description": "The name of the template",
"type": "string"
},
"group": {
"description": "The group of the template",
"type": "string"
},
"sub_group": {
"description": "The geometry type of the template",
"type": "string"
},
"description": {
"description": "The description of the template",
"type": "string"
Expand Down
Loading