File indexing completed on 2024-11-03 12:36:20

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 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(5, 102)
0092     /**
0093      * Set global shortcut context.
0094      *
0095      * A global shortcut context allows an application to have different sets
0096      * of global shortcuts and to switch between them. This is used by
0097      * plasma to switch the active global shortcuts when switching between
0098      * activities.
0099      *
0100      * @param context the name of the context.
0101      *
0102      * @since 4.2
0103      * @deprecated since 5.102. Shortcut contexts are deprecated. No known users.
0104      */
0105     KGLOBALACCEL_DEPRECATED_VERSION(5, 102, "Shortcut contexts are deprecated.")
0106     static void activateGlobalShortcutContext(const QString &contextUnique, const QString &contextFriendly, const QString &programName);
0107 #endif
0108 
0109     /**
0110      * Clean the shortcuts for component @a componentUnique.
0111      *
0112      * If the component is not active all global shortcut registrations are
0113      * purged and the component is removed completely.
0114      *
0115      * If the component is active all global shortcut registrations not in use
0116      * will be purged. If there is no shortcut registration left the component
0117      * is purged too.
0118      *
0119      * If a purged component or shortcut is activated the next time it will
0120      * reregister itself. All you probably will lose on wrong usage are the
0121      * user's set shortcuts.
0122      *
0123      * If you make sure your component is running and all global shortcuts it
0124      * has are active this function can be used to clean up the registry.
0125      *
0126      * Handle with care!
0127      *
0128      * If the method return @c true at least one shortcut was purged so handle
0129      * all previously acquired information with care.
0130      */
0131     static bool cleanComponent(const QString &componentUnique);
0132 
0133     /**
0134      * Check if @a component is active.
0135      *
0136      * @param componentUnique the components unique identifier
0137      * @return @c true if active, @false if not
0138      */
0139     static bool isComponentActive(const QString &componentName);
0140 
0141 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(5, 90)
0142     /**
0143      * Returns a list of global shortcuts registered for the shortcut @p seq.
0144      *
0145      * If the list contains more that one entry it means the component
0146      * that registered the shortcuts uses global shortcut contexts. All
0147      * returned shortcuts belong to the same component.
0148      *
0149      * @since 4.2
0150      * @deprecated Since 5.90, use globalShortcutsByKey(const QKeySequence&, int) instead.
0151      */
0152     KGLOBALACCEL_DEPRECATED_VERSION(5, 90, "Use globalShortcutsByKey(const QKeySequence&, int) instead.")
0153     static QList<KGlobalShortcutInfo> getGlobalShortcutsByKey(const QKeySequence &seq);
0154 #endif
0155 
0156     /**
0157      * Returns a list of global shortcuts registered for the shortcut @p seq.
0158      *
0159      * If the list contains more that one entry it means the component
0160      * that registered the shortcuts uses global shortcut contexts. All
0161      * returned shortcuts belong to the same component.
0162      *
0163      * @param type a value from the KGlobalAccel::MatchType enum
0164      *
0165      * @since 5.90
0166      */
0167     static QList<KGlobalShortcutInfo> globalShortcutsByKey(const QKeySequence &seq, MatchType type = Equal);
0168 
0169     /**
0170      * Check if the shortcut @seq is available for the @p component. The
0171      * component is only of interest if the current application uses global shortcut
0172      * contexts. In that case a global shortcut by @p component in an inactive
0173      * global shortcut contexts does not block the @p seq for us.
0174      *
0175      * @since 4.2
0176      */
0177     static bool isGlobalShortcutAvailable(const QKeySequence &seq, const QString &component = QString());
0178 
0179     /**
0180      * Show a messagebox to inform the user that a global shortcut is already occupied,
0181      * and ask to take it away from its current action(s). This is GUI only, so nothing will
0182      * be actually changed.
0183      *
0184      * @see stealShortcutSystemwide()
0185      *
0186      * @since 4.2
0187      */
0188     static bool promptStealShortcutSystemwide(QWidget *parent, const QList<KGlobalShortcutInfo> &shortcuts, const QKeySequence &seq);
0189 
0190     /**
0191      * Assign a default global shortcut for a given QAction.
0192      * For more information about global shortcuts @see setShortcut
0193      * Upon shortcut change the globalShortcutChanged will be triggered so other applications get notified
0194      *
0195      * @sa globalShortcutChanged
0196      *
0197      * @since 5.0
0198      */
0199     bool setDefaultShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
0200 
0201     /**
0202      * Assign a global shortcut for the given action. Global shortcuts
0203      * allow an action to respond to key shortcuts independently of the focused window,
0204      * i.e. the action will trigger if the keys were pressed no matter where in the X session.
0205      *
0206      * The action must have a per main component unique
0207      * action->objectName() to enable cross-application bookkeeping. If the action->objectName() is empty this method will
0208      * do nothing and will return false.
0209      *
0210      * It is mandatory that the action->objectName() doesn't change once the shortcut has been successfully registered.
0211      *
0212      * \note KActionCollection::insert(name, action) will set action's objectName to name so you often
0213      * don't have to set an objectName explicitly.
0214      *
0215      * When an action, identified by main component name and objectName(), is assigned
0216      * a global shortcut for the first time on a KDE installation the assignment will
0217      * be saved. The shortcut will then be restored every time setGlobalShortcut() is
0218      * called with @p loading == Autoloading.
0219      *
0220      * If you actually want to change the global shortcut you have to set
0221      * @p loading to NoAutoloading. The new shortcut will be automatically saved again.
0222      *
0223      * @param action the action for which the shortcut will be assigned
0224      * @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
0225      * method (see above).
0226      * @param loadFlag if Autoloading, assign the global shortcut this action has previously had if any.
0227      *                   That way user preferences and changes made to avoid clashes will be conserved.
0228      *                if NoAutoloading the given shortcut will be assigned without looking up old values.
0229      *                   You should only do this if the user wants to change the shortcut or if you have
0230      *                   another very good reason. Key combinations that clash with other shortcuts will be
0231      *                   dropped.
0232      *
0233      * \note the default shortcut will never be influenced by autoloading - it will be set as given.
0234      * @sa shortcut()
0235      * @sa globalShortcutChanged
0236      * @since 5.0
0237      */
0238     bool setShortcut(QAction *action, const QList<QKeySequence> &shortcut, GlobalShortcutLoading loadFlag = Autoloading);
0239 
0240     /**
0241      * Convenient method to set both active and default shortcut.
0242      *
0243      * If more control for loading the shortcuts is needed use the variants offering more control.
0244      *
0245      * @sa setShortcut
0246      * @sa setDefaultShortcut
0247      * @since 5.0
0248      **/
0249     static bool setGlobalShortcut(QAction *action, const QList<QKeySequence> &shortcut);
0250 
0251     /**
0252      * Convenient method to set both active and default shortcut.
0253      *
0254      * This method is suited for the case that only one shortcut is to be configured.
0255      *
0256      * If more control for loading the shortcuts is needed use the variants offering more control.
0257      *
0258      * @sa setShortcut
0259      * @sa setDefaultShortcut
0260      * @since 5.0
0261      **/
0262     static bool setGlobalShortcut(QAction *action, const QKeySequence &shortcut);
0263 
0264     /**
0265      * Get the global default shortcut for this action, if one exists. Global shortcuts
0266      * allow your actions to respond to accellerators independently of the focused window.
0267      * Unlike regular shortcuts, the application's window does not need focus
0268      * for them to be activated.
0269      *
0270      * @sa setDefaultShortcut()
0271      * @since 5.0
0272      */
0273     QList<QKeySequence> defaultShortcut(const QAction *action) const;
0274 
0275     /**
0276      * Get the global shortcut for this action, if one exists. Global shortcuts
0277      * allow your actions to respond to accellerators independently of the focused window.
0278      * Unlike regular shortcuts, the application's window does not need focus
0279      * for them to be activated.
0280      *
0281      * @note that this method only works together with setShortcut() because the action pointer
0282      * is used to retrieve the result. If you would like to retrieve the shortcut as stored
0283      * in the global settings, use the globalShortcut(componentName, actionId) instead.
0284      *
0285      * @sa setShortcut()
0286      * @since 5.0
0287      */
0288     QList<QKeySequence> shortcut(const QAction *action) const;
0289 
0290     /**
0291      * Retrieves the shortcut as defined in global settings by
0292      * componentName (e.g. "kwin") and actionId (e.g. "Kill Window").
0293      *
0294      * @since 5.10
0295      */
0296     QList<QKeySequence> globalShortcut(const QString &componentName, const QString &actionId) const;
0297 
0298     /**
0299      * Unregister and remove all defined global shortcuts for the given action.
0300      *
0301      * @since 5.0
0302      */
0303     void removeAllShortcuts(QAction *action);
0304 
0305     /**
0306      * Returns true if a shortcut or a default shortcut has been registered for the given action
0307      *
0308      * @since 5.0
0309      */
0310     bool hasShortcut(const QAction *action) const;
0311 
0312 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 4)
0313     /**
0314      * No effect.
0315      *
0316      * @deprecated Since 4.4.
0317      */
0318     KGLOBALACCEL_DEPRECATED_VERSION(4, 4, "Property no longer used")
0319     bool isEnabled() const;
0320 #endif
0321 
0322 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 4)
0323     /**
0324      * No effect.
0325      *
0326      * @deprecated Since 4.4.
0327      */
0328     KGLOBALACCEL_DEPRECATED_VERSION(4, 4, "Property no longer used")
0329     void setEnabled(bool enabled);
0330 #endif
0331 
0332 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 2)
0333     /**
0334      * Return the unique and common names of all main components that have global shortcuts.
0335      * The action strings of the returned actionId stringlists will be empty.
0336      *
0337      * @deprecated Since 4.2. Do not use.
0338      */
0339     KGLOBALACCEL_DEPRECATED_VERSION(4, 2, "Do not use")
0340     QList<QStringList> allMainComponents();
0341 #endif
0342 
0343 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 2)
0344     /**
0345      * @deprecated Since 4.2. Do not use
0346      */
0347     KGLOBALACCEL_DEPRECATED_VERSION(4, 2, "Do not use")
0348     QList<QStringList> allActionsForComponent(const QStringList &actionId);
0349 #endif
0350 
0351 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 2)
0352     /**
0353      * @deprecated Since 4.2, use KGlobalAccel::getGlobalShortcutsByKey(const QKeySequence &)
0354      */
0355     KGLOBALACCEL_DEPRECATED_VERSION(4, 2, "Use KGlobalAccel::getGlobalShortcutsByKey(const QKeySequence &)")
0356     static QStringList findActionNameSystemwide(const QKeySequence &seq);
0357 #endif
0358 
0359 #if KGLOBALACCEL_ENABLE_DEPRECATED_SINCE(4, 2)
0360     /**
0361      * @deprecated Since 4.2, use KGlobalAccel::promptStealShortcutSystemwide(QWidget *, const QList<KGlobalShortcutInfo> &, const QKeySequence &)
0362      */
0363     KGLOBALACCEL_DEPRECATED_VERSION(4,
0364                                     2,
0365                                     "Use KGlobalAccel::promptStealShortcutSystemwide(QWidget *, const QList<KGlobalShortcutInfo> &, const QKeySequence &)")
0366     static bool promptStealShortcutSystemwide(QWidget *parent, const QStringList &actionIdentifier, const QKeySequence &seq);
0367 #endif
0368 
0369 #if KGLOBALACCEL_BUILD_DEPRECATED_SINCE(5, 9)
0370     /**
0371      * @internal
0372      * Override no longer needed, left for BIC
0373      */
0374     bool eventFilter(QObject *watched, QEvent *event) override;
0375 #endif
0376 
0377 Q_SIGNALS:
0378     /**
0379      * Emitted when the global shortcut is changed. A global shortcut is
0380      * subject to be changed by the global shortcuts kcm.
0381      *
0382      * @param action pointer to the action for which the changed shortcut was registered
0383      * @param seq the key sequence that corresponds to the changed shortcut
0384      *
0385      * @see setGlobalShortcut
0386      * @see setDefaultShortcut
0387      * @since 5.0
0388      */
0389     void globalShortcutChanged(QAction *action, const QKeySequence &seq);
0390     void globalShortcutActiveChanged(QAction *action, bool active);
0391 
0392 private:
0393     /// Creates a new KGlobalAccel object
0394     KGLOBALACCEL_NO_EXPORT KGlobalAccel();
0395 
0396     /// Destructor
0397     KGLOBALACCEL_NO_EXPORT ~KGlobalAccel() override;
0398 
0399     //! get component @p componentUnique
0400     KGLOBALACCEL_NO_EXPORT OrgKdeKglobalaccelComponentInterface *getComponent(const QString &componentUnique);
0401 
0402     class KGlobalAccelPrivate *const d;
0403 
0404     friend class KGlobalAccelSingleton;
0405 };
0406 
0407 KGLOBALACCEL_EXPORT QDBusArgument &operator<<(QDBusArgument &argument, const KGlobalAccel::MatchType &type);
0408 KGLOBALACCEL_EXPORT const QDBusArgument &operator>>(const QDBusArgument &argument, KGlobalAccel::MatchType &type);
0409 
0410 #endif // _KGLOBALACCEL_H_