Przejdź do treści

Commands & menus

Commands

ICommandRegistry is the single execution funnel for every user-invocable action — menu items, toolbar buttons, shortcuts, and (later) Python scripts.

struct CommandDescriptor {
    std::string id;          // "helloworld.sayHi"
    std::string title;       // "Say Hi"
    std::string shortcut;    // portable: "Ctrl+Alt+H"
    std::string category;    // "Hello"
};

using CommandHandler = std::function<void()>;

class ICommandRegistry {
public:
    virtual CommandToken registerCommand(CommandDescriptor, CommandHandler) = 0;
    virtual void         invoke(std::string_view commandId) = 0;
    virtual bool         exists(std::string_view commandId) const = 0;
};

registerCommand returns a CommandToken (RAII). Destroying it removes the command, its menu entries, and its shortcut. Hold every token as a member so the whole plugin tears down automatically in shutdown().

Menu paths use / as the separator; the host creates intermediate submenus on demand:

class IMenuRegistry {
public:
    virtual MenuToken addItem(std::string menuPath, std::string commandId) = 0;
    virtual MenuToken addSeparator(std::string menuPath) = 0;
};
m_menu = ctx.menus().addItem("File/Export/As HTML...", "myplugin.exportHtml");

MenuToken is RAII like CommandToken.

Where a plugin's top-level menu sits is data-driven via the menus array in plugin.json — the host never hard-codes plugin menu names:

"menus": [
  { "title": "Plugins", "barPriority": 70, "itemPriority": 100 }
]
  • title — the top-level menu; matches the first /-separated segment of your menuPath.
  • barPriority — horizontal position on the menu bar (lower = further left). Core menus are fixed: File 10, Edit 20, View 40, Language 60, Window 80; plugins fill the gaps (Search 30, Encoding 50, Plugins 70).
  • itemPriority — vertical rank of this plugin's block within title (lower = higher up; default 1000). Items inside one plugin's block keep the order they are added in code.

Note

Because plugin.json is embedded as Qt plugin metadata, edits to it take effect only after a rebuild.