Command - base class for command objects
#include <Unidraw/Commands/command.h>
Command is an abstract base class for objects that define
operations on components and other objects. Commands are similar to messages
in traditional object-oriented systems in that components can receive and
respond to them. Commands can also be executed in isolation to perform
arbitrary computation, and they can reverse the effects of such execution to
support undo.
Some commands (termed purely interpretive commands) are
interpreted by components but never executed in isolation, some are executed
but never interpreted (non-interpretive commands), and some are used
in both ways. Some commands may be directly accessible to the user through
menus, while others are internal to the application. In general, an undoable
operation should be carried out by a command object.
- virtual void
Execute()
- virtual void
Unexecute()
- virtual boolean
Reversible()
- Execute performs computation to carry out the command's semantics.
Unexecute performs computation to reverse the effects of a previous
Execute, based on whatever internal state the command maintains. A command
is responsible for maintaining enough state to reverse one Execute
operation; repeated Unexecute operations will not undo the effects of more
than one Execute.
By default, Execute examines the current selection maintained
in the command's editor (see below). Execute will do nothing if the
nothing is selected and the command's clipboard (see below) is empty or
non-existent. Otherwise, if something is selected and the command's
clipboard is non-existent, then Execute creates a clipboard containing
the selected component subjects. Finally, Execute will tell each
component on the command's clipboard to interpret this.
Conversely, Unexecute tells each component on the clipboard (if any) to
Uninterpret this this. Thus, commands are purely interpretive by
default.
It may not be meaningful or appropriate, however, for some
commands to reverse their effect. For example, it is probably not
feasible to undo a command that generates an external representation.
The Reversible operation returns whether or not the command is
unexecutable and uninterpretable. If the command is irreversible, then
it is ignored during the undo process. By default, Reversible examines
the command's clipboard; if the command doesn't have one, then the
command is reversible if the user has at least one component view
selected. If the command has a non-empty clipboard, then it is deemed
reversible. Subclasses may redefine Reversible to base the command's
reversibility on their own criteria.
- virtual void
Store(Component*, Data* = nil)
- virtual Data*
Recall(Component*)
- Since a command can affect more than one component, commands must let
components that interpret them store undo information somewhere. The
commands must also let components recall the information during
uninterpretation. Store lets a component store a Data object in the
command itself as part of the component's interpretation process. The
component can later retrieve the data with the Recall operation. Store and
Recall require a Component argument to distinguish requests from
potentially many components.
- virtual void
Log()
- A convenience function for calling the equivalent function on the global
unidraw object.
- virtual void
SetControlInfo(ControlInfo*)
- virtual void
SetEditor(Editor*)
- virtual void
SetClipboard(Clipboard*)
- virtual
ControlInfo* GetControlInfo()
- virtual Editor*
GetEditor()
- virtual
Clipboard* GetClipboard()
- Operations for setting and getting constructor-specified state stored in
the command. Commands use a ControlInfo object to store information from
which to build a user interface for executing the command. Commands keep a
pointer to the Editor instance they potentially affect. Finally, a command
uses a clipboard to store the components it affects or affected. A
clipboard containing the components to be affected can be supplied in the
constructor, but more often the command itself creates and primes a
clipboard based on the editor's selected components. The Set... operations
do not delete the object being replaced.
- virtual void
First(Iterator&)
- virtual void
Last(Iterator&)
- virtual void
Next(Iterator&)
- virtual void
Prev(Iterator&)
- virtual boolean
Done(Iterator)
- Operations for iterating over the command's children, if any. These
operations do nothing by default. Commands that compose other commands
should redefine these operations to permit traversal of their children.
First and Last initialize an iterator to point to the beginning and end of
the list of children, respectively. Next increments the iterator to point
to the following child, while Prev decrements the iterator to point to the
preceding child. Done returns whether or not the iterator points beyond
the first or last child in the list.
- virtual
Component* Copy()
- Return a copy of the command. Subclasses should redefine this operation to
return an instance of their type.
- virtual void
Read(istream&)
- virtual void
Write(ostream&)
- Read and write the command's contents to a stream to support catalog
operations. Read and write typically call first the corresponding
operations defined by their parent class, and then they read or write
their class-specific state. Note that you must ensure that the objects are
read in the same order they are written.
- virtual ClassId
GetClassId()
- virtual boolean
IsA(ClassId)
- GetClassId returns the unique class identifier for the Command subclass,
while IsA returns whether the instance is of a class or subclass
corresponding to the given identifier. IsA typically checks the given
identifier against the instance's own (as defined by its GetClassId
operation) and, failing that, calls its parent classes' IsA operation. All
subclasses must redefine GetClassId and IsA to ensure that their
identifiers are unique and that instances are written and read
properly.
- virtual ClassId
GetSubstId(const char*& delim)
- A Command subclasses can redefine GetSubstId to specify a command that can
substitute for it. This lets applications that do not define a particular
command subclass still read in a substitute that is compatible with the
subclass. The substitute class should be one of the predefined commands in
the Unidraw library. This guarantees that all applications can instantiate
the substitute.
GetSubstId returns the class identifier for the substitute.
When an another Unidraw application's catalog reads this object, it can
create an instance of the substitute (which it is guaranteed to define)
instead of the original (which it may not define).
The original should read and write a superset of the
substitute's data. The catalog will read to the end of the substitute's
data and then advance the stream to the point following the sequence of
characters specified by delim, saving the extra characters
between the two points in the stream. When the substitute object is
saved subsequently, the original class identifier will be written along
with the substitute's data plus the extra characters saved previously.
Thus information needn't be lost as a result of being read and written
by an unsophisticated application.
- Command(ControlInfo*,
Clipboard* = nil)
- Command(Editor*
= nil, Clipboard* = nil)
- The constructors are protected to prevent instatiation of the abstract
base class. You can supply a ControlInfo or Editor and an optional
clipboard. Only commands that will be accessible to the user need a
ControlInfo object. All commands should be given an editor object before
they are used.
- void
InitCopy(Command*)
- ControlInfo*
CopyControlInfo()
- Clipboard*
CopyClipboard()
- Clipboard*
DeepCopyClipboard()
- Convenience functions for use by subclasses in their Copy operation.
InitCopy gives this a copy of the given command's editor,
clipboard, and interpretation data stored by the components that
interpreted it, if any. CopyControlInfo and CopyClipboard return copies of
the command's ControlInfo and Clipboard objects, respectively, if they are
non-nil. Both CopyControlInfo and CopyClipboard simply check for a nil
argument before calling the corresponding Copy operations on the objects.
DeepCopyClipboard checks for a nil clipboard before calling DeepCopy on
the command's clipboard and returning the result.
- GraphicComp*
GetGraphicComp()
- A convenience function that returns the GraphicComp in the editor that the
command affects.
Catalog(3U), Clipboard(3U), ControlInfo(3U), Data(3U), Editor(3U),
GraphicComp(3U), Iterator(3U), Unidraw(3U), classes(3U), globals(3U),
istream(3C++), ostream(3C++)