Is this an acceptable approach to undo/redo in Python?

Posted by Codemonkey on Programmers See other posts from Programmers or by Codemonkey
Published on 2012-11-27T21:26:21Z Indexed on 2012/11/27 23:28 UTC
Read the original article Hit count: 256

Filed under:
|

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 do and undo. The 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. 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?

© Programmers or respective owner

Related posts about design

Related posts about python