Development/Architecture/KDE3/Action Pattern

    From KDE TechBase

    Introduction

    Creating a graphical user interface with the Qt/KDE3 development framework often means calling a lot of insertItem() and insertButton() like methods on all kinds of menu-, tool- and statusbar objects.

    This concept has two major disadvantages for dynamic ui's, where standard ui items get activated/deactivated, item texts or pixmaps get changed or certain elements get disabled, depending on the user's input and the application's data. With the standard framework there's a lot of unnecessary code duplication and complexity, regarding the handling of these elements.

    An often mentioned example are standard editing ui items, like "cut", "copy" and "paste". These items show up in multiple places in the ui, like in the toolbar, the "edit" menu in the menubar and in a context sensitive popup menu.

    From the programmer's point of view changing the state of "copy" (enable/disable for example) means calling methods of three ui container objects (menu, toolbar and popupmenu). And each time the same "thing" is added somewhere else in the application's ui, you have to go through the whole code and update any code which is supposed to change the "thing".

    Now from the user's point of view that "thing" is nothing but an action. An action he is able to activate (by activating the corresponding ui item), an action he has control over.

    The Action Concept in KDE

    For the user an action is one thing, for the developer it used to mean dealing with multiple ui container objects. The KDE Action classes centralize this scheme for the developer, too.

    The developer allocates a KAction object and connects to the activation signal of the object, which gets emitted whenever the user decides to activate the action.

    Now this action object can be plugged into any kind of ui container object, like a QMenuBar or a KToolBar for example. The process of plugging in the object is the same for all container types, it's just calling the plug() method. The action object then automatically takes care of inserting "itself" into the container object and therefore creates a visual representation of the action, like a menu item or a toolbar button, which the user is able to activate, select or choose, for example, depending on the type of action.

    The point is that an action object can be plugged into multiple container objects at the same time. Of course changing a property of an action, like the displayed text for example, results in an immediate change in all plugged containers.

    The Action Classes

    The KDE UI library provide action class implementations for most ui container classes and most kinds of ui items (from a simple item to a list of items or toggle items for example).

    When no action class is available for a certain ui container type or kind of item, then you should simply inherit from the nearest action class available and re-implement the virtual plug()/unplug() methods and the property setting methods (like setText() for example).

    When inheritting from an action class, don't forget to call the previous implementation!

    Initial Author: Simon Hausmann