1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org>
4 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
5 SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef _KGLOBALACCEL_H_
11#define _KGLOBALACCEL_H_
12
13#include "kglobalshortcutinfo.h"
14#include <kglobalaccel_export.h>
15
16#include <QKeySequence>
17#include <QList>
18#include <QObject>
19
20class QAction;
21class OrgKdeKglobalaccelComponentInterface;
22
23/**
24 * @short Configurable global shortcut support
25 *
26 * KGlobalAccel allows you to have global accelerators that are independent of
27 * the focused window. Unlike regular shortcuts, the application's window does not need focus
28 * for them to be activated.
29 *
30 * @see KKeyChooser
31 * @see KKeyDialog
32 */
33class KGLOBALACCEL_EXPORT KGlobalAccel : public QObject
34{
35 Q_OBJECT
36
37public:
38 /**
39 * An enum about global shortcut setter semantics
40 */
41 enum GlobalShortcutLoading {
42 /// Look up the action in global settings (using its main component's name and text())
43 /// and set the shortcut as saved there.
44 /// @see setGlobalShortcut()
45 Autoloading = 0x0,
46 /// Prevent autoloading of saved global shortcut for action
47 NoAutoloading = 0x4,
48 };
49
50 /**
51 * Index for actionId QStringLists
52 */
53 enum actionIdFields {
54 ComponentUnique = 0, //!< Components Unique Name (ID)
55 ActionUnique = 1, //!< Actions Unique Name(ID)
56 ComponentFriendly = 2, //!< Components Friendly Translated Name
57 ActionFriendly = 3, //!< Actions Friendly Translated Name
58 };
59
60 /**
61 * Keysequence match semantics.
62 *
63 * Assuming we have an Emacs-style shortcut, for example (Alt+B, Alt+F, Alt+G) already assigned,
64 * how a new shortcut is compared depends on which value of the enum is used:
65 * @c Equal : Exact matching: (Alt+B, Alt+F, Alt+G)
66 * @c Shadows : Sequence shadowing: (Alt+B, Alt+F), (Alt+F, Alt+G)
67 * @c Shadowed : Sequence being shadowed: (Alt+B, Alt+F, Alt+G, <any key>), (<any key>, Alt+B, Alt+F, Alt+G)
68 *
69 * @since 5.90
70 */
71 enum MatchType {
72 Equal,
73 Shadows,
74 Shadowed,
75 };
76 Q_ENUM(MatchType)
77
78 /**
79 * Returns (and creates if necessary) the singleton instance
80 */
81 static KGlobalAccel *self();
82
83 /**
84 * Take away the given shortcut from the named action it belongs to.
85 * This applies to all actions with global shortcuts in any KDE application.
86 *
87 * @see promptStealShortcutSystemwide()
88 */
89 static void stealShortcutSystemwide(const QKeySequence &seq);
90
91 /**
92 * Clean the shortcuts for component @a componentUnique.
93 *
94 * If the component is not active all global shortcut registrations are
95 * purged and the component is removed completely.
96 *
97 * If the component is active all global shortcut registrations not in use
98 * will be purged. If there is no shortcut registration left the component
99 * is purged too.
100 *
101 * If a purged component or shortcut is activated the next time it will
102 * reregister itself. All you probably will lose on wrong usage are the
103 * user's set shortcuts.
104 *
105 * If you make sure your component is running and all global shortcuts it
106 * has are active this function can be used to clean up the registry.
107 *
108 * Handle with care!
109 *
110 * If the method return @c true at least one shortcut was purged so handle
111 * all previously acquired information with care.
112 */
113 static bool cleanComponent(const QString &componentUnique);
114
115 /**
116 * Check if @a component is active.
117 *
118 * @param componentUnique the components unique identifier
119 * @return @c true if active, @false if not
120 */
121 static bool isComponentActive(const QString &componentName);
122
123 /**
124 * Returns a list of global shortcuts registered for the shortcut @p seq.
125 *
126 * If the list contains more that one entry it means the component
127 * that registered the shortcuts uses global shortcut contexts. All
128 * returned shortcuts belong to the same component.
129 *
130 * @param type a value from the KGlobalAccel::MatchType enum
131 *
132 * @since 5.90
133 */
134 static QList<KGlobalShortcutInfo> globalShortcutsByKey(const QKeySequence &seq, MatchType type = Equal);
135
136 /**
137 * Check if the shortcut @seq is available for the @p component. The
138 * component is only of interest if the current application uses global shortcut
139 * contexts. In that case a global shortcut by @p component in an inactive
140 * global shortcut contexts does not block the @p seq for us.
141 *
142 * @since 4.2
143 */
144 static bool isGlobalShortcutAvailable(const QKeySequence &seq, const QString &component = QString());
145
146 /**
147 * Show a messagebox to inform the user that a global shortcut is already occupied,
148 * and ask to take it away from its current action(s). This is GUI only, so nothing will
149 * be actually changed.
150 *
151 * @see stealShortcutSystemwide()
152 *
153 * @since 4.2
154 */
155 static bool promptStealShortcutSystemwide(QWidget *parent, const QList<KGlobalShortcutInfo> &shortcuts, const QKeySequence &seq);
156
157 /**
158 * Assign a default global shortcut for a given QAction.
159 * For more information about global shortcuts @see setShortcut
160 * Upon shortcut change the globalShortcutChanged will be triggered so other applications get notified
161 *
162 * @sa globalShortcutChanged
163 *
164 * @since 5.0
165 */
166 bool setDefaultShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
167
168 /**
169 * Assign a global shortcut for the given action. Global shortcuts
170 * allow an action to respond to key shortcuts independently of the focused window,
171 * i.e. the action will trigger if the keys were pressed no matter where in the X session.
172 *
173 * The action must have a per main component unique
174 * action->objectName() to enable cross-application bookkeeping. If the action->objectName() is empty this method will
175 * do nothing and will return false.
176 *
177 * It is mandatory that the action->objectName() doesn't change once the shortcut has been successfully registered.
178 *
179 * \note KActionCollection::insert(name, action) will set action's objectName to name so you often
180 * don't have to set an objectName explicitly.
181 *
182 * When an action, identified by main component name and objectName(), is assigned
183 * a global shortcut for the first time on a KDE installation the assignment will
184 * be saved. The shortcut will then be restored every time setGlobalShortcut() is
185 * called with @p loading == Autoloading.
186 *
187 * If you actually want to change the global shortcut you have to set
188 * @p loading to NoAutoloading. The new shortcut will be automatically saved again.
189 *
190 * @param action the action for which the shortcut will be assigned
191 * @param shortcut global shortcut(s) to assign. Will be ignored unless @p loading is set to NoAutoloading or this is the first time ever you call this
192 * method (see above).
193 * @param loadFlag if Autoloading, assign the global shortcut this action has previously had if any.
194 * That way user preferences and changes made to avoid clashes will be conserved.
195 * if NoAutoloading the given shortcut will be assigned without looking up old values.
196 * You should only do this if the user wants to change the shortcut or if you have
197 * another very good reason. Key combinations that clash with other shortcuts will be
198 * dropped.
199 *
200 * \note the default shortcut will never be influenced by autoloading - it will be set as given.
201 * @sa shortcut()
202 * @sa globalShortcutChanged
203 * @since 5.0
204 */
205 bool setShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
206
207 /**
208 * Convenient method to set both active and default shortcut.
209 *
210 * If more control for loading the shortcuts is needed use the variants offering more control.
211 *
212 * @sa setShortcut
213 * @sa setDefaultShortcut
214 * @since 5.0
215 **/
216 static bool setGlobalShortcut(QAction *action, const QList<QKeySequence> &shortcut);
217
218 /**
219 * Convenient method to set both active and default shortcut.
220 *
221 * This method is suited for the case that only one shortcut is to be configured.
222 *
223 * If more control for loading the shortcuts is needed use the variants offering more control.
224 *
225 * @sa setShortcut
226 * @sa setDefaultShortcut
227 * @since 5.0
228 **/
229 static bool setGlobalShortcut(QAction *action, const QKeySequence &shortcut);
230
231 /**
232 * Get the global default shortcut for this action, if one exists. Global shortcuts
233 * allow your actions to respond to accellerators independently of the focused window.
234 * Unlike regular shortcuts, the application's window does not need focus
235 * for them to be activated.
236 *
237 * @sa setDefaultShortcut()
238 * @since 5.0
239 */
240 QList<QKeySequence> defaultShortcut(const QAction *action) const;
241
242 /**
243 * Get the global shortcut for this action, if one exists. Global shortcuts
244 * allow your actions to respond to accellerators independently of the focused window.
245 * Unlike regular shortcuts, the application's window does not need focus
246 * for them to be activated.
247 *
248 * @note that this method only works together with setShortcut() because the action pointer
249 * is used to retrieve the result. If you would like to retrieve the shortcut as stored
250 * in the global settings, use the globalShortcut(componentName, actionId) instead.
251 *
252 * @sa setShortcut()
253 * @since 5.0
254 */
255 QList<QKeySequence> shortcut(const QAction *action) const;
256
257 /**
258 * Retrieves the shortcut as defined in global settings by
259 * componentName (e.g. "kwin") and actionId (e.g. "Kill Window").
260 *
261 * @since 5.10
262 */
263 QList<QKeySequence> globalShortcut(const QString &componentName, const QString &actionId) const;
264
265 /**
266 * Unregister and remove all defined global shortcuts for the given action.
267 *
268 * @since 5.0
269 */
270 void removeAllShortcuts(QAction *action);
271
272 /**
273 * Returns true if a shortcut or a default shortcut has been registered for the given action
274 *
275 * @since 5.0
276 */
277 bool hasShortcut(const QAction *action) const;
278
279Q_SIGNALS:
280 /**
281 * Emitted when the global shortcut is changed. A global shortcut is
282 * subject to be changed by the global shortcuts kcm.
283 *
284 * @param action pointer to the action for which the changed shortcut was registered
285 * @param seq the key sequence that corresponds to the changed shortcut
286 *
287 * @see setGlobalShortcut
288 * @see setDefaultShortcut
289 * @since 5.0
290 */
291 void globalShortcutChanged(QAction *action, const QKeySequence &seq);
292 void globalShortcutActiveChanged(QAction *action, bool active);
293
294private:
295 /// Creates a new KGlobalAccel object
296 KGLOBALACCEL_NO_EXPORT KGlobalAccel();
297
298 /// Destructor
299 KGLOBALACCEL_NO_EXPORT ~KGlobalAccel() override;
300
301 //! get component @p componentUnique
302 KGLOBALACCEL_NO_EXPORT OrgKdeKglobalaccelComponentInterface *getComponent(const QString &componentUnique);
303
304 class KGlobalAccelPrivate *const d;
305
306 friend class KGlobalAccelSingleton;
307};
308
309KGLOBALACCEL_EXPORT QDBusArgument &operator<<(QDBusArgument &argument, const KGlobalAccel::MatchType &type);
310KGLOBALACCEL_EXPORT const QDBusArgument &operator>>(const QDBusArgument &argument, KGlobalAccel::MatchType &type);
311
312#endif // _KGLOBALACCEL_H_
313

source code of kglobalaccel/src/kglobalaccel.h