Skip to content

Commit

Permalink
Improve line edits (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
soininen authored Mar 1, 2024
2 parents 9b81ecc + 69a4673 commit 52dacaf
Show file tree
Hide file tree
Showing 41 changed files with 699 additions and 307 deletions.
75 changes: 47 additions & 28 deletions spine_items/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,54 @@


class UpdateCancelOnErrorCommand(SpineToolboxCommand):
def __init__(self, project_item, cancel_on_error):
def __init__(self, item_name, cancel_on_error, project):
"""Command to update Importer, Exporter, and Merger cancel on error setting.
Args:
project_item (ProjectItem): Item
item_name (str): Item's name
cancel_on_error (bool): New setting
project (SpineToolboxProject): project
"""
super().__init__()
self._project_item = project_item
self._item_name = item_name
self._redo_cancel_on_error = cancel_on_error
self._undo_cancel_on_error = not cancel_on_error
self.setText(f"change {project_item.name} cancel on error setting")
self._project = project
self.setText(f"change {item_name} cancel on error setting")

def redo(self):
self._project_item.set_cancel_on_error(self._redo_cancel_on_error)
item = self._project.get_item(self._item_name)
item.set_cancel_on_error(self._redo_cancel_on_error)

def undo(self):
self._project_item.set_cancel_on_error(self._undo_cancel_on_error)
item = self._project.get_item(self._item_name)
item.set_cancel_on_error(self._undo_cancel_on_error)


class UpdateOnConflictCommand(SpineToolboxCommand):
def __init__(self, project_item, on_conflict):
def __init__(self, item_name, on_conflict, project):
"""Command to update Importer and Merger 'on conflict' setting.
Args:
project_item (ProjectItem): Item
item_name (str): Item's name
on_conflict (str): New setting
project (SpineToolboxProject): project
"""
super().__init__()
self._project_item = project_item
self._item_name = item_name
self._redo_on_conflict = on_conflict
self._undo_on_conflict = self._project_item.on_conflict
self.setText(f"change {project_item.name} on conflict setting")
project_item = project.get_item(item_name)
self._undo_on_conflict = project_item.on_conflict
self._project = project
self.setText(f"change {item_name} on conflict setting")

def redo(self):
self._project_item.set_on_conflict(self._redo_on_conflict)
item = self._project.get_item(self._item_name)
item.set_on_conflict(self._redo_on_conflict)

def undo(self):
self._project_item.set_on_conflict(self._undo_on_conflict)
item = self._project.get_item(self._item_name)
item.set_on_conflict(self._undo_on_conflict)


class ChangeItemSelectionCommand(SpineToolboxCommand):
Expand All @@ -80,42 +89,52 @@ def undo(self):


class UpdateCmdLineArgsCommand(SpineToolboxCommand):
def __init__(self, item, cmd_line_args):
def __init__(self, item_name, cmd_line_args, project):
"""Command to update Tool command line args.
Args:
item (ProjectItemBase): the item
item_name (str): item's name
cmd_line_args (list): list of command line args
project (SpineToolboxProject): project
"""
super().__init__()
self.item = item
self.redo_cmd_line_args = cmd_line_args
self.undo_cmd_line_args = self.item.cmd_line_args
self.setText(f"change command line arguments of {item.name}")
self._item_name = item_name
self._redo_cmd_line_args = cmd_line_args
item = project.get_item(item_name)
self._undo_cmd_line_args = item.cmd_line_args
self._project = project
self.setText(f"change command line arguments of {item_name}")

def redo(self):
self.item.update_cmd_line_args(self.redo_cmd_line_args)
item = self._project.get_item(self._item_name)
item.update_cmd_line_args(self._redo_cmd_line_args)

def undo(self):
self.item.update_cmd_line_args(self.undo_cmd_line_args)
item = self._project.get_item(self._item_name)
item.update_cmd_line_args(self._undo_cmd_line_args)


class UpdateGroupIdCommand(SpineToolboxCommand):
def __init__(self, item, group_id):
def __init__(self, item_name, group_id, project):
"""Command to update item group identifier.
Args:
item (ProjectItemBase): the item
item_name (str): item's name
group_id (str): group identifier
project (SpineToolboxProject): project
"""
super().__init__()
self._item = item
self._item_name = item_name
self._redo_group_id = group_id
self._undo_group_id = self._item.group_id
self.setText(f"change group identifier of {item.name}")
item = project.get_item(item_name)
self._undo_group_id = item.group_id
self._project = project
self.setText(f"change group identifier of {item_name}")

def redo(self):
self._item.do_set_group_id(self._redo_group_id)
item = self._project.get_item(self._item_name)
item.do_set_group_id(self._redo_group_id)

def undo(self):
self._item.do_set_group_id(self._undo_group_id)
item = self._project.get_item(self._item_name)
item.do_set_group_id(self._undo_group_id)
60 changes: 36 additions & 24 deletions spine_items/data_connection/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,79 @@
class AddDCReferencesCommand(SpineToolboxCommand):
"""Command to add DC references."""

def __init__(self, dc, file_refs, db_refs):
def __init__(self, dc_name, file_refs, db_refs, project):
"""
Args:
dc (DataConnection): the DC
dc_name (str): DC name
file_refs (list of str): list of file refs to add
db_refs (list of str): list of db refs to add
project (SpineToolboxProject): project
"""
super().__init__()
self.dc = dc
self.file_refs = file_refs
self.db_refs = db_refs
self.setText(f"add references to {dc.name}")
self._dc_name = dc_name
self._file_refs = file_refs
self._db_refs = db_refs
self._project = project
self.setText(f"add references to {dc_name}")

def redo(self):
self.dc.do_add_references(self.file_refs, self.db_refs)
dc = self._project.get_item(self._dc_name)
dc.do_add_references(self._file_refs, self._db_refs)

def undo(self):
self.dc.do_remove_references(self.file_refs, self.db_refs)
dc = self._project.get_item(self._dc_name)
dc.do_remove_references(self._file_refs, self._db_refs)


class RemoveDCReferencesCommand(SpineToolboxCommand):
"""Command to remove DC references."""

def __init__(self, dc, file_refs, db_refs):
def __init__(self, dc_name, file_refs, db_refs, project):
"""
Args:
dc (DataConnection): the DC
dc_name (str): DC name
file_refs (list of str): list of file refs to remove
db_refs (list of str): list of db refs to remove
project (SpineToolboxProject): project
"""
super().__init__()
self.dc = dc
self.file_refs = file_refs
self.db_refs = db_refs
self.setText(f"remove references from {dc.name}")
self._dc_name = dc_name
self._file_refs = file_refs
self._db_refs = db_refs
self._project = project
self.setText(f"remove references from {dc_name}")

def redo(self):
self.dc.do_remove_references(self.file_refs, self.db_refs)
dc = self._project.get_item(self._dc_name)
dc.do_remove_references(self._file_refs, self._db_refs)

def undo(self):
self.dc.do_add_references(self.file_refs, self.db_refs)
dc = self._project.get_item(self._dc_name)
dc.do_add_references(self._file_refs, self._db_refs)


class MoveReferenceToData(SpineToolboxCommand):
"""Command to move DC references to data."""

def __init__(self, dc, paths):
def __init__(self, dc_name, paths, project):
"""
Args:
dc (DataConnection): the DC
dc_name (str): DC name
paths (list of str): list of paths to move
project (SpineToolboxProject): project
"""
super().__init__()
self._dc = dc
self._dc_name = dc_name
self._paths = paths
self.setText("copy references to data")
self._project = project
self.setText(f"copy references to data in {dc_name}")

def redo(self):
self._dc.do_copy_to_project(self._paths)
self._dc.do_remove_references(self._paths, [])
dc = self._project.get_item(self._dc_name)
dc.do_copy_to_project(self._paths)
dc.do_remove_references(self._paths, [])

def undo(self):
self._dc.delete_files_from_project([Path(p).name for p in self._paths])
self._dc.do_add_references(self._paths, [])
dc = self._project.get_item(self._dc_name)
dc.delete_files_from_project([Path(p).name for p in self._paths])
dc.do_add_references(self._paths, [])
12 changes: 8 additions & 4 deletions spine_items/data_connection/data_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def _add_file_references(self, paths):
if repeated_paths:
self._logger.msg_warning.emit(f"Reference to file(s) <b>{repeated_paths}</b> already exists")
if new_paths:
self._toolbox.undo_stack.push(AddDCReferencesCommand(self, new_paths, []))
self._toolbox.undo_stack.push(AddDCReferencesCommand(self.name, new_paths, [], self._project))

@Slot(bool)
def show_add_db_reference_dialog(self, _=False):
Expand All @@ -231,7 +231,7 @@ def show_add_db_reference_dialog(self, _=False):
self._database_validator.validate_url(
url["dialect"], sa_url, self._log_database_reference_error, success_slot=None
)
self._toolbox.undo_stack.push(AddDCReferencesCommand(self, [], [url]))
self._toolbox.undo_stack.push(AddDCReferencesCommand(self.name, [], [url], self._project))

def _has_db_reference(self, url):
"""Checks if given database URL exists already.
Expand Down Expand Up @@ -302,7 +302,9 @@ def remove_references(self, _=False):
file_references.append(index.data(Qt.ItemDataRole.DisplayRole))
elif parent == db_ref_root_index:
db_references.append(index.data(_Role.DB_URL_REFERENCE))
self._toolbox.undo_stack.push(RemoveDCReferencesCommand(self, file_references, db_references))
self._toolbox.undo_stack.push(
RemoveDCReferencesCommand(self.name, file_references, db_references, self._project)
)
self._logger.msg.emit("Selected references removed")

def do_remove_references(self, file_refs, db_refs):
Expand Down Expand Up @@ -496,7 +498,9 @@ def copy_to_project(self, _=False):
if not selected_indexes:
self._logger.msg_warning.emit("No files to copy")
return
self._toolbox.undo_stack.push(MoveReferenceToData(self, [index.data() for index in selected_indexes]))
self._toolbox.undo_stack.push(
MoveReferenceToData(self.name, [index.data() for index in selected_indexes], self._project)
)

def do_copy_to_project(self, paths):
"""Copies given files to item's data directory.
Expand Down
46 changes: 28 additions & 18 deletions spine_items/data_store/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,41 @@ class CommandId(IntEnum):


class UpdateDSURLCommand(SpineToolboxCommand):
def __init__(self, ds, was_url_valid, **kwargs):
"""Command to update DS url.
"""Command to update DS url."""

def __init__(self, ds_name, was_url_valid, project, **kwargs):
"""
Args:
ds (DataStore): the DS
ds_name (str): DS name
was_url_valid (bool): True if previous URL was valid, False otherwise
kwargs: url keys and their values
project (SpineToolboxProject): project
**kwargs: url keys and their values
"""
super().__init__()
self.ds = ds
self._ds_name = ds_name
self._undo_url_is_valid = was_url_valid
self.redo_kwargs = kwargs
self.undo_kwargs = {k: self.ds.url()[k] for k in kwargs}
self._redo_kwargs = kwargs
ds = project.get_item(ds_name)
self._undo_kwargs = {k: ds.url()[k] for k in kwargs}
self._project = project
if len(kwargs) == 1:
self.setText(f"change {list(kwargs.keys())[0]} of {ds.name}")
self.setText(f"change {list(kwargs.keys())[0]} of {ds_name}")
else:
self.setText(f"change url of {ds.name}")
self.setText(f"change url of {ds_name}")

def id(self):
return CommandId.UPDATE_URL.value

def mergeWith(self, command):
if not isinstance(command, UpdateDSURLCommand) or self.ds is not command.ds or command._undo_url_is_valid:
if (
not isinstance(command, UpdateDSURLCommand)
or self._ds_name != command._ds_name
or command._undo_url_is_valid
):
return False
diff_key = None
for key, value in self.redo_kwargs.items():
old_value = self.undo_kwargs[key]
for key, value in self._redo_kwargs.items():
old_value = self._undo_kwargs[key]
if value != old_value:
if diff_key is not None:
return False
Expand All @@ -57,16 +65,18 @@ def mergeWith(self, command):
raise RuntimeError("Logic error: nothing changes between undo and redo URLs.")
if diff_key == "dialect":
return False
changed_value = command.redo_kwargs[diff_key]
if self.redo_kwargs[diff_key] == changed_value:
changed_value = command._redo_kwargs[diff_key]
if self._redo_kwargs[diff_key] == changed_value:
return False
self.redo_kwargs[diff_key] = changed_value
if self.redo_kwargs[diff_key] == self.undo_kwargs[diff_key]:
self._redo_kwargs[diff_key] = changed_value
if self._redo_kwargs[diff_key] == self._undo_kwargs[diff_key]:
self.setObsolete(True)
return True

def redo(self):
self.ds.do_update_url(**self.redo_kwargs)
ds = self._project.get_item(self._ds_name)
ds.do_update_url(**self._redo_kwargs)

def undo(self):
self.ds.do_update_url(**self.undo_kwargs)
ds = self._project.get_item(self._ds_name)
ds.do_update_url(**self._undo_kwargs)
2 changes: 1 addition & 1 deletion spine_items/data_store/data_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def update_url(self, **kwargs):
kwargs = {k: v for k, v in kwargs.items() if v != self._url[k]}
if not kwargs:
return False
self._toolbox.undo_stack.push(UpdateDSURLCommand(self, invalidating_url, **kwargs))
self._toolbox.undo_stack.push(UpdateDSURLCommand(self.name, invalidating_url, self._project, **kwargs))
return True

def do_update_url(self, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def setupUi(self, Form):

def retranslateUi(self, Form):
Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
self.specification_label.setText(QCoreApplication.translate("Form", u"Specification", None))
self.specification_label.setText(QCoreApplication.translate("Form", u"Specification:", None))
#if QT_CONFIG(tooltip)
self.specification_combo_box.setToolTip(QCoreApplication.translate("Form", u"<html><head/><body><p>Tool specification for this Tool</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<!--
######################################################################################################################
# Copyright (C) 2017-2022 Spine project consortium
# Copyright Spine Items contributors
# This file is part of Spine Items.
# Spine Items 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)
Expand Down Expand Up @@ -46,7 +47,7 @@
</size>
</property>
<property name="text">
<string>Specification</string>
<string>Specification:</string>
</property>
</widget>
</item>
Expand Down
Loading

0 comments on commit 52dacaf

Please sign in to comment.