Source code for spinetoolbox.import_editor.commands

######################################################################################################################
# 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/>.
######################################################################################################################
"""
Contains undo and redo commands for Import editor.

:author: A. Soininen (VTT)
:date:   4.8.2020
"""
from enum import auto, IntEnum, unique
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QUndoCommand
from spinedb_api import parameter_mapping_from_dict


[docs]@unique class _Id(IntEnum):
[docs] SET_OPTION = auto()
[docs]class PasteMappings(QUndoCommand): """Command to paste copied mappings""" def __init__(self, import_editor, source_table_name, copied_mappings, previous_mappings): """ Args: import_editor (ImportEditor): import editor source_table_name (src): name of the target source table copied_mappings (Iterable): mappings to paste previous_mappings (Iterable): mappings before pasting """ text = "paste mappings" super().__init__(text) self._import_editor = import_editor self._source_table_name = source_table_name self._mappings = copied_mappings self._previous_mappings = previous_mappings
[docs] def redo(self): """Pastes the copied mappings""" self._import_editor.paste_mappings(self._source_table_name, self._mappings)
[docs] def undo(self): """Restores mappings to their previous state.""" self._import_editor.paste_mappings(self._source_table_name, self._previous_mappings)
[docs]class PasteOptions(QUndoCommand): """Command to paste copied mapping options.""" def __init__(self, import_editor, source_table_name, copied_options, previous_options): """ Args: import_editor (ImportEditor): import editor source_table_name (src): name of the target source table copied_options (dict): options from the internal clipboard previous_options (dict): previous options """ text = "paste options" super().__init__(text) self._import_editor = import_editor self._source_table_name = source_table_name self._options = copied_options self._previous_options = previous_options
[docs] def redo(self): """Pastes the options.""" self._import_editor.paste_options(self._source_table_name, self._options)
[docs] def undo(self):
"""Restores the options to their previous values."""
[docs]class SetTableChecked(QUndoCommand): """Command to change a source table's checked state.""" def __init__(self, table_name, table_list_model, row, checked): """ Args: table_name (str): source table name table_list_model (SourceTableListModel): source table model row (int): table row on the list checked (bool): new checked state """ text = ("select" if checked else "deselect") + f" '{table_name}'" super().__init__(text) self._model = table_list_model self._row = row self._checked = checked
[docs] def redo(self): """Changes the checked state.""" self._model.set_checked(self._row, self._checked)
[docs] def undo(self): """Restores the previous checked state.""" self._model.set_checked(self._row, not self._checked)
[docs]class RenameMapping(QUndoCommand): """A command to change the name of a mapping.""" def __init__(self, row, mapping_list_model, name, previous_name): """ Args: mapping_list_model (MappingListModel): model holding the mapping names name (str): new name previous_name (str): original name """ text = "rename mapping" super().__init__(text) self._row = row self._model = mapping_list_model self._name = name self._previous_name = previous_name
[docs] def redo(self): """Renames the mapping.""" self._model.rename_mapping(self._row, self._name)
[docs] def undo(self): """Reverts renaming of the mapping.""" self._model.rename_mapping(self._row, self._previous_name)
[docs]class SetComponentMappingType(QUndoCommand): """Sets the type of a component mapping.""" def __init__( self, component_display_name, mapping_specification_model, mapping_type, previous_type, previous_reference ): """ Args: component_display_name (str): component name on the mapping specification table mapping_specification_model (MappingSpecificationModel): specification model mapping_type (str): name of the new type previous_type (str): name of the original type previous_reference (str or int): original mapping's reference """ text = "change source mapping" super().__init__(text) self._model = mapping_specification_model self._component_display_name = component_display_name self._new_type = mapping_type self._previous_type = previous_type self._previous_reference = previous_reference
[docs] def redo(self): """Changes a component mapping's type.""" self._model.set_type(self._component_display_name, self._new_type)
[docs] def undo(self): """Restores component mapping's original type.""" self._model.set_type(self._component_display_name, self._previous_type) self._model.set_value(self._component_display_name, self._previous_reference)
[docs]class SetComponentMappingReference(QUndoCommand): """Sets the reference for a component mapping.""" def __init__( self, component_display_name, mapping_specification_model, reference, previous_reference, previous_mapping_type_was_none, ): """ Args: component_display_name (str): component name on the mapping specification table mapping_specification_model (MappingSpecificationModel): specification model reference (str or int): new value for the reference previous_reference (str or int): preference's original value previous_mapping_type_was_none (bool): True if the mapping was originally a :class:`NoneMapping` """ text = "change source mapping reference" super().__init__(text) self._model = mapping_specification_model self._component_display_name = component_display_name self._reference = reference self._previous_reference = previous_reference self._previous_mapping_type_was_none = previous_mapping_type_was_none
[docs] def redo(self): """Sets the reference's value.""" self._model.set_value(self._component_display_name, self._reference)
[docs] def undo(self): """Restores the reference's value and, if necessary, mapping type to their original values.""" if self._previous_mapping_type_was_none: self._model.set_type(self._component_display_name, "None") else: self._model.set_value(self._component_display_name, self._previous_reference)
[docs]class SetConnectorOption(QUndoCommand): """Command to set a :class:`ConnectorManager` option.""" def __init__(self, source_table, option_key, options_widget, value, previous_value): """ Args: source_table (str): source table name option_key (str): option's key options_widget (OptionsWidget): connector options widget value (str or int or bool): option's new value previous_value (str or int or bool): option's previous value """ text = f"change {option_key}" super().__init__(text) self._source_table = source_table self._option_key = option_key self._options_widget = options_widget self._value = value self._previous_value = previous_value
[docs] def id(self): """ This command's id. Returns: int: id """ return _Id.SET_OPTION
[docs] def mergeWith(self, command): """ Merges command with another :class:`SetConnectorOption`. Args: command (QUndoCommand): a command to merge with Returns: bool: True if merge was successful, False otherwise """ if not isinstance(command, SetConnectorOption): return False return command._option_key == self._option_key and command._value == self._value
[docs] def redo(self): """Changes the connector's option.""" self._options_widget.set_option_without_undo(self._source_table, self._option_key, self._value)
[docs] def undo(self): """Restores the option back to its original value.""" self._options_widget.set_option_without_undo(self._source_table, self._option_key, self._previous_value)
[docs]class CreateMapping(QUndoCommand): """Creates a new mapping.""" def __init__(self, source_table_name, import_mappings, row): """ Args: source_table_name (src): source table name import_mappings (ImportMappings): mappings manager row (int): row where the new mapping should be created """ text = "new mapping" super().__init__(text) self._source_table_name = source_table_name self._import_mappings = import_mappings self._mapping_name = None self._row = row self._stored_mapping_specification = None
[docs] def redo(self): """Creates a new mapping at the given row in mappings list.""" if self._mapping_name is None: self._mapping_name = self._import_mappings.create_mapping() else: self._import_mappings.insert_mapping_specification( self._source_table_name, self._mapping_name, self._row, self._stored_mapping_specification
)
[docs] def undo(self): """Deletes the created mapping.""" self._stored_mapping_specification = self._import_mappings.delete_mapping( self._source_table_name, self._mapping_name
)
[docs]class DeleteMapping(QUndoCommand): """Command to delete a mapping.""" def __init__(self, source_table_name, import_mappings, mapping_name, row): """ Args: source_table_name (src): source table name import_mappings (ImportMappings): mappings manager mapping_name (str): name of the mapping to delete row (int): mapping's row in the mapping list """ text = "delete mapping" super().__init__(text) self._source_table_name = source_table_name self._import_mappings = import_mappings self._mapping_name = mapping_name self._row = row self._stored_mapping_specification = None
[docs] def redo(self): """Deletes the mapping.""" self._stored_mapping_specification = self._import_mappings.delete_mapping( self._source_table_name, self._mapping_name
)
[docs] def undo(self): """Restores the deleted mapping.""" self._import_mappings.insert_mapping_specification( self._source_table_name, self._mapping_name, self._row, self._stored_mapping_specification
)
[docs]class SetItemMappingType(QUndoCommand): """Command to change item mapping's type.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, new_type, previous_mapping): """ Args: source_table_name (src): name of the source table mapping_specification_name (str): name of the mapping options_widget (ImportMappingOptions): options widget new_type (str): name of the new mapping type previous_mapping (ItemMappingBase): the previous mapping """ text = "mapping type change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._new_type = new_type self._previous_mapping = previous_mapping
[docs] def redo(self): """Sets the mapping type to its new value.""" self._options_widget.set_item_mapping_type( self._source_table_name, self._mapping_specification_name, self._new_type
)
[docs] def undo(self): """Resets the mapping type to its former value.""" self._options_widget.set_item_mapping( self._source_table_name, self._mapping_specification_name, self._previous_mapping
)
[docs]class SetImportObjectsFlag(QUndoCommand): """Command to set item mapping's import objects flag.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, import_objects): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget import_objects (bool): new flag value """ text = "import objects flag change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._import_objects = import_objects
[docs] def redo(self): """Changes the import objects flag.""" self._options_widget.set_import_objects_flag( self._source_table_name, self._mapping_specification_name, self._import_objects
)
[docs] def undo(self): """Restores the import objects flag.""" self._options_widget.set_import_objects_flag( self._source_table_name, self._mapping_specification_name, not self._import_objects
)
[docs]class SetParameterType(QUndoCommand): """Command to change the parameter type of an item mapping.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, new_type, previous_parameter): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget new_type (str): name of the new parameter type previous_parameter (ParameterDefinitionMapping): previous parameter mapping """ text = "parameter type change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._new_type = new_type self._previous_parameter = previous_parameter.to_dict()
[docs] def redo(self): """Changes a parameter's type.""" self._options_widget.set_parameter_type( self._source_table_name, self._mapping_specification_name, self._new_type
)
[docs] def undo(self): """Restores a parameter to its previous type""" mapping = parameter_mapping_from_dict(self._previous_parameter) self._options_widget.set_parameter_mapping(self._source_table_name, self._mapping_specification_name, mapping)
[docs]class SetReadStartRow(QUndoCommand): """Command to change item mapping's read start row option.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, start_row, previous_start_row): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget start_row (int): new read start row previous_start_row (int): previous read start row value """ text = "mapping read start row change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._start_row = start_row self._previous_start_row = previous_start_row
[docs] def redo(self): """Changes item mapping's read start row to a new value.""" self._options_widget.set_read_start_row( self._source_table_name, self._mapping_specification_name, self._start_row
)
[docs] def undo(self): """Restores item mapping's read start row to its previous value.""" self._options_widget.set_read_start_row( self._source_table_name, self._mapping_specification_name, self._previous_start_row
)
[docs]class SetItemMappingDimension(QUndoCommand): """Command to change item mapping's dimension option.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, dimension, previous_dimension): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget dimension (int): new dimension previous_dimension (int): previous dimension """ text = "mapping dimension change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._dimension = dimension self._previous_dimension = previous_dimension
[docs] def redo(self): """Changes the item mapping's dimension to the new value.""" self._options_widget.set_dimension(self._source_table_name, self._mapping_specification_name, self._dimension)
[docs] def undo(self): """Changes the item mapping's dimension to its previous value.""" self._options_widget.set_dimension( self._source_table_name, self._mapping_specification_name, self._previous_dimension
)
[docs]class SetTimeSeriesRepeatFlag(QUndoCommand): """Command to change the repeat flag for time series.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, repeat): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget repeat (bool): new repeat flag value """ text = "change time series repeat flag" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._repeat = repeat
[docs] def redo(self): """Sets the repeat flag to given value.""" self._options_widget.set_time_series_repeat_flag( self._source_table_name, self._mapping_specification_name, self._repeat
)
[docs] def undo(self): """Restores the repeat flag to its previous value.""" self._options_widget.set_time_series_repeat_flag( self._source_table_name, self._mapping_specification_name, not self._repeat
)
[docs]class SetMapDimensions(QUndoCommand): """Command to change the dimensions of a Map parameter value type.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, dimensions, previous_dimensions): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget dimensions (int): new dimensions previous_dimensions (int): previous dimensions """ text = "map dimensions change" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._dimensions = dimensions self._previous_dimensions = previous_dimensions
[docs] def redo(self): """Sets the Map dimensions to the new value.""" self._options_widget.set_map_dimensions( self._source_table_name, self._mapping_specification_name, self._dimensions
)
[docs] def undo(self): """Restores the previous Map dimensions value.""" self._options_widget.set_map_dimensions( self._source_table_name, self._mapping_specification_name, self._previous_dimensions
)
[docs]class SetMapCompressFlag(QUndoCommand): """Command to change the Map compress flag.""" def __init__(self, source_table_name, mapping_specification_name, options_widget, compress): """ Args: source_table_name (str): name of the source table mapping_specification_name (str): name of the mapping specification options_widget (ImportMappingOptions): options widget compress (bool): compress flag value """ text = ("enable" if compress else "disable") + " Map compression" super().__init__(text) self._source_table_name = source_table_name self._mapping_specification_name = mapping_specification_name self._options_widget = options_widget self._compress = compress
[docs] def redo(self): """Sets the compress flag.""" self._options_widget.set_map_compress(self._source_table_name, self._mapping_specification_name, self._compress)
[docs] def undo(self): """Resets the compress flag to previous value.""" self._options_widget.set_map_compress( self._source_table_name, self._mapping_specification_name, not self._compress
)
[docs]class SetColumnOrRowType(QUndoCommand): """Command to change the type of columns or rows.""" def __init__(self, source_table_name, header_widget, sections, new_type, previous_type): """ Args: source_table_name (src): name of the source table header_widget (HeaderWithButton): widget of origin sections (Iterable of int): row or column indexes new_type (ConvertSpec): conversion specification for the rows/columns previous_type (ConvertSpec): previous conversion specification for the rows/columns """ text = ("row" if header_widget.orientation() == Qt.Vertical else "column") + " type change" super().__init__(text) self._source_table_name = source_table_name self._header_widget = header_widget self._sections = sections self._new_type = new_type self._previous_type = previous_type
[docs] def redo(self): """Sets column/row type.""" self._header_widget.set_data_types(self._source_table_name, self._sections, self._new_type)
[docs] def undo(self): """Restores column/row type to its previous value.""" self._header_widget.set_data_types(self._source_table_name, self._sections, self._previous_type)
[docs]class RestoreMappingsFromDict(QUndoCommand): """Restores mappings from a dict.""" def __init__(self, import_editor, mapping_dict): """ Args: import_editor (ImportEditor): import editor mapping_dict (dict): mappings to """ super().__init__("import mappings") self._import_editor = import_editor self._mapping_dict = mapping_dict self._previous_mapping_dict = import_editor.get_settings_dict()
[docs] def redo(self): """Restores the mappings.""" self._import_editor.import_mappings(self._mapping_dict)
[docs] def undo(self): """Reverts back to previous mappings.""" self._import_editor.import_mappings(self._previous_mapping_dict)