diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,38 +34,28 @@ Sonnet DocTools Init + GlobalAccel ) -find_package(KHotKeysDBusInterface QUIET) if (EXISTS "${CMAKE_SOURCE_DIR}/.git") - add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) - add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000) + add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) + add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000) endif() - #add_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_CAST_FROM_BYTEARRAY) add_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_FROM_BYTEARRAY) add_subdirectory( pixmaps ) add_subdirectory( doc ) +add_subdirectory(kconf_update) -set(kmenueditcommon_STAT_SRCS preferencesdlg.cpp klinespellchecking.cpp basictab.cpp treeview.cpp kmenuedit.cpp menufile.cpp menuinfo.cpp configurationmanager.cpp ) +set(kmenueditcommon_STAT_SRCS preferencesdlg.cpp klinespellchecking.cpp basictab.cpp treeview.cpp kmenuedit.cpp menufile.cpp menuinfo.cpp configurationmanager.cpp globalaccel.cpp) ########### next target ############### qt5_add_dbus_adaptor( kmenueditcommon_STAT_SRCS org.kde.kmenuedit.xml kmenuedit.h KMenuEdit) ecm_qt_declare_logging_category(kmenueditcommon_STAT_SRCS HEADER kmenuedit_debug.h IDENTIFIER KMENUEDIT_LOG CATEGORY_NAME org.kde.kmenuedit) -if(NOT WIN32 AND KHotKeysDBusInterface_FOUND) -qt5_add_dbus_interface( - kmenueditcommon_STAT_SRCS - ${KHOTKEYS_DBUS_INTERFACE} - khotkeys_interface) -set(kmenueditcommon_STAT_SRCS ${kmenueditcommon_STAT_SRCS} khotkeys.cpp) - -add_definitions(-DWITH_HOTKEYS) -endif() - set(kmenuedit_KDEINIT_SRCS main.cpp ${kmenueditcommon_STAT_SRCS}) kf5_add_kdeinit_executable( kmenuedit ${kmenuedit_KDEINIT_SRCS}) @@ -75,6 +65,7 @@ Qt5::DBus Qt5::Xml KF5::DBusAddons + KF5::GlobalAccel KF5::I18n KF5::IconThemes KF5::KIOCore diff --git a/basictab.cpp b/basictab.cpp --- a/basictab.cpp +++ b/basictab.cpp @@ -35,9 +35,7 @@ #include #include -#ifndef Q_OS_WIN -#include "khotkeys.h" -#endif +#include "globalaccel.h" #include "klinespellchecking.h" #include "menuinfo.h" @@ -49,11 +47,6 @@ initAdvancedTab(); initConnections(); -#ifdef WITH_HOTKEYS - if (!KHotKeys::present()) { - _keyBindingGroup->hide(); - } -#endif slotDisableAction(); } @@ -349,15 +342,11 @@ _iconButton->setIcon(df->readIcon()); // key binding part -#ifdef WITH_HOTKEYS - if (KHotKeys::present()) { - if (!entryInfo->shortcut().isEmpty()) { - _keyBindingEdit->setKeySequence(entryInfo->shortcut()); - } else { - _keyBindingEdit->clearKeySequence(); - } + if (!entryInfo->shortcut().isEmpty()) { + _keyBindingEdit->setKeySequence(entryInfo->shortcut()); + } else { + _keyBindingEdit->clearKeySequence(); } -#endif _execEdit->lineEdit()->setText(df->desktopGroup().readEntry("Exec")); _pathEdit->lineEdit()->setText(df->readPath()); @@ -496,14 +485,12 @@ return; } QKeySequence cut(seq); -#ifdef WITH_HOTKEYS - if (_menuEntryInfo->isShortcutAvailable(cut) && KHotKeys::present()) { + if (_menuEntryInfo->isShortcutAvailable(cut)) { _menuEntryInfo->setShortcut(cut); } else { // We will not assign the shortcut so reset the visible key sequence _keyBindingEdit->setKeySequence(QKeySequence()); } -#endif if (_menuEntryInfo) { emit changed(_menuEntryInfo); } diff --git a/globalaccel.h b/globalaccel.h new file mode 100644 --- /dev/null +++ b/globalaccel.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef GLOBALACCEL_H +#define GLOBALACCEL_H + +#include +#include + +class GlobalAccel +{ +public: + static QKeySequence getMenuEntryShortcut(const QString &storageId); + static void changeMenuEntryShortcut(const QString &storageId, const QKeySequence &shortcut); +}; + +#endif // GLOBALACCEL_H diff --git a/globalaccel.cpp b/globalaccel.cpp new file mode 100644 --- /dev/null +++ b/globalaccel.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "globalaccel.h" + +#include +#include +#include + +#include +#include +#include + +void GlobalAccel::changeMenuEntryShortcut(const QString &storageId, const QKeySequence &shortcut) +{ + const KService::Ptr service = KService::serviceByStorageId(storageId); + const QString desktopFile = QStringLiteral("%1.desktop").arg(service->desktopEntryName()); + + if (!KGlobalAccel::isComponentActive(desktopFile)) { + const QString destination = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + QStringLiteral("/kglobalaccel/") + desktopFile; + QFile::copy(service->entryPath(), destination); + } + QAction action(i18n("Launch %1", service->name())); + action.setProperty("componentName", desktopFile); + action.setProperty("componentDisplayName", service->name()); + action.setObjectName(QStringLiteral("_launch")); + //Make sure that the action is marked active + KGlobalAccel::self()->setShortcut(&action, {shortcut}); + action.setProperty("isConfigurationAction", true); + KGlobalAccel::self()->setShortcut(&action, {shortcut}, KGlobalAccel::NoAutoloading); + +} + +QKeySequence GlobalAccel::getMenuEntryShortcut(const QString &storageId) +{ + const KService::Ptr service = KService::serviceByStorageId(storageId); + const QString desktopFile = QStringLiteral("%1.desktop").arg(service->desktopEntryName()); + const QList shortcut = KGlobalAccel::self()->globalShortcut(desktopFile, QStringLiteral("_launch")); + if (!shortcut.isEmpty()) { + return shortcut[0]; + } + return QKeySequence(); +} + + diff --git a/kconf_update/CMakeLists.txt b/kconf_update/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/kconf_update/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(kmenuedit_globalaccel globalaccel.cpp ../globalaccel.cpp) + +target_link_libraries(kmenuedit_globalaccel Qt5::DBus KF5::ConfigCore KF5::ConfigCore KF5::GlobalAccel KF5::I18n KF5::Service) + +install(TARGETS kmenuedit_globalaccel DESTINATION ${KDE_INSTALL_LIBDIR}/kconf_update_bin) diff --git a/kconf_update/globalaccel.cpp b/kconf_update/globalaccel.cpp new file mode 100644 --- /dev/null +++ b/kconf_update/globalaccel.cpp @@ -0,0 +1,62 @@ +#include +#include +#include + +#include +#include +#include +#include "kglobalaccel_interface.h" + +#include "../globalaccel.h" + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QDBusInterface khotkeys(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/khotkeys"), + QStringLiteral("org.kde.khotkeys")); + khotkeys.call(QStringLiteral("declareConfigOutDated")); + KConfig khotkeysrc(QStringLiteral("khotkeysrc"), KConfig::SimpleConfig); + const int dataCount = KConfigGroup(&khotkeysrc, "Data").readEntry("DataCount", 0); + bool foundKmenuedit = false; + int kmenueditIndex; + KConfigGroup kmenueditGroup; + for (int i = 1; i <= dataCount; ++i) { + kmenueditGroup = KConfigGroup(&khotkeysrc, QStringLiteral("Data_%1").arg(i)); + if (kmenueditGroup.readEntry("Name", QString()) == QLatin1String("KMenuEdit")) { + foundKmenuedit = true; + kmenueditIndex = i; + break; + } + } + if (!foundKmenuedit) { + return 0; + } + const int numShortcuts = kmenueditGroup.readEntry("DataCount", 0); + for (int i = 1; i <= numShortcuts; ++i) { + const QString groupName = QStringLiteral("Data_%1_%2").arg(kmenueditIndex).arg(i); + // only migrate the launch actions for now, not the default search action + if (KConfigGroup(&khotkeysrc, groupName).readEntry("Type") != QLatin1String("MENUENTRY_SHORTCUT_ACTION_DATA")) { + continue; + } + const QString storageId = KConfigGroup(&khotkeysrc, groupName + QStringLiteral("Actions0")).readEntry("CommandURL"); + const QString id = KConfigGroup(&khotkeysrc, groupName + QStringLiteral("Triggers0")).readEntry("Uuid"); + //ask globalaccel about the current shortcut rather than parsing it ourselves + const QList shortcut = KGlobalAccel::self()->globalShortcut(QStringLiteral("khotkeys"), id); + QAction action; + action.setObjectName(id); + action.setProperty("componentName", QStringLiteral("khotkeys")); + KGlobalAccel::self()->setShortcut(&action, {}); + KGlobalAccel::self()->removeAllShortcuts(&action); + if (!shortcut.isEmpty() && !shortcut[0].isEmpty()) { + GlobalAccel::changeMenuEntryShortcut(storageId, shortcut[0]); + } + khotkeysrc.deleteGroup(groupName); + khotkeysrc.deleteGroup(groupName + QStringLiteral("Actions")); + khotkeysrc.deleteGroup(groupName + QStringLiteral("Actions0")); + khotkeysrc.deleteGroup(groupName + QStringLiteral("Conditions")); + khotkeysrc.deleteGroup(groupName + QStringLiteral("Triggers")); + khotkeysrc.deleteGroup(groupName + QStringLiteral("Triggers0")); + } + khotkeysrc.sync(); + khotkeys.call(QStringLiteral("reread_configuration")); +} diff --git a/kconf_update/globalaccel.upd b/kconf_update/globalaccel.upd new file mode 100644 --- /dev/null +++ b/kconf_update/globalaccel.upd @@ -0,0 +1,4 @@ +Version=5 +Id=kmenuedit_globalaccel +File=khotkeysrc +Script=kmenuedit_globalaccel diff --git a/khotkeys.h b/khotkeys.h deleted file mode 100644 --- a/khotkeys.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2000 Matthias Elter - * Lubos Lunak - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef khotkeys_public_h -#define khotkeys_public_h - -#include - -// see kdebase/khotkeys/kcontrol for info on these - -class KHotKeys -{ -public: - static bool init(); - static void cleanup(); - static bool present(); - static QString getMenuEntryShortcut(const QString &entry_P); - static QString changeMenuEntryShortcut(const QString &entry_P, const QString shortcut_P); -}; - -#endif diff --git a/khotkeys.cpp b/khotkeys.cpp deleted file mode 100644 --- a/khotkeys.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2000 Matthias Elter - * Lubos Lunak - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "khotkeys.h" -#include "khotkeys_interface.h" - -#include "kmenuedit_debug.h" -#include -#include - -static bool khotkeys_present = false; -static bool khotkeys_inited = false; -static OrgKdeKhotkeysInterface *khotkeysInterface = nullptr; - -bool KHotKeys::init() -{ - khotkeys_inited = true; - - // Check if khotkeys is running - QDBusConnection bus = QDBusConnection::sessionBus(); - khotkeysInterface = new OrgKdeKhotkeysInterface( - QStringLiteral("org.kde.kded5"), - QStringLiteral("/modules/khotkeys"), - bus, - NULL); - - if (!khotkeysInterface->isValid()) { - QDBusError err = khotkeysInterface->lastError(); - if (err.isValid()) { - qCCritical(KMENUEDIT_LOG) << err.name() << ":" << err.message(); - } - KMessageBox::error( - NULL, - QStringLiteral("") + i18n("Unable to contact khotkeys. Your changes are saved, but they could not be activated.") + QStringLiteral("")); - } - - khotkeys_present = khotkeysInterface->isValid(); - - qCDebug(KMENUEDIT_LOG) << khotkeys_present; - return true; -} - -void KHotKeys::cleanup() -{ - if (khotkeys_inited && khotkeys_present) { - // CleanUp ??? - } - - khotkeys_inited = false; -} - -bool KHotKeys::present() -{ - qCDebug(KMENUEDIT_LOG) << khotkeys_inited; - - if (!khotkeys_inited) { - init(); - } - - qCDebug(KMENUEDIT_LOG) << khotkeys_present; - - return khotkeys_present; -} - -QString KHotKeys::getMenuEntryShortcut(const QString &entry_P) -{ - if (!khotkeys_inited) { - init(); - } - - if (!khotkeys_present || !khotkeysInterface->isValid()) { - return QLatin1String(""); - } - qCDebug(KMENUEDIT_LOG) << khotkeys_inited; - qCDebug(KMENUEDIT_LOG) << khotkeys_present; - qCDebug(KMENUEDIT_LOG) << entry_P; - QDBusReply reply = khotkeysInterface->get_menuentry_shortcut(entry_P); - if (!reply.isValid()) { - qCCritical(KMENUEDIT_LOG) << reply.error(); - return QLatin1String(""); - } else { - qCDebug(KMENUEDIT_LOG) << reply; - return reply; - } -} - -QString KHotKeys::changeMenuEntryShortcut( - const QString &entry_P, const QString shortcut_P) -{ - if (!khotkeys_inited) { - init(); - } - - if (!khotkeys_present || !khotkeysInterface->isValid()) { - return QLatin1String(""); - } - - qCDebug(KMENUEDIT_LOG) << khotkeys_inited; - qCDebug(KMENUEDIT_LOG) << khotkeys_present; - qCDebug(KMENUEDIT_LOG) << entry_P; - qCDebug(KMENUEDIT_LOG) << shortcut_P; - - QDBusReply reply = khotkeysInterface->register_menuentry_shortcut( - entry_P, - shortcut_P); - - if (!reply.isValid()) { - qCCritical(KMENUEDIT_LOG) << reply.error(); - return QLatin1String(""); - } else { - qCDebug(KMENUEDIT_LOG) << reply; - return reply; - } -} diff --git a/main.cpp b/main.cpp --- a/main.cpp +++ b/main.cpp @@ -27,9 +27,6 @@ #include #include #include "kmenuedit.h" -#ifndef Q_OS_WIN -#include "khotkeys.h" -#endif static const char description[] = I18N_NOOP("KDE menu editor"); @@ -46,14 +43,6 @@ QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); QApplication::setApplicationDisplayName(i18n("KDE Menu Editor")); } - -#ifdef WITH_HOTKEYS - virtual ~KMenuApplication() - { - KHotKeys::cleanup(); - } - -#endif }; extern "C" int Q_DECL_EXPORT kdemain(int argc, char **argv) diff --git a/menuinfo.cpp b/menuinfo.cpp --- a/menuinfo.cpp +++ b/menuinfo.cpp @@ -26,10 +26,8 @@ #include #include +#include "globalaccel.h" #include "menufile.h" -#ifdef WITH_HOTKEYS -#include "khotkeys.h" -#endif // // MenuFolderInfo @@ -179,14 +177,12 @@ void MenuFolderInfo::save(MenuFile *menuFile) { if (s_deletedApps) { -#ifdef WITH_HOTKEYS // Remove hotkeys for applications that have been deleted for (QStringList::ConstIterator it = s_deletedApps->constBegin(); it != s_deletedApps->constEnd(); ++it) { // The shorcut is deleted if we set a empty sequence - KHotKeys::changeMenuEntryShortcut(*it, QLatin1String("")); + GlobalAccel::changeMenuEntryShortcut(*it, QKeySequence()); } -#endif delete s_deletedApps; s_deletedApps = nullptr; } @@ -327,14 +323,10 @@ m_desktopFile->sync(); dirty = false; } -#ifdef WITH_HOTKEYS if (shortcutDirty) { - if (KHotKeys::present()) { - KHotKeys::changeMenuEntryShortcut(service->storageId(), shortCut.toString()); - } + GlobalAccel::changeMenuEntryShortcut(service->storageId(), shortCut); shortcutDirty = false; } -#endif } void MenuEntryInfo::setCaption(const QString &_caption) @@ -370,14 +362,10 @@ QKeySequence MenuEntryInfo::shortcut() { -#ifdef WITH_HOTKEYS if (!shortcutLoaded) { shortcutLoaded = true; - if (KHotKeys::present()) { - shortCut = QKeySequence(KHotKeys::getMenuEntryShortcut(service->storageId())); - } + shortCut = GlobalAccel::getMenuEntryShortcut(service->storageId()); } -#endif return shortCut; }