1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org> |
4 | SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org> |
5 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org> |
6 | SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org> |
7 | SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org> |
8 | SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org> |
9 | SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org> |
10 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org> |
11 | |
12 | SPDX-License-Identifier: LGPL-2.0-only |
13 | */ |
14 | |
15 | #ifndef KACTIONCOLLECTION_H |
16 | #define KACTIONCOLLECTION_H |
17 | |
18 | #include <KStandardAction> |
19 | #include <kxmlgui_export.h> |
20 | |
21 | #include <QAction> |
22 | #include <QObject> |
23 | #include <memory> |
24 | |
25 | class KXMLGUIClient; |
26 | class KConfigGroup; |
27 | class QActionGroup; |
28 | class QString; |
29 | |
30 | /** |
31 | * @class KActionCollection kactioncollection.h KActionCollection |
32 | * |
33 | * \short A container for a set of QAction objects. |
34 | * |
35 | * KActionCollection manages a set of QAction objects. It |
36 | * allows them to be grouped for organized presentation of configuration to the user, |
37 | * saving + loading of configuration, and optionally for automatic plugging into |
38 | * specified widget(s). |
39 | * |
40 | * Additionally, KActionCollection provides several convenience functions for locating |
41 | * named actions, and actions grouped by QActionGroup. |
42 | * |
43 | * \note If you create your own action collection and need to assign shortcuts |
44 | * to the actions within, you have to call associateWidget() or |
45 | * addAssociatedWidget() to have them working. |
46 | */ |
47 | class KXMLGUI_EXPORT KActionCollection : public QObject |
48 | { |
49 | friend class KXMLGUIClient; |
50 | |
51 | Q_OBJECT |
52 | |
53 | Q_PROPERTY(QString configGroup READ configGroup WRITE setConfigGroup) |
54 | Q_PROPERTY(bool configIsGlobal READ configIsGlobal WRITE setConfigGlobal) |
55 | |
56 | public: |
57 | /** |
58 | * Constructor. Allows specification of a component name other than the default |
59 | * application name, where needed (remember to call setComponentDisplayName() too). |
60 | */ |
61 | explicit KActionCollection(QObject *parent, const QString &cName = QString()); |
62 | |
63 | /** |
64 | * Destructor. |
65 | */ |
66 | ~KActionCollection() override; |
67 | |
68 | /** |
69 | * Access the list of all action collections in existence for this app |
70 | */ |
71 | static const QList<KActionCollection *> &allCollections(); |
72 | |
73 | /** |
74 | * Clears the entire action collection, deleting all actions. |
75 | */ |
76 | void clear(); |
77 | |
78 | /** |
79 | * Associate all actions in this collection to the given @p widget. |
80 | * Unlike addAssociatedWidget(), this method only adds all current actions |
81 | * in the collection to the given widget. Any action added after this call |
82 | * will not be added to the given widget automatically. |
83 | * So this is just a shortcut for a foreach loop and a widget->addAction call. |
84 | */ |
85 | void associateWidget(QWidget *widget) const; |
86 | |
87 | /** |
88 | * Associate all actions in this collection to the given @p widget, including any actions |
89 | * added after this association is made. |
90 | * |
91 | * This does not change the action's shortcut context, so if you need to have the actions only |
92 | * trigger when the widget has focus, you'll need to set the shortcut context on each action |
93 | * to Qt::WidgetShortcut (or better still, Qt::WidgetWithChildrenShortcut with Qt 4.4+) |
94 | */ |
95 | void addAssociatedWidget(QWidget *widget); |
96 | |
97 | /** |
98 | * Remove an association between all actions in this collection and the given @p widget, i.e. |
99 | * remove those actions from the widget, and stop associating newly added actions as well. |
100 | */ |
101 | void removeAssociatedWidget(QWidget *widget); |
102 | |
103 | /** |
104 | * Return a list of all associated widgets. |
105 | */ |
106 | QList<QWidget *> associatedWidgets() const; |
107 | |
108 | /** |
109 | * Clear all associated widgets and remove the actions from those widgets. |
110 | */ |
111 | void clearAssociatedWidgets(); |
112 | |
113 | /** |
114 | * Returns the KConfig group with which settings will be loaded and saved. |
115 | */ |
116 | QString configGroup() const; |
117 | |
118 | /** |
119 | * Returns whether this action collection's configuration should be global to KDE ( @c true ), |
120 | * or specific to the application ( @c false ). |
121 | */ |
122 | bool configIsGlobal() const; |
123 | |
124 | /** |
125 | * Sets @p group as the KConfig group with which settings will be loaded and saved. |
126 | */ |
127 | void setConfigGroup(const QString &group); |
128 | |
129 | /** |
130 | * Set whether this action collection's configuration should be global to KDE ( @c true ), |
131 | * or specific to the application ( @c false ). |
132 | */ |
133 | void setConfigGlobal(bool global); |
134 | |
135 | /** |
136 | * Read all key associations from @p config. |
137 | * |
138 | * If @p config is zero, read all key associations from the |
139 | * application's configuration file KSharedConfig::openConfig(), |
140 | * in the group set by setConfigGroup(). |
141 | */ |
142 | void readSettings(KConfigGroup *config = nullptr); |
143 | |
144 | /** |
145 | * Import from @p config all configurable global key associations. |
146 | * |
147 | * \since 4.1 |
148 | * |
149 | * \param config Config object to read from |
150 | */ |
151 | void importGlobalShortcuts(KConfigGroup *config); |
152 | |
153 | /** |
154 | * Export the current configurable global key associations to @p config. |
155 | * |
156 | * \since 4.1 |
157 | * |
158 | * \param config Config object to save to |
159 | * \param writeDefaults set to true to write settings which are already at defaults. |
160 | */ |
161 | void exportGlobalShortcuts(KConfigGroup *config, bool writeDefaults = false) const; |
162 | |
163 | /** |
164 | * Write the current configurable key associations to @p config. What the |
165 | * function does if @p config is zero depends. If this action collection |
166 | * belongs to a KXMLGUIClient the setting are saved to the kxmlgui |
167 | * definition file. If not the settings are written to the applications |
168 | * config file. |
169 | * |
170 | * \note @p oneAction and @p writeDefaults have no meaning for the kxmlgui |
171 | * configuration file. |
172 | * |
173 | * \param config Config object to save to, or null (see above) |
174 | * \param writeDefaults set to true to write settings which are already at defaults. |
175 | * \param oneAction pass an action here if you just want to save the values for one action, eg. |
176 | * if you know that action is the only one which has changed. |
177 | */ |
178 | void writeSettings(KConfigGroup *config = nullptr, bool writeDefaults = false, QAction *oneAction = nullptr) const; |
179 | |
180 | /** |
181 | * Returns the number of actions in the collection. |
182 | * |
183 | * This is equivalent to actions().count(). |
184 | */ |
185 | int count() const; |
186 | |
187 | /** |
188 | * Returns whether the action collection is empty or not. |
189 | */ |
190 | bool isEmpty() const; |
191 | |
192 | /** |
193 | * Return the QAction* at position @p index in the action collection. |
194 | * |
195 | * This is equivalent to actions().value(index); |
196 | */ |
197 | QAction *action(int index) const; |
198 | |
199 | /** |
200 | * Get the action with the given \p name from the action collection. |
201 | * |
202 | * This won't return the action for the menus defined using a "<Menu>" tag |
203 | * in XMLGUI files (e.g. "<Menu name="menuId">" in "applicationNameui.rc"). |
204 | * To access menu actions defined like this, use e.g. |
205 | * \code |
206 | * qobject_cast<QMenu *>(guiFactory()->container("menuId", this)); |
207 | * \endcode |
208 | * after having called setupGUI() or createGUI(). |
209 | * |
210 | * @param name Name of the QAction |
211 | * @return A pointer to the QAction in the collection which matches the parameters or |
212 | * null if nothing matches. |
213 | */ |
214 | Q_INVOKABLE QAction *action(const QString &name) const; |
215 | |
216 | /** |
217 | * Returns the list of QActions which belong to this action collection. |
218 | * |
219 | * The list is guaranteed to be in the same order the action were put into |
220 | * the collection. |
221 | */ |
222 | QList<QAction *> actions() const; |
223 | |
224 | /** |
225 | * Returns the list of QActions without an QAction::actionGroup() which belong to this action collection. |
226 | */ |
227 | const QList<QAction *> actionsWithoutGroup() const; |
228 | |
229 | /** |
230 | * Returns the list of all QActionGroups associated with actions in this action collection. |
231 | */ |
232 | const QList<QActionGroup *> actionGroups() const; |
233 | |
234 | /** |
235 | * Set the @p componentName associated with this action collection. |
236 | * |
237 | * \warning Don't call this method on a KActionCollection that contains |
238 | * actions. This is not supported. |
239 | * |
240 | * \param componentData the name which is to be associated with this action collection, |
241 | * or QString() to indicate the app name. This is used to load/save settings into XML files. |
242 | * KXMLGUIClient::setComponentName takes care of calling this. |
243 | */ |
244 | void setComponentName(const QString &componentName); |
245 | |
246 | /** The component name with which this class is associated. */ |
247 | QString componentName() const; |
248 | |
249 | /** |
250 | * Set the component display name associated with this action collection. |
251 | * (e.g. for the toolbar editor) |
252 | * KXMLGUIClient::setComponentName takes care of calling this. |
253 | */ |
254 | void setComponentDisplayName(const QString &displayName); |
255 | |
256 | /** The display name for the associated component. */ |
257 | QString componentDisplayName() const; |
258 | |
259 | /** |
260 | * The parent KXMLGUIClient, or null if not available. |
261 | */ |
262 | const KXMLGUIClient *parentGUIClient() const; |
263 | |
264 | Q_SIGNALS: |
265 | /** |
266 | * Indicates that @p action was inserted into this action collection. |
267 | */ |
268 | void inserted(QAction *action); |
269 | |
270 | /** |
271 | * Emitted when an action has been inserted into, or removed from, this action collection. |
272 | * @since 5.66 |
273 | */ |
274 | void changed(); |
275 | |
276 | /** |
277 | * Indicates that @p action was hovered. |
278 | */ |
279 | void actionHovered(QAction *action); |
280 | |
281 | /** |
282 | * Indicates that @p action was triggered |
283 | */ |
284 | void actionTriggered(QAction *action); |
285 | |
286 | protected: |
287 | /// Overridden to perform connections when someone wants to know whether an action was highlighted or triggered |
288 | void connectNotify(const QMetaMethod &signal) override; |
289 | |
290 | protected Q_SLOTS: |
291 | virtual void slotActionTriggered(); |
292 | |
293 | private Q_SLOTS: |
294 | KXMLGUI_NO_EXPORT void slotActionHovered(); |
295 | |
296 | public: |
297 | /** |
298 | * Add an action under the given name to the collection. |
299 | * |
300 | * Inserting an action that was previously inserted under a different name will replace the |
301 | * old entry, i.e. the action will not be available under the old name anymore but only under |
302 | * the new one. |
303 | * |
304 | * Inserting an action under a name that is already used for another action will replace |
305 | * the other action in the collection (but will not delete it). |
306 | * |
307 | * If KAuthorized::authorizeAction() reports that the action is not |
308 | * authorized, it will be disabled and hidden. |
309 | * |
310 | * The ownership of the action object is not transferred. |
311 | * If the action is destroyed it will be removed automatically from the KActionCollection. |
312 | * |
313 | * @param name The name by which the action be retrieved again from the collection. |
314 | * @param action The action to add. |
315 | * @return the same as the action given as parameter. This is just for convenience |
316 | * (chaining calls) and consistency with the other addAction methods, you can also |
317 | * simply ignore the return value. |
318 | */ |
319 | Q_INVOKABLE QAction *addAction(const QString &name, QAction *action); |
320 | |
321 | /** |
322 | * Adds a list of actions to the collection. |
323 | * |
324 | * The objectName of the actions is used as their internal name in the collection. |
325 | * |
326 | * The ownership of the action objects is not transferred. |
327 | * If the action is destroyed it will be removed automatically from the KActionCollection. |
328 | * |
329 | * Uses addAction(const QString&, QAction*). |
330 | * |
331 | * @param actions the list of the actions to add. |
332 | * |
333 | * @see addAction() |
334 | * @since 5.0 |
335 | */ |
336 | void addActions(const QList<QAction *> &actions); |
337 | |
338 | /** |
339 | * Removes an action from the collection and deletes it. |
340 | * @param action The action to remove. |
341 | */ |
342 | void removeAction(QAction *action); |
343 | |
344 | /** |
345 | * Removes an action from the collection. |
346 | * |
347 | * The ownership of the action object is not changed. |
348 | * |
349 | * @param action the action to remove. |
350 | */ |
351 | QAction *takeAction(QAction *action); |
352 | |
353 | /** |
354 | * Creates a new standard action, adds it to the collection and connects the |
355 | * action's triggered(bool) signal to the specified receiver/member. The |
356 | * newly created action is also returned. |
357 | * |
358 | * @note Using KStandardAction::OpenRecent will cause a different signal than |
359 | * triggered(bool) to be used, see KStandardAction for more information. |
360 | * |
361 | * The action can be retrieved later from the collection by its standard name as per |
362 | * KStandardAction::stdName. |
363 | * |
364 | * The KActionCollection takes ownership of the action object. |
365 | * |
366 | * @param actionType The standard action type of the action to create. |
367 | * @param receiver The QObject to connect the triggered(bool) signal to. Leave nullptr if no |
368 | * connection is desired. |
369 | * @param member The SLOT to connect the triggered(bool) signal to. Leave nullptr if no |
370 | * connection is desired. |
371 | * @return new action of the given type ActionType. |
372 | */ |
373 | QAction *addAction(KStandardAction::StandardAction actionType, const QObject *receiver = nullptr, const char *member = nullptr); |
374 | |
375 | /** |
376 | * Creates a new standard action, adds to the collection under the given name |
377 | * and connects the action's triggered(bool) signal to the specified |
378 | * receiver/member. The newly created action is also returned. |
379 | * |
380 | * @note Using KStandardAction::OpenRecent will cause a different signal than |
381 | * triggered(bool) to be used, see KStandardAction for more information. |
382 | * |
383 | * The action can be retrieved later from the collection by the specified name. |
384 | * |
385 | * The KActionCollection takes ownership of the action object. |
386 | * |
387 | * @param actionType The standard action type of the action to create. |
388 | * @param name The name by which the action be retrieved again from the collection. |
389 | * @param receiver The QObject to connect the triggered(bool) signal to. Leave nullptr if no |
390 | * connection is desired. |
391 | * @param member The SLOT to connect the triggered(bool) signal to. Leave nullptr if no |
392 | * connection is desired. |
393 | * @return new action of the given type ActionType. |
394 | */ |
395 | QAction *addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver = nullptr, const char *member = nullptr); |
396 | |
397 | /** |
398 | * This is the same as addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver, const char *member) using |
399 | * new style connect syntax. |
400 | * |
401 | * @param actionType The standard action type of the action to create. |
402 | * @param name The name by which the action be retrieved again from the collection. |
403 | * @param receiver The QObject to connect the triggered(bool) signal to. |
404 | * @param slot The slot or lambda to connect the triggered(bool) signal to. |
405 | * @return new action of the given type ActionType. |
406 | * |
407 | * @see addAction(KStandardAction::StandardAction, const QString &, const QObject *, const char *) |
408 | * @since 5.80 |
409 | */ |
410 | #ifdef K_DOXYGEN |
411 | inline QAction *addAction(KStandardAction::StandardAction actionType, const QString &name, const Receiver *receiver, Func slot) |
412 | #else |
413 | template<class Receiver, class Func> |
414 | inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, QAction>::type * |
415 | addAction(KStandardAction::StandardAction actionType, const QString &name, const Receiver *receiver, Func slot) |
416 | #endif |
417 | { |
418 | QAction *action = KStandardAction::create(actionType, receiver, slot, nullptr); |
419 | action->setParent(this); |
420 | action->setObjectName(name); |
421 | return addAction(name, action); |
422 | } |
423 | |
424 | /** |
425 | * Creates a new action under the given name to the collection and connects |
426 | * the action's triggered(bool) signal to the specified receiver/member. The |
427 | * newly created action is returned. |
428 | * |
429 | * NOTE: KDE prior to 4.2 used the triggered() signal instead of the triggered(bool) |
430 | * signal. |
431 | * |
432 | * Inserting an action that was previously inserted under a different name will replace the |
433 | * old entry, i.e. the action will not be available under the old name anymore but only under |
434 | * the new one. |
435 | * |
436 | * Inserting an action under a name that is already used for another action will replace |
437 | * the other action in the collection. |
438 | * |
439 | * The KActionCollection takes ownership of the action object. |
440 | * |
441 | * @param name The name by which the action be retrieved again from the collection. |
442 | * @param receiver The QObject to connect the triggered(bool) signal to. Leave nullptr if no |
443 | * connection is desired. |
444 | * @param member The SLOT to connect the triggered(bool) signal to. Leave nullptr if no |
445 | * connection is desired. |
446 | * @return new action of the given type ActionType. |
447 | */ |
448 | QAction *addAction(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr); |
449 | |
450 | /** |
451 | * Creates a new action under the given name, adds it to the collection and connects the action's triggered(bool) |
452 | * signal to the specified receiver/member. The receiver slot may accept either a bool or no |
453 | * parameters at all (i.e. slotTriggered(bool) or slotTriggered() ). |
454 | * The type of the action is specified by the template parameter ActionType. |
455 | * |
456 | * NOTE: KDE prior to 4.2 connected the triggered() signal instead of the triggered(bool) |
457 | * signal. |
458 | * |
459 | * The KActionCollection takes ownership of the action object. |
460 | * |
461 | * @param name The internal name of the action (e.g. "file-open"). |
462 | * @param receiver The QObject to connect the triggered(bool) signal to. Leave nullptr if no |
463 | * connection is desired. |
464 | * @param member The SLOT to connect the triggered(bool) signal to. Leave nullptr if no |
465 | * connection is desired. |
466 | * @return new action of the given type ActionType. |
467 | * |
468 | * @see addAction() |
469 | */ |
470 | template<class ActionType> |
471 | ActionType *add(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr) |
472 | { |
473 | ActionType *a = new ActionType(this); |
474 | if (receiver && member) { |
475 | connect(a, SIGNAL(triggered(bool)), receiver, member); |
476 | } |
477 | addAction(name, a); |
478 | return a; |
479 | } |
480 | |
481 | /** |
482 | * This is the same as add(const QString &name, const QObject *receiver, const char *member) using |
483 | * new style connect syntax. |
484 | * |
485 | * @param name The internal name of the action (e.g. "file-open"). |
486 | * @param receiver The QObject to connect the triggered(bool) signal to. |
487 | * @param slot The slot or lambda to connect the triggered(bool) signal to. |
488 | * @return new action of the given type ActionType. |
489 | * |
490 | * @see add(const QString &, const QObject *, const char *) |
491 | * @since 5.28 |
492 | */ |
493 | #ifdef K_DOXYGEN |
494 | template<class ActionType> |
495 | inline ActionType *add(const QString &name, const Receiver *receiver, Func slot) |
496 | #else |
497 | template<class ActionType, class Receiver, class Func> |
498 | inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, ActionType>::type * |
499 | add(const QString &name, const Receiver *receiver, Func slot) |
500 | #endif |
501 | { |
502 | ActionType *a = new ActionType(this); |
503 | connect(a, &QAction::triggered, receiver, slot); |
504 | addAction(name, a); |
505 | return a; |
506 | } |
507 | |
508 | /** |
509 | * This is the same as addAction(const QString &name, const QObject *receiver, const char *member) using |
510 | * new style connect syntax. |
511 | * |
512 | * @param name The internal name of the action (e.g. "file-open"). |
513 | * @param receiver The QObject to connect the triggered(bool) signal to. |
514 | * @param slot The slot or lambda to connect the triggered(bool) signal to. |
515 | * @return new action of the given type ActionType. |
516 | * |
517 | * @see addAction(const QString &, const QObject *, const char *) |
518 | * @since 5.28 |
519 | */ |
520 | #ifdef K_DOXYGEN |
521 | inline QAction *addAction(const QString &name, const Receiver *receiver, Func slot) |
522 | #else |
523 | template<class Receiver, class Func> |
524 | inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, QAction>::type * |
525 | addAction(const QString &name, const Receiver *receiver, Func slot) |
526 | #endif |
527 | { |
528 | return add<QAction>(name, receiver, slot); |
529 | } |
530 | |
531 | /** |
532 | * Get the default primary shortcut for the given action. |
533 | * |
534 | * @param action the action for which the default primary shortcut should be returned. |
535 | * @return the default primary shortcut of the given action |
536 | * @since 5.0 |
537 | */ |
538 | static QKeySequence defaultShortcut(QAction *action); |
539 | |
540 | /** |
541 | * Get the default shortcuts for the given action. |
542 | * |
543 | * @param action the action for which the default shortcuts should be returned. |
544 | * @return the default shortcuts of the given action |
545 | * @since 5.0 |
546 | */ |
547 | static QList<QKeySequence> defaultShortcuts(QAction *action); |
548 | |
549 | /** |
550 | * Set the default shortcut for the given action. |
551 | * Since 5.2, this also calls action->setShortcut(shortcut), i.e. the default shortcut is |
552 | * made active initially. |
553 | * |
554 | * @param action the action for which the default shortcut should be set. |
555 | * @param shortcut the shortcut to use for the given action in its specified shortcutContext() |
556 | * @since 5.0 |
557 | */ |
558 | static void setDefaultShortcut(QAction *action, const QKeySequence &shortcut); |
559 | |
560 | /** |
561 | * Set the default shortcuts for the given action. |
562 | * Since 5.2, this also calls action->setShortcuts(shortcuts), i.e. the default shortcut is |
563 | * made active initially. |
564 | * |
565 | * @param action the action for which the default shortcut should be set. |
566 | * @param shortcuts the shortcuts to use for the given action in its specified shortcutContext() |
567 | * @since 5.0 |
568 | */ |
569 | Q_INVOKABLE static void setDefaultShortcuts(QAction *action, const QList<QKeySequence> &shortcuts); |
570 | |
571 | /** |
572 | * Returns true if the given action's shortcuts may be configured by the user. |
573 | * |
574 | * @param action the action for the hint should be verified. |
575 | * @since 5.0 |
576 | */ |
577 | static bool isShortcutsConfigurable(QAction *action); |
578 | |
579 | /** |
580 | * Indicate whether the user may configure the action's shortcuts. |
581 | * |
582 | * @param action the action for the hint should be verified. |
583 | * @param configurable set to true if the shortcuts of the given action may be configured by the user, otherwise false. |
584 | * @since 5.0 |
585 | */ |
586 | static void setShortcutsConfigurable(QAction *action, bool configurable); |
587 | |
588 | private: |
589 | KXMLGUI_NO_EXPORT explicit KActionCollection(const KXMLGUIClient *parent); // used by KXMLGUIClient |
590 | |
591 | friend class KActionCollectionPrivate; |
592 | std::unique_ptr<class KActionCollectionPrivate> const d; |
593 | }; |
594 | |
595 | #endif |
596 | |