diff --git a/zxlive/commands.py b/zxlive/commands.py index eeb798de..a3f128f1 100644 --- a/zxlive/commands.py +++ b/zxlive/commands.py @@ -47,6 +47,16 @@ def update_graph_view(self, select_new: bool = False) -> None: # we could store "dirty flags" for each node/edge. self.graph_view.update_graph(self.g, select_new) +@dataclass +class UndoableChange(BaseCommand): + undo: Callable[[], None] + redo: Callable[[], None] + + def undo(self) -> None: + self.undo(self) + + def redo(self) -> None: + self.redo(self) @dataclass class SetGraph(BaseCommand): diff --git a/zxlive/common.py b/zxlive/common.py index a27d543a..cfa39128 100644 --- a/zxlive/common.py +++ b/zxlive/common.py @@ -1,16 +1,15 @@ import os from enum import IntEnum -from typing import Final +from typing import Final, Callable from typing_extensions import TypeAlias from PySide6.QtCore import QSettings -from PySide6.QtGui import QColor +from PySide6.QtGui import QColor, QUndoCommand import pyzx _ROOT = os.path.abspath(os.path.dirname(__file__)) - def get_data(path: str) -> str: return os.path.join(os.environ.get("_MEIPASS", _ROOT), path) diff --git a/zxlive/proof_panel.py b/zxlive/proof_panel.py index e0f676b3..82095b26 100644 --- a/zxlive/proof_panel.py +++ b/zxlive/proof_panel.py @@ -18,7 +18,7 @@ from . import animations as anims from .base_panel import BasePanel, ToolbarSection -from .commands import AddRewriteStep, GoToRewriteStep, MoveNodeInStep +from .commands import AddRewriteStep, GoToRewriteStep, MoveNodeInStep, UndoableChange from .common import (ET, VT, GraphT, get_data, pos_from_view, pos_to_view, colors) from .dialogs import show_error_msg @@ -77,9 +77,16 @@ def __doubleClickHandler(self, index: QModelIndex | QPersistentModelIndex): new_name, ok = QInputDialog.getText( self, "Rename proof step", "Enter display name of proof step" ) + if ok: # Subtract 1 from index since the START step isn't part of the model - index.model().rename_step(index.row()-1, new_name) + old_name = self.proof_model.steps[index.row()-1].display_name + self.undo_stack.push(UndoableChange(self, + lambda: self.proof_model.rename_step(index.row()-1, old_name), + lambda: self.proof_model.rename_step(index.row()-1, new_name) + )) + + self.proof_model.rename_step(index.row()-1,new_name) def _toolbar_sections(self) -> Iterator[ToolbarSection]: icon_size = QSize(32, 32)