File indexing completed on 2024-04-21 15:05:46

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org>
0004     SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
0005     SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org>
0006     SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
0007     SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org>
0008     SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org>
0009     SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org>
0010     SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
0011 
0012     SPDX-License-Identifier: LGPL-2.0-only
0013 */
0014 
0015 #ifndef KACTIONCOLLECTION_H
0016 #define KACTIONCOLLECTION_H
0017 
0018 #include <KStandardAction>
0019 #include <kxmlgui_export.h>
0020 
0021 #include <QAction>
0022 #include <QObject>
0023 #include <memory>
0024 
0025 class KXMLGUIClient;
0026 class KConfigGroup;
0027 class QActionGroup;
0028 class QString;
0029 
0030 /**
0031  * @class KActionCollection kactioncollection.h KActionCollection
0032  *
0033  * \short A container for a set of QAction objects.
0034  *
0035  * KActionCollection manages a set of QAction objects.  It
0036  * allows them to be grouped for organized presentation of configuration to the user,
0037  * saving + loading of configuration, and optionally for automatic plugging into
0038  * specified widget(s).
0039  *
0040  * Additionally, KActionCollection provides several convenience functions for locating
0041  * named actions, and actions grouped by QActionGroup.
0042  *
0043  * \note If you create your own action collection and need to assign shortcuts
0044  * to the actions within, you have to call associateWidget() or
0045  * addAssociatedWidget() to have them working.
0046  */
0047 class KXMLGUI_EXPORT KActionCollection : public QObject
0048 {
0049     friend class KXMLGUIClient;
0050 
0051     Q_OBJECT
0052 
0053     Q_PROPERTY(QString configGroup READ configGroup WRITE setConfigGroup)
0054     Q_PROPERTY(bool configIsGlobal READ configIsGlobal WRITE setConfigGlobal)
0055 
0056 public:
0057     /**
0058      * Constructor.  Allows specification of a component name other than the default
0059      * application name, where needed (remember to call setComponentDisplayName() too).
0060      */
0061     explicit KActionCollection(QObject *parent, const QString &cName = QString());
0062 
0063     /**
0064      * Destructor.
0065      */
0066     ~KActionCollection() override;
0067 
0068     /**
0069      * Access the list of all action collections in existence for this app
0070      */
0071     static const QList<KActionCollection *> &allCollections();
0072 
0073     /**
0074      * Clears the entire action collection, deleting all actions.
0075      */
0076     void clear();
0077 
0078     /**
0079      * Associate all actions in this collection to the given @p widget.
0080      * Unlike addAssociatedWidget(), this method only adds all current actions
0081      * in the collection to the given widget. Any action added after this call
0082      * will not be added to the given widget automatically.
0083      * So this is just a shortcut for a foreach loop and a widget->addAction call.
0084      */
0085     void associateWidget(QWidget *widget) const;
0086 
0087     /**
0088      * Associate all actions in this collection to the given @p widget, including any actions
0089      * added after this association is made.
0090      *
0091      * This does not change the action's shortcut context, so if you need to have the actions only
0092      * trigger when the widget has focus, you'll need to set the shortcut context on each action
0093      * to Qt::WidgetShortcut (or better still, Qt::WidgetWithChildrenShortcut with Qt 4.4+)
0094      */
0095     void addAssociatedWidget(QWidget *widget);
0096 
0097     /**
0098      * Remove an association between all actions in this collection and the given @p widget, i.e.
0099      * remove those actions from the widget, and stop associating newly added actions as well.
0100      */
0101     void removeAssociatedWidget(QWidget *widget);
0102 
0103     /**
0104      * Return a list of all associated widgets.
0105      */
0106     QList<QWidget *> associatedWidgets() const;
0107 
0108     /**
0109      * Clear all associated widgets and remove the actions from those widgets.
0110      */
0111     void clearAssociatedWidgets();
0112 
0113     /**
0114      * Returns the KConfig group with which settings will be loaded and saved.
0115      */
0116     QString configGroup() const;
0117 
0118     /**
0119      * Returns whether this action collection's configuration should be global to KDE ( @c true ),
0120      * or specific to the application ( @c false ).
0121      */
0122     bool configIsGlobal() const;
0123 
0124     /**
0125      * Sets @p group as the KConfig group with which settings will be loaded and saved.
0126      */
0127     void setConfigGroup(const QString &group);
0128 
0129     /**
0130      * Set whether this action collection's configuration should be global to KDE ( @c true ),
0131      * or specific to the application ( @c false ).
0132      */
0133     void setConfigGlobal(bool global);
0134 
0135     /**
0136      * Read all key associations from @p config.
0137      *
0138      * If @p config is zero, read all key associations from the
0139      * application's configuration file KSharedConfig::openConfig(),
0140      * in the group set by setConfigGroup().
0141      */
0142     void readSettings(KConfigGroup *config = nullptr);
0143 
0144     /**
0145      * Import from @p config all configurable global key associations.
0146      *
0147      * \since 4.1
0148      *
0149      * \param config Config object to read from
0150      */
0151     void importGlobalShortcuts(KConfigGroup *config);
0152 
0153     /**
0154      * Export the current configurable global key associations to @p config.
0155      *
0156      * \since 4.1
0157      *
0158      * \param config Config object to save to
0159      * \param writeDefaults set to true to write settings which are already at defaults.
0160      */
0161     void exportGlobalShortcuts(KConfigGroup *config, bool writeDefaults = false) const;
0162 
0163     /**
0164      * Write the current configurable key associations to @p config. What the
0165      * function does if @p config is zero depends. If this action collection
0166      * belongs to a KXMLGUIClient the setting are saved to the kxmlgui
0167      * definition file. If not the settings are written to the applications
0168      * config file.
0169      *
0170      * \note @p oneAction and @p writeDefaults have no meaning for the kxmlgui
0171      * configuration file.
0172      *
0173      * \param config Config object to save to, or null (see above)
0174      * \param writeDefaults set to true to write settings which are already at defaults.
0175      * \param oneAction pass an action here if you just want to save the values for one action, eg.
0176      *                  if you know that action is the only one which has changed.
0177      */
0178     void writeSettings(KConfigGroup *config = nullptr, bool writeDefaults = false, QAction *oneAction = nullptr) const;
0179 
0180     /**
0181      * Returns the number of actions in the collection.
0182      *
0183      * This is equivalent to actions().count().
0184      */
0185     int count() const;
0186 
0187     /**
0188      * Returns whether the action collection is empty or not.
0189      */
0190     bool isEmpty() const;
0191 
0192     /**
0193      * Return the QAction* at position @p index in the action collection.
0194      *
0195      * This is equivalent to actions().value(index);
0196      */
0197     QAction *action(int index) const;
0198 
0199     /**
0200      * Get the action with the given \p name from the action collection.
0201      *
0202      * This won't return the action for the menus defined using a "<Menu>" tag
0203      * in XMLGUI files (e.g. "<Menu name="menuId">" in "applicationNameui.rc").
0204      * To access menu actions defined like this, use e.g.
0205      * \code
0206      * qobject_cast<QMenu *>(guiFactory()->container("menuId", this));
0207      * \endcode
0208      * after having called setupGUI() or createGUI().
0209      *
0210      * @param name Name of the QAction
0211      * @return A pointer to the QAction in the collection which matches the parameters or
0212      * null if nothing matches.
0213      */
0214     QAction *action(const QString &name) const;
0215 
0216     /**
0217      * Returns the list of QActions which belong to this action collection.
0218      *
0219      * The list is guaranteed to be in the same order the action were put into
0220      * the collection.
0221      */
0222     QList<QAction *> actions() const;
0223 
0224     /**
0225      * Returns the list of QActions without an QAction::actionGroup() which belong to this action collection.
0226      */
0227     const QList<QAction *> actionsWithoutGroup() const;
0228 
0229     /**
0230      * Returns the list of all QActionGroups associated with actions in this action collection.
0231      */
0232     const QList<QActionGroup *> actionGroups() const;
0233 
0234     /**
0235      * Set the @p componentName associated with this action collection.
0236      *
0237      * \warning Don't call this method on a KActionCollection that contains
0238      * actions. This is not supported.
0239      *
0240      * \param componentData the name which is to be associated with this action collection,
0241      * or QString() to indicate the app name. This is used to load/save settings into XML files.
0242      * KXMLGUIClient::setComponentName takes care of calling this.
0243      */
0244     void setComponentName(const QString &componentName);
0245 
0246     /** The component name with which this class is associated. */
0247     QString componentName() const;
0248 
0249     /**
0250      * Set the component display name associated with this action collection.
0251      * (e.g. for the toolbar editor)
0252      * KXMLGUIClient::setComponentName takes care of calling this.
0253      */
0254     void setComponentDisplayName(const QString &displayName);
0255 
0256     /** The display name for the associated component. */
0257     QString componentDisplayName() const;
0258 
0259     /**
0260      * The parent KXMLGUIClient, or null if not available.
0261      */
0262     const KXMLGUIClient *parentGUIClient() const;
0263 
0264 Q_SIGNALS:
0265     /**
0266      * Indicates that @p action was inserted into this action collection.
0267      */
0268     void inserted(QAction *action);
0269 
0270 #if KXMLGUI_ENABLE_DEPRECATED_SINCE(5, 0)
0271     /**
0272      * Indicates that @p action was removed from this action collection.
0273      * @deprecated Since 5.0, use changed() (added in 5.66) instead.
0274      */
0275     KXMLGUI_DEPRECATED_VERSION(5, 0, "removed() is sometimes emitted with partially destroyed objects; use changed() instead (added in 5.66)")
0276     QT_MOC_COMPAT void removed(QAction *action);
0277 #endif
0278 
0279     /**
0280      * Emitted when an action has been inserted into, or removed from, this action collection.
0281      * @since 5.66
0282      */
0283     void changed();
0284 
0285 #if KXMLGUI_ENABLE_DEPRECATED_SINCE(5, 0)
0286     /**
0287      * Indicates that @p action was highlighted (hovered over).
0288      * @deprecated Since 5.0. Replaced by actionHovered(QAction* action);
0289      */
0290     KXMLGUI_DEPRECATED_VERSION(5, 0, "Use KActionCollection::actionHovered(QAction* action)")
0291     QT_MOC_COMPAT void actionHighlighted(QAction *action);
0292 #endif
0293 
0294     /**
0295      * Indicates that @p action was hovered.
0296      */
0297     void actionHovered(QAction *action);
0298 
0299     /**
0300      * Indicates that @p action was triggered
0301      */
0302     void actionTriggered(QAction *action);
0303 
0304 protected:
0305     /// Overridden to perform connections when someone wants to know whether an action was highlighted or triggered
0306     void connectNotify(const QMetaMethod &signal) override;
0307 
0308 protected Q_SLOTS:
0309     virtual void slotActionTriggered();
0310 
0311 #if KXMLGUI_ENABLE_DEPRECATED_SINCE(5, 0)
0312     /**
0313      * @internal
0314      * @deprecated Since 5.0. Replaced by slotActionHovered();
0315      */
0316     KXMLGUI_DEPRECATED_VERSION(5, 0, "Use KActionCollection::slotActionHovered()")
0317     QT_MOC_COMPAT virtual void slotActionHighlighted();
0318 #endif
0319 
0320 private Q_SLOTS:
0321     KXMLGUI_NO_EXPORT void slotActionHovered();
0322 
0323 public:
0324     /**
0325      * Add an action under the given name to the collection.
0326      *
0327      * Inserting an action that was previously inserted under a different name will replace the
0328      * old entry, i.e. the action will not be available under the old name anymore but only under
0329      * the new one.
0330      *
0331      * Inserting an action under a name that is already used for another action will replace
0332      * the other action in the collection (but will not delete it).
0333      *
0334      * If KAuthorized::authorizeAction() reports that the action is not
0335      * authorized, it will be disabled and hidden.
0336      *
0337      * The ownership of the action object is not transferred.
0338      * If the action is destroyed it will be removed automatically from the KActionCollection.
0339      *
0340      * @param name The name by which the action be retrieved again from the collection.
0341      * @param action The action to add.
0342      * @return the same as the action given as parameter. This is just for convenience
0343      * (chaining calls) and consistency with the other addAction methods, you can also
0344      * simply ignore the return value.
0345      */
0346     Q_INVOKABLE QAction *addAction(const QString &name, QAction *action);
0347 
0348     /**
0349      * Adds a list of actions to the collection.
0350      *
0351      * The objectName of the actions is used as their internal name in the collection.
0352      *
0353      * The ownership of the action objects is not transferred.
0354      * If the action is destroyed it will be removed automatically from the KActionCollection.
0355      *
0356      * Uses addAction(const QString&, QAction*).
0357      *
0358      * @param actions the list of the actions to add.
0359      *
0360      * @see addAction()
0361      * @since 5.0
0362      */
0363     void addActions(const QList<QAction *> &actions);
0364 
0365     /**
0366      * Removes an action from the collection and deletes it.
0367      * @param action The action to remove.
0368      */
0369     void removeAction(QAction *action);
0370 
0371     /**
0372      * Removes an action from the collection.
0373      *
0374      * The ownership of the action object is not changed.
0375      *
0376      * @param action the action to remove.
0377      */
0378     QAction *takeAction(QAction *action);
0379 
0380     /**
0381      * Creates a new standard action, adds it to the collection and connects the
0382      * action's triggered(bool) signal to the specified receiver/member. The
0383      * newly created action is also returned.
0384      *
0385      * @note Using KStandardAction::OpenRecent will cause a different signal than
0386      * triggered(bool) to be used, see KStandardAction for more information.
0387      *
0388      * The action can be retrieved later from the collection by its standard name as per
0389      * KStandardAction::stdName.
0390      *
0391      * The KActionCollection takes ownership of the action object.
0392      *
0393      * @param actionType The standard action type of the action to create.
0394      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave nullptr if no
0395      *                 connection is desired.
0396      * @param member The SLOT to connect the triggered(bool) signal to.  Leave nullptr if no
0397      *               connection is desired.
0398      * @return new action of the given type ActionType.
0399      */
0400     QAction *addAction(KStandardAction::StandardAction actionType, const QObject *receiver = nullptr, const char *member = nullptr);
0401 
0402     /**
0403      * Creates a new standard action, adds to the collection under the given name
0404      * and connects the action's triggered(bool) signal to the specified
0405      * receiver/member. The newly created action is also returned.
0406      *
0407      * @note Using KStandardAction::OpenRecent will cause a different signal than
0408      * triggered(bool) to be used, see KStandardAction for more information.
0409      *
0410      * The action can be retrieved later from the collection by the specified name.
0411      *
0412      * The KActionCollection takes ownership of the action object.
0413      *
0414      * @param actionType The standard action type of the action to create.
0415      * @param name The name by which the action be retrieved again from the collection.
0416      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave nullptr if no
0417      *                 connection is desired.
0418      * @param member The SLOT to connect the triggered(bool) signal to.  Leave nullptr if no
0419      *               connection is desired.
0420      * @return new action of the given type ActionType.
0421      */
0422     QAction *addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver = nullptr, const char *member = nullptr);
0423 
0424 /**
0425  * This is the same as addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver, const char *member) using
0426  * new style connect syntax.
0427  *
0428  * @param actionType The standard action type of the action to create.
0429  * @param name The name by which the action be retrieved again from the collection.
0430  * @param receiver The QObject to connect the triggered(bool) signal to.
0431  * @param slot The slot or lambda to connect the triggered(bool) signal to.
0432  * @return new action of the given type ActionType.
0433  *
0434  * @see addAction(KStandardAction::StandardAction, const QString &, const QObject *, const char *)
0435  * @since 5.80
0436  */
0437 #ifdef K_DOXYGEN
0438     inline QAction *addAction(KStandardAction::StandardAction actionType, const QString &name, const Receiver *receiver, Func slot)
0439 #else
0440     template<class Receiver, class Func>
0441     inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, QAction>::type *
0442     addAction(KStandardAction::StandardAction actionType, const QString &name, const Receiver *receiver, Func slot)
0443 #endif
0444     {
0445         QAction *action = KStandardAction::create(actionType, receiver, slot, nullptr);
0446         action->setParent(this);
0447         action->setObjectName(name);
0448         return addAction(name, action);
0449     }
0450 
0451     /**
0452      * Creates a new action under the given name to the collection and connects
0453      * the action's triggered(bool) signal to the specified receiver/member. The
0454      * newly created action is returned.
0455      *
0456      * NOTE: KDE prior to 4.2 used the triggered() signal instead of the triggered(bool)
0457      * signal.
0458      *
0459      * Inserting an action that was previously inserted under a different name will replace the
0460      * old entry, i.e. the action will not be available under the old name anymore but only under
0461      * the new one.
0462      *
0463      * Inserting an action under a name that is already used for another action will replace
0464      * the other action in the collection.
0465      *
0466      * The KActionCollection takes ownership of the action object.
0467      *
0468      * @param name The name by which the action be retrieved again from the collection.
0469      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave nullptr if no
0470      *                 connection is desired.
0471      * @param member The SLOT to connect the triggered(bool) signal to.  Leave nullptr if no
0472      *               connection is desired.
0473      * @return new action of the given type ActionType.
0474      */
0475     QAction *addAction(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr);
0476 
0477     /**
0478      * Creates a new action under the given name, adds it to the collection and connects the action's triggered(bool)
0479      * signal to the specified receiver/member. The receiver slot may accept either a bool or no
0480      * parameters at all (i.e. slotTriggered(bool) or slotTriggered() ).
0481      * The type of the action is specified by the template parameter ActionType.
0482      *
0483      * NOTE: KDE prior to 4.2 connected the triggered() signal instead of the triggered(bool)
0484      * signal.
0485      *
0486      * The KActionCollection takes ownership of the action object.
0487      *
0488      * @param name The internal name of the action (e.g. "file-open").
0489      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave nullptr if no
0490      *                 connection is desired.
0491      * @param member The SLOT to connect the triggered(bool) signal to.  Leave nullptr if no
0492      *               connection is desired.
0493      * @return new action of the given type ActionType.
0494      *
0495      * @see addAction()
0496      */
0497     template<class ActionType>
0498     ActionType *add(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr)
0499     {
0500         ActionType *a = new ActionType(this);
0501         if (receiver && member) {
0502             connect(a, SIGNAL(triggered(bool)), receiver, member);
0503         }
0504         addAction(name, a);
0505         return a;
0506     }
0507 
0508 /**
0509  * This is the same as add(const QString &name, const QObject *receiver, const char *member) using
0510  * new style connect syntax.
0511  *
0512  * @param name The internal name of the action (e.g. "file-open").
0513  * @param receiver The QObject to connect the triggered(bool) signal to.
0514  * @param slot The slot or lambda to connect the triggered(bool) signal to.
0515  * @return new action of the given type ActionType.
0516  *
0517  * @see add(const QString &, const QObject *, const char *)
0518  * @since 5.28
0519  */
0520 #ifdef K_DOXYGEN
0521     template<class ActionType>
0522     inline ActionType *add(const QString &name, const Receiver *receiver, Func slot)
0523 #else
0524     template<class ActionType, class Receiver, class Func>
0525     inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, ActionType>::type *
0526     add(const QString &name, const Receiver *receiver, Func slot)
0527 #endif
0528     {
0529         ActionType *a = new ActionType(this);
0530         connect(a, &QAction::triggered, receiver, slot);
0531         addAction(name, a);
0532         return a;
0533     }
0534 
0535 /**
0536  * This is the same as addAction(const QString &name, const QObject *receiver, const char *member) using
0537  * new style connect syntax.
0538  *
0539  * @param name The internal name of the action (e.g. "file-open").
0540  * @param receiver The QObject to connect the triggered(bool) signal to.
0541  * @param slot The slot or lambda to connect the triggered(bool) signal to.
0542  * @return new action of the given type ActionType.
0543  *
0544  * @see addAction(const QString &, const QObject *, const char *)
0545  * @since 5.28
0546  */
0547 #ifdef K_DOXYGEN
0548     inline QAction *addAction(const QString &name, const Receiver *receiver, Func slot)
0549 #else
0550     template<class Receiver, class Func>
0551     inline typename std::enable_if<!std::is_convertible<Func, const char *>::value, QAction>::type *
0552     addAction(const QString &name, const Receiver *receiver, Func slot)
0553 #endif
0554     {
0555         return add<QAction>(name, receiver, slot);
0556     }
0557 
0558     /**
0559      * Get the default primary shortcut for the given action.
0560      *
0561      * @param action the action for which the default primary shortcut should be returned.
0562      * @return the default primary shortcut of the given action
0563      * @since 5.0
0564      */
0565     QKeySequence defaultShortcut(QAction *action) const;
0566 
0567     /**
0568      * Get the default shortcuts for the given action.
0569      *
0570      * @param action the action for which the default shortcuts should be returned.
0571      * @return the default shortcuts of the given action
0572      * @since 5.0
0573      */
0574     QList<QKeySequence> defaultShortcuts(QAction *action) const;
0575 
0576     // TODO KF6: Make setDefaultShortcut static
0577     /**
0578      * Set the default shortcut for the given action.
0579      * Since 5.2, this also calls action->setShortcut(shortcut), i.e. the default shortcut is
0580      * made active initially.
0581      *
0582      * @param action the action for which the default shortcut should be set.
0583      * @param shortcut the shortcut to use for the given action in its specified shortcutContext()
0584      * @since 5.0
0585      */
0586     void setDefaultShortcut(QAction *action, const QKeySequence &shortcut);
0587 
0588     /**
0589      * Set the default shortcuts for the given action.
0590      * Since 5.2, this also calls action->setShortcuts(shortcuts), i.e. the default shortcut is
0591      * made active initially.
0592      *
0593      * @param action the action for which the default shortcut should be set.
0594      * @param shortcuts the shortcuts to use for the given action in its specified shortcutContext()
0595      * @since 5.0
0596      */
0597     Q_INVOKABLE void setDefaultShortcuts(QAction *action, const QList<QKeySequence> &shortcuts);
0598 
0599     /**
0600      * Returns true if the given action's shortcuts may be configured by the user.
0601      *
0602      * @param action the action for the hint should be verified.
0603      * @since 5.0
0604      */
0605     bool isShortcutsConfigurable(QAction *action) const;
0606 
0607     /**
0608      * Indicate whether the user may configure the action's shortcuts.
0609      *
0610      * @param action the action for the hint should be verified.
0611      * @param configurable set to true if the shortcuts of the given action may be configured by the user, otherwise false.
0612      * @since 5.0
0613      */
0614     void setShortcutsConfigurable(QAction *action, bool configurable);
0615 
0616 private:
0617     KXMLGUI_NO_EXPORT explicit KActionCollection(const KXMLGUIClient *parent); // used by KXMLGUIClient
0618 
0619     friend class KActionCollectionPrivate;
0620     std::unique_ptr<class KActionCollectionPrivate> const d;
0621 };
0622 
0623 #endif