This page is partially outdated. See gui instead.

The src/editor directory contains 3 kinds of files: files which are part of a generic editing framework, and concrete implementation files, and view (widget) implementation files.

The generic editor framework

Note: The description here is partially outdated and invalid. The new documentation will be created in OpenDocument (odt) format. The used software here is IBM Lotus Symphony. The new documentation is available here: editor.odt. The Primitive-related parts are not finished yet.


The Document class stores and manages one firework root object. It has additional functionality what is not part of the data model. The Document manages the file on disk, undo history and a dictionary which contains every data object in the model.

Modifying the document

A Primitive is a command which does an "atomic change" in the document. For example, change the name of a particle template object or create a new particle template. A PrimitiveGroup is an ordered list of primitives which are always executed together. PrimitiveGroups execute the Primitives in them. A Command is a command that is visible to the user (like QAction) and can be performed for example by choosing a menu or pressing a toolbar button. The commands can be performed: this means (usually) create and execute a PrimitiveGroup. After execution the newly created PrimitiveGroup becomes a data part of the document and can be undone and re-executed.


A primitive is a "small change" in the document which can be done when the document is in a consistent state and leads to another consistent state. One instance of a Primitive is a concrete single change in the document. Performing this change is called execution of the primitive. Performing the change in the reverse direction is called undoing a primitive. After one primitive is executed it can only be undone, and after an undo it can only be executed. One primitive belongs to one document and is only applied on this document and only at a single fixed place in the document's undo history. A primitive receives at initialization parameters of the change what it does. After that it must be able to execute and undo itself without any other information.
  • state: A Primitive has 4 states:
    • incomplete - The initial state.
    • before_first - After preparation and before first execution.
    • after - After execution, before undo. In this state only undo can be called.
    • before - After undo, before execution. In this state only exec can be called.
There is a simple state diagram for this but the image for this is not ready yet. The state is managed internally and subclasses can not change it.
  • operations: These are called by other parts of the framework automatically. Every concrete primitive must provide implementation for these.
    • prepare_impl - Called as part of the prepare operation. This is called once before the first execution of the primitive. Here it receives arguments which tell parameters of the change (for example, a rename primitive can receive an id what to rename and a new name argument). The arguments are passed in an user-defined struct which must be derived from PrimitiveArgs.
    • exec_impl - Called to do the execution of the primitive.
    • undo_impl - Called to do the "undo-ation" of the primitive.
    • create_exec_doc_event - This should create and return a DocEvent which describes the change of the execution of this primitive. This will be automatically broadcasted to the views of the document. There is a default implementation which creates a generic event which means "something has changed", but it is not efficient to use this because then every view will redraw everything since they don't know the concrete change.
    • create_undo_doc_event - This should create and return a DocEvent which describes the change of the undo-ation of this primitive.

Primitives are always executed (and undone) as part of a PrimitiveGroup execution (or undo), but for a Primitive this should really be irrelevant. Every PrimitiveGroup what was applied to the document is stored in the document in a tree structure. This makes it possible to undo and redo every user command.


A PrimitiveGroup is a complete editor command which was performed by the user. It is always an instance of a concrete executed command with its concrete attributes. The concept is that the program does remember every action that the user did, so there is unlimited undo and redo possibility. The PrimitiveGroup is one such action, and the undo history consists of PrimitiveGroups. A PrimitiveGroup is an ordered list of primitives. It is needed to allow storage of user commands which consist of smaller reusable parts. (But often one PrimitiveGroup consists of just one Primitive.) It can be executed and undone similar to primitives. Execution means executing every primitive in it, and undoing means undoing every primitive in the reverse order. A PrimitiveGroup is only a generic container for primitives, but it does not create the primitives. (The primitives in it are added by the Command objects.)

Every PrimitiveGroup has a "description" property which explains the command to the user. This description will be shown in undo and redo menu items or command history widgets. It can be a generic description ("rename particle template") but it is better to have a concrete description ("rename particle template X to Y").

Normally PrimitiveGroups are created by the Command objects. The Command first creates an empty PrimitiveGroup, then sets its description with set_description(), then the Command creates and adds primitives to the group by calling add_and_exec(), then it must call finalize() on the PrimitiveGroup. After this the new group is already executed and added to the undo history in the document. The add_and_exec() function adds the primitive to the group and immediately executes it. This makes it possible to use the change done by a primitive as argument to the next primitive. The finalize() function is adding the group to the undo history. After this the group can be only undone and executed.

Last edited Dec 19, 2011 at 4:31 PM by fruitfruit, version 10


No comments yet.