Source code for spinetoolbox.widgets.custom_delegates

######################################################################################################################
# Copyright (C) 2017-2020 Spine project consortium
# 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/>.
######################################################################################################################

"""
Custom item delegates.

:author: M. Marin (KTH)
:date:   1.9.2018
"""

from PySide2.QtCore import Qt, Signal, QEvent, QPoint, QRect
from PySide2.QtWidgets import QComboBox, QItemDelegate, QStyleOptionButton, QStyle, QApplication, QStyleOptionComboBox
from PySide2.QtGui import QIcon
from spinedb_api import from_database, DateTime, Duration, Map, ParameterValueFormatError, TimePattern, TimeSeries
from .custom_editors import (
    CustomComboEditor,
    CustomLineEditor,
    SearchBarEditor,
    CheckListEditor,
    NumberParameterInlineEditor,
)


[docs]class ComboBoxDelegate(QItemDelegate): def __init__(self, parent, choices): super().__init__(parent) self.editor = None self.items = choices
[docs] def createEditor(self, parent, option, index): self.editor = QComboBox(parent) self.editor.addItems(self.items) # self.editor.currentIndexChanged.connect(self.currentItemChanged) return self.editor
[docs] def paint(self, painter, option, index): value = index.data(Qt.DisplayRole) style = QApplication.style() opt = QStyleOptionComboBox() opt.text = str(value) opt.rect = option.rect style.drawComplexControl(QStyle.CC_ComboBox, opt, painter) QItemDelegate.paint(self, painter, option, index)
[docs] def setEditorData(self, editor, index): value = index.data(Qt.DisplayRole) num = self.items.index(value) editor.setCurrentIndex(num)
[docs] def setModelData(self, editor, model, index): value = editor.currentText() model.setData(index, value, Qt.EditRole)
[docs] def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect)
[docs] def currentItemChanged(self): self.commitData.emit(self.sender())
[docs]class LineEditDelegate(QItemDelegate): """A delegate that places a fully functioning QLineEdit. Attributes: parent (QMainWindow): either data store or spine datapackage widget """
[docs] data_committed = Signal("QModelIndex", "QVariant", name="data_committed")
[docs] def createEditor(self, parent, option, index): """Return CustomLineEditor. Set up a validator depending on datatype.""" return CustomLineEditor(parent)
[docs] def setEditorData(self, editor, index): """Init the line editor with previous data from the index.""" editor.set_data(index.data(Qt.EditRole))
[docs] def setModelData(self, editor, model, index): """Send signal.""" self.data_committed.emit(index, editor.data())
[docs]class CheckBoxDelegate(QItemDelegate): """A delegate that places a fully functioning QCheckBox. Attributes: parent (QMainWindow): either toolbox or spine datapackage widget centered (bool): whether or not the checkbox should be center-aligned in the widget """
[docs] data_committed = Signal("QModelIndex")
def __init__(self, parent, centered=True): super().__init__(parent) self._centered = centered self._checkbox_pressed = None
[docs] def createEditor(self, parent, option, index): """Important, otherwise an editor is created if the user clicks in this cell. ** Need to hook up a signal to the model.""" return None
[docs] def paint(self, painter, option, index): """Paint a checkbox without the label.""" if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) checkbox_style_option = QStyleOptionButton() if (index.flags() & Qt.ItemIsEditable) > 0: checkbox_style_option.state |= QStyle.State_Enabled else: checkbox_style_option.state |= QStyle.State_ReadOnly checked = index.data() if checked is None: checkbox_style_option.state |= QStyle.State_NoChange elif checked: checkbox_style_option.state |= QStyle.State_On else: checkbox_style_option.state |= QStyle.State_Off checkbox_style_option.rect = self.get_checkbox_rect(option) # noinspection PyArgumentList QApplication.style().drawControl(QStyle.CE_CheckBox, checkbox_style_option, painter)
[docs] def editorEvent(self, event, model, option, index): """Change the data in the model and the state of the checkbox when user presses left mouse button and this cell is editable. Otherwise do nothing.""" if not (index.flags() & Qt.ItemIsEditable) > 0: return False # Do nothing on double-click if event.type() == QEvent.MouseButtonDblClick: return True if event.type() == QEvent.MouseButtonPress: self._checkbox_pressed = self.get_checkbox_rect(option).contains(event.pos()) if event.type() == QEvent.MouseButtonPress: if self._checkbox_pressed and self.get_checkbox_rect(option).contains(event.pos()): self._checkbox_pressed = False self.data_committed.emit(index, not index.data(Qt.EditRole)) return True return False
[docs] def setModelData(self, editor, model, index):
"""Do nothing. Model data is updated by handling the `data_committed` signal."""
[docs] def get_checkbox_rect(self, option): checkbox_style_option = QStyleOptionButton() checkbox_rect = QApplication.style().subElementRect(QStyle.SE_CheckBoxIndicator, checkbox_style_option, None) if self._centered: checkbox_anchor = QPoint( option.rect.x() + option.rect.width() / 2 - checkbox_rect.width() / 2, option.rect.y() + option.rect.height() / 2 - checkbox_rect.height() / 2, ) else: checkbox_anchor = QPoint( option.rect.x() + checkbox_rect.width() / 2, option.rect.y() + checkbox_rect.height() / 2 ) return QRect(checkbox_anchor, checkbox_rect.size())
[docs]class PivotTableDelegate(CheckBoxDelegate):
[docs] parameter_value_editor_requested = Signal("QModelIndex", str, object)
[docs] data_committed = Signal("QModelIndex", "QVariant")
[docs] def setModelData(self, editor, model, index): """Send signal.""" self.data_committed.emit(index, editor.data())
[docs] def _is_entity_index(self, index): return not self.parent().is_value_input_type() and index.model().sourceModel().index_in_data(index)
[docs] def paint(self, painter, option, index): if self._is_entity_index(index): super().paint(painter, option, index) else: QItemDelegate.paint(self, painter, option, index)
[docs] def editorEvent(self, event, model, option, index): if self._is_entity_index(index): return super().editorEvent(event, model, option, index) return QItemDelegate.editorEvent(self, event, model, option, index)
[docs] def createEditor(self, parent, option, index): if self._is_entity_index(index): return super().createEditor(parent, option, index) if self.parent().pivot_table_model.index_in_data(index): try: value = from_database(index.data(role=Qt.EditRole)) except ParameterValueFormatError: value = None if isinstance(value, (DateTime, Duration, Map, TimePattern, TimeSeries)) or value is None: value_name = index.model().sourceModel().value_name(index) # FIXME: get the actual name self.parameter_value_editor_requested.emit(index, value_name, value) return None return CustomLineEditor(parent)
[docs]class GetObjectClassIdMixin: """Allows getting the object class id from the name."""
[docs] def _get_object_class_id(self, index, db_map): h = index.model().header.index object_class_name = index.sibling(index.row(), h("object_class_name")).data() object_class = self.db_mngr.get_item_by_field(db_map, "object class", "name", object_class_name) return object_class.get("id")
[docs]class GetRelationshipClassIdMixin: """Allows getting the relationship class id from the name."""
[docs] def _get_relationship_class_id(self, index, db_map): h = index.model().header.index relationship_class_name = index.sibling(index.row(), h("relationship_class_name")).data() relationship_class = self.db_mngr.get_item_by_field( db_map, "relationship class", "name", relationship_class_name ) return relationship_class.get("id")
[docs]class ParameterDelegate(QItemDelegate): """Base class for all custom parameter delegates. Attributes: parent (DataStoreForm): tree or graph view form db_mngr (SpineDBManager) """
[docs] data_committed = Signal("QModelIndex", "QVariant")
def __init__(self, parent, db_mngr): super().__init__(parent) self.db_mngr = db_mngr
[docs] def setModelData(self, editor, model, index): """Send signal.""" self.data_committed.emit(index, editor.data())
[docs] def updateEditorGeometry(self, editor, option, index): super().updateEditorGeometry(editor, option, index) if isinstance(editor, (SearchBarEditor, CheckListEditor)): size = option.rect.size() if index.data(Qt.DecorationRole): size.setWidth(size.width() - 22) # FIXME editor.set_base_size(size) editor.update_geometry()
[docs] def _close_editor(self, editor, index): """Closes editor. Needed by SearchBarEditor.""" self.closeEditor.emit(editor) self.setModelData(editor, index.model(), index)
[docs] def _get_db_map(self, index): """Returns the db_map for the database at given index or None if not set yet.""" model = index.model() header = model.horizontal_header_labels() database = index.sibling(index.row(), header.index("database")).data() db_map = next(iter(x for x in self.db_mngr.db_maps if x.codename == database), None) if not db_map: self.parent().msg_error.emit("Please select database first.") return db_map
[docs]class DatabaseNameDelegate(ParameterDelegate): """A delegate for the database name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" editor = SearchBarEditor(self.parent(), parent) editor.set_data(index.data(Qt.DisplayRole), [x.codename for x in self.db_mngr.db_maps]) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class ParameterValueOrDefaultValueDelegate(ParameterDelegate): """A delegate for the either the value or the default value."""
[docs] parameter_value_editor_requested = Signal("QModelIndex", str, object)
[docs] def setModelData(self, editor, model, index): """Emits the data_committed signal with new data.""" if isinstance(editor, NumberParameterInlineEditor): self.data_committed.emit(index, editor.data()) return value = self._str_to_int_or_float(editor.data()) self.data_committed.emit(index, value)
@staticmethod
[docs] def _str_to_int_or_float(string): try: return int(string) except ValueError: try: return float(string) except ValueError: return string
[docs] def _create_or_request_parameter_value_editor(self, parent, option, index, db_map): """Returns a CustomLineEditor or NumberParameterInlineEditor if the data from index is not of special type. Otherwise, emit the signal to request a standalone `ParameterValueEditor` from parent widget. """ try: value = from_database(index.data(role=Qt.EditRole)) except ParameterValueFormatError: value = None if isinstance(value, (DateTime, Duration, Map, TimePattern, TimeSeries)): value_name = index.model().value_name(index) self.parameter_value_editor_requested.emit(index, value_name, value) return None if isinstance(value, (float, int)): editor = NumberParameterInlineEditor(parent) else: editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) return editor
[docs]class ParameterDefaultValueDelegate(ParameterValueOrDefaultValueDelegate): """A delegate for the either the default value."""
[docs] def createEditor(self, parent, option, index): """Returns or requests a parameter value editor.""" db_map = self._get_db_map(index) if not db_map: return None return self._create_or_request_parameter_value_editor(parent, option, index, db_map)
[docs]class ParameterValueDelegate(ParameterValueOrDefaultValueDelegate): """A delegate for the parameter value."""
[docs] def _get_entity_class_id(self, index, db_map): raise NotImplementedError()
[docs] def _get_value_list(self, index, db_map): """Returns a value list item for the given index and db_map.""" h = index.model().header.index parameter_name = index.sibling(index.row(), h("parameter_name")).data() parameters = self.db_mngr.get_items_by_field(db_map, "parameter definition", "parameter_name", parameter_name) entity_class_id = self._get_entity_class_id(index, db_map) parameter_ids = {p["id"] for p in parameters if p[self.entity_class_id_key] == entity_class_id} value_list_ids = { self.db_mngr.get_item(db_map, "parameter definition", id_).get("value_list_id") for id_ in parameter_ids } if len(value_list_ids) == 1: value_list_id = next(iter(value_list_ids)) return self.db_mngr.get_item(db_map, "parameter value list", value_list_id).get("value_list")
[docs] def createEditor(self, parent, option, index): """If the parameter has associated a value list, returns a SearchBarEditor . Otherwise returns or requests a dedicated parameter value editor. """ db_map = self._get_db_map(index) if not db_map: return None value_list = self._get_value_list(index, db_map) if value_list: editor = SearchBarEditor(self.parent(), parent) value_list = [from_database(x) for x in value_list.split(",")] editor.set_data(index.data(Qt.DisplayRole), value_list) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor return self._create_or_request_parameter_value_editor(parent, option, index, db_map)
[docs]class ObjectParameterValueDelegate(GetObjectClassIdMixin, ParameterValueDelegate): """A delegate for the object parameter value.""" @property
[docs] def entity_class_id_key(self): return "object_class_id"
[docs] def _get_entity_class_id(self, index, db_map): return self._get_object_class_id(index, db_map)
[docs]class RelationshipParameterValueDelegate(GetRelationshipClassIdMixin, ParameterValueDelegate): """A delegate for the relationship parameter value.""" @property
[docs] def entity_class_id_key(self): return "relationship_class_id"
[docs] def _get_entity_class_id(self, index, db_map): return self._get_relationship_class_id(index, db_map)
[docs]class TagListDelegate(ParameterDelegate): """A delegate for the parameter tag list."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = CheckListEditor(self.parent(), parent) all_parameter_tag_list = [x["tag"] for x in self.db_mngr.get_parameter_tags(db_map)] try: parameter_tag_list = index.data(Qt.EditRole).split(",") except AttributeError: # Gibberish in the cell parameter_tag_list = [] editor.set_data(all_parameter_tag_list, parameter_tag_list) return editor
[docs]class ValueListDelegate(ParameterDelegate): """A delegate for the parameter value-list."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) name_list = [x["name"] for x in self.db_mngr.get_parameter_value_lists(db_map)] editor.set_data(index.data(Qt.EditRole), name_list) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class ObjectClassNameDelegate(ParameterDelegate): """A delegate for the object class name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) object_classes = self.db_mngr.get_object_classes(db_map) editor.set_data(index.data(Qt.EditRole), [x["name"] for x in object_classes]) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class RelationshipClassNameDelegate(ParameterDelegate): """A delegate for the relationship class name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) relationship_classes = self.db_mngr.get_relationship_classes(db_map) editor.set_data(index.data(Qt.EditRole), [x["name"] for x in relationship_classes]) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class ObjectParameterNameDelegate(GetObjectClassIdMixin, ParameterDelegate): """A delegate for the object parameter name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) object_class_id = self._get_object_class_id(index, db_map) parameter_definitions = self.db_mngr.get_object_parameter_definitions(db_map, object_class_id=object_class_id) name_list = [x["parameter_name"] for x in parameter_definitions] editor.set_data(index.data(Qt.EditRole), name_list) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class RelationshipParameterNameDelegate(GetRelationshipClassIdMixin, ParameterDelegate): """A delegate for the relationship parameter name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) relationship_class_id = self._get_relationship_class_id(index, db_map) parameter_definitions = self.db_mngr.get_relationship_parameter_definitions( db_map, relationship_class_id=relationship_class_id ) name_list = [x["parameter_name"] for x in parameter_definitions] editor.set_data(index.data(Qt.EditRole), name_list) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class ObjectNameDelegate(GetObjectClassIdMixin, ParameterDelegate): """A delegate for the object name."""
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None editor = SearchBarEditor(self.parent(), parent) object_class_id = self._get_object_class_id(index, db_map) name_list = [x["name"] for x in self.db_mngr.get_objects(db_map, class_id=object_class_id)] editor.set_data(index.data(Qt.EditRole), name_list) editor.data_committed.connect(lambda editor=editor, index=index: self._close_editor(editor, index)) return editor
[docs]class ObjectNameListDelegate(GetRelationshipClassIdMixin, ParameterDelegate): """A delegate for the object name list."""
[docs] object_name_list_editor_requested = Signal("QModelIndex", int, "QVariant")
[docs] def createEditor(self, parent, option, index): """Returns editor.""" db_map = self._get_db_map(index) if not db_map: return None relationship_class_id = self._get_relationship_class_id(index, db_map) if not relationship_class_id: editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) return editor self.object_name_list_editor_requested.emit(index, relationship_class_id, db_map)
[docs]class ManageItemsDelegate(QItemDelegate): """A custom delegate for the model in {Add/Edit}ItemDialogs. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] data_committed = Signal("QModelIndex", "QVariant", name="data_committed")
[docs] def setModelData(self, editor, model, index): """Send signal.""" self.data_committed.emit(index, editor.data())
[docs] def close_editor(self, editor, index, model): self.closeEditor.emit(editor) self.setModelData(editor, model, index)
[docs] def updateEditorGeometry(self, editor, option, index): super().updateEditorGeometry(editor, option, index) if isinstance(editor, (SearchBarEditor, CheckListEditor)): size = option.rect.size() if index.data(Qt.DecorationRole): size.setWidth(size.width() - 22) # FIXME editor.set_base_size(size) editor.update_geometry()
[docs] def connect_editor_signals(self, editor, index): """Connect editor signals if necessary. """ if isinstance(editor, SearchBarEditor): model = index.model() editor.data_committed.connect(lambda e=editor, i=index, m=model: self.close_editor(e, i, m))
[docs] def _create_database_editor(self, parent, option, index): editor = CheckListEditor(parent) all_databases = self.parent().all_databases(index.row()) databases = index.data(Qt.DisplayRole).split(",") editor.set_data(all_databases, databases) return editor
[docs]class ManageObjectClassesDelegate(ManageItemsDelegate): """A delegate for the model and view in {Add/Edit}ObjectClassesDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] icon_color_editor_requested = Signal("QModelIndex", name="icon_color_editor_requested")
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'display icon': self.icon_color_editor_requested.emit(index) editor = None elif header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) else: editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) self.connect_editor_signals(editor, index) return editor
[docs] def paint(self, painter, option, index): """Get a pixmap from the index data and paint it in the middle of the cell.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'display icon': pixmap = self.parent().create_object_pixmap(index.data(Qt.DisplayRole)) icon = QIcon(pixmap) icon.paint(painter, option.rect, Qt.AlignVCenter | Qt.AlignHCenter) else: super().paint(painter, option, index)
[docs]class ManageObjectsDelegate(ManageItemsDelegate): """A delegate for the model and view in {Add/Edit}ObjectsDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'object class name': editor = SearchBarEditor(parent) object_class_name_list = self.parent().object_class_name_list(index.row()) editor.set_data(index.data(Qt.EditRole), object_class_name_list) elif header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) else: editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) self.connect_editor_signals(editor, index) return editor
[docs]class ManageRelationshipClassesDelegate(ManageItemsDelegate): """A delegate for the model and view in {Add/Edit}RelationshipClassesDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'relationship class name': editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) elif header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) else: editor = SearchBarEditor(parent) object_class_name_list = self.parent().object_class_name_list(index.row()) editor.set_data(index.data(Qt.EditRole), object_class_name_list) self.connect_editor_signals(editor, index) return editor
[docs]class ManageRelationshipsDelegate(ManageItemsDelegate): """A delegate for the model and view in {Add/Edit}RelationshipsDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'relationship name': editor = CustomLineEditor(parent) data = index.data(Qt.EditRole) editor.set_data(data) elif header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) else: editor = SearchBarEditor(parent) object_name_list = self.parent().object_name_list(index.row(), index.column()) editor.set_data(index.data(Qt.EditRole), object_name_list) self.connect_editor_signals(editor, index) return editor
[docs]class RemoveEntitiesDelegate(ManageItemsDelegate): """A delegate for the model and view in RemoveEntitiesDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) self.connect_editor_signals(editor, index) return editor
[docs]class ManageParameterTagsDelegate(ManageItemsDelegate): """A delegate for the model and view in ManageParameterTagsDialog. Attributes: parent (ManageItemsDialog): parent dialog """
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'remove': return None if header[index.column()] == 'databases': editor = self._create_database_editor(parent, option, index) else: editor = CustomLineEditor(parent) editor.set_data(index.data(Qt.EditRole)) self.connect_editor_signals(editor, index) return editor
[docs]class ForeignKeysDelegate(QItemDelegate): """A QComboBox delegate with checkboxes. Attributes: parent (SpineDatapackageWidget): spine datapackage widget """
[docs] data_committed = Signal("QModelIndex", "QVariant", name="data_committed")
[docs] def close_field_name_list_editor(self, editor, index, model): self.closeEditor.emit(editor) self.data_committed.emit(index, editor.data())
def __init__(self, parent): super().__init__(parent) self.datapackage = None self.selected_resource_name = None
[docs] def createEditor(self, parent, option, index): """Return editor.""" header = index.model().horizontal_header_labels() if header[index.column()] == 'fields': editor = CheckListEditor(self.parent(), parent) model = index.model() editor.data_committed.connect(lambda e=editor, i=index, m=model: self.close_field_name_list_editor(e, i, m)) return editor if header[index.column()] == 'reference resource': return CustomComboEditor(parent) if header[index.column()] == 'reference fields': editor = CheckListEditor(self.parent(), parent) model = index.model() editor.data_committed.connect(lambda e=editor, i=index, m=model: self.close_field_name_list_editor(e, i, m)) return editor return None
[docs] def setEditorData(self, editor, index): """Set editor data.""" self.datapackage = self.parent().datapackage self.selected_resource_name = self.parent().selected_resource_name header = index.model().horizontal_header_labels() h = header.index if header[index.column()] == 'fields': current_field_names = index.data(Qt.DisplayRole).split(',') if index.data(Qt.DisplayRole) else [] field_names = self.datapackage.get_resource(self.selected_resource_name).schema.field_names editor.set_data(field_names, current_field_names) elif header[index.column()] == 'reference resource': editor.set_data(index.data(Qt.EditRole), self.datapackage.resource_names) elif header[index.column()] == 'reference fields': current_field_names = index.data(Qt.DisplayRole).split(',') if index.data(Qt.DisplayRole) else [] reference_resource_name = index.sibling(index.row(), h('reference resource')).data(Qt.DisplayRole) reference_resource = self.datapackage.get_resource(reference_resource_name) if not reference_resource: field_names = [] else: field_names = reference_resource.schema.field_names editor.set_data(field_names, current_field_names)
[docs] def setModelData(self, editor, model, index): """Send signal.""" self.data_committed.emit(index, editor.data())