Merging KParts Actions Without Duplicates
I embedded a part and ended up with two Edit menus, three separators, and no obvious place to put Find. Every individual action worked. Their diplomacy was lacking.
KParts uses XMLGUI to merge the shell’s actions with the active part’s actions. The shell supplies a main XML resource, the part supplies its own, and named menu locations and merge points tell the GUI factory where contributions belong. The names, not their visual positions, form the contract.
A part can declare an action and place it into a standard menu:
<!DOCTYPE kpartgui>
<kpartgui name="note_part" version="1">
<MenuBar>
<Menu name="edit"><text>Edit</text>
<Action name="note_find"/>
</Menu>
</MenuBar>
</kpartgui>
The C++ action collection must use the same action name:
KAction *find = new KAction(i18n("Find"), "find", CTRL + Key_F,
this, SLOT(slotFind()),
actionCollection(), "note_find");
If the XML name and action-collection name differ, the merge cannot place the action. If the part invents a menu name that the shell does not recognize, it may create a second menu instead of contributing to the first. I now compare the shell and part resource files side by side before touching C++.
Activation matters too. A shell hosting several parts should add the active client’s GUI and remove or replace it when focus moves. Leaving an old client registered explains actions that continue targeting a document no longer visible. I test by switching parts repeatedly, not just by opening one and closing the program.
Versioning the XML resource helps installed updates replace cached expectations, but it does not excuse stale files in the wrong prefix. When changes appear to be ignored, I inspect the paths reported by kde-config, remove obsolete application-owned resources, and rebuild the service cache if appropriate.
Action state remains the part’s responsibility. When a read-only document becomes active, its Cut action should be disabled before the GUI is merged, and selection changes should update it afterward. The shell should not infer document capabilities from menu names. It hosts the action; the part knows whether invoking it makes sense.
For debugging, I temporarily give each contribution an unmistakable label and watch the terminal for XMLGUI warnings. Once placement is correct, I restore the proper translated text. This is faster than deciding which of two identical separators came from which file.
I prefer a small part resource that contributes document-specific actions while the shell owns window actions such as New Window and Quit. The caveat is that the boundary requires discipline: an action should live where its state and target live. Otherwise XMLGUI can merge the menu perfectly and still dispatch Find to yesterday’s document, which is technically impressive but not helpful.