Extensible context menus
Jakob Petsovits
jpetso at gmx.at
Mon Mar 10 12:19:15 UTC 2008
On Saturday, 8. March 2008, Andreas Pakulat wrote:
> Hi,
>
> the recent mail from David (thanks for kicking me) made me think again
> about how we currently provide extensible context menu.
>
> Currently each plugin can contribute by overriding a virtual method and
> then provide a name and list of actions, which results in a submenu
> entry in the context menu that has the given name as title.
>
> Now this works quite well for plugins that only need to be in "their
> own" group, however there are some plugins for which it makes a lot of
> sense to have multiple groups. One example is the project management
> view, this plugin should provide renaming/moving files in a project, as
> well as building and configuring a project. And the former actions are
> pretty much separate from the building and should be in a submenu like
> "refactor" as thats really what it does.
>
> So I'm currently trying to think about how we get really extendable
> context menus, where a plugin can contribute to existing submenus as
> well as top-level menu items and its own new submenu.
>
> Something that came to my mind is having a small structure like:
>
> class ContextMenuContribution
> {
>
> public:
> /** user visible string for the submenu */
> QString subMennuName();
> /** id to uniquely identify the submenu */
> QString subMenuId();
> /** list of actions to append to the submenu */
> QList<QAction*> actions();
> };
>
> And then a plugin would simply return a list of such instances. We could
> either have an id of "ContextMenu" for adding the actions to the context
> menu, or use an empty id to do that.
>
> One problem I see with this is order of actions. Basically the order of
> the actions might change after each start of kdevelop, as other plugins
> might get loaded that might contribute to an already populated menu.
> Ideas how to solve that?
The classic Drupal influenced mindset's approach: weights.
class ContextMenuContribution
{
public:
...
virtual int subMenuWeight() { return 0; }
...
}
Then sort all menus by weight (for example, -20 as first sub-menu, 0 as second
one, 17 as third one) and you've got a persistent order - assuming that
plugins try to keep their weights reasonable in comparison to other modules.
If a ContextMenuContribution is supposed to be used in multiple contexts, that
context (QString uniqueContextIdentifier?) would probably need to be passed
as parameter for the weight method.
More information about the KDevelop-devel
mailing list