John Anderson wrote:
I was hoping, someday, to have the commit point be the unit of undo, e.g. if you did a delete, you'd commit after the operation. Of course this requires the ability to roll back changes to previous commit points, which doesn't yet exist. Personally, I think that trying to tie Undo transactions to repository transactions is going to land us in a heap of trouble. I'm all for thinking of Undo-able actions as a series of repository changes, but there is a disconnect between what the user probably considers "undoable" events and what the repository considers uncommittable. Here are a few scenarios that I think would cause us trouble if we were to tie undo points directly to calls to commit()/uncommit(). I'm using the term "undoable change" to be a user-comprehensible change, such as deleting an event or changing data in the detail view - one that the user would consider "undoable" by selecting Edit->Undo. I'm using the term "uncommit" to refer to playing back a series of changes in reverse order - this may or may not mean simply rolling back, as you'll see below. Scenario 1: an undoable change may actually span multiple commits A user makes an undoable change that causes commit() to be called three times just because of the codepath it follows happens to have an extra commit() or two.. (maybe it goes through sharing and that causes some repository view manipulation) Now any sort of "Undo" command would have to be run three times to uncommit that single user action Scenario 2: A user manipulates the UI after making an undoable change A user makes an undoable change, and then clicks on another collection. Thanks to CPIA, changes in the UI are also changes in the repository. This means that "Undo" operation might actually just cause the user to switch back to their preview collection. It would take a 2nd Undo operation to actually "undo" the original change. Scenario 3: Some changes might occur in different repository views A user makes an undoable change, and that change may cause changes in multiple views - i.e. sharing. What exactly do we "undo" when we uncommit? Personally, I think we need to be very explicit about undoable changes. I think we need to bracket such changes with some sort of begin/end undoable transaction mechanism. We can still exploit all the benefits of the repository though - for instance: 1) an undoable transaction might just be a pair of repository version numbers - and we just play back all the changes backwards from the newest version to the oldest. (i..e even if we're at version 103, the previous undoable change might be from revision 100 to 101, so we'd just play the changes backwards between 101 and 100) 2) notifications would fire when we play back the changes, so the UI would (hopefully) stay up to date 3) perhaps we could even look ahead at the changes to be played back, to see if an undo operation is even valid. (i.e. if it might cause conflicts or something) 4) Redo support would be easy - even multiple redo support like in Word/etc. An explicit Undo mechanism gives us another advantage: we could assign user-visible names to the undo actions.. and then we could display that user-visible name in the edit menu, so it might say "Undo Cut" instead of just "Undo" Here's an example of this system in action: UndoManager.BeginTransaction(_(u"Cut")) self.CutSomething() UndoManger.EndTransaction() Maybe there's even a more pythonic way to handle this: UndoManager.DoTransaction(_(u"Cut"), self.CutSomething) Alec
|
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Open Source Applications Foundation "Dev" mailing list http://lists.osafoundation.org/mailman/listinfo/dev
