1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Creator documentation.
7**
8** Commercial License Usage
9** Licensees holding valid commercial Qt licenses may use this file in
10** accordance with the commercial license agreement provided with the
11** Software or, alternatively, in accordance with the terms contained in
12** a written agreement between you and The Qt Company. For licensing terms
13** and conditions see https://www.qt.io/terms-conditions. For further
14** information use the contact form at https://www.qt.io/contact-us.
15**
16** GNU Free Documentation License Usage
17** Alternatively, this file may be used under the terms of the GNU Free
18** Documentation License version 1.3 as published by the Free Software
19** Foundation and appearing in the file included in the packaging of
20** this file. Please review the following information to ensure
21** the GNU Free Documentation License version 1.3 requirements
22** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
23**
24****************************************************************************/
25
26/*!
27    \page actionmanager.html
28    \title The Action Manager and Commands
29
30    \QC provides a central options page for managing shortcuts for actions in
31    \uicontrol Tools > \uicontrol Options > \uicontrol Environment >
32    \uicontrol Keyboard. Plugins must tell \QC about the actions they provide,
33    so they can appear in the options. Also some actions, like \uicontrol Edit >
34    \uicontrol Undo, need to be dispatched to different plugins depending on the
35    context which the user is currently in, for example a text editor, or
36    a UI design component. The Core::ActionManager and Core::Command classes
37    are used to manage this.
38
39    The action manager contains a list of Core::Command instances. Each command
40    represents an entry in the keyboard shortcut settings.
41
42    A command also manages which actual QAction is currently represented by the
43    command, depending on context. For this, a command has its own QAction which
44    is accessible via Core::Command::action(), and should be used when adding
45    the command to the UI like the menu and tool buttons. This QAction delegates
46    its \c triggered() and \c toggled() signals to the currently active QAction.
47
48    \image actionmanager.png
49
50    \section1 Command
51
52    The class Core::Command represents an action with a shortcut that can be
53    set by the user in the settings, and can be delegated to an actual
54    QAction in a plugin, depending on context.
55
56    A command is referred to by its unique ID. Plugins use the ID when
57    registering an action for the command in a specified context with
58    Core::ActionManager::registerAction(). That method returns a Core::Command
59    instance that is then used to further configure the action.
60    If multiple QActions are registered for the same command (the same ID),
61    they must be registered for different contexts.
62    The ID is also used for grouping in the options page: everything up to the
63    first dot in the ID is used as the category, under which to show the
64    command.
65
66    By default, the options page shows the text of the currently active QAction
67    in addition to the ID. If that does not fit the purpose well, you can set a
68    different display text with Core::Command::setDescription().
69
70    Use the command's Core::Command::setDefaultKeySequence() method to set the
71    default key sequence that is used if the user doesn't customize it.
72    The shortcut on the QAction that you register with
73    Core::ActionManager::registerAction() is never used, so do not set that.
74
75    Core::Command::action() returns the action that should be used for UI and
76    user interaction. Add this to menus and tool buttons. You should never
77    set properties like the enabled or visibility state on this QAction
78    directly. It is managed by the action manager and reflects the state of the
79    currently active QAction in some plugin.
80
81    The QAction that you registered in the action manager is for your internal
82    purposes. Use that to connect your logic to the QAction::triggered()
83    signal, and to set the enabled and visibility state.
84    Core::Command::action() will reflect these changes, if your QAction is
85    active, determined by the active context. For performance reasons the
86    action text, tool tip and icon are not updated by default. They are only
87    copied from the first QAction registered for the command. Set the
88    corresponding Core::Command::CommandAttribute if you need dynamic updates
89    of these properties.
90
91    \section1 Contexts
92
93    When plugins register a QAction for a command, they need to provide a
94    Core::Context. Which of the registered QActions for a command is currently
95    active is decided via an ordered list of current contexts.
96
97    Contexts are collected from multiple sources:
98
99    \list
100        \li Global context. This is a context that is always active, with lowest
101            priority order.
102        \li Application focus. Instances of QWidget can be associated to a
103            context via Core::IContext. All contexts from the current focus
104            widget up the widget hierarchy are added to the current context.
105        \li Manually managed contexts. Contexts can be added and removed
106            manually via ICore::updateAdditionalContexts().
107    \endlist
108
109    \section2 Using IContext
110
111    Core::IContext is a separate object that associates the QWidget from
112    Core::IContext::widget() with the context Core::IContext::context().
113
114    To associate a widget with a context, create a Core::IContext instance,
115    set the widget and context on it, and register it with
116    Core::ICore::addContextObject(). Whenever your widget is in the parent
117    chain of the application focus widget, the context that you specified
118    will be active as well.
119
120    \code
121    auto contextObj = new Core::IContext(this);
122    contextObj->setWidget(myWidget);
123    contextObj->setContext(myContext);
124    Core::ICore::addContextObject(contextObj);
125    \endcode
126
127    IContext instances are automatically unregistered when they are deleted.
128    Use Core::ICore::removeContextObject() if you need to unregister an IContext
129    instance manually.
130
131    Some constructs in \QC automatically have an associated context, like
132    Core::IEditor and Core::IMode.
133
134    \section2 Manually Managing Contexts
135
136    If you want a context to be active or inactive independently of the
137    application focus, you can add and remove contexts manually with
138    Core::ICore::updateAdditionalContexts(), Core::ICore::addAdditionalContext()
139    and Core::ICore::removeAdditionalContext().
140    Prefer Core::ICore::updateAdditionalContexts() if you need to remove and add
141    contexts, to avoid overhead introduced by removing and adding contexts
142    in separate calls.
143
144    \section1 Registering Actions
145
146    Prefer registering actions in your plugin's
147    ExtensionSystem::IPlugin::initialize() method. This way any plugin depending
148    on your plugin has access to these actions.
149
150    \code
151    namespace Constants {
152    const char ACTION_ID[] = "Example.Action";
153    } // Constants
154
155    bool ExamplePlugin::initialize(const QStringList &arguments, QString *errorString)
156    {
157        // some other setup ...
158
159        QAction *action = new QAction(tr("Example Action"), this);
160        Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID,
161                                                Core::Context(Core::Constants::C_GLOBAL));
162        cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A")));
163        connect(action, &QAction::triggered, this, [this] {
164            // do something
165        });
166
167        // more setup ...
168
169        return true;
170    }
171    \endcode
172
173    This snippet sets up a sample action with the ID \c ACTION_ID that is always
174    active (specified by the context \c {Core::Constants::C_GLOBAL}), and gives
175    it the keyboard shortcut \c {Ctrl+Alt+Meta+A}. The \c {QAction *action}
176    that is registered for the global context for the action is owned by the
177    plugin. Connect to this QAction's triggered signal, and manage the action's
178    state by calling the corresponding methods on this QAction instance.
179
180    \section1 Summary
181
182    \list
183        \li Use Core::ActionManager::registerAction() to register your own
184            QAction for a command with the specified ID.
185        \li If multiple QActions are registered for the same command, they need
186            to be registered for different contexts.
187        \li Use Core::Command::setDefaultKeySequence(), do \e not use
188            QAction::setShortcut().
189        \li Use Core::Command::action() for user-facing purposes, such as
190            menus and tool buttons.
191        \li Use your own QAction to set properties like text and icon, and to
192            connect your application logic.
193    \endlist
194*/
195