File indexing completed on 2024-06-16 04:15:36

0001 /* This file is part of the KDE libraries
0002     SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org>
0003     SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
0004     SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org>
0005     SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
0006     SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org>
0007     SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org>
0008     SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org>
0009     SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
0010 
0011     SPDX-License-Identifier: LGPL-2.0-only
0012 */
0013 
0014 #ifndef KACTIONCOLLECTION_H
0015 #define KACTIONCOLLECTION_H
0016 #include "config-xmlgui.h"
0017 #include <kritawidgetutils_export.h>
0018 #include <kstandardaction.h>
0019 #include <QObject>
0020 
0021 class QAction;
0022 class KisKXMLGUIClient;
0023 class KConfigGroup;
0024 class QActionGroup;
0025 class QString;
0026 class KisKActionCategory;
0027 
0028 /**
0029  * \short A container for a set of QAction objects.
0030  *
0031  * KisKActionCollection manages a set of QAction objects.  It
0032  * allows them to be grouped for organized presentation of configuration to the user,
0033  * saving + loading of configuration, and optionally for automatic plugging into
0034  * specified widget(s).
0035  *
0036  * Additionally, KisKActionCollection provides several convenience functions for locating
0037  * named actions, and actions grouped by QActionGroup.
0038  *
0039  * \note If you create your own action collection and need to assign shortcuts
0040  * to the actions within, you have to call associateWidget() or
0041  * addAssociatedWidget() to have them working.
0042  */
0043 class KRITAWIDGETUTILS_EXPORT KisKActionCollection : public QObject
0044 {
0045     friend class KisKXMLGUIClient;
0046 
0047     Q_OBJECT
0048 
0049     Q_PROPERTY(QString configGroup READ configGroup WRITE setConfigGroup)
0050 
0051 public:
0052     /**
0053      * Constructor.  Allows specification of a component name other than the default
0054      * application name, where needed (remember to call setComponentDisplayName() too).
0055      */
0056     explicit KisKActionCollection(QObject *parent, const QString &cName = QString());
0057 
0058     /**
0059      * Destructor.
0060      */
0061     ~KisKActionCollection() override;
0062 
0063     /**
0064      * Access the list of all action collections in existence for this app
0065      */
0066     static const QList<KisKActionCollection *> &allCollections();
0067 
0068     /**
0069      * Clears the entire action collection, deleting all actions.
0070      */
0071     void clear();
0072 
0073     /**
0074      * Associate all actions in this collection to the given \a widget.
0075      * Unlike addAssociatedWidget, this method only adds all current actions
0076      * in the collection to the given widget. Any action added after this call
0077      * will not be added to the given widget automatically.
0078      * So this is just a shortcut for a foreach loop and a widget->addAction call.
0079      */
0080     void associateWidget(QWidget *widget) const;
0081 
0082     /**
0083      * Associate all actions in this collection to the given \a widget, including any actions
0084      * added after this association is made.
0085      *
0086      * This does not change the action's shortcut context, so if you need to have the actions only
0087      * trigger when the widget has focus, you'll need to set the shortcut context on each action
0088      * to Qt::WidgetShortcut (or better still, Qt::WidgetWithChildrenShortcut with Qt 4.4+)
0089      */
0090     void addAssociatedWidget(QWidget *widget);
0091 
0092     /**
0093      * Remove an association between all actions in this collection and the given \a widget, i.e.
0094      * remove those actions from the widget, and stop associating newly added actions as well.
0095      */
0096     void removeAssociatedWidget(QWidget *widget);
0097 
0098     /**
0099      * Return a list of all associated widgets.
0100      */
0101     QList<QWidget *> associatedWidgets() const;
0102 
0103     /**
0104      * Clear all associated widgets and remove the actions from those widgets.
0105      */
0106     void clearAssociatedWidgets();
0107 
0108     /**
0109      * Returns the KConfig group with which settings will be loaded and saved.
0110      */
0111     QString configGroup() const;
0112 
0113     /**
0114      * Sets \a group as the KConfig group with which settings will be loaded and saved.
0115      */
0116     void setConfigGroup(const QString &group);
0117 
0118     /**
0119       * Read all key associations from @p config.
0120       *
0121       * If @p config is zero, read all key associations from the
0122       * application's configuration file KSharedConfig::openConfig(),
0123       * in the group set by setConfigGroup().
0124       */
0125     void readSettings();
0126 
0127     /**
0128      * Update shortcuts from the KisActionRegistry.
0129      */
0130     void updateShortcuts();
0131 
0132     /**
0133       * Write the current configurable key associations. If @a is nonzero, use
0134       * that configuration group.
0135       *
0136       * Otherwise, the output file is determined as follows. If this action
0137       * collection belongs to a KXMLGuiClient the setting are saved to the
0138       * kxmlgui definition file. If not the settings are written to the
0139       * applications config file.
0140       *
0141       * \note oneAction() and writeDefaults() have no meaning for the kxmlgui
0142       * configuration file.
0143       *
0144       * \param config Config object to save to, or null (see above)
0145       * \param writeScheme set to true if we export all settings as new shortcut scheme
0146       * \param oneAction pass an action here if you just want to save the values for one action, eg.
0147       *                  if you know that action is the only one which has changed.
0148       */
0149     void writeSettings(KConfigGroup *config = 0, bool writeScheme = false, QAction *oneAction = 0) const;
0150 
0151     /**
0152      * Returns the number of actions in the collection.
0153      *
0154      * This is equivalent to actions().count().
0155      */
0156     int count() const;
0157 
0158     /**
0159      * Returns whether the action collection is empty or not.
0160      */
0161     bool isEmpty() const;
0162 
0163     /**
0164      * Return the QAction* at position "index" in the action collection.
0165      *
0166      * This is equivalent to actions().value(index);
0167      */
0168     QAction *action(int index) const;
0169 
0170     /**
0171      * Get the action with the given \a name from the action collection.
0172      *
0173      * @param name Name of the QAction
0174      * @return A pointer to the QAction in the collection which matches the parameters or
0175      * null if nothing matches.
0176      */
0177     QAction *action(const QString &name) const;
0178 
0179     /**
0180      * Returns the list of QActions which belong to this action collection.
0181      *
0182      * The list is guaranteed to be in the same order the action were put into
0183      * the collection.
0184      */
0185     QList<QAction *> actions() const;
0186 
0187     /**
0188      * Returns the list of QActions without an QAction::actionGroup() which belong to this action collection.
0189      */
0190     const QList<QAction *> actionsWithoutGroup() const;
0191 
0192     /**
0193      * Returns the list of all QActionGroups associated with actions in this action collection.
0194      */
0195     const QList<QActionGroup *> actionGroups() const;
0196 
0197     /**
0198      * Set the \a componentName associated with this action collection.
0199      *
0200      * \warning Don't call this method on a KisKActionCollection that contains
0201      * actions. This is not supported.
0202      *
0203      * \param componentName the name which is to be associated with this action collection,
0204      * or QString() to indicate the app name. This is used to load/save settings into XML files.
0205      * KXmlGuiClient::setComponentName takes care of calling this.
0206      */
0207     void setComponentName(const QString &componentName);
0208 
0209     /** The component name with which this class is associated. */
0210     QString componentName() const;
0211 
0212     /**
0213      * Set the component display name associated with this action collection.
0214      * (e.g. for the toolbar editor)
0215      * KXmlGuiClient::setComponentName takes care of calling this.
0216      */
0217     void setComponentDisplayName(const QString &displayName);
0218 
0219     /** The display name for the associated component. */
0220     QString componentDisplayName() const;
0221 
0222     /**
0223      * The parent KisKXMLGUIClient, or null if not available.
0224      */
0225     const KisKXMLGUIClient *parentGUIClient() const;
0226 
0227 
0228     /**
0229      * Returns the KActionCategories inside this collection
0230      */
0231     QList<KisKActionCategory *> categories() const;
0232 
0233 
0234     /**
0235      * Gets a category with name @p name inside this collection.
0236      *
0237      * Creates a new category if one does not exist.
0238      */
0239     KisKActionCategory *getCategory(const QString &categoryName);
0240 
0241 Q_SIGNALS:
0242     /**
0243      * Indicates that \a action was inserted into this action collection.
0244      */
0245     void inserted(QAction *action);
0246 
0247     /**
0248      * Indicates that \a action was highlighted (hovered over).
0249      * @deprecated Replaced by actionHovered(QAction* action);
0250      */
0251     QT_MOC_COMPAT void actionHighlighted(QAction *action);
0252 
0253     /**
0254      * Indicates that \a action was hovered.
0255      */
0256     void actionHovered(QAction *action);
0257 
0258     /**
0259      * Indicates that \a action was triggered
0260      */
0261     void actionTriggered(QAction *action);
0262 
0263 protected:
0264     /// Overridden to perform connections when someone wants to know whether an action was highlighted or triggered
0265     void connectNotify(const QMetaMethod &signal) override;
0266 
0267 protected Q_SLOTS:
0268     virtual void slotActionTriggered();
0269 
0270     /**
0271      * @internal
0272      * @deprecated Replaced by slotActionHovered();
0273      */
0274     QT_MOC_COMPAT virtual void slotActionHighlighted();
0275 
0276 private Q_SLOTS:
0277     void slotActionHovered();
0278 
0279 public:
0280     /**
0281      * Add an action under the given name to the collection.
0282      *
0283      * Inserting an action that was previously inserted under a different name will replace the
0284      * old entry, i.e. the action will not be available under the old name anymore but only under
0285      * the new one.
0286      *
0287      * Inserting an action under a name that is already used for another action will replace
0288      * the other action in the collection (but will not delete it).
0289      *
0290      * @param name The name by which the action be retrieved again from the collection.
0291      * @param action The action to add.
0292      * @return the same as the action given as parameter. This is just for convenience
0293      * (chaining calls) and consistency with the other addAction methods, you can also
0294      * simply ignore the return value.
0295      */
0296     Q_INVOKABLE QAction *addAction(const QString &name, QAction *action);
0297 
0298     /**
0299      * Adds a new action to the collection in category @p category.
0300      *
0301      * The category will be created if it does not already exist.
0302      */
0303     Q_INVOKABLE QAction *addCategorizedAction(const QString &name, QAction *action, const QString &categoryName);
0304 
0305     /**
0306      * Adds a list of actions to the collection.
0307      *
0308      * The objectName of the actions is used as their internal name in the collection.
0309      *
0310      * Uses addAction(QString, QAction*).
0311      *
0312      * @param actions the list of the actions to add.
0313      *
0314      * @see addAction()
0315      * @since 5.0
0316      */
0317     void addActions(const QList<QAction *> &actions);
0318 
0319     /**
0320      * Removes an action from the collection and deletes it.
0321      * @param action The action to remove.
0322      */
0323     void removeAction(QAction *action);
0324 
0325     /**
0326      * Removes an action from the collection.
0327      * @param action the action to remove.
0328      */
0329     QAction *takeAction(QAction *action);
0330 
0331     /**
0332      * Creates a new standard action, adds it to the collection and connects the
0333      * action's triggered(bool) signal to the specified receiver/member. The
0334      * newly created action is also returned.
0335      *
0336      * Note: Using KStandardAction::OpenRecent will cause a different signal than
0337      * triggered(bool) to be used, see KStandardAction for more information.
0338      *
0339      * The action can be retrieved later from the collection by its standard name as per
0340      * KStandardAction::stdName.
0341      *
0342      * @param actionType The standard action type of the action to create.
0343      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave 0 if no
0344      *                 connection is desired.
0345      * @param member The SLOT to connect the triggered(bool) signal to.  Leave 0 if no
0346      *               connection is desired.
0347      * @return new action of the given type ActionType.
0348      */
0349     QAction *addAction(KStandardAction::StandardAction actionType, const QObject *receiver = 0, const char *member = 0);
0350 
0351     /**
0352      * Creates a new standard action, adds to the collection under the given name
0353      * and connects the action's triggered(bool) signal to the specified
0354      * receiver/member. The newly created action is also returned.
0355      *
0356      * Note: Using KStandardAction::OpenRecent will cause a different signal than
0357      * triggered(bool) to be used, see KStandardAction for more information.
0358      *
0359      * The action can be retrieved later from the collection by the specified name.
0360      *
0361      * @param actionType The standard action type of the action to create.
0362      * @param name The name by which the action be retrieved again from the collection.
0363      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave 0 if no
0364      *                 connection is desired.
0365      * @param member The SLOT to connect the triggered(bool) signal to.  Leave 0 if no
0366      *               connection is desired.
0367      * @return new action of the given type ActionType.
0368      */
0369     QAction *addAction(KStandardAction::StandardAction actionType, const QString &name,
0370                        const QObject *receiver = 0, const char *member = 0);
0371 
0372     /**
0373      * Creates a new action under the given name to the collection and connects
0374      * the action's triggered(bool) signal to the specified receiver/member. The
0375      * newly created action is returned.
0376      *
0377      * NOTE: KDE prior to 4.2 used the triggered() signal instead of the triggered(bool)
0378      * signal.
0379      *
0380      * Inserting an action that was previously inserted under a different name will replace the
0381      * old entry, i.e. the action will not be available under the old name anymore but only under
0382      * the new one.
0383      *
0384      * Inserting an action under a name that is already used for another action will replace
0385      * the other action in the collection.
0386      *
0387      * @param name The name by which the action be retrieved again from the collection.
0388      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave 0 if no
0389      *                 connection is desired.
0390      * @param member The SLOT to connect the triggered(bool) signal to.  Leave 0 if no
0391      *               connection is desired.
0392      * @return new action of the given type ActionType.
0393      */
0394     QAction *addAction(const QString &name, const QObject *receiver = 0, const char *member = 0);
0395 
0396     /**
0397      * Creates a new action under the given name, adds it to the collection and connects the action's triggered(bool)
0398      * signal to the specified receiver/member. The receiver slot may accept either a bool or no
0399      * parameters at all (i.e. slotTriggered(bool) or slotTriggered() ).
0400      * The type of the action is specified by the template parameter ActionType.
0401      *
0402      * NOTE: KDE prior to 4.2 connected the triggered() signal instead of the triggered(bool)
0403      * signal.
0404      *
0405      * @param name The internal name of the action (e.g. "file-open").
0406      * @param receiver The QObject to connect the triggered(bool) signal to.  Leave 0 if no
0407      *                 connection is desired.
0408      * @param member The SLOT to connect the triggered(bool) signal to.  Leave 0 if no
0409      *               connection is desired.
0410      * @return new action of the given type ActionType.
0411      *
0412      * @see addAction()
0413      */
0414     template<class ActionType>
0415     ActionType *add(const QString &name, const QObject *receiver = 0, const char *member = 0)
0416     {
0417         ActionType *a = new ActionType(this);
0418         if (receiver && member) {
0419             connect(a, SIGNAL(triggered(bool)), receiver, member);
0420         }
0421         addAction(name, a);
0422         return a;
0423     }
0424 
0425     /**
0426      * Get the default primary shortcut for the given action.
0427      *
0428      * @param action the action for which the default primary shortcut should be returned.
0429      * @return the default primary shortcut of the given action
0430      * @since 5.0
0431      */
0432     QKeySequence defaultShortcut(QAction *action) const;
0433 
0434     /**
0435      * Get the default shortcuts for the given action.
0436      *
0437      * @param action the action for which the default shortcuts should be returned.
0438      * @return the default shortcuts of the given action
0439      * @since 5.0
0440      */
0441     QList<QKeySequence> defaultShortcuts(QAction *action) const;
0442 
0443     //TODO KF6: Make setDefaultShortcut static
0444     /**
0445      * Set the default shortcut for the given action.
0446      * Since 5.2, this also calls action->setShortcut(shortcut), i.e. the default shortcut is
0447      * made active initially.
0448      *
0449      * @param action the action for which the default shortcut should be set.
0450      * @param shortcut the shortcut to use for the given action in its specified shortcutContext()
0451      * @since 5.0
0452      */
0453     void setDefaultShortcut(QAction *action, const QKeySequence &shortcut);
0454 
0455     /**
0456      * Set the default shortcuts for the given action.
0457      * Since 5.2, this also calls action->setShortcuts(shortcuts), i.e. the default shortcut is
0458      * made active initially.
0459      *
0460      * @param action the action for which the default shortcut should be set.
0461      * @param shortcuts the shortcuts to use for the given action in its specified shortcutContext()
0462      * @since 5.0
0463      */
0464     Q_INVOKABLE void setDefaultShortcuts(QAction *action, const QList<QKeySequence> &shortcuts);
0465 
0466     /**
0467      * Returns true if the given action's shortcuts may be configured by the user.
0468      *
0469      * @param action the action for the hint should be verified.
0470      * @since 5.0
0471      */
0472     bool isShortcutsConfigurable(QAction *action) const;
0473 
0474     /**
0475      * Indicate whether the user may configure the action's shortcuts.
0476      *
0477      * @param action the action for the hint should be verified.
0478      * @param configurable set to true if the shortcuts of the given action may be configured by the user, otherwise false.
0479      * @since 5.0
0480      */
0481     void setShortcutsConfigurable(QAction *action, bool configurable);
0482 
0483 private:
0484     Q_PRIVATE_SLOT(d, void _k_actionDestroyed(QObject *))
0485     Q_PRIVATE_SLOT(d, void _k_associatedWidgetDestroyed(QObject *))
0486 
0487     KisKActionCollection(const KisKXMLGUIClient *parent);   // used by KisKXMLGUIClient
0488 
0489     friend class KisKActionCollectionPrivate;
0490     class KisKActionCollectionPrivate *const d;
0491 };
0492 
0493 #endif