With the undo/redo feature, you can add capability to your application to undo various actions in the spreadsheet performed by your end user. You make use of the UndoAction class and several specific classes that correspond with those various user actions. There is also a manager class that keeps track of the end user actions that can be undone and re-done.
The SpreadView class and FpSpread class have properties, AllowUndo and UndoManager, which turn on and off the undo/redo feature and return the UndoManager for that SpreadView instance, respectively. Each SpreadView has its own UndoManager.
Action Assignment
The UndoAction class is an abstract class that inherits from Action and adds new methods to the class: Undo and SaveUndoState. It also inherits the PerformAction method from Action.
SaveUndoState is where you put code to save undo state information (in fields of the class). PerformAction is where you put code to do the action. Undo is where you put code to reverse the action (using the undo state information in the fields).
Each of the classes inheriting from UndoAction is designed to do one specific action (for example, edit a cell, resize a column, move a range, etc.), and to undo that action. All relevant information to do that action should be passed into the constructor for the object, and all relevant information to undo that action should be stored in the SaveUndoState implementation. Once the UndoAction object is created, the variables of that specific action are fixed (specified by the values passed to the constructor). For example, edit cell A1 in sheet1 and change the value to "test", resize column B to 24 pixels, move the range C4:F6 to A1:D:3, etc. And the action can only do that specific action in that specific way.
Managing the Actions
The UndoManager class manages the undo and redo stacks. It keeps track of which actions have been done and undone, and in what order. An UndoAction must be passed into the PerformUndoAction method of UndoManager to do the action in order for it to be undoable by the UndoManager. When that happens, the UndoManager pushes the UndoAction onto the undo stack and calls PerformAction on the UndoAction, and then the CanUndo method returns true (indicating there is something to undo). When CanUndo returns false, that means the undo stack is empty, and there is no action ready to undo. You might want to use this to disable the Undo menu item in the Edit menu, for example, if your application has Edit menu.
When an action is ready to undo, you can call Undo on the UndoManager, and it moves the last action performed from the undo stack to the redo stack, and call Undo on the action, and then the CanRedo method returns true (indicating there is something to redo).
When CanRedo returns false, that means the redo stack is empty, and there is no action ready to redo. You might want to use this to disable the Redo menu item in the Edit menu, for example, if your application has Edit menu.
When an action is ready to redo, you can call Redo on the UndoManager, and it moves the last action undone from the redo stack to the undo stack, and call PerformAction on the action, and the CanUndo method returns true.
You can call PerformAction on the UndoManager with a sequence of UndoAction objects, and it performs each of action in sequence, and remembers each action and the order in which they are done. Then you can call Undo to undo some of those actions, and each can be re-done with Redo (and then un-done again with Undo).
But, when you call PerformAction to perform a new action, if there are any actions pending in the redo stack, those actions are cleared, and CanRedo returns false (that is, once you perform a new action, you will not be able to redo any actions that you have undone with Undo). That is why the PushUndo method in the UndoManager class has a flag to indicate whether the redo stack should be cleared when the action is pushed onto the undo stack.
Some of the UndoAction classes will be replacing Action objects in the action maps, so that those actions are routed through the UndoManager and become undoable. Other UndoAction classes will not be part of the action maps, but instead are used in the SheetView or SpreadView code to make the action undoable.
Other API Updates
The input maps include new items to map the CTRL+Z and CTRL+Y keys to the new UndoAction and RedoAction action objects, respectively. These actions make calls into the UndoManager to the Undo and Redo methods, respectively.