File indexing completed on 2024-12-01 06:44:10

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org>
0004     SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
0005     SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef _KGLOBALACCEL_H_
0011 #define _KGLOBALACCEL_H_
0012 
0013 #include "kglobalshortcutinfo.h"
0014 #include <kglobalaccel_export.h>
0015 
0016 #include <QKeySequence>
0017 #include <QList>
0018 #include <QObject>
0019 
0020 class QAction;
0021 class OrgKdeKglobalaccelComponentInterface;
0022 
0023 /**
0024  * @short Configurable global shortcut support
0025  *
0026  * KGlobalAccel allows you to have global accelerators that are independent of
0027  * the focused window.  Unlike regular shortcuts, the application's window does not need focus
0028  * for them to be activated.
0029  *
0030  * @see KKeyChooser
0031  * @see KKeyDialog
0032  */
0033 class KGLOBALACCEL_EXPORT KGlobalAccel : public QObject
0034 {
0035     Q_OBJECT
0036 
0037 public:
0038     /**
0039      * An enum about global shortcut setter semantics
0040      */
0041     enum GlobalShortcutLoading {
0042         /// Look up the action in global settings (using its main component's name and text())
0043         /// and set the shortcut as saved there.
0044         /// @see setGlobalShortcut()
0045         Autoloading = 0x0,
0046         /// Prevent autoloading of saved global shortcut for action
0047         NoAutoloading = 0x4,
0048     };
0049 
0050     /**
0051      * Index for actionId QStringLists
0052      */
0053     enum actionIdFields {
0054         ComponentUnique = 0, //!< Components Unique Name (ID)
0055         ActionUnique = 1, //!< Actions Unique Name(ID)
0056         ComponentFriendly = 2, //!< Components Friendly Translated Name
0057         ActionFriendly = 3, //!< Actions Friendly Translated Name
0058     };
0059 
0060     /**
0061      * Keysequence match semantics.
0062      *
0063      * Assuming we have an Emacs-style shortcut, for example (Alt+B, Alt+F, Alt+G) already assigned,
0064      * how a new shortcut is compared depends on which value of the enum is used:
0065      * @c Equal : Exact matching: (Alt+B, Alt+F, Alt+G)
0066      * @c Shadows : Sequence shadowing: (Alt+B, Alt+F), (Alt+F, Alt+G)
0067      * @c Shadowed : Sequence being shadowed: (Alt+B, Alt+F, Alt+G, <any key>), (<any key>, Alt+B, Alt+F, Alt+G)
0068      *
0069      * @since 5.90
0070      */
0071     enum MatchType {
0072         Equal,
0073         Shadows,
0074         Shadowed,
0075     };
0076     Q_ENUM(MatchType)
0077 
0078     /**
0079      * Returns (and creates if necessary) the singleton instance
0080      */
0081     static KGlobalAccel *self();
0082 
0083     /**
0084      * Take away the given shortcut from the named action it belongs to.
0085      * This applies to all actions with global shortcuts in any KDE application.
0086      *
0087      * @see promptStealShortcutSystemwide()
0088      */
0089     static void stealShortcutSystemwide(const QKeySequence &seq);
0090 
0091     /**
0092      * Clean the shortcuts for component @a componentUnique.
0093      *
0094      * If the component is not active all global shortcut registrations are
0095      * purged and the component is removed completely.
0096      *
0097      * If the component is active all global shortcut registrations not in use
0098      * will be purged. If there is no shortcut registration left the component
0099      * is purged too.
0100      *
0101      * If a purged component or shortcut is activated the next time it will
0102      * reregister itself. All you probably will lose on wrong usage are the
0103      * user's set shortcuts.
0104      *
0105      * If you make sure your component is running and all global shortcuts it
0106      * has are active this function can be used to clean up the registry.
0107      *
0108      * Handle with care!
0109      *
0110      * If the method return @c true at least one shortcut was purged so handle
0111      * all previously acquired information with care.
0112      */
0113     static bool cleanComponent(const QString &componentUnique);
0114 
0115     /**
0116      * Check if @a component is active.
0117      *
0118      * @param componentUnique the components unique identifier
0119      * @return @c true if active, @false if not
0120      */
0121     static bool isComponentActive(const QString &componentName);
0122 
0123     /**
0124      * Returns a list of global shortcuts registered for the shortcut @p seq.
0125      *
0126      * If the list contains more that one entry it means the component
0127      * that registered the shortcuts uses global shortcut contexts. All
0128      * returned shortcuts belong to the same component.
0129      *
0130      * @param type a value from the KGlobalAccel::MatchType enum
0131      *
0132      * @since 5.90
0133      */
0134     static QList<KGlobalShortcutInfo> globalShortcutsByKey(const QKeySequence &seq, MatchType type = Equal);
0135 
0136     /**
0137      * Check if the shortcut @seq is available for the @p component. The
0138      * component is only of interest if the current application uses global shortcut
0139      * contexts. In that case a global shortcut by @p component in an inactive
0140      * global shortcut contexts does not block the @p seq for us.
0141      *
0142      * @since 4.2
0143      */
0144     static bool isGlobalShortcutAvailable(const QKeySequence &seq, const QString &component = QString());
0145 
0146     /**
0147      * Show a messagebox to inform the user that a global shortcut is already occupied,
0148      * and ask to take it away from its current action(s). This is GUI only, so nothing will
0149      * be actually changed.
0150      *
0151      * @see stealShortcutSystemwide()
0152      *
0153      * @since 4.2
0154      */
0155     static bool promptStealShortcutSystemwide(QWidget *parent, const QList<KGlobalShortcutInfo> &shortcuts, const QKeySequence &seq);
0156 
0157     /**
0158      * Assign a default global shortcut for a given QAction.
0159      * For more information about global shortcuts @see setShortcut
0160      * Upon shortcut change the globalShortcutChanged will be triggered so other applications get notified
0161      *
0162      * @sa globalShortcutChanged
0163      *
0164      * @since 5.0
0165      */
0166     bool setDefaultShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
0167 
0168     /**
0169      * Assign a global shortcut for the given action. Global shortcuts
0170      * allow an action to respond to key shortcuts independently of the focused window,
0171      * i.e. the action will trigger if the keys were pressed no matter where in the X session.
0172      *
0173      * The action must have a per main component unique
0174      * action->objectName() to enable cross-application bookkeeping. If the action->objectName() is empty this method will
0175      * do nothing and will return false.
0176      *
0177      * It is mandatory that the action->objectName() doesn't change once the shortcut has been successfully registered.
0178      *
0179      * \note KActionCollection::insert(name, action) will set action's objectName to name so you often
0180      * don't have to set an objectName explicitly.
0181      *
0182      * When an action, identified by main component name and objectName(), is assigned
0183      * a global shortcut for the first time on a KDE installation the assignment will
0184      * be saved. The shortcut will then be restored every time setGlobalShortcut() is
0185      * called with @p loading == Autoloading.
0186      *
0187      * If you actually want to change the global shortcut you have to set
0188      * @p loading to NoAutoloading. The new shortcut will be automatically saved again.
0189      *
0190      * @param action the action for which the shortcut will be assigned
0191      * @param shortcut global shortcut(s) to assign. Will be ignored unless @p loading is set to NoAutoloading or this is the first time ever you call this
0192      * method (see above).
0193      * @param loadFlag if Autoloading, assign the global shortcut this action has previously had if any.
0194      *                   That way user preferences and changes made to avoid clashes will be conserved.
0195      *                if NoAutoloading the given shortcut will be assigned without looking up old values.
0196      *                   You should only do this if the user wants to change the shortcut or if you have
0197      *                   another very good reason. Key combinations that clash with other shortcuts will be
0198      *                   dropped.
0199      *
0200      * \note the default shortcut will never be influenced by autoloading - it will be set as given.
0201      * @sa shortcut()
0202      * @sa globalShortcutChanged
0203      * @since 5.0
0204      */
0205     bool setShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
0206 
0207     /**
0208      * Convenient method to set both active and default shortcut.
0209      *
0210      * If more control for loading the shortcuts is needed use the variants offering more control.
0211      *
0212      * @sa setShortcut
0213      * @sa setDefaultShortcut
0214      * @since 5.0
0215      **/
0216     static bool setGlobalShortcut(QAction *action, const QList<QKeySequence> &shortcut);
0217 
0218     /**
0219      * Convenient method to set both active and default shortcut.
0220      *
0221      * This method is suited for the case that only one shortcut is to be configured.
0222      *
0223      * If more control for loading the shortcuts is needed use the variants offering more control.
0224      *
0225      * @sa setShortcut
0226      * @sa setDefaultShortcut
0227      * @since 5.0
0228      **/
0229     static bool setGlobalShortcut(QAction *action, const QKeySequence &shortcut);
0230 
0231     /**
0232      * Get the global default shortcut for this action, if one exists. Global shortcuts
0233      * allow your actions to respond to accellerators independently of the focused window.
0234      * Unlike regular shortcuts, the application's window does not need focus
0235      * for them to be activated.
0236      *
0237      * @sa setDefaultShortcut()
0238      * @since 5.0
0239      */
0240     QList<QKeySequence> defaultShortcut(const QAction *action) const;
0241 
0242     /**
0243      * Get the global shortcut for this action, if one exists. Global shortcuts
0244      * allow your actions to respond to accellerators independently of the focused window.
0245      * Unlike regular shortcuts, the application's window does not need focus
0246      * for them to be activated.
0247      *
0248      * @note that this method only works together with setShortcut() because the action pointer
0249      * is used to retrieve the result. If you would like to retrieve the shortcut as stored
0250      * in the global settings, use the globalShortcut(componentName, actionId) instead.
0251      *
0252      * @sa setShortcut()
0253      * @since 5.0
0254      */
0255     QList<QKeySequence> shortcut(const QAction *action) const;
0256 
0257     /**
0258      * Retrieves the shortcut as defined in global settings by
0259      * componentName (e.g. "kwin") and actionId (e.g. "Kill Window").
0260      *
0261      * @since 5.10
0262      */
0263     QList<QKeySequence> globalShortcut(const QString &componentName, const QString &actionId) const;
0264 
0265     /**
0266      * Unregister and remove all defined global shortcuts for the given action.
0267      *
0268      * @since 5.0
0269      */
0270     void removeAllShortcuts(QAction *action);
0271 
0272     /**
0273      * Returns true if a shortcut or a default shortcut has been registered for the given action
0274      *
0275      * @since 5.0
0276      */
0277     bool hasShortcut(const QAction *action) const;
0278 
0279 Q_SIGNALS:
0280     /**
0281      * Emitted when the global shortcut is changed. A global shortcut is
0282      * subject to be changed by the global shortcuts kcm.
0283      *
0284      * @param action pointer to the action for which the changed shortcut was registered
0285      * @param seq the key sequence that corresponds to the changed shortcut
0286      *
0287      * @see setGlobalShortcut
0288      * @see setDefaultShortcut
0289      * @since 5.0
0290      */
0291     void globalShortcutChanged(QAction *action, const QKeySequence &seq);
0292     void globalShortcutActiveChanged(QAction *action, bool active);
0293 
0294 private:
0295     /// Creates a new KGlobalAccel object
0296     KGLOBALACCEL_NO_EXPORT KGlobalAccel();
0297 
0298     /// Destructor
0299     KGLOBALACCEL_NO_EXPORT ~KGlobalAccel() override;
0300 
0301     //! get component @p componentUnique
0302     KGLOBALACCEL_NO_EXPORT OrgKdeKglobalaccelComponentInterface *getComponent(const QString &componentUnique);
0303 
0304     class KGlobalAccelPrivate *const d;
0305 
0306     friend class KGlobalAccelSingleton;
0307 };
0308 
0309 KGLOBALACCEL_EXPORT QDBusArgument &operator<<(QDBusArgument &argument, const KGlobalAccel::MatchType &type);
0310 KGLOBALACCEL_EXPORT const QDBusArgument &operator>>(const QDBusArgument &argument, KGlobalAccel::MatchType &type);
0311 
0312 #endif // _KGLOBALACCEL_H_