File indexing completed on 2024-05-12 17:07:18
0001 /* 0002 SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "keysdata.h" 0008 0009 #include <KGlobalAccel> 0010 #include <KGlobalShortcutInfo> 0011 #include <KPluginFactory> 0012 #include <KStandardShortcut> 0013 #include <kglobalaccel_component_interface.h> 0014 #include <kglobalaccel_interface.h> 0015 0016 KeysData::KeysData(QObject *parent, const QVariantList &args) 0017 : KCModuleData(parent, args) 0018 { 0019 for (int i = KStandardShortcut::AccelNone + 1; i < KStandardShortcut::StandardShortcutCount; ++i) { 0020 const auto id = static_cast<KStandardShortcut::StandardShortcut>(i); 0021 const QList<QKeySequence> activeShortcuts = KStandardShortcut::shortcut(id); 0022 const QList<QKeySequence> defaultShortcuts = KStandardShortcut::hardcodedDefaultShortcut(id); 0023 if (activeShortcuts != defaultShortcuts) { 0024 m_isDefault = false; 0025 return; 0026 } 0027 } 0028 0029 KGlobalAccelInterface globalAccelInterface(QStringLiteral("org.kde.kglobalaccel"), QStringLiteral("/kglobalaccel"), QDBusConnection::sessionBus()); 0030 if (!globalAccelInterface.isValid()) { 0031 return; 0032 } 0033 0034 // Default behavior of KCModuleData is to Q_EMIT the 'aboutToLoad' after construction which 0035 // triggers the 'loaded' signal. Because we query the data in an async way we Q_EMIT 'loaded' 0036 // manually when were are done. 0037 disconnect(this, &KCModuleData::aboutToLoad, this, &KCModuleData::loaded); 0038 0039 auto componentsWatcher = new QDBusPendingCallWatcher(globalAccelInterface.allComponents()); 0040 connect(componentsWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { 0041 QDBusPendingReply<QList<QDBusObjectPath>> componentsReply = *watcher; 0042 if (componentsReply.isError() || componentsReply.value().isEmpty()) { 0043 Q_EMIT loaded(); 0044 return; 0045 } 0046 const auto components = componentsReply.value(); 0047 for (const auto &componentPath : components) { 0048 KGlobalAccelComponentInterface component(QStringLiteral("org.kde.kglobalaccel"), componentPath.path(), QDBusConnection::sessionBus()); 0049 ++m_pendingComponentCalls; 0050 auto shortcutsWatcher = new QDBusPendingCallWatcher(component.allShortcutInfos()); 0051 connect(shortcutsWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { 0052 QDBusPendingReply<QList<KGlobalShortcutInfo>> shortcutsReply = *watcher; 0053 if (shortcutsReply.isValid()) { 0054 const auto allShortcuts = shortcutsReply.value(); 0055 bool isNotDefault = std::any_of(allShortcuts.cbegin(), allShortcuts.cend(), [](const KGlobalShortcutInfo &info) { 0056 return info.defaultKeys() != info.keys(); 0057 }); 0058 m_isDefault &= isNotDefault; 0059 } 0060 if (--m_pendingComponentCalls == 0) { 0061 Q_EMIT loaded(); 0062 } 0063 }); 0064 } 0065 }); 0066 } 0067 0068 bool KeysData::isDefaults() const 0069 { 0070 return m_isDefault; 0071 }