I'm making an application (wxPython) to process some data from Excel documents. I want the user to be able to undo and redo actions, even gigantic actions like processing the contents of 10 000 cells simultaneously. I Googled the topic, and all the solutions I could find involves a lot of black magic or is overly complicated.
Here is how I imagine my simple undo/redo scheme. I write two classes - one called
ActionStack and an abstract one called
Action. Every "undoable" operation must be a subclass of
Action and define the methods
Action subclass is passed the instance of the "document", or data model, and is responsible for committing the operation and remembering how to undo the change.
Now, every document is associated with an instance of the
ActionStack maintains a stack of actions (surprise!). Every time actions are undone and new actions are performed, all undone actions are removed for ever. The
ActionStack will also automatically remove the oldest
Action when the stack reaches the configurable maximum amount.
I imagine the workflow would produce code looking something like this:
class TableDocument(object): def __init__(self, table): self.table = table self.action_stack = ActionStack(history_limit=50) # ... def delete_cells(self, cells): self.action_stack.push( DeleteAction(self, cells) ) def add_column(self, index, name=''): self.action_stack.push( AddColumnAction(self, index, name) ) # ... def undo(self, count=1): self.action_stack.undo(count) def redo(self, count=1): self.action_stack.redo(count)
Given that none of the methods I've found are this simple, I thought I'd get the experts' opinion before I go ahead with this plan. More specifically, what I'm wondering about is - are there any glaring holes in this plan that I'm not seeing?