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
25class KXMLGUIClient;
26class KConfigGroup;
27class QActionGroup;
28class 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 */
47class 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
56public:
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
264Q_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
286protected:
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
290protected Q_SLOTS:
291 virtual void slotActionTriggered();
292
293private Q_SLOTS:
294 KXMLGUI_NO_EXPORT void slotActionHovered();
295
296public:
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
588private:
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

source code of kxmlgui/src/kactioncollection.h