File indexing completed on 2024-05-19 05:29:56
0001 /* 0002 SPDX-FileCopyrightText: 2008 Michael Jansen <kde@michael-jansen.biz> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef GLOBALSHORTCUTSREGISTRY_H 0008 #define GLOBALSHORTCUTSREGISTRY_H 0009 0010 #include "kglobalaccel.h" 0011 0012 #include "component.h" 0013 #include "kserviceactioncomponent.h" 0014 0015 #include <KSharedConfig> 0016 0017 #include <QDBusObjectPath> 0018 #include <QHash> 0019 #include <QKeySequence> 0020 #include <QObject> 0021 0022 #include "kglobalaccel_export.h" 0023 0024 class Component; 0025 class GlobalShortcut; 0026 class KGlobalAccelInterface; 0027 0028 /** 0029 * Global Shortcut Registry. 0030 * 0031 * Shortcuts are registered by component. A component is for example kmail or 0032 * amarok. 0033 * 0034 * A component can have contexts. Currently on plasma is planned to support 0035 * that feature. A context enables plasma to keep track of global shortcut 0036 * settings when switching containments. 0037 * 0038 * A shortcut (WIN+x) can be registered by one component only. The component 0039 * is allowed to register it more than once in different contexts. 0040 * 0041 * @author Michael Jansen <kde@michael-jansen.biz> 0042 */ 0043 class KGLOBALACCEL_EXPORT GlobalShortcutsRegistry : public QObject 0044 { 0045 Q_OBJECT 0046 0047 Q_CLASSINFO("D-Bus Interface", "org.kde.KdedGlobalAccel.GlobalShortcutsRegistry") 0048 0049 public: 0050 /** 0051 * Use GlobalShortcutsRegistry::self() 0052 * 0053 * @internal 0054 */ 0055 GlobalShortcutsRegistry(); 0056 ~GlobalShortcutsRegistry() override; 0057 0058 /** 0059 * Activate all shortcuts having their application present. 0060 */ 0061 void activateShortcuts(); 0062 0063 /** 0064 * Returns a list of D-Bus paths of registered Components. 0065 * 0066 * The returned paths are absolute (i.e. no need to prepend anything). 0067 */ 0068 QList<QDBusObjectPath> componentsDbusPaths() const; 0069 0070 /** 0071 * Returns a list of QStringLists (one string list per registered component, 0072 * with each string list containing four strings, one for each enumerator in 0073 * KGlobalAccel::actionIdFields). 0074 */ 0075 QList<QStringList> allComponentNames() const; 0076 0077 /** 0078 * Return the root dbus path for the registry. 0079 */ 0080 QDBusObjectPath dbusPath() const; 0081 0082 /** 0083 * Deactivate all currently active shortcuts. 0084 */ 0085 void deactivateShortcuts(bool temporarily = false); 0086 0087 /** 0088 */ 0089 Component *getComponent(const QString &uniqueName); 0090 0091 /** 0092 * Get the shortcut corresponding to key. Active and inactive shortcuts 0093 * are considered. But if the matching application uses contexts only one 0094 * shortcut is returned. 0095 * 0096 * @see getShortcutsByKey(int key) 0097 */ 0098 GlobalShortcut *getShortcutByKey(const QKeySequence &key, KGlobalAccel::MatchType type = KGlobalAccel::MatchType::Equal) const; 0099 0100 /** 0101 * Get the shortcuts corresponding to key. Active and inactive shortcuts 0102 * are considered. 0103 * 0104 * @see getShortcutsByKey(int key) 0105 */ 0106 QList<GlobalShortcut *> getShortcutsByKey(const QKeySequence &key, KGlobalAccel::MatchType type) const; 0107 0108 /** 0109 * Checks if @p shortcut is available for @p component. 0110 * 0111 * It is available if not used by another component in any context or used 0112 * by @p component only in not active contexts. 0113 */ 0114 bool isShortcutAvailable(const QKeySequence &shortcut, const QString &component, const QString &context) const; 0115 0116 static GlobalShortcutsRegistry *self(); 0117 0118 bool registerKey(const QKeySequence &key, GlobalShortcut *shortcut); 0119 0120 void setDBusPath(const QDBusObjectPath &path); 0121 0122 bool unregisterKey(const QKeySequence &key, GlobalShortcut *shortcut); 0123 0124 public Q_SLOTS: 0125 0126 void clear(); 0127 0128 void loadSettings(); 0129 0130 void writeSettings(); 0131 0132 // Grab the keys 0133 void grabKeys(); 0134 0135 // Ungrab the keys 0136 void ungrabKeys(); 0137 0138 private: 0139 friend struct KGlobalAccelDPrivate; 0140 friend class Component; 0141 friend class KGlobalAccelInterface; 0142 0143 Component *createComponent(const QString &uniqueName, const QString &friendlyName); 0144 KServiceActionComponent *createServiceActionComponent(const QString &uniqueName); 0145 KServiceActionComponent *createServiceActionComponent(KService::Ptr service); 0146 void migrateConfig(); 0147 void migrateKHotkeys(); 0148 0149 static void unregisterComponent(Component *component); 0150 using ComponentPtr = std::unique_ptr<Component, decltype(&unregisterComponent)>; 0151 0152 Component *registerComponent(ComponentPtr component); 0153 0154 // called by the implementation to inform us about key presses 0155 // returns true if the key was handled 0156 bool keyPressed(int keyQt); 0157 bool keyReleased(int keyQt); 0158 0159 QHash<QKeySequence, GlobalShortcut *> _active_keys; 0160 QKeySequence _active_sequence; 0161 QHash<int, int> _keys_count; 0162 0163 using ComponentVec = std::vector<ComponentPtr>; 0164 ComponentVec m_components; 0165 ComponentVec::const_iterator findByName(const QString &name) const 0166 { 0167 return std::find_if(m_components.cbegin(), m_components.cend(), [&name](const ComponentPtr &comp) { 0168 return comp->uniqueName() == name; 0169 }); 0170 } 0171 0172 KGlobalAccelInterface *_manager = nullptr; 0173 0174 mutable KConfig _config; 0175 0176 QDBusObjectPath _dbusPath; 0177 GlobalShortcut *m_lastShortcut = nullptr; 0178 }; 0179 0180 #endif /* #ifndef GLOBALSHORTCUTSREGISTRY_H */