diff --git a/doc/qtcreatordev/images/actionmanager.png b/doc/qtcreatordev/images/actionmanager.png new file mode 100644 index 00000000000..0c2a954eed6 Binary files /dev/null and b/doc/qtcreatordev/images/actionmanager.png differ diff --git a/doc/qtcreatordev/images/actionmanager.qmodel b/doc/qtcreatordev/images/actionmanager.qmodel new file mode 100644 index 00000000000..f8c56fe1b3a --- /dev/null +++ b/doc/qtcreatordev/images/actionmanager.qmodel @@ -0,0 +1,854 @@ + + + + {f7c67e69-57c5-4eb1-9303-f12bb2ae0a23} + + + + + + + + {9a360a3d-a5ff-4fa0-9a86-540d2cbdfa28} + + + actionmanager + + + + + + + {6f6e0572-b8cc-4d97-95c5-edae83d0a3d2} + + + + + + + + + + {6f6e0572-b8cc-4d97-95c5-edae83d0a3d2} + + + actionmanager + + + + + + + + + + + + {0a2e2d40-ad38-4b91-b9c1-6af2e3d2cf95} + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + ActionManager + x:300;y:90 + x:-50;y:-15;w:100;h:30 + 0 + 1 + + + false + + + + + + + + + + + {d918082a-dd32-48b8-bdcb-21ade3c1d067} + + + {a3950ef4-9fd9-466f-a575-dc75790749c3} + QAction + x:125;y:340 + x:-30;y:-15;w:60;h:30 + 0 + + + false + + + + + + + + + {d197d1e0-23ef-4041-845f-27c65fe11b70} + + + Context + x:125;y:335 + x:-50;y:-40;w:100;h:80 + + + + + + + + + {613641ea-8fec-4b44-890b-8c6ea42eb9eb} + + + Plugin + x:125;y:330 + x:-65;y:-70;w:130;h:140 + + + + + + + + + + + {c9758c28-e527-4f1b-b911-9c4f7571571c} + + + {ac06f227-7618-422e-a87e-5913950c91d7} + QAction + x:275;y:340 + x:-30;y:-15;w:60;h:30 + 0 + + + false + + + + + + + + + + + {d87082a8-6b2b-404f-abd3-9082585166f4} + + + {0cc14318-53df-4193-8aeb-0d29d4cd1561} + QAction + x:405;y:340 + x:-30;y:-15;w:60;h:30 + 0 + + + false + + + + + + + + + {168c5e3d-54bc-412c-9cb1-9b5481100f2b} + + + Context + x:275;y:335 + x:-50;y:-40;w:100;h:80 + + + + + + + + + {3447fe60-8ac5-4fe9-b518-80daba7e960a} + + + Context + x:405;y:335 + x:-50;y:-40;w:100;h:80 + + + + + + + + + {fcf93e87-8ce6-43ea-ab5e-7ca651d1f429} + + + Plugin + x:340;y:335 + x:-135;y:-70;w:270;h:140 + + + + + + + + + + + {8df1e5cf-5e76-453a-ba69-0fcf31f46d4e} + + + {68e762c3-f1cc-479b-9700-bdb01f208340} + Command + x:195;y:180 + x:-40;y:-35;w:80;h:70 + 0 + + + true + + + + + + + + + + + {a4401c84-57c3-4f34-a88d-f35e28239944} + + + {42259fbc-5917-4caf-836e-0828a032d908} + {0a2e2d40-ad38-4b91-b9c1-6af2e3d2cf95} + {8df1e5cf-5e76-453a-ba69-0fcf31f46d4e} + + + + + + + + + + + + + {7ff85acd-0d85-4fe2-8cc9-d0511f96443c} + + + {39911558-001e-4d0b-9827-d1d372049e86} + Command + x:405;y:180 + x:-40;y:-35;w:80;h:70 + 0 + + + true + + + + + + + + + + + {815d855b-8814-4ac7-8b75-17c3adb45344} + + + {fa3943f6-6bf7-4040-acae-d04c880fb329} + {0a2e2d40-ad38-4b91-b9c1-6af2e3d2cf95} + {7ff85acd-0d85-4fe2-8cc9-d0511f96443c} + + + + + + + + + + + + + {f4567b84-e58c-4212-8d0b-c7040c00639a} + + + {8d18c30e-51c8-4fa2-ad22-ad6962273120} + {8df1e5cf-5e76-453a-ba69-0fcf31f46d4e} + {d918082a-dd32-48b8-bdcb-21ade3c1d067} + + + + + + + + + + + + + {df1469a1-91d8-4c05-8b19-fddffbfc05d6} + + + {8d11e47d-b745-4bf4-b7d2-eb042c307ddf} + {8df1e5cf-5e76-453a-ba69-0fcf31f46d4e} + {c9758c28-e527-4f1b-b911-9c4f7571571c} + + + + + + + + + + + + + {b6288087-3aca-4e28-988c-c11ca3def425} + + + {9f1e7858-c06c-4c7c-97d6-209d3c96360f} + {7ff85acd-0d85-4fe2-8cc9-d0511f96443c} + {d87082a8-6b2b-404f-abd3-9082585166f4} + + + + + + + + + + + + + {ee71f328-354b-4993-8a63-8f4605285440} + + + {158de17f-753a-4b00-8ddf-2f4432871d07} + Menu + x:100;y:190 + x:-25;y:-15;w:50;h:30 + 0 + 1 + + + false + + + + + + + + + {5b8fc43d-fb36-4523-ac54-4262dc0affce} + + + x:270;y:190 + x:-205;y:-20;w:410;h:40 + + + + + + 1586427331500 + General + + + + + + + + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + + + + + + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + + + ActionManager + + + + + + + {d5111c81-0745-4724-8d01-8ac36994e31c} + + + + + + + + {d5111c81-0745-4724-8d01-8ac36994e31c} + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + {c2d3f5b7-87c5-4f67-9911-96a4a251ddd5} + + + + + + + + + + {6308a511-1fd1-472d-bdc2-0bf173c6850c} + + + + + + + + {6308a511-1fd1-472d-bdc2-0bf173c6850c} + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + {d6694b35-bb04-4830-9713-99470b22b7d7} + + + + + + + + + + {42259fbc-5917-4caf-836e-0828a032d908} + + + + + + + + {42259fbc-5917-4caf-836e-0828a032d908} + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + {68e762c3-f1cc-479b-9700-bdb01f208340} + + + + + + + + + + {fa3943f6-6bf7-4040-acae-d04c880fb329} + + + + + + + + {fa3943f6-6bf7-4040-acae-d04c880fb329} + + + {0fa7cf39-5531-4f41-9e2f-d890ef2a248d} + {39911558-001e-4d0b-9827-d1d372049e86} + + + + + + + + + + + + + + + + + + + + + {c2d3f5b7-87c5-4f67-9911-96a4a251ddd5} + + + + + + + + {c2d3f5b7-87c5-4f67-9911-96a4a251ddd5} + + + Command + + + + + + + {e5b7a324-70ab-46b9-8d36-9f2ad6c0db57} + + + + + + + + {e5b7a324-70ab-46b9-8d36-9f2ad6c0db57} + + + {c2d3f5b7-87c5-4f67-9911-96a4a251ddd5} + {a3950ef4-9fd9-466f-a575-dc75790749c3} + + + + + + + + + + {703dd2bc-f99c-41b7-8f90-a7292645feb8} + + + + + + + + {703dd2bc-f99c-41b7-8f90-a7292645feb8} + + + {c2d3f5b7-87c5-4f67-9911-96a4a251ddd5} + {ac06f227-7618-422e-a87e-5913950c91d7} + + + + + + + + + + + + + + + + + + + + + {d6694b35-bb04-4830-9713-99470b22b7d7} + + + + + + + + {d6694b35-bb04-4830-9713-99470b22b7d7} + + + Command + + + + + + + {4dc1c5bd-a124-4961-ad65-476e66cb6efe} + + + + + + + + {4dc1c5bd-a124-4961-ad65-476e66cb6efe} + + + {d6694b35-bb04-4830-9713-99470b22b7d7} + {0cc14318-53df-4193-8aeb-0d29d4cd1561} + + + + + + + + + + + + + + + + + + + + + {a3950ef4-9fd9-466f-a575-dc75790749c3} + + + + + + + + {a3950ef4-9fd9-466f-a575-dc75790749c3} + + + QAction + + + + + + + + + + {ac06f227-7618-422e-a87e-5913950c91d7} + + + + + + + + {ac06f227-7618-422e-a87e-5913950c91d7} + + + QAction + + + + + + + + + + {0cc14318-53df-4193-8aeb-0d29d4cd1561} + + + + + + + + {0cc14318-53df-4193-8aeb-0d29d4cd1561} + + + QAction + + + + + + + + + + {68e762c3-f1cc-479b-9700-bdb01f208340} + + + + + + + + {68e762c3-f1cc-479b-9700-bdb01f208340} + + + Command + + + + + + + {8d18c30e-51c8-4fa2-ad22-ad6962273120} + + + + + + + + {8d18c30e-51c8-4fa2-ad22-ad6962273120} + + + {68e762c3-f1cc-479b-9700-bdb01f208340} + {a3950ef4-9fd9-466f-a575-dc75790749c3} + + + + + + + + + + {8d11e47d-b745-4bf4-b7d2-eb042c307ddf} + + + + + + + + {8d11e47d-b745-4bf4-b7d2-eb042c307ddf} + + + {68e762c3-f1cc-479b-9700-bdb01f208340} + {ac06f227-7618-422e-a87e-5913950c91d7} + + + + + + + + + + + + + + + + + + {5d8da03d-d556-4eed-ae0d-6d306453496e} + 1 + QAction + + + + + + + + + + + + {39911558-001e-4d0b-9827-d1d372049e86} + + + + + + + + {39911558-001e-4d0b-9827-d1d372049e86} + + + Command + + + + + + + {9f1e7858-c06c-4c7c-97d6-209d3c96360f} + + + + + + + + {9f1e7858-c06c-4c7c-97d6-209d3c96360f} + + + {39911558-001e-4d0b-9827-d1d372049e86} + {0cc14318-53df-4193-8aeb-0d29d4cd1561} + + + + + + + + + + + + + + + + + + {2d428a77-4751-4fa7-bbb7-7f58995da129} + 1 + QAction + + + + + + + + + + + + {158de17f-753a-4b00-8ddf-2f4432871d07} + + + + + + + + {158de17f-753a-4b00-8ddf-2f4432871d07} + + + Menu + + + + + + + + + + + + + + + + + + diff --git a/doc/qtcreatordev/src/actionmanager.qdoc b/doc/qtcreatordev/src/actionmanager.qdoc new file mode 100644 index 00000000000..194d0eefdff --- /dev/null +++ b/doc/qtcreatordev/src/actionmanager.qdoc @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Creator documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \page actionmanager.html + \title The Action Manager and Commands + + \QC provides a central options page for managing shortcuts for actions in + \uicontrol Tools > \uicontrol Options > \uicontrol Environment > + \uicontrol Keyboard. Plugins must tell \QC about the actions they provide, + so they can appear in the options. Also some actions, like \uicontrol Edit > + \uicontrol Undo, need to be dispatched to different plugins depending on the + context which the user is currently in, for example a text editor, or + a UI design component. The Core::ActionManager and Core::Command classes + are used to manage this. + + The action manager contains a list of Core::Command instances. Each command + represents an entry in the keyboard shortcut settings. + + A command also manages which actual QAction is currently represented by the + command, depending on context. For this, a command has its own QAction which + is accessible via Core::Command::action(), and should be used when adding + the command to the UI like the menu and tool buttons. This QAction delegates + its \c triggered() and \c toggled() signals to the currently active QAction. + + \image actionmanager.png + + \section1 Command + + The class Core::Command represents an action with a shortcut that can be + set by the user in the settings, and can be delegated to an actual + QAction in a plugin, depending on context. + + A command is referred to by its unique ID. Plugins use the ID when + registering an action for the command in a specified context with + Core::ActionManager::registerAction(). That method returns a Core::Command + instance that is then used to further configure the action. + If multiple QActions are registered for the same command (the same ID), + they must be registered for different contexts. + The ID is also used for grouping in the options page: everything up to the + first dot in the ID is used as the category, under which to show the + command. + + By default, the options page shows the text of the currently active QAction + in addition to the ID. If that does not fit the purpose well, you can set a + different display text with Core::Command::setDescription(). + + Use the command's Core::Command::setDefaultKeySequence() method to set the + default key sequence that is used if the user doesn't customize it. + The shortcut on the QAction that you register with + Core::ActionManager::registerAction() is never used, so do not set that. + + Core::Command::action() returns the action that should be used for UI and + user interaction. Add this to menus and tool buttons. You should never + set properties like the enabled or visibility state on this QAction + directly. It is managed by the action manager and reflects the state of the + currently active QAction in some plugin. + + The QAction that you registered in the action manager is for your internal + purposes. Use that to connect your logic to the QAction::triggered() + signal, and to set the enabled and visibility state. + Core::Command::action() will reflect these changes, if your QAction is + active, determined by the active context. For performance reasons the + action text, tool tip and icon are not updated by default. They are only + copied from the first QAction registered for the command. Set the + corresponding Core::Command::CommandAttribute if you need dynamic updates + of these properties. + + \section1 Contexts + + When plugins register a QAction for a command, they need to provide a + Core::Context. Which of the registered QActions for a command is currently + active is decided via an ordered list of current contexts. + + Contexts are collected from multiple sources: + + \list + \li Global context. This is a context that is always active, with lowest + priority order. + \li Application focus. Instances of QWidget can be associated to a + context via Core::IContext. All contexts from the current focus + widget up the widget hierarchy are added to the current context. + \li Manually managed contexts. Contexts can be added and removed + manually via ICore::updateAdditionalContexts(). + \endlist + + \section2 Using IContext + + Core::IContext is a separate object that associates the QWidget from + Core::IContext::widget() with the context Core::IContext::context(). + + To associate a widget with a context, create a Core::IContext instance, + set the widget and context on it, and register it with + Core::ICore::addContextObject(). Whenever your widget is in the parent + chain of the application focus widget, the context that you specified + will be active as well. + + \code + auto contextObj = new Core::IContext(this); + contextObj->setWidget(myWidget); + contextObj->setContext(myContext); + Core::ICore::addContextObject(contextObj); + \endcode + + You also have to unregister the IContext object with + Core::ICore::removeContextObject() when you do not need it anymore. + + Some constructs in \QC automatically have an associated context, like + Core::IEditor and Core::IMode. + + \section2 Manually Managing Contexts + + If you want a context to be active or inactive independently of the + application focus, you can add and remove contexts manually with + Core::ICore::updateAdditionalContexts(), Core::ICore::addAdditionalContext() + and Core::ICore::removeAdditionalContext(). + Prefer Core::ICore::updateAdditionalContexts() if you need to remove and add + contexts, to avoid overhead introduced by removing and adding contexts + in separate calls. + + \section1 Registering Actions + + Prefer registering actions in your plugin's + ExtensionSystem::IPlugin::initialize() method. This way any plugin depending + on your plugin has access to these actions. + + \code + namespace Constants { + const char ACTION_ID[] = "Example.Action"; + } // Constants + + bool ExamplePlugin::initialize(const QStringList &arguments, QString *errorString) + { + // some other setup ... + + QAction *action = new QAction(tr("Example Action"), this); + Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, + Core::Context(Core::Constants::C_GLOBAL)); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); + connect(action, &QAction::triggered, this, [this] { + // do something + }); + + // more setup ... + + return true; + } + \endcode + + This snippet sets up a sample action with the ID \c ACTION_ID that is always + active (specified by the context \c {Core::Constants::C_GLOBAL}), and gives + it the keyboard shortcut \c {Ctrl+Alt+Meta+A}. The \c {QAction *action} + that is registered for the global context for the action is owned by the + plugin. Connect to this QAction's triggered signal, and manage the action's + state by calling the corresponding methods on this QAction instance. + + \section1 Summary + + \list + \li Use Core::ActionManager::registerAction() to register your own + QAction for a command with the specified ID. + \li If multiple QActions are registered for the same command, they need + to be registered for different contexts. + \li Use Core::Command::setDefaultKeySequence(), do \e not use + QAction::setShortcut(). + \li Use Core::Command::action() for user-facing purposes, such as + menus and tool buttons. + \li Use your own QAction to set properties like text and icon, and to + connect your application logic. + \endlist +*/ diff --git a/doc/qtcreatordev/src/creating-plugins.qdoc b/doc/qtcreatordev/src/creating-plugins.qdoc index 9b736b0c517..5a8bf7905dc 100644 --- a/doc/qtcreatordev/src/creating-plugins.qdoc +++ b/doc/qtcreatordev/src/creating-plugins.qdoc @@ -63,6 +63,7 @@ \list \li \l{The Plugin Manager, the Object Pool, and Registered Objects} + \li \l{The Action Manager and Commands} \omit \li \l{Aggregations} \li \l{Extending and Providing Interfaces}