Next: , Previous: The Context, Up: The Command Structure



7.3.2 Command Definitions

The command template is stored in the file gui/commands.c. The command structure is a tree-like hierarchical structure where each node has a list of subcommands (commands with nonempty lists are called command categories) and a pointer to the next command in the same category. The command definition structure is this:

     struct cmd
     {
         char * title;
         char * description;
         uns type;
         uns flags;
         char * icon_path;
         GdkPixbuf * icon_pixbuf;
         int accel;
         GdkModifierType modifier;
         union
         {
             struct
             {
                 uns request_mask;
                 int request_cnt;
                 uns request_type;
                 void (*modify_state_f)(struct cmd *, GtkWidget * widget);
                 void (*action_f)(void *);
             } func;
             struct
             {
                 struct of_state * of_state;
             } op;
             struct
             {
                 uns flags;
                 struct cmd * first;
                 struct cmd * selected;
             } ctg;
         } spec;
         struct cmd * parent;
         struct cmd * next;
     };

The type can be one of CT_FUNC, CT_FACTORY_OP, CT_CATEGORY, CT_SEPARATOR and defines which part of the union spec is used.

Function commands The function commands have type equal to CT_FUNC. They are the most common menu or toolbar items. They contain an action function action_f to be called, a context request defining when the function can be called (and the command enabled) and a modify_state_f function to modify the command state additionally. The command state (enabled, visible, checked, etc.) is stored in the flags bitmask together with the command location and other flags.

The command request consists of:

For example, consider the following command:

     { "Save", "Save the file", CT_FUNC, CL_UB_MENU | CL_VIEW_MENU | CS_VIS_EN,
        0, 0, GDK_S, GDK_CONTROL_MASK,
        { .func = { VTM_DOCUMENT | VTM_CT_DOC, 1, RT_META,
        NULL, &on_file_save } },
        NULL, &file_save_as_cmd };

It requests exactly one document (in the meta selection or in the context), is located in the Universe Browser menu and in the View menu, and is visible and enabled before the context evaluations take effect.

Context Match Evaluation and Command Execution When a command state needs to be evaluated, the command request is compared with the current context using the following function:

     int context_matches( struct cmd * cmd );

First, the context window, group, tlo and document are tried. If any of them satisfies the request, the conditions are fulfilled and the object will be passed as the void * argument of the command's action function action_f later when the command is executed. If it is not the case, the selection is tried (meta selection or selection within a group, depending on the request type). If neither the selection is suitable, then the context object (the last used object) is tried and if matches, it will later be passed as the void * argument of the action function. The selection is not passed as any argument; in case that the action function gets a NULL as the argument, it uses the selection.

After the evaluation of the context_matches function, the modify_state_f function is called (with the menu/tool item widget as an additional argument) to alter the command state according to some additional criteria.

To prevent possible errors, the context match is verified one more time, just before the command execution. It might happen that the menu or toolbar item has been activated but the request ceased to be fulfilled before the activation signals were distributed to our callbacks. Or the modify_state_f function just had violated the evaluated flags and re-enabled a disabled command. Both cases are detected with an additional context check and if the context does not match, the command execution is cancelled.

Factory Operation Commands These commands (with type equal to CT_FACTORY_OP) switch the GO Factory (see The GO Factory) into the given state stored in of_state. They have no context requests as the states of GO Factory commands are evaluated in a special way.

Categories Category commands (with type equal to CT_CATEGORY) are not actually commands, they are just branching nodes and have a list of subcommands (starting with first). They create submenus in menus, in toolbars, they are just expanded. In the View toolbar, some categories have their icons and can expand their contents into the right View toolbar.

The additional flags store the flags of the category contents.

Separators The separators have type equal to CT_SEPARATOR and represent separator menu items (invisible in toolbars).