KDE UI Tutorial
Preface: Conventions
Step 0: Getting Started
Step 1: Initial Code
Step 2: Core Dump
Step 3: Line by Line
Step 4: Detail... Details..
Step 5: App Specific Details

Additional Notes
   Enabling/Disabling Actions
   State Changes
   Creating RMB Menus
   Configuring Action Properties
   Using KKeyDialog::configureKeys
   Adding Separators

Kurt Granroth <granroth@kde.org>

Enabling/Disabling Actions

Now that you've migrated to using KActions, you will find that enabling and disabling is much simpler: there's no need to remember all the places you need to disable/enable an item (especially when your action can be invoked from three different places, e.g., the toolbar, a menu and a RMB menu!).

There are two ways to disable or enable an action. The first way involves saving a pointer (you may decide to make this a data member so you can access it from different member functions):


 KAction *open_action =
   KStdAction::open(this, SLOT(file_open()), actionCollection()); 

 ...

 open_action->setEnabled(false);

The second way is to obtain a pointer just when you need it:


 KAction *open_action =
   actionCollection()->action(KStdAction::stdName(KStdAction::open)); 
 open_action->setEnabled(false);

But this can get tedious when you have a large number of KActions to deal with. For this you will want to use "application state changes".

State changes

State changes are a way to specify which actions should be enabled or disabled depending on which state the application is in ("new document created", or "document modified", or "user selected something"). These "states" are just free-form strings which you're free to define as you see fit. Here's an example :


<State name="file_changed">
  <enable>
    <Action name="file_save"/>
    <Action name="edit_undo"/>
  </enable>
</State>

<State name="have_selection">
  <enable>
    <Action name="edit_cut"/>
    <Action name="edit_copy"/>
  </enable>
  <disable>
    <Action name="edit_paste"/>
  </disable>
</State>

To use those states, you need to use KMainWindow::stateChanged() (inherited from KXMLGUIClient), like this :


stateChanged("file_changed");

This will enable both the 'file_save' and 'edit_undo' actions. KMainWindow::stateChanged() also accepts an optional 2nd argument which tells if the state must be "reversed", that is actions to enable will be disabled, and actions to disable will be enabled. For instance :


stateChanged("file_loaded", StateReverse);

will enable 'edit_paste' and disable 'edit_cut' and 'edit_copy'.

This method makes it much easier to deal with KAction enabling/disabling at the application level. There is also a KMainWindow::slotStateChanged() slot to which you can connect signals from other parts of your application.

Creating RMB Menus

To create a RMB (right-mouse-button) menu, you need to define the menu layout in the rc file. In the following example, we have the standard name for the Open File action, and the name of a KAction defined by the developer:


<Menu name="popup">
  <Action name="file_open"/> 
  <Action name="myaction"/>
</Menu>

The following code snippet shows how to invoke the popup menu, given a QPoint aPoint at which to pop it up:


 QPopupMenu *pop = (QPopupMenu *)factory()->container("popup", this); 
 pop->popup(aPoint);

Configuring Action Properties

Sometimes you may wish to configure how a standard action is manifested in your application. Here is an example snippet from an rc file showing you how to change the icon for the standard action New File:


<ActionProperties>
  <Action name="file_new" icon="my_new_icon"/> 
</ActionProperties>

Refer to the function KStdAction::stdName() in kdelibs/kdeui/kstdaction.cpp for a list of the names of standard actions.

Here's how to change the displayed text (this goes in the source code rather than the rc file so that the text can be properly internationalized):


  newAction = KStdAction::openNew(this, SLOT(file_new()), 
				  actionCollection());
  newAction->setText(i18n("New Foo"));

Using KKeyDialog::configureKeys

If you used a KAccel in your code and got rid of it only to find that you need a KAccel object to invoke KKeyDialog::configureKeys, the following code may help:


  KKeyDialog::configureKeys(actionCollection(), xmlFile()); 

Adding Separators

If you'd like to add an invisible separator to the toolbar or menubar, put this in the appropriate position in your XML file:


 <Separator/> 

For a visible separator, use this:


 <Separator lineSeparator="true"/> 


<< Prev Next >>