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

Kaavamääräysten hallinta -paneeli #132

Merged
merged 3 commits into from
Jan 28, 2025
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
8 changes: 4 additions & 4 deletions arho_feature_template/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,10 @@ class Proposition:

@dataclass
class RegulationGroup:
type_code_id: str | None
name: str | None
short_name: str | None
color_code: str | None
type_code_id: str | None = None
name: str | None = None
short_name: str | None = None
color_code: str | None = None
group_number: int | None = None
regulations: list[Regulation] = field(default_factory=list)
propositions: list[Proposition] = field(default_factory=list)
Expand Down
93 changes: 83 additions & 10 deletions arho_feature_template/core/plan_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@
FeatureTemplateLibrary,
Plan,
PlanFeature,
RegulationGroup,
RegulationGroupCategory,
RegulationGroupLibrary,
)
from arho_feature_template.exceptions import UnsavedChangesError
from arho_feature_template.gui.dialogs.load_plan_dialog import LoadPlanDialog
from arho_feature_template.gui.dialogs.new_plan_regulation_group_form import NewPlanRegulationGroupForm
from arho_feature_template.gui.dialogs.plan_attribute_form import PlanAttributeForm
from arho_feature_template.gui.dialogs.plan_feature_form import PlanFeatureForm
from arho_feature_template.gui.dialogs.plan_regulation_group_form import PlanRegulationGroupForm
from arho_feature_template.gui.dialogs.serialize_plan import SerializePlan
from arho_feature_template.gui.docks.new_feature_dock import NewFeatureDock
from arho_feature_template.gui.docks.regulation_groups_dock import RegulationGroupsDock
from arho_feature_template.gui.tools.inspect_plan_features_tool import InspectPlanFeatures
from arho_feature_template.project.layers.code_layers import PlanRegulationGroupTypeLayer, code_layers
from arho_feature_template.project.layers.plan_layers import (
Expand Down Expand Up @@ -53,7 +55,7 @@
if TYPE_CHECKING:
from qgis.core import QgsFeature

from arho_feature_template.core.models import Proposition, Regulation, RegulationGroup
from arho_feature_template.core.models import Proposition, Regulation

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -87,6 +89,15 @@ def __init__(self):
self.new_feature_dock.tool_activated.connect(self.add_new_plan_feature)
self.new_feature_dock.hide()

# Initialize regulation groups dock
self.regulation_groups_dock = RegulationGroupsDock()
self.regulation_groups_dock.new_regulation_group_requested.connect(self.create_new_regulation_group)
self.regulation_groups_dock.edit_regulation_group_requested.connect(self.edit_regulation_group)
self.regulation_groups_dock.delete_regulation_group_requested.connect(self.delete_regulation_group)
if get_active_plan_id():
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())
self.regulation_groups_dock.hide()

# Initialize digitize tools
self.plan_digitize_map_tool = PlanDigitizeMapTool(iface.mapCanvas(), iface.cadDockWidget())
self.plan_digitize_map_tool.digitizingCompleted.connect(self._plan_geom_digitized)
Expand Down Expand Up @@ -135,6 +146,25 @@ def initialize_libraries(self):
]
self.new_feature_dock.initialize_feature_template_libraries(self.feature_template_libraries)

def create_new_regulation_group(self):
self._open_regulation_group_form(RegulationGroup())

def edit_regulation_group(self, regulation_group: RegulationGroup):
self._open_regulation_group_form(regulation_group)

def _open_regulation_group_form(self, regulation_group: RegulationGroup):
regulation_group_form = PlanRegulationGroupForm(regulation_group)
if regulation_group_form.exec_():
if regulation_group_form.save_as_config is True:
save_regulation_group_as_config(regulation_group_form.model)
else:
save_regulation_group(regulation_group_form.model)
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def delete_regulation_group(self, group: RegulationGroup):
delete_regulation_group(group)
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def toggle_identify_plan_features(self, activate: bool): # noqa: FBT001
if activate:
self.previous_map_tool = iface.mapCanvas().mapTool()
Expand Down Expand Up @@ -202,6 +232,7 @@ def edit_plan(self):
attribute_form = PlanAttributeForm(plan_model, self.regulation_group_libraries)
if attribute_form.exec_():
feature = save_plan(attribute_form.model)
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def add_new_plan_feature(self):
if not handle_unsaved_changes():
Expand Down Expand Up @@ -261,6 +292,7 @@ def _plan_feature_geom_digitized(self, feature: QgsFeature):
)
if attribute_form.exec_():
save_plan_feature(attribute_form.model)
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def edit_plan_feature(self, feature: QgsFeature, layer_name: str):
layer_class = FEATURE_LAYER_NAME_TO_CLASS_MAP[layer_name]
Expand All @@ -273,6 +305,7 @@ def edit_plan_feature(self, feature: QgsFeature, layer_name: str):
)
if attribute_form.exec_():
save_plan_feature(attribute_form.model)
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def set_active_plan(self, plan_id: str | None):
"""Update the project layers based on the selected land use plan.
Expand All @@ -297,6 +330,9 @@ def set_active_plan(self, plan_id: str | None):
if previously_in_edit_mode:
plan_layer.startEditing()

# Update regulation group dock
self.regulation_groups_dock.initialize_regulation_groups(regulation_group_library_from_active_plan())

def load_land_use_plan(self):
"""Load an existing land use plan using a dialog selection."""
connection_names = get_existing_database_connection_names()
Expand Down Expand Up @@ -364,14 +400,6 @@ def save_plan_jsons(self, plan_json, outline_json):
"Kaava ja sen ulkoraja tallennettu onnistuneesti.",
)

def create_new_regulation_group(self):
new_regulation_group_form = NewPlanRegulationGroupForm()
if new_regulation_group_form.exec_():
if new_regulation_group_form.save_as_config is True:
save_regulation_group_as_config(new_regulation_group_form.model)
else:
save_regulation_group(new_regulation_group_form.model)

def unload(self):
# Lambda service
self.lambda_service.jsons_received.disconnect(self.save_plan_jsons)
Expand All @@ -396,6 +424,13 @@ def unload(self):
iface.removeDockWidget(self.new_feature_dock)
self.new_feature_dock.deleteLater()

# Regulation group dock
self.regulation_groups_dock.new_regulation_group_requested.disconnect()
self.regulation_groups_dock.edit_regulation_group_requested.disconnect()
self.regulation_groups_dock.delete_regulation_group_requested.disconnect()
iface.removeDockWidget(self.regulation_groups_dock)
self.regulation_groups_dock.deleteLater()


def regulation_group_library_from_active_plan() -> RegulationGroupLibrary:
category_features = list(PlanRegulationGroupTypeLayer.get_features())
Expand Down Expand Up @@ -548,6 +583,30 @@ def save_regulation_group(regulation_group: RegulationGroup, plan_id: str | None
return feature


def delete_regulation_group(regulation_group: RegulationGroup, plan_id: str | None = None):
if regulation_group.id_ is None:
return

feature = RegulationGroupLayer.feature_from_model(regulation_group, plan_id)
layer = RegulationGroupLayer.get_from_project()

# # Handle regulations
# for regulation in regulation_group.regulations:
# delete_regulation(regulation)

# # Handle propositions
# for proposition in regulation_group.propositions:
# delete_proposition(proposition)

_delete_feature(feature, layer, "Kaavamääräysryhmän poisto")

# # Handle assocations
# associations = RegulationGroupAssociationLayer.get_associations_for_regulation_group(str(regulation_group.id_))
# association_layer = RegulationGroupAssociationLayer.get_from_project()
# for association in associations:
# _delete_feature(association, association_layer, "Kaavamääräysryhmän assosiaation poisto")


def save_regulation_group_as_config(regulation_group: RegulationGroup):
pass

Expand Down Expand Up @@ -575,6 +634,13 @@ def save_regulation(regulation: Regulation) -> QgsFeature:
return feature


def delete_regulation(regulation: Regulation):
feature = PlanRegulationLayer.feature_from_model(regulation)
layer = PlanRegulationLayer.get_from_project()

_delete_feature(feature, layer, "Kaavamääräyksen poisto")


def save_proposition(proposition: Proposition) -> QgsFeature:
feature = PlanPropositionLayer.feature_from_model(proposition)
layer = PlanPropositionLayer.get_from_project()
Expand All @@ -587,3 +653,10 @@ def save_proposition(proposition: Proposition) -> QgsFeature:
)

return feature


def delete_proposition(proposition: Proposition):
feature = PlanPropositionLayer.feature_from_model(proposition)
layer = PlanPropositionLayer.get_from_project()

_delete_feature(feature, layer, "Kaavasuosituksen poisto")
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from qgis.core import QgsApplication
from qgis.PyQt import uic
from qgis.PyQt.QtCore import pyqtSignal
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QWidget

from arho_feature_template.core.models import Proposition, Regulation, RegulationGroup
from arho_feature_template.gui.components.plan_proposition_widget import PropositionWidget
from arho_feature_template.gui.components.plan_regulation_widget import RegulationWidget
from arho_feature_template.project.layers.code_layers import PlanRegulationGroupTypeLayer
from arho_feature_template.qgis_plugin_tools.tools.resources import resources_path

if TYPE_CHECKING:
from qgis.PyQt.QtWidgets import QFormLayout, QFrame, QLabel, QLineEdit, QPushButton
Expand All @@ -23,9 +25,10 @@
class RegulationGroupWidget(QWidget, FormClass): # type: ignore
"""A widget representation of a plan regulation group."""

open_as_form_signal = pyqtSignal(QWidget)
delete_signal = pyqtSignal(QWidget)

def __init__(self, regulation_group_data: RegulationGroup, layer_name: str):
def __init__(self, regulation_group: RegulationGroup, layer_name: str):
super().__init__()
self.setupUi(self)

Expand All @@ -34,24 +37,36 @@ def __init__(self, regulation_group_data: RegulationGroup, layer_name: str):
self.name: QLineEdit
self.short_name: QLineEdit
self.short_name_label: QLabel
self.edit_btn: QPushButton
self.del_btn: QPushButton
self.regulation_group_details_layout: QFormLayout

# INIT
self.regulation_group_data = regulation_group_data
self.regulation_widgets: list[RegulationWidget] = [
self.add_regulation_widget(regulation) for regulation in self.regulation_group_data.regulations
]
self.proposition_widgets: list[PropositionWidget] = [
self.add_proposition_widget(proposition) for proposition in self.regulation_group_data.propositions
]

regulation_group_data.type_code_id = PlanRegulationGroupTypeLayer.get_id_by_feature_layer_name(layer_name)
self.name.setText(self.regulation_group_data.name if self.regulation_group_data.name else "")
self.short_name.setText(self.regulation_group_data.short_name if self.regulation_group_data.short_name else "")
self.regulation_widgets: list[RegulationWidget] = []
self.proposition_widgets: list[PropositionWidget] = []

regulation_group.type_code_id = PlanRegulationGroupTypeLayer.get_id_by_feature_layer_name(layer_name)
self.from_model(regulation_group)

self.edit_btn.setIcon(QIcon(resources_path("icons", "settings.svg")))
self.edit_btn.clicked.connect(lambda: self.open_as_form_signal.emit(self))
self.del_btn.setIcon(QgsApplication.getThemeIcon("mActionDeleteSelected.svg"))
self.del_btn.clicked.connect(lambda: self.delete_signal.emit(self))

def from_model(self, regulation_group: RegulationGroup):
self.regulation_group = regulation_group

self.name.setText(regulation_group.name if regulation_group.name else "")
self.short_name.setText(regulation_group.short_name if regulation_group.short_name else "")

# Remove existing child widgets if reinitializing
for widget in self.regulation_widgets:
self.delete_regulation_widget(widget)
for widget in self.proposition_widgets:
self.delete_proposition_widget(widget)
self.regulation_widgets = [self.add_regulation_widget(reg) for reg in regulation_group.regulations]
self.proposition_widgets = [self.add_proposition_widget(prop) for prop in regulation_group.propositions]

def add_regulation_widget(self, regulation: Regulation) -> RegulationWidget:
widget = RegulationWidget(regulation=regulation, parent=self.frame)
widget.delete_signal.connect(self.delete_regulation_widget)
Expand All @@ -76,11 +91,11 @@ def delete_proposition_widget(self, proposition_widget: RegulationWidget):

def into_model(self) -> RegulationGroup:
return RegulationGroup(
type_code_id=self.regulation_group_data.type_code_id,
type_code_id=self.regulation_group.type_code_id,
name=self.name.text(),
short_name=None if not self.short_name.text() else self.short_name.text(),
color_code=self.regulation_group_data.color_code,
color_code=self.regulation_group.color_code,
regulations=[widget.into_model() for widget in self.regulation_widgets],
propositions=[widget.into_model() for widget in self.proposition_widgets],
id_=self.regulation_group_data.id_,
id_=self.regulation_group.id_,
)
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,28 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="edit_btn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Muokkaa kaavamääräysryhmää</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="del_btn">
<property name="sizePolicy">
Expand All @@ -82,6 +104,9 @@
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Poista kaavamääräysryhmä</string>
</property>
<property name="text">
<string/>
</property>
Expand Down
10 changes: 10 additions & 0 deletions arho_feature_template/gui/dialogs/plan_attribute_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
from arho_feature_template.core.models import Plan, RegulationGroup, RegulationGroupLibrary
from arho_feature_template.gui.components.plan_regulation_group_widget import RegulationGroupWidget
from arho_feature_template.gui.components.tree_with_search_widget import TreeWithSearchWidget
from arho_feature_template.gui.dialogs.plan_regulation_group_form import PlanRegulationGroupForm
from arho_feature_template.project.layers.code_layers import (
LifeCycleStatusLayer,
OrganisationLayer,
PlanTypeLayer,
)
from arho_feature_template.utils.misc_utils import disconnect_signal

if TYPE_CHECKING:
from qgis.PyQt.QtWidgets import QComboBox, QLineEdit, QTextEdit, QVBoxLayout, QWidget
Expand Down Expand Up @@ -132,12 +134,20 @@ def add_selected_plan_regulation_group(self, item: QTreeWidgetItem, column: int)
def add_plan_regulation_group(self, regulation_group: RegulationGroup):
regulation_group_widget = RegulationGroupWidget(regulation_group, layer_name="Kaava")
regulation_group_widget.delete_signal.connect(self.remove_plan_regulation_group)
regulation_group_widget.open_as_form_signal.connect(self.open_plan_regulation_group_form)
self._remove_spacer()
self.plan_regulation_group_scrollarea_contents.layout().addWidget(regulation_group_widget)
self.regulation_group_widgets.append(regulation_group_widget)
self._add_spacer()

def open_plan_regulation_group_form(self, regulation_group_widget: RegulationGroupWidget):
group_as_form = PlanRegulationGroupForm(regulation_group_widget.into_model())
if group_as_form.exec_():
regulation_group_widget.from_model(group_as_form.model)

def remove_plan_regulation_group(self, regulation_group_widget: RegulationGroupWidget):
disconnect_signal(regulation_group_widget.delete_signal)
disconnect_signal(regulation_group_widget.open_as_form_signal)
self.plan_regulation_group_scrollarea_contents.layout().removeWidget(regulation_group_widget)
self.regulation_group_widgets.remove(regulation_group_widget)
regulation_group_widget.deleteLater()
Expand Down
10 changes: 10 additions & 0 deletions arho_feature_template/gui/dialogs/plan_feature_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
from arho_feature_template.core.models import PlanFeature, RegulationGroup
from arho_feature_template.gui.components.plan_regulation_group_widget import RegulationGroupWidget
from arho_feature_template.gui.components.tree_with_search_widget import TreeWithSearchWidget
from arho_feature_template.gui.dialogs.plan_regulation_group_form import PlanRegulationGroupForm
from arho_feature_template.project.layers.code_layers import UndergroundTypeLayer
from arho_feature_template.utils.misc_utils import disconnect_signal

if TYPE_CHECKING:
from qgis.PyQt.QtWidgets import QVBoxLayout, QWidget
Expand Down Expand Up @@ -105,12 +107,20 @@ def add_selected_plan_regulation_group(self, item: QTreeWidgetItem, column: int)
def add_plan_regulation_group(self, definition: RegulationGroup):
regulation_group_widget = RegulationGroupWidget(definition, cast(str, self.layer_name))
regulation_group_widget.delete_signal.connect(self.remove_plan_regulation_group)
regulation_group_widget.open_as_form_signal.connect(self.open_plan_regulation_group_form)
self._remove_spacer()
self.plan_regulation_group_scrollarea_contents.layout().addWidget(regulation_group_widget)
self.regulation_group_widgets.append(regulation_group_widget)
self._add_spacer()

def open_plan_regulation_group_form(self, regulation_group_widget: RegulationGroupWidget):
group_as_form = PlanRegulationGroupForm(regulation_group_widget.into_model())
if group_as_form.exec_():
regulation_group_widget.from_model(group_as_form.model)

def remove_plan_regulation_group(self, regulation_group_widget: RegulationGroupWidget):
disconnect_signal(regulation_group_widget.delete_signal)
disconnect_signal(regulation_group_widget.open_as_form_signal)
self.plan_regulation_group_scrollarea_contents.layout().removeWidget(regulation_group_widget)
self.regulation_group_widgets.remove(regulation_group_widget)
regulation_group_widget.deleteLater()
Expand Down
Loading
Loading