Skip to content

Commit

Permalink
Implement parameter_type in Database editor
Browse files Browse the repository at this point in the history
Parameter definition table now has a 'valid types' column that
contains parameter type information.

Re #2791
  • Loading branch information
soininen committed Jul 29, 2024
1 parent ee3bc45 commit 4e2cd30
Show file tree
Hide file tree
Showing 16 changed files with 554 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
- Entity group column in *Add entities* dialog. If filled, the created entity will be added to the specified group.
If the group doesn't yet exist, it will be created.
- Native kernel (i.e. python3 for Python) can now be used in the Detached Console or in Tool execution.
- It is now possible to specify valid value types for parameters in the Parameter definition table in Database editor.
- [Bundled App] **Embedded Python** now includes pip.
- Graph view in database editor now also supports filtering by alternative and scenario tree selections.
- Option to disable auto-build in entity graph.
Expand Down
10 changes: 5 additions & 5 deletions spinetoolbox/spine_db_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(self, db_mngr, db_map, **kwargs):
"""
Args:
db_mngr (SpineDBManager): SpineDBManager instance
db_map (DiffDatabaseMapping): DiffDatabaseMapping instance
db_map (DatabaseMapping): DatabaseMapping instance
"""
super().__init__(**kwargs)
self.db_mngr = db_mngr
Expand All @@ -96,7 +96,7 @@ def __init__(self, db_mngr, db_map, item_type, data, check=True, **kwargs):
"""
Args:
db_mngr (SpineDBManager): SpineDBManager instance
db_map (DiffDatabaseMapping): DiffDatabaseMapping instance
db_map (DatabaseMapping): DatabaseMapping instance
data (list): list of dict-items to add
item_type (str): the item type
"""
Expand Down Expand Up @@ -130,7 +130,7 @@ def __init__(self, db_mngr, db_map, item_type, data, check=True, **kwargs):
"""
Args:
db_mngr (SpineDBManager): SpineDBManager instance
db_map (DiffDatabaseMapping): DiffDatabaseMapping instance
db_map (DatabaseMapping): DatabaseMapping instance
item_type (str): the item type
data (list): list of dict-items to update
"""
Expand Down Expand Up @@ -166,7 +166,7 @@ def __init__(self, db_mngr, db_map, item_type, data, check=True, **kwargs):
"""
Args:
db_mngr (SpineDBManager): SpineDBManager instance
db_map (DiffDatabaseMapping): DiffDatabaseMapping instance
db_map (DatabaseMapping): DatabaseMapping instance
item_type (str): the item type
data (list): list of dict-items to add-update
"""
Expand Down Expand Up @@ -215,7 +215,7 @@ def __init__(self, db_mngr, db_map, item_type, ids, check=True, **kwargs):
"""
Args:
db_mngr (SpineDBManager): SpineDBManager instance
db_map (DiffDatabaseMapping): DiffDatabaseMapping instance
db_map (DatabaseMapping): DatabaseMapping instance
item_type (str): the item type
ids (set): set of ids to remove
"""
Expand Down
7 changes: 6 additions & 1 deletion spinetoolbox/spine_db_editor/mvcmodels/compound_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ def _make_header(self):
return [
"entity_class_name",
"parameter_name",
"valid types",
"value_list_name",
"default_value",
"description",
Expand All @@ -560,7 +561,11 @@ def _make_header(self):

@property
def field_map(self):
return {"parameter_name": "name", "value_list_name": "parameter_value_list_name"}
return {
"parameter_name": "name",
"valid types": "parameter_type_list",
"value_list_name": "parameter_value_list_name",
}

@property
def _single_model_type(self):
Expand Down
13 changes: 8 additions & 5 deletions spinetoolbox/spine_db_editor/mvcmodels/single_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
######################################################################################################################

"""Single models for parameter definitions and values (as 'for a single entity')."""
from typing import Iterable
from PySide6.QtCore import Qt
from spinetoolbox.helpers import DB_ITEM_SEPARATOR, order_key, plain_to_rich
from ...mvcmodels.minimal_table_model import MinimalTableModel
Expand Down Expand Up @@ -44,6 +45,8 @@ def _sort_key(self, element):
class SingleModelBase(HalfSortedTableModel):
"""Base class for all single models that go in a CompoundModelBase subclass."""

group_fields: Iterable[str] = ()

def __init__(self, parent, db_map, entity_class_id, committed, lazy=False):
"""
Args:
Expand Down Expand Up @@ -112,10 +115,6 @@ def dimension_id_list(self):
def fixed_fields(self):
return ["entity_class_name", "database"]

@property
def group_fields(self):
return ["entity_byname"]

@property
def can_be_filtered(self):
return True
Expand Down Expand Up @@ -231,7 +230,7 @@ def batch_set_data(self, indexes, data):

def split_value(value, column):
if self.header[column] in self.group_fields:
return tuple(value.split(DB_ITEM_SEPARATOR))
return tuple(value.split(DB_ITEM_SEPARATOR)) if value else ()
return value

if not indexes or not data:
Expand Down Expand Up @@ -342,6 +341,8 @@ def data(self, index, role=Qt.ItemDataRole.DisplayRole):


class EntityMixin:
group_fields = ("entity_byname",)

def update_items_in_db(self, items):
"""Overriden to create entities on the fly first."""
for item in items:
Expand All @@ -367,6 +368,8 @@ def _do_update_items_in_db(self, db_map_data):
class SingleParameterDefinitionModel(SplitValueAndTypeMixin, ParameterMixin, SingleModelBase):
"""A parameter_definition model for a single entity_class."""

group_fields = ("valid types",)

@property
def item_type(self):
return "parameter_definition"
Expand Down
174 changes: 174 additions & 0 deletions spinetoolbox/spine_db_editor/ui/parameter_type_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# -*- coding: utf-8 -*-
######################################################################################################################
# Copyright (C) 2017-2022 Spine project consortium
# Copyright Spine Toolbox contributors
# This file is part of Spine Toolbox.
# Spine Toolbox is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
# any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details. You should have received a copy of the GNU Lesser General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################################################################

################################################################################
## Form generated from reading UI file 'parameter_type_editor.ui'
##
## Created by: Qt User Interface Compiler version 6.6.3
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QGridLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QSizePolicy,
QSpacerItem, QVBoxLayout, QWidget)

class Ui_Form(object):
def setupUi(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
Form.resize(278, 178)
self.verticalLayout = QVBoxLayout(Form)
self.verticalLayout.setObjectName(u"verticalLayout")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.select_all_button = QPushButton(Form)
self.select_all_button.setObjectName(u"select_all_button")

self.horizontalLayout.addWidget(self.select_all_button)

self.clear_all_button = QPushButton(Form)
self.clear_all_button.setObjectName(u"clear_all_button")

self.horizontalLayout.addWidget(self.clear_all_button)

self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)

self.horizontalLayout.addItem(self.horizontalSpacer)


self.verticalLayout.addLayout(self.horizontalLayout)

self.label_2 = QLabel(Form)
self.label_2.setObjectName(u"label_2")

self.verticalLayout.addWidget(self.label_2)

self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
self.duration_check_box = QCheckBox(Form)
self.duration_check_box.setObjectName(u"duration_check_box")

self.gridLayout.addWidget(self.duration_check_box, 1, 1, 1, 1)

self.bool_check_box = QCheckBox(Form)
self.bool_check_box.setObjectName(u"bool_check_box")

self.gridLayout.addWidget(self.bool_check_box, 0, 2, 1, 1)

self.float_check_box = QCheckBox(Form)
self.float_check_box.setObjectName(u"float_check_box")

self.gridLayout.addWidget(self.float_check_box, 0, 0, 1, 1)

self.str_check_box = QCheckBox(Form)
self.str_check_box.setObjectName(u"str_check_box")

self.gridLayout.addWidget(self.str_check_box, 0, 1, 1, 1)

self.date_time_check_box = QCheckBox(Form)
self.date_time_check_box.setObjectName(u"date_time_check_box")

self.gridLayout.addWidget(self.date_time_check_box, 1, 0, 1, 1)

self.array_check_box = QCheckBox(Form)
self.array_check_box.setObjectName(u"array_check_box")

self.gridLayout.addWidget(self.array_check_box, 2, 0, 1, 1)

self.time_pattern_check_box = QCheckBox(Form)
self.time_pattern_check_box.setObjectName(u"time_pattern_check_box")

self.gridLayout.addWidget(self.time_pattern_check_box, 2, 1, 1, 1)

self.time_series_check_box = QCheckBox(Form)
self.time_series_check_box.setObjectName(u"time_series_check_box")

self.gridLayout.addWidget(self.time_series_check_box, 2, 2, 1, 1)


self.verticalLayout.addLayout(self.gridLayout)

self.horizontalLayout_3 = QHBoxLayout()
self.horizontalLayout_3.setSpacing(0)
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.map_check_box = QCheckBox(Form)
self.map_check_box.setObjectName(u"map_check_box")

self.horizontalLayout_3.addWidget(self.map_check_box)

self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setSpacing(0)
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.horizontalLayout_2.setContentsMargins(6, -1, 0, -1)
self.label = QLabel(Form)
self.label.setObjectName(u"label")

self.horizontalLayout_2.addWidget(self.label)

self.map_rank_line_edit = QLineEdit(Form)
self.map_rank_line_edit.setObjectName(u"map_rank_line_edit")

self.horizontalLayout_2.addWidget(self.map_rank_line_edit)


self.horizontalLayout_3.addLayout(self.horizontalLayout_2)


self.verticalLayout.addLayout(self.horizontalLayout_3)

QWidget.setTabOrder(self.select_all_button, self.clear_all_button)
QWidget.setTabOrder(self.clear_all_button, self.float_check_box)
QWidget.setTabOrder(self.float_check_box, self.str_check_box)
QWidget.setTabOrder(self.str_check_box, self.bool_check_box)
QWidget.setTabOrder(self.bool_check_box, self.date_time_check_box)
QWidget.setTabOrder(self.date_time_check_box, self.duration_check_box)
QWidget.setTabOrder(self.duration_check_box, self.array_check_box)
QWidget.setTabOrder(self.array_check_box, self.time_pattern_check_box)
QWidget.setTabOrder(self.time_pattern_check_box, self.time_series_check_box)
QWidget.setTabOrder(self.time_series_check_box, self.map_check_box)
QWidget.setTabOrder(self.map_check_box, self.map_rank_line_edit)

self.retranslateUi(Form)

QMetaObject.connectSlotsByName(Form)
# setupUi

def retranslateUi(self, Form):
Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
self.select_all_button.setText(QCoreApplication.translate("Form", u"Select &all", None))
self.clear_all_button.setText(QCoreApplication.translate("Form", u"&Clear all", None))
self.label_2.setText(QCoreApplication.translate("Form", u"No selection means any type is valid.", None))
self.duration_check_box.setText(QCoreApplication.translate("Form", u"d&uration", None))
self.bool_check_box.setText(QCoreApplication.translate("Form", u"&bool", None))
self.float_check_box.setText(QCoreApplication.translate("Form", u"&float", None))
self.str_check_box.setText(QCoreApplication.translate("Form", u"&str", None))
self.date_time_check_box.setText(QCoreApplication.translate("Form", u"&date_time", None))
self.array_check_box.setText(QCoreApplication.translate("Form", u"a&rray", None))
self.time_pattern_check_box.setText(QCoreApplication.translate("Form", u"time_&pattern", None))
self.time_series_check_box.setText(QCoreApplication.translate("Form", u"&time_series", None))
self.map_check_box.setText(QCoreApplication.translate("Form", u"&map", None))
self.label.setText(QCoreApplication.translate("Form", u"Ranks:", None))
#if QT_CONFIG(tooltip)
self.map_rank_line_edit.setToolTip(QCoreApplication.translate("Form", u"A comma separated list of valid ranks.", None))
#endif // QT_CONFIG(tooltip)
self.map_rank_line_edit.setText(QCoreApplication.translate("Form", u"1", None))
# retranslateUi

Loading

0 comments on commit 4e2cd30

Please sign in to comment.