| Story Library |
The engine represents user-commands with subclasses of Story::CCmd. This base class defines a basic interface of Do(), Undo() and Redo(). Do() performs an action for the first time. Undo() reverses Do(). Redo() reverses Undo(). Clone() copies the command.
Redo() is not the same as repeating Do(); for example, if Do() imports a file, Redo() will not import it a second time and won't see changes made to the original file. Instead it will put back exactly the text which Undo() removed. To "Repeat" the previous command you would clone it and then execute Do() on the new object. That would see changes to the original file.
The Do() routine takes as argument a Story::CSelection, which will usually be the selection of the current layout. Most commands use this to figure out what text they are supposed to affect. Some commands, eg affecting the style sheet, make sense even when there is no layout or story. Story::CRoot::GetRootSelection() returns a special selection, attached to the root itself rather than a specific layout, which can be used in that case.
All changes to the story should be encapsulated by a command, so that they can be undone consistently. The engine provides an undo stack called Story::CCmdStack, which you can use if you want. It uses an open/close metaphor; several commands added in the same open block will be undone as a unit. PagePlus uses a small CCmdSession object to encapsulate the open and close with the Resource Acquisition is Initialisation pattern. The engine does not try to provide this class because its details will be application-specific.
Here is the current command hierarchy:
The Story::CCmdSelect command changes the current selection. It uses little objects of type Story::CSelecter to specify how the selection should be changed. For example:
new Story::CCmdSelect( new Story::CSelecterWordLeft, false, 2 ) );
The other commands all work with the selection in a similar way. They all start their Undo() by restoring the selection to the state it had when Do()/Redo() finished, and similarly they start Redo() by restoring it to the Undo() state. This common logic is implemented by Story::CCmdWithSelection.
Several commands overwrite the current selection (if any) with new text. Story::CCmdReplaceText implements the common logic of deleting the selected text in Do() and pretty much everything necessary for Undo() and Redo(), so that subclasses just have to provide the new text. They do that by overriding Story::CCmdReplaceText ImportAt().
Story::CCmdInsertToc and Story::CCmdInsertIndex replace the current selection with a "Table Of Contents" and an "Index" respectively, inferred by searching all stories for styles or indexing glyphs. This process is governed by Story::CTocAtts and Story::CIndexAtts. These are made separate objects so they can be stored with the document if desired.
Commands need to notify the application of what they have done. This is managed by the Story::CChangeSession class.
See also Command Classes, Keyboard, menu and mouse events.