From 530ed0c029379f3d958c8c2fb54bbe519e007281 Mon Sep 17 00:00:00 2001 From: Niko Aarnio <niko.aarnio@protonmail.com> Date: Wed, 27 Nov 2024 13:47:16 +0200 Subject: [PATCH 1/2] redesign plan regulation widget buttons, add expand/hide button --- .../gui/plan_regulation_widget.py | 87 +++++--- .../gui/plan_regulation_widget.ui | 201 ++++++++++-------- 2 files changed, 181 insertions(+), 107 deletions(-) diff --git a/arho_feature_template/gui/plan_regulation_widget.py b/arho_feature_template/gui/plan_regulation_widget.py index 6f0fdbd..2eb19c8 100644 --- a/arho_feature_template/gui/plan_regulation_widget.py +++ b/arho_feature_template/gui/plan_regulation_widget.py @@ -1,6 +1,5 @@ from __future__ import annotations -from collections import defaultdict from importlib import resources from typing import TYPE_CHECKING, cast @@ -16,6 +15,7 @@ QMenu, QSizePolicy, QTextEdit, + QToolButton, QWidget, ) @@ -23,8 +23,6 @@ from arho_feature_template.utils.misc_utils import get_additional_information_name if TYPE_CHECKING: - from numbers import Number - from qgis.PyQt.QtWidgets import QPushButton from arho_feature_template.core.plan_regulation_group_config import PlanRegulationDefinition @@ -56,21 +54,23 @@ def __init__(self, config: PlanRegulationConfig, parent=None): self.setupUi(self) # TYPES + # self.spacer_layout: QBoxLayout self.plan_regulation_name: QLineEdit self.form_layout: QFormLayout self.add_additional_information_btn: QPushButton - self.add_regulation_number_btn: QPushButton - self.add_file_btn: QPushButton + self.add_field_btn: QPushButton self.del_btn: QPushButton + self.expand_hide_btn: QToolButton + + self.code_label: QLabel + self.code: QLineEdit # INIT self.config = config self.regulation_number_added = False - # Key is related field name, value is 1) widget, 2) tuple of widget and default value - # NOTE: Maybe this is not something needed? Instead, when user clicks Ok, write into a YAML - # in a separate script? - self.attribute_widgets: dict[str, QWidget | tuple[QWidget, str | Number]] = defaultdict(dict) + self.expanded = True + self.widgets: list[tuple] = [] self.plan_regulation_name.setText(config.name) self.plan_regulation_name.setReadOnly(True) self.init_value_fields() @@ -157,31 +157,58 @@ def init_buttons(self): type_main_menu.addMenu(type_menu) type_main_menu.addMenu(signifigance_menu) self.add_additional_information_btn.setMenu(type_main_menu) - - # REGULATION NUMBER - self.add_regulation_number_btn.clicked.connect(self.add_regulation_number) - - # ADD FILE - self.add_file_btn.clicked.connect(self.add_file) + self.add_additional_information_btn.setIcon(QgsApplication.getThemeIcon("mActionPropertiesWidget.svg")) + + # OTHER INFO / ADD FIELD + add_field_menu = QMenu(self) + add_field_menu.addAction("Määräysnumero").triggered.connect(self.add_regulation_number) + add_field_menu.addAction("Liiteasiakirja").triggered.connect(self.add_file) + self.add_field_btn.setMenu(add_field_menu) + self.add_field_btn.setIcon(QgsApplication.getThemeIcon("mActionAdd.svg")) + + # EXPAND BTN + self.expand_hide_btn.clicked.connect(self._on_expand_hide_btn_clicked) + + def _on_expand_hide_btn_clicked(self): + if self.expanded: + for label, widget in self.widgets: + self.form_layout.removeWidget(label) + label.hide() + self.form_layout.removeWidget(widget) + widget.hide() + self.expand_hide_btn.setArrowType(Qt.ArrowType.DownArrow) + self.expanded = False + else: + for label, widget in self.widgets: + label.show() + widget.show() + self.form_layout.addRow(label, widget) + self.expand_hide_btn.setArrowType(Qt.ArrowType.UpArrow) + self.expanded = True def add_decimal_input(self, layout: QHBoxLayout, value_type: ValueType): value_widget = QgsDoubleSpinBox() - label_text = "Desimaali" + label = QLabel("Arvo") if value_type == ValueType.POSITIVE_DECIMAL: value_widget.setMinimum(0.0) - label_text += " (positiivinen)" + label.setToolTip("Tyyppi: desimaali (positiivinen)") else: value_widget.setMinimum(-9999.9) + label.setToolTip("Tyyppi: desimaali") value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layout.addWidget(value_widget) - self.form_layout.addRow(label_text, layout) + self.form_layout.addRow(label, layout) + self.widgets.append((label, value_widget)) def add_positive_integer_input(self, layout: QHBoxLayout): value_widget = QgsSpinBox() value_widget.setMinimum(0) value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layout.addWidget(value_widget) - self.form_layout.addRow("Kokonaisluku (positiivinen)", layout) + label = QLabel("Arvo") + label.setToolTip("Tyyppi: kokonaisluku (positiivinen)") + self.form_layout.addRow(label, layout) + self.widgets.append((label, value_widget)) def add_positive_integer_range_input(self, layout: QHBoxLayout): min_widget = QgsSpinBox() @@ -194,12 +221,18 @@ def add_positive_integer_range_input(self, layout: QHBoxLayout): dash_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) layout.addWidget(dash_label) layout.addWidget(max_widget) - self.form_layout.addRow("Kokonaisluku arvoväli (positiivinen)", layout) + label = QLabel("Arvo") + label.setToolTip("Tyyppi: kokonaisluku arvoväli (positiivinen)") + self.form_layout.addRow(label, layout) + self.widgets.append((label, layout)) def add_versioned_text_input(self, layout: QHBoxLayout): text_widget = QTextEdit() layout.addWidget(text_widget) - self.form_layout.addRow("Kieliversioitu teksti", layout) + label = QLabel("Arvo") + label.setToolTip("Tyyppi: kieliversioitu teksti") + self.form_layout.addRow(label, layout) + self.widgets.append((label, text_widget)) def add_additional_info(self, info_type: str) -> QHBoxLayout: layout = QHBoxLayout() @@ -207,15 +240,21 @@ def add_additional_info(self, info_type: str) -> QHBoxLayout: info_type_label = QLineEdit(info_name) info_type_label.setReadOnly(True) layout.addWidget(info_type_label) - self.form_layout.addRow("Lisätiedonlaji", layout) + label = QLabel("Lisätiedonlaji") + self.form_layout.addRow(label, layout) + self.widgets.append((label, info_type_label)) return layout def add_regulation_number(self): if not self.regulation_number_added: number_widget = QgsSpinBox() - self.form_layout.addRow("Määräysnumero", number_widget) + label = QLabel("Määräysnumero") + self.form_layout.addRow(label, number_widget) + self.widgets.append((label, number_widget)) self.regulation_number_added = True def add_file(self): file_input = QgsFileWidget() - self.form_layout.addRow("Liiteasiakirja", file_input) + label = QLabel("Liiteasiakirja") + self.form_layout.addRow(label, file_input) + self.widgets.append((label, file_input)) diff --git a/arho_feature_template/gui/plan_regulation_widget.ui b/arho_feature_template/gui/plan_regulation_widget.ui index e6f5225..e767ec4 100644 --- a/arho_feature_template/gui/plan_regulation_widget.ui +++ b/arho_feature_template/gui/plan_regulation_widget.ui @@ -7,131 +7,166 @@ <x>0</x> <y>0</y> <width>694</width> - <height>108</height> + <height>131</height> </rect> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="windowTitle"> <string>Form</string> </property> + <property name="styleSheet"> + <string notr="true"/> + </property> <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QFormLayout" name="form_layout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Kaavamääräyslaji</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLineEdit" name="plan_regulation_name"/> - </item> - <item> - <widget class="QPushButton" name="del_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="text"> - <string/> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> - <widget class="QPushButton" name="add_additional_information_btn"> - <property name="text"> - <string>Lisätieto</string> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </widget> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> </item> <item> - <widget class="QPushButton" name="add_regulation_number_btn"> + <widget class="QPushButton" name="add_additional_information_btn"> <property name="text"> - <string>Määräysnumero</string> + <string>Lisätieto</string> </property> </widget> </item> <item> - <widget class="QPushButton" name="add_file_btn"> + <widget class="QPushButton" name="add_field_btn"> <property name="text"> - <string>Liiteasiakirja</string> + <string>Muu tieto</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <widget class="QPushButton" name="del_btn"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - <property name="sizeHint" stdset="0"> + <property name="maximumSize"> <size> - <width>40</width> - <height>20</height> + <width>16777215</width> + <height>16777215</height> </size> </property> - </spacer> + <property name="text"> + <string>Poista</string> + </property> + </widget> </item> </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> + <layout class="QFormLayout" name="form_layout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Kaavamääräyslaji</string> </property> - </spacer> + </widget> </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="plan_regulation_name"/> + </item> + <item> + <widget class="QToolButton" name="expand_hide_btn"> + <property name="text"> + <string>Laajenna</string> + </property> + <property name="autoRaise"> + <bool>false</bool> + </property> + <property name="arrowType"> + <enum>Qt::UpArrow</enum> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="spacer_layout"> <item> - <widget class="Line" name="line"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>20</height> - </size> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="Line" name="line"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> </item> <item> - <spacer name="horizontalSpacer_5"> + <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> - <height>20</height> + <width>20</width> + <height>15</height> </size> </property> </spacer> From e8359a0b5d5be34a94f3d8604f4656825ab895af Mon Sep 17 00:00:00 2001 From: Niko Aarnio <niko.aarnio@protonmail.com> Date: Wed, 27 Nov 2024 15:27:23 +0200 Subject: [PATCH 2/2] fix expand button by not nesting layouts inside form layout of plan regulation, add topic tag (name) and theme --- .../gui/plan_regulation_widget.py | 138 +++++++++--------- 1 file changed, 73 insertions(+), 65 deletions(-) diff --git a/arho_feature_template/gui/plan_regulation_widget.py b/arho_feature_template/gui/plan_regulation_widget.py index 2eb19c8..fcdbbb4 100644 --- a/arho_feature_template/gui/plan_regulation_widget.py +++ b/arho_feature_template/gui/plan_regulation_widget.py @@ -9,7 +9,6 @@ from qgis.PyQt.QtCore import Qt, pyqtSignal from qgis.PyQt.QtWidgets import ( QFormLayout, - QHBoxLayout, QLabel, QLineEdit, QMenu, @@ -20,7 +19,7 @@ ) from arho_feature_template.core.plan_regulation_config import PlanRegulationConfig, Unit, ValueType -from arho_feature_template.utils.misc_utils import get_additional_information_name +from arho_feature_template.utils.misc_utils import get_additional_information_name, get_layer_by_name if TYPE_CHECKING: from qgis.PyQt.QtWidgets import QPushButton @@ -70,7 +69,7 @@ def __init__(self, config: PlanRegulationConfig, parent=None): self.config = config self.regulation_number_added = False self.expanded = True - self.widgets: list[tuple] = [] + self.widgets: list[tuple[QLabel, QWidget]] = [] self.plan_regulation_name.setText(config.name) self.plan_regulation_name.setReadOnly(True) self.init_value_fields() @@ -80,44 +79,35 @@ def populate_from_definition(self, definition: PlanRegulationDefinition): # Additional information for info in definition.additional_information: info_type: str = cast("str", info["type"]) - layout = self.add_additional_info(info_type) - if info_type in ADDITIONAL_INFORMATION_TYPES_WITH_INPUT: + self.add_additional_info(info_type) + if info_type == "kayttotarkoituskohdistus": info_value_widget = QLineEdit() - layout.addWidget(info_value_widget) + label = QLabel(get_additional_information_name(info_type)) value = info.get("value") if value: info_value_widget.setText(value) + self.form_layout.addRow(label, info_value_widget) # TODO: Other saved information from PlanRegulationDefinition def init_value_fields(self): - layout = QHBoxLayout() value_type = self.config.value_type if value_type: - self._add_value_input(value_type, layout) + self._add_value_input(value_type, self.config.unit) - unit = self.config.unit - if unit: - self._add_value_unit(unit, layout) - - def _add_value_input(self, value_type: ValueType, layout: QHBoxLayout): + def _add_value_input(self, value_type: ValueType, unit: Unit | None): if value_type in [ValueType.DECIMAL, ValueType.POSITIVE_DECIMAL]: - self.add_decimal_input(layout, value_type) + self.add_decimal_input(value_type, unit) elif value_type == ValueType.POSITIVE_INTEGER: - self.add_positive_integer_input(layout) + self.add_positive_integer_input(unit) elif value_type == ValueType.POSITIVE_INTEGER_RANGE: - self.add_positive_integer_range_input(layout) + self.add_positive_integer_range_input(unit) elif value_type == ValueType.VERSIONED_TEXT: - self.add_versioned_text_input(layout) + self.add_versioned_text_input() else: msg = f"Invalid input value type for plan regulation: {value_type}" raise ValueError(msg) - def _add_value_unit(self, unit: Unit, layout: QHBoxLayout): - # NOTE: Unit could also be suffix in the QgsSpinBox, could be clearer? - unit_label = QLabel(unit.value) - layout.addWidget(unit_label) - def init_buttons(self): # DEL self.del_btn.setIcon(QgsApplication.getThemeIcon("mActionDeleteSelected.svg")) @@ -163,6 +153,16 @@ def init_buttons(self): add_field_menu = QMenu(self) add_field_menu.addAction("Määräysnumero").triggered.connect(self.add_regulation_number) add_field_menu.addAction("Liiteasiakirja").triggered.connect(self.add_file) + add_field_menu.addAction("Aihetunniste").triggered.connect(self.add_topic_tag) + + theme_menu = QMenu("Kaavoitusteema", self) + language = "fin" + for feature in get_layer_by_name("Kaavoitusteemat").getFeatures(): + name = feature["name"][language] + action = theme_menu.addAction(name) + action.triggered.connect(lambda _, name=name: self.add_theme(name)) + add_field_menu.addMenu(theme_menu) + self.add_field_btn.setMenu(add_field_menu) self.add_field_btn.setIcon(QgsApplication.getThemeIcon("mActionAdd.svg")) @@ -171,22 +171,28 @@ def init_buttons(self): def _on_expand_hide_btn_clicked(self): if self.expanded: - for label, widget in self.widgets: + for label, value_widget in self.widgets: self.form_layout.removeWidget(label) label.hide() - self.form_layout.removeWidget(widget) - widget.hide() + self.form_layout.removeWidget(value_widget) + value_widget.hide() self.expand_hide_btn.setArrowType(Qt.ArrowType.DownArrow) self.expanded = False else: - for label, widget in self.widgets: + for label, value_widget in self.widgets: + self.form_layout.addRow(label, value_widget) label.show() - widget.show() - self.form_layout.addRow(label, widget) + value_widget.show() self.expand_hide_btn.setArrowType(Qt.ArrowType.UpArrow) self.expanded = True - def add_decimal_input(self, layout: QHBoxLayout, value_type: ValueType): + def _add_widgets_to_form(self, label: QLabel, widget: QWidget): + self.form_layout.addRow(label, widget) + self.widgets.append((label, widget)) + if not self.expanded: + self._on_expand_hide_btn_clicked() + + def add_decimal_input(self, value_type: ValueType, unit: Unit | None): value_widget = QgsDoubleSpinBox() label = QLabel("Arvo") if value_type == ValueType.POSITIVE_DECIMAL: @@ -196,65 +202,67 @@ def add_decimal_input(self, layout: QHBoxLayout, value_type: ValueType): value_widget.setMinimum(-9999.9) label.setToolTip("Tyyppi: desimaali") value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) - layout.addWidget(value_widget) - self.form_layout.addRow(label, layout) - self.widgets.append((label, value_widget)) + if unit: + value_widget.setSuffix(f" {unit.value}") + self._add_widgets_to_form(label, value_widget) - def add_positive_integer_input(self, layout: QHBoxLayout): + def add_positive_integer_input(self, unit: Unit | None): value_widget = QgsSpinBox() value_widget.setMinimum(0) value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) - layout.addWidget(value_widget) + if unit: + value_widget.setSuffix(f" {unit.value}") label = QLabel("Arvo") label.setToolTip("Tyyppi: kokonaisluku (positiivinen)") - self.form_layout.addRow(label, layout) - self.widgets.append((label, value_widget)) + self._add_widgets_to_form(label, value_widget) - def add_positive_integer_range_input(self, layout: QHBoxLayout): + def add_positive_integer_range_input(self, unit: Unit | None): min_widget = QgsSpinBox() min_widget.setMinimum(0) + min_label = QLabel("Arvo minimi") + min_label.setToolTip("Tyyppi: kokonaisluku arvoväli (positiivinen)") + max_widget = QgsSpinBox() max_widget.setMinimum(0) - layout.addWidget(min_widget) - dash_label = QLabel(" — ") - dash_label.setAlignment(Qt.AlignCenter) - dash_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) - layout.addWidget(dash_label) - layout.addWidget(max_widget) - label = QLabel("Arvo") - label.setToolTip("Tyyppi: kokonaisluku arvoväli (positiivinen)") - self.form_layout.addRow(label, layout) - self.widgets.append((label, layout)) + max_label = QLabel("Arvo maksimi") + max_label.setToolTip("Tyyppi: kokonaisluku arvoväli (positiivinen)") + if unit: + min_widget.setSuffix(f" {unit.value}") + max_widget.setSuffix(f" {unit.value}") + self._add_widgets_to_form(min_label, min_widget) + self._add_widgets_to_form(max_label, max_widget) - def add_versioned_text_input(self, layout: QHBoxLayout): + def add_versioned_text_input(self): text_widget = QTextEdit() - layout.addWidget(text_widget) label = QLabel("Arvo") label.setToolTip("Tyyppi: kieliversioitu teksti") - self.form_layout.addRow(label, layout) - self.widgets.append((label, text_widget)) - - def add_additional_info(self, info_type: str) -> QHBoxLayout: - layout = QHBoxLayout() - info_name = get_additional_information_name(info_type) - info_type_label = QLineEdit(info_name) - info_type_label.setReadOnly(True) - layout.addWidget(info_type_label) + self._add_widgets_to_form(label, text_widget) + + def add_additional_info(self, info_type: str): + info_type_line = QLineEdit(get_additional_information_name(info_type)) + info_type_line.setReadOnly(True) label = QLabel("Lisätiedonlaji") - self.form_layout.addRow(label, layout) - self.widgets.append((label, info_type_label)) - return layout + self._add_widgets_to_form(label, info_type_line) def add_regulation_number(self): if not self.regulation_number_added: number_widget = QgsSpinBox() label = QLabel("Määräysnumero") - self.form_layout.addRow(label, number_widget) - self.widgets.append((label, number_widget)) + self._add_widgets_to_form(label, number_widget) self.regulation_number_added = True def add_file(self): file_input = QgsFileWidget() label = QLabel("Liiteasiakirja") - self.form_layout.addRow(label, file_input) - self.widgets.append((label, file_input)) + self._add_widgets_to_form(label, file_input) + + def add_topic_tag(self): + text_input = QLineEdit() + label = QLabel("Aihetunniste") + self._add_widgets_to_form(label, text_input) + + def add_theme(self, theme_name: str): + theme_type_line = QLineEdit(theme_name) + theme_type_line.setReadOnly(True) + label = QLabel("Kaavoitusteema") + self._add_widgets_to_form(label, theme_type_line)