This section describes the ViewKit ObjectPak undo manager, which supports reversing, or "undoing," actions.
The VkMenuUndoManager class is the basis of ObjectPak's undo manager. The ViewKit ObjectPak undo manager provides an easy-to-use method for users to undo commands that they issue to your application.
The user interface to the ObjectPak undo manager is a single menu item that you add to one of your application's menus. By default, the label of that menu item is "Undo: last_command", where last_command is the name of the last command the user issued. Whenever the user issues a command, the undo manager automatically updates the menu item to reflect the latest command. To undo the command, the user simply selects the undo manager's menu item.
By default, ObjectPak's undo manager provides multi-level undo support. The undo manager keeps commands on a stack. When the user undoes a command, the undo manager pops it from the stack, revealing the previously executed command. Once a user has undone at least one command, executing any new command clears the undo stack. Also, executing any non-undoable command clears the undo stack. If you choose, you can also force the undo manager to provide only single-level undo support, where it remembers only the last command the user issued.
You can use the undo manager to support undoing any command, regardless of whether the user issues the command through a menu or through other interface methods (for example, pushbuttons). The undo manager also supports undoing command classes as implemented by the VkAction(3) and VkMenuActionObject(3) classes described in "Command Classes" . In most cases, all you need to provide for each command is a callback function that reverses the effects of that command.
The programmatic interface to the undo manager is simple to use. Because the VkMenuUndoManager class is a subclass of VkMenuItem, you can add it to a menu and manipulate it as you would any other menu item.
To add undo support for an undoable menu item (VkMenuAction(3) and VkMenuToggle(3) items), simply provide an undo callback function (a function that reverses the effects of the item's action) when you either statically or dynamically define the menu item. Similarly, to add undo support for a command class (VkAction and VkMenuActionObject objects), you provide a member function to undo the effects of the command. For those action that are not implemented in your application as menu items or action classes, you can add undo callbacks directly to the undo stack.
Do not directly instantiate a VkMenuUndoManager object in your program. If you provide an undo callback to any menu item or if you use a subclass of VkAction or VkMenuActionObject in your program, ObjectPak automatically creates an instance of VkMenuUndoManager named "Undo". ("Command Classes" describes the VkAction and VkMenuActionObject classes.) The <Vk/VkMenuItem.h> header file provides theUndoManager, a global pointer to this instance. To access the ObjectPak undo manager, simply use this global pointer.1
You add the undo manager to a menu just as you would any other menu item: using the VkMenu::add() function of the menu object to which you want to add the undo manager. For example, the following line adds the undo manager to a menu pane specified by the variable edit:
edit->add(theUndoManager);
You cannot include the undo manager in a static menu description; however, you can add the undo manager to a statically-defined menu after creating the menu. To specify the position of the undo manager within the menu, include a position parameter when you add the undo manager. For example, the following line adds the undo manager to the top of a menu pane specified by the variable edit:
edit->add(theUndoManager, 0);
To add undo support for an undoable menu item (VkMenuAction and VkMenuToggle items), simply provide an undo callback function when you define the menu item. The undo callback function should reverse the effects of the item's action.
For example, the following static description describes a "Cut" menu item that executes the callback function cutCallback() when the user selects the item and undoCutCallback() when the user undoes the command:
Sometimes, you might want to provide undo support for an action not implemented as a menu item (for example, an action invoked by a pushbutton). ViewKit ObjectPak allows you to do this by adding the action directly to the undo stack using VkMenuUndoManager::add():
The name argument provides a name for the action to appear in the undo manager's menu item. The undoCallback argument must be an Xt-style callback function that the undo manager can call to undo the action. The undo manager passes the clientData argument to the undo callback function as client data when it invokes the callback. Following ObjectPak conventions as described in "Using Xt Callbacks with Components" , you should pass the this pointer as client data so that the callback function can retrieve the pointer, cast it to the expected component type, and call a corresponding member function.
Note: add() simply adds an action to the undo stack; it does not "register" a permanent undo callback for an action. Once the undo stack is cleared, the undo information for that action is deleted. If you later perform the action again and you want to provide undo support for that action, you must use add() again to add the action to the undo stack.
Example 30. shows a simple example of adding an action to the undo stack. The MyComponent constructor creates a pushbutton as part of its widget hierarchy and registers actionCallback() as the button's activation callback function. actionCallback(), in addition to performing an action, adds undoActionCallback() to the undo stack.
The ViewKit ObjectPak classes that support command classes, VkAction and VkMenuActionObject, both require you to override the pure virtual function undoit(), which the undo manager calls to undo an action implemented as a command class. "Command Classes" describes how to use VkAction and VkMenuActionObject to implement command classes.
By default, VkMenuUndoManager provides multi-level undo support. The undo manager keeps commands on a stack. When the user undoes a command, the undo manager pops it from the stack, revealing the previously executed command. Once a user has undone at least one command, executing any new command clears the undo stack. Also, executing any undoable command clears the undo stack.
Supporting multi-level undo in your application can be difficult. If you prefer to support undoing only the last command executed, you can change the behavior of the undo manager with the VkMenuUndoManager::multiLevel() function:
void multiLevel(Boolean flag)
If flag is FALSE, the undo manager remembers only the last command executed.
You can force the undo manager to clear its command stack with the VkMenuUndoManager::reset() function:
void reset()
You can examine the contents of the undo manager's command stack using VkMenuUndoManager::historyList():
VkComponentList *historyList()
historyList() returns a list of objects representing commands that have been executed and are available to be undone. Commands are listed in order of execution; the last command executed is the last item in the list. All of the objects in the list are subclasses of VkMenuItem. Commands added directly to the undo stack (as described in "Using the Undo Manager" ) or commands implemented as VkAction objects (as described in "Command Classes" ) appear as VkMenuActionStub objects. VkMenuActionStub is an empty subclass of VkMenuAction.
The label that the undo manager menu item displays is of the form Undo_label:Command_label. Undo_label is the value of the labelXmNlabelString resource of the undo manager. By default, this value is "Undo". You can change this string (for example, for a German-language app-defaults file) by providing a different value for the XmNlabelString resource. For example, you could set the resource as follows:
*Undo.labelString: Annul
Command_label is the label for the last executed command registered with the undo manager, determined as follows:
Example 31. shows an example of using the undo manager.