diff --git a/CMakeLists.txt b/CMakeLists.txt index c680c38..457d15f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,105 +1,96 @@ project(kmenuedit) set(PROJECT_VERSION "5.17.80") cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(QT_MIN_VERSION "5.12.0") set(KF5_MIN_VERSION "5.62.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(FeatureSummary) include(ECMAddAppIcon) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMQtDeclareLoggingCategory) include(KDEClangFormat) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core DBus Xml ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS I18n XmlGui DBusAddons IconThemes KIO ItemViews 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}) target_compile_definitions(kdeinit_kmenuedit PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") target_link_libraries(kdeinit_kmenuedit Qt5::DBus Qt5::Xml KF5::DBusAddons + KF5::GlobalAccel KF5::I18n KF5::IconThemes KF5::KIOCore KF5::KIOWidgets KF5::ItemViews KF5::SonnetCore KF5::SonnetUi KF5::XmlGui ) # add clang-format target for all our real source files file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) install(TARGETS kdeinit_kmenuedit DESTINATION ${KDE_INSTALL_LIBDIR} ) target_link_libraries( kmenuedit kdeinit_kmenuedit ) install(TARGETS kmenuedit ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) ########### install files ############### install( PROGRAMS org.kde.kmenuedit.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) install( FILES kmenueditui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/kmenuedit ) ecm_install_icons( ICONS 16-apps-kmenuedit.png 22-apps-kmenuedit.png 32-apps-kmenuedit.png 48-apps-kmenuedit.png DESTINATION ${KDE_INSTALL_ICONDIR} THEME hicolor ) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) install(FILES kmenuedit.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) diff --git a/basictab.cpp b/basictab.cpp index 88a417b..fc327db 100644 --- a/basictab.cpp +++ b/basictab.cpp @@ -1,519 +1,506 @@ /* * Copyright (C) 2000 Matthias Elter * Copyright (C) 2008 Laurent Montel * * 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 "basictab.h" #include #include #include #include #include #include #include #include #include #include #include #include #include -#ifndef Q_OS_WIN -#include "khotkeys.h" -#endif +#include "globalaccel.h" #include "klinespellchecking.h" #include "menuinfo.h" BasicTab::BasicTab(QWidget *parent) : QTabWidget(parent) { initGeneralTab(); initAdvancedTab(); initConnections(); -#ifdef WITH_HOTKEYS - if (!KHotKeys::present()) { - _keyBindingGroup->hide(); - } -#endif slotDisableAction(); } void BasicTab::initGeneralTab() { // general tab QWidget *generalTab = new QWidget(); QGridLayout *generalTabLayout = new QGridLayout(generalTab); generalTab->setAcceptDrops(false); // name _nameLabel = new QLabel(i18n("&Name:")); generalTabLayout->addWidget(_nameLabel, 0, 0); _nameEdit = new QLineEdit(); _nameEdit->setAcceptDrops(false); _nameEdit->setClearButtonEnabled(true); _nameLabel->setBuddy(_nameEdit); generalTabLayout->addWidget(_nameEdit, 0, 1, 1, 1); // description _descriptionLabel = new QLabel(i18n("&Description:")); generalTabLayout->addWidget(_descriptionLabel, 1, 0); _descriptionEdit = new KLineSpellChecking(); _descriptionEdit->setAcceptDrops(false); _descriptionLabel->setBuddy(_descriptionEdit); generalTabLayout->addWidget(_descriptionEdit, 1, 1, 1, 1); // comment _commentLabel = new QLabel(i18n("&Comment:")); generalTabLayout->addWidget(_commentLabel, 2, 0); _commentEdit = new KLineSpellChecking(); _commentEdit->setAcceptDrops(false); _commentLabel->setBuddy(_commentEdit); generalTabLayout->addWidget(_commentEdit, 2, 1, 1, 2); // command _execLabel = new QLabel(i18n("Co&mmand:")); generalTabLayout->addWidget(_execLabel, 3, 0); _execEdit = new KUrlRequester(); _execEdit->lineEdit()->setAcceptDrops(false); _execEdit->setWhatsThis(i18n( "Following the command, you can have several place holders which will be replaced " "with the actual values when the actual program is run:\n" "%f - a single file name\n" "%F - a list of files; use for applications that can open several local files at once\n" "%u - a single URL\n" "%U - a list of URLs\n" "%d - the folder of the file to open\n" "%D - a list of folders\n" "%i - the icon\n" "%m - the mini-icon\n" "%c - the caption")); _execLabel->setBuddy(_execEdit); generalTabLayout->addWidget(_execEdit, 3, 1, 1, 2); // launch feedback _launchCB = new QCheckBox(i18n("Enable &launch feedback")); generalTabLayout->addWidget(_launchCB, 4, 0, 1, 3); // KDE visibility _onlyShowInKdeCB = new QCheckBox(i18n("Only show in KDE")); generalTabLayout->addWidget(_onlyShowInKdeCB, 5, 0, 1, 3); // hidden entry _hiddenEntryCB = new QCheckBox(i18n("Hidden entry")); _hiddenEntryCB->hide(); generalTabLayout->addWidget(_hiddenEntryCB, 6, 0, 1, 3); // icon _iconButton = new KIconButton(); _iconButton->setFixedSize(56, 56); _iconButton->setIconSize(32); generalTabLayout->addWidget(_iconButton, 0, 2, 2, 1); generalTabLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 8, 0, 1, 3); // add the general group addTab(generalTab, i18n("General")); } void BasicTab::initAdvancedTab() { // advanced tab QWidget *advancedTab = new QWidget(); QVBoxLayout *advancedTabLayout = new QVBoxLayout(advancedTab); // work path _workPathGroup = new QGroupBox(); QHBoxLayout *workPathGroupLayout = new QHBoxLayout(_workPathGroup); _pathLabel = new QLabel(i18n("&Work path:")); workPathGroupLayout->addWidget(_pathLabel); _pathEdit = new KUrlRequester(); _pathEdit->setMode(KFile::Directory | KFile::LocalOnly); _pathEdit->lineEdit()->setAcceptDrops(false); _pathLabel->setBuddy(_pathEdit); workPathGroupLayout->addWidget(_pathEdit); advancedTabLayout->addWidget(_workPathGroup); // terminal CB _terminalGroup = new QGroupBox(); QVBoxLayout *terminalGroupLayout = new QVBoxLayout(_terminalGroup); _terminalCB = new QCheckBox(i18n("Run in term&inal")); terminalGroupLayout->addWidget(_terminalCB); // terminal options QWidget *terminalOptionsGroup = new QWidget(); QHBoxLayout *terminalOptionsGroupLayout = new QHBoxLayout(terminalOptionsGroup); _terminalOptionsLabel = new QLabel(i18n("Terminal &options:")); terminalOptionsGroupLayout->addWidget(_terminalOptionsLabel); _terminalOptionsEdit = new QLineEdit(); _terminalOptionsEdit->setClearButtonEnabled(true); _terminalOptionsEdit->setAcceptDrops(false); _terminalOptionsEdit->setEnabled(false); _terminalOptionsLabel->setBuddy(_terminalOptionsEdit); terminalOptionsGroupLayout->addWidget(_terminalOptionsEdit); terminalGroupLayout->addWidget(terminalOptionsGroup); advancedTabLayout->addWidget(_terminalGroup); // user name CB _userGroup = new QGroupBox(); QVBoxLayout *userGroupLayout = new QVBoxLayout(_userGroup); _userCB = new QCheckBox(i18n("&Run as a different user")); userGroupLayout->addWidget(_userCB); // user name QWidget *userNameGroup = new QWidget(); QHBoxLayout *userNameGroupLayout = new QHBoxLayout(userNameGroup); _userNameLabel = new QLabel(i18n("&Username:")); userNameGroupLayout->addWidget(_userNameLabel); _userNameEdit = new QLineEdit(); _userNameEdit->setClearButtonEnabled(true); _userNameEdit->setAcceptDrops(false); _userNameEdit->setEnabled(false); _userNameLabel->setBuddy(_userNameEdit); userNameGroupLayout->addWidget(_userNameEdit); userGroupLayout->addWidget(userNameGroup); advancedTabLayout->addWidget(_userGroup); // key binding _keyBindingGroup = new QGroupBox(); QHBoxLayout *keyBindingGroupLayout = new QHBoxLayout(_keyBindingGroup); _keyBindingLabel = new QLabel(i18n("Current shortcut &key:")); keyBindingGroupLayout->addWidget(_keyBindingLabel); _keyBindingEdit = new KKeySequenceWidget(); _keyBindingEdit->setMultiKeyShortcutsAllowed(false); _keyBindingLabel->setBuddy(_keyBindingEdit); keyBindingGroupLayout->addWidget(_keyBindingEdit); advancedTabLayout->addWidget(_keyBindingGroup); // push components to the top advancedTabLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding)); // add the general group addTab(advancedTab, i18n("Advanced")); } void BasicTab::initConnections() { // general tab's components connect(_nameEdit, &QLineEdit::textChanged, this, &BasicTab::slotChanged); connect(_descriptionEdit, &KLineSpellChecking::textChanged, this, &BasicTab::slotChanged); connect(_commentEdit, &KLineSpellChecking::textChanged, this, &BasicTab::slotChanged); connect(_execEdit, &KUrlRequester::textChanged, this, &BasicTab::slotChanged); connect(_execEdit, &KUrlRequester::urlSelected, this, &BasicTab::slotExecSelected); connect(_launchCB, &QCheckBox::clicked, this, &BasicTab::launchcb_clicked); connect(_onlyShowInKdeCB, &QCheckBox::clicked, this, &BasicTab::onlyshowcb_clicked); connect(_hiddenEntryCB, &QCheckBox::clicked, this, &BasicTab::hiddenentrycb_clicked); connect(_iconButton, &KIconButton::iconChanged, this, &BasicTab::slotChanged); // advanced tab's components connect(_pathEdit, &KUrlRequester::textChanged, this, &BasicTab::slotChanged); connect(_terminalCB, &QCheckBox::clicked, this, &BasicTab::termcb_clicked); connect(_terminalOptionsEdit, &QLineEdit::textChanged, this, &BasicTab::slotChanged); connect(_userCB, &QCheckBox::clicked, this, &BasicTab::uidcb_clicked); connect(_userNameEdit, &QLineEdit::textChanged, this, &BasicTab::slotChanged); connect(_keyBindingEdit, &KKeySequenceWidget::keySequenceChanged, this, &BasicTab::slotCapturedKeySequence); } void BasicTab::slotDisableAction() { //disable all group at the beginning. //because there is not file selected. _nameEdit->setEnabled(false); _descriptionEdit->setEnabled(false); _commentEdit->setEnabled(false); _execEdit->setEnabled(false); _launchCB->setEnabled(false); _onlyShowInKdeCB->setEnabled(false); _hiddenEntryCB->setEnabled(false); _nameLabel->setEnabled(false); _descriptionLabel->setEnabled(false); _commentLabel->setEnabled(false); _execLabel->setEnabled(false); _workPathGroup->setEnabled(false); _terminalGroup->setEnabled(false); _userGroup->setEnabled(false); _iconButton->setEnabled(false); // key binding part _keyBindingGroup->setEnabled(false); } void BasicTab::enableWidgets(bool isDF, bool isDeleted) { // set only basic attributes if it is not a .desktop file _nameEdit->setEnabled(!isDeleted); _descriptionEdit->setEnabled(!isDeleted); _commentEdit->setEnabled(!isDeleted); _iconButton->setEnabled(!isDeleted); _execEdit->setEnabled(isDF && !isDeleted); _launchCB->setEnabled(isDF && !isDeleted); _onlyShowInKdeCB->setEnabled(isDF && !isDeleted); _hiddenEntryCB->setEnabled(isDF && !isDeleted); _nameLabel->setEnabled(!isDeleted); _descriptionLabel->setEnabled(!isDeleted); _commentLabel->setEnabled(!isDeleted); _execLabel->setEnabled(isDF && !isDeleted); _workPathGroup->setEnabled(isDF && !isDeleted); _terminalGroup->setEnabled(isDF && !isDeleted); _userGroup->setEnabled(isDF && !isDeleted); _keyBindingGroup->setEnabled(isDF && !isDeleted); _terminalOptionsEdit->setEnabled(isDF && !isDeleted && _terminalCB->isChecked()); _terminalOptionsLabel->setEnabled(isDF && !isDeleted && _terminalCB->isChecked()); _userNameEdit->setEnabled(isDF && !isDeleted && _userCB->isChecked()); _userNameLabel->setEnabled(isDF && !isDeleted && _userCB->isChecked()); } void BasicTab::setFolderInfo(MenuFolderInfo *folderInfo) { blockSignals(true); _menuFolderInfo = folderInfo; _menuEntryInfo = 0; _nameEdit->setText(folderInfo->caption); _descriptionEdit->setText(folderInfo->genericname); _descriptionEdit->setCursorPosition(0); _commentEdit->setText(folderInfo->comment); _commentEdit->setCursorPosition(0); _iconButton->setIcon(folderInfo->icon); // clean all disabled fields and return _execEdit->lineEdit()->clear(); _pathEdit->lineEdit()->clear(); _terminalOptionsEdit->clear(); _userNameEdit->clear(); _launchCB->setChecked(false); _terminalCB->setChecked(false); _onlyShowInKdeCB->setChecked(false); _hiddenEntryCB->setChecked(false); _userCB->setChecked(false); _keyBindingEdit->clearKeySequence(); enableWidgets(false, folderInfo->hidden); blockSignals(false); } void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo) { blockSignals(true); _menuFolderInfo = 0; _menuEntryInfo = entryInfo; if (!entryInfo) { _nameEdit->clear(); _descriptionEdit->clear(); _commentEdit->clear(); _iconButton->setIcon(QString()); // key binding part _keyBindingEdit->clearKeySequence(); _execEdit->lineEdit()->clear(); _onlyShowInKdeCB->setChecked(false); _hiddenEntryCB->setChecked(false); _pathEdit->lineEdit()->clear(); _terminalOptionsEdit->clear(); _userNameEdit->clear(); _launchCB->setChecked(false); _terminalCB->setChecked(false); _userCB->setChecked(false); enableWidgets(true, true); blockSignals(false); return; } KDesktopFile *df = entryInfo->desktopFile(); _nameEdit->setText(df->readName()); _descriptionEdit->setText(df->readGenericName()); _descriptionEdit->setCursorPosition(0); _commentEdit->setText(df->readComment()); _commentEdit->setCursorPosition(0); _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()); _terminalOptionsEdit->setText(df->desktopGroup().readEntry("TerminalOptions")); _userNameEdit->setText(df->desktopGroup().readEntry("X-KDE-Username")); if (df->desktopGroup().hasKey("StartupNotify")) { _launchCB->setChecked(df->desktopGroup().readEntry("StartupNotify", true)); } else { // backwards comp. _launchCB->setChecked(df->desktopGroup().readEntry("X-KDE-StartupNotify", true)); } _onlyShowInKdeCB->setChecked(df->desktopGroup().readXdgListEntry("OnlyShowIn").contains(QLatin1String("KDE"))); // or maybe enable only if it contains nothing but KDE? if (df->desktopGroup().hasKey("NoDisplay")) { _hiddenEntryCB->setChecked(df->desktopGroup().readEntry("NoDisplay", true)); } else { _hiddenEntryCB->setChecked(false); } if (df->desktopGroup().readEntry("Terminal", 0) == 1) { _terminalCB->setChecked(true); } else { _terminalCB->setChecked(false); } _userCB->setChecked(df->desktopGroup().readEntry("X-KDE-SubstituteUID", false)); enableWidgets(true, entryInfo->hidden); blockSignals(false); } void BasicTab::apply() { if (_menuEntryInfo) { _menuEntryInfo->setDirty(); _menuEntryInfo->setCaption(_nameEdit->text()); _menuEntryInfo->setDescription(_descriptionEdit->text()); _menuEntryInfo->setIcon(_iconButton->icon()); KDesktopFile *df = _menuEntryInfo->desktopFile(); KConfigGroup dg = df->desktopGroup(); dg.writeEntry("Comment", _commentEdit->text()); dg.writeEntry("Exec", _execEdit->lineEdit()->text()); dg.writePathEntry("Path", _pathEdit->lineEdit()->text()); if (_terminalCB->isChecked()) { dg.writeEntry("Terminal", 1); } else { dg.writeEntry("Terminal", 0); } dg.writeEntry("TerminalOptions", _terminalOptionsEdit->text()); dg.writeEntry("X-KDE-SubstituteUID", _userCB->isChecked()); dg.writeEntry("X-KDE-Username", _userNameEdit->text()); dg.writeEntry("StartupNotify", _launchCB->isChecked()); dg.writeEntry("NoDisplay", _hiddenEntryCB->isChecked()); QStringList onlyShowIn = df->desktopGroup().readXdgListEntry("OnlyShowIn"); /* the exact semantics of this checkbox are unclear if there is more than just KDE in the list... * For example: - The list is "Gnome;", the user enables "Only show in KDE" - should we remove Gnome? * - The list is "Gnome;KDE;", the user unchecks the box - should we keep Gnome? */ if (_onlyShowInKdeCB->isChecked() && !onlyShowIn.contains(QLatin1String("KDE"))) { onlyShowIn << QStringLiteral("KDE"); } else if (!_onlyShowInKdeCB->isChecked() && onlyShowIn.contains(QLatin1String("KDE"))) { onlyShowIn.removeAll(QStringLiteral("KDE")); } if (onlyShowIn.isEmpty()) { dg.deleteEntry("OnlyShowIn"); } else { dg.writeXdgListEntry("OnlyShowIn", onlyShowIn); } } else { _menuFolderInfo->setCaption(_nameEdit->text()); _menuFolderInfo->setGenericName(_descriptionEdit->text()); _menuFolderInfo->setComment(_commentEdit->text()); _menuFolderInfo->setIcon(_iconButton->icon()); } } void BasicTab::slotChanged() { if (signalsBlocked()) { return; } apply(); if (_menuEntryInfo) { emit changed(_menuEntryInfo); } else { emit changed(_menuFolderInfo); } } void BasicTab::launchcb_clicked() { slotChanged(); } void BasicTab::onlyshowcb_clicked() { slotChanged(); } void BasicTab::hiddenentrycb_clicked() { slotChanged(); } void BasicTab::termcb_clicked() { _terminalOptionsEdit->setEnabled(_terminalCB->isChecked()); _terminalOptionsLabel->setEnabled(_terminalCB->isChecked()); slotChanged(); } void BasicTab::uidcb_clicked() { _userNameEdit->setEnabled(_userCB->isChecked()); _userNameLabel->setEnabled(_userCB->isChecked()); slotChanged(); } void BasicTab::slotExecSelected() { QString path = _execEdit->lineEdit()->text(); if (!path.startsWith(QLatin1Char('\''))) { _execEdit->lineEdit()->setText(KShell::quoteArg(path)); } } void BasicTab::slotCapturedKeySequence(const QKeySequence &seq) { if (signalsBlocked()) { 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); } } void BasicTab::updateHiddenEntry(bool show) { if (show) { _hiddenEntryCB->show(); } else { _hiddenEntryCB->hide(); } } diff --git a/globalaccel.cpp b/globalaccel.cpp new file mode 100644 index 0000000..a1fc99d --- /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/globalaccel.h b/globalaccel.h new file mode 100644 index 0000000..547185d --- /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/kconf_update/CMakeLists.txt b/kconf_update/CMakeLists.txt new file mode 100644 index 0000000..9a17675 --- /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 index 0000000..4af350e --- /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 index 0000000..ec69684 --- /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.cpp b/khotkeys.cpp deleted file mode 100644 index 4640d17..0000000 --- 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/khotkeys.h b/khotkeys.h deleted file mode 100644 index af3fc37..0000000 --- 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/main.cpp b/main.cpp index 745a078..d63a47f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,105 +1,94 @@ /* * Copyright (C) 2000 Matthias Elter * Copyright (C) 2001-2002 Raffaele Sandrini #include #include #include #include #include #include "kmenuedit.h" -#ifndef Q_OS_WIN -#include "khotkeys.h" -#endif static const char description[] = I18N_NOOP("KDE menu editor"); static KMenuEdit *menuEdit = nullptr; class KMenuApplication : public QApplication { public: KMenuApplication(int &argc, char **argv) : QApplication(argc, argv) { QCoreApplication::setApplicationName(QStringLiteral("kmenuedit")); QCoreApplication::setApplicationVersion(QLatin1String(PROJECT_VERSION)); 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) { KMenuApplication app(argc, argv); Kdelibs4ConfigMigrator migrate(QStringLiteral("kmenuedit")); migrate.setConfigFiles(QStringList() << QStringLiteral("kmenueditrc")); migrate.setUiFiles(QStringList() << QStringLiteral("kmenueditui.rc")); migrate.migrate(); QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); KLocalizedString::setApplicationDomain("kmenuedit"); KAboutData aboutData(QStringLiteral("kmenuedit"), i18n("KDE Menu Editor"), QLatin1String(PROJECT_VERSION), i18n(description), KAboutLicense::GPL, i18n("(C) 2000-2003, Waldo Bastian, Raffaele Sandrini, Matthias Elter")); aboutData.addAuthor(i18n("Waldo Bastian"), i18n("Maintainer"), QStringLiteral("bastian@kde.org")); aboutData.addAuthor(i18n("Raffaele Sandrini"), i18n("Previous Maintainer"), QStringLiteral("sandrini@kde.org")); aboutData.addAuthor(i18n("Matthias Elter"), i18n("Original Author"), QStringLiteral("elter@kde.org")); aboutData.addAuthor(i18n("Montel Laurent"), QString(), QStringLiteral("montel@kde.org")); KAboutData::setApplicationData(aboutData); KDBusService service(KDBusService::Unique); QCommandLineParser parser; parser.setApplicationDescription(i18n("KDE Menu Editor")); parser.addPositionalArgument(QStringLiteral("menu"), i18n("Sub menu to pre-select"), QStringLiteral("[menu]")); parser.addPositionalArgument(QStringLiteral("menu-id"), i18n("Menu entry to pre-select"), QStringLiteral("[menu-id]")); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); const auto args = parser.positionalArguments(); menuEdit = new KMenuEdit(); if (!args.isEmpty()) { menuEdit->selectMenu(args.at(0)); if (args.count() > 1) { menuEdit->selectMenuEntry(args.at(1)); } } menuEdit->show(); return app.exec(); } diff --git a/menuinfo.cpp b/menuinfo.cpp index 2ba2ce6..4d43c5f 100644 --- a/menuinfo.cpp +++ b/menuinfo.cpp @@ -1,477 +1,465 @@ /* * Copyright (C) 2003 Waldo Bastian * * 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 "menuinfo.h" #include #include #include #include +#include "globalaccel.h" #include "menufile.h" -#ifdef WITH_HOTKEYS -#include "khotkeys.h" -#endif // // MenuFolderInfo // static QStringList *s_newShortcuts = nullptr; static QStringList *s_freeShortcuts = nullptr; static QStringList *s_deletedApps = nullptr; // Add separator MenuFolderInfo::~MenuFolderInfo() { qDeleteAll(subFolders); subFolders.clear(); } void MenuFolderInfo::add(MenuSeparatorInfo *info, bool initial) { if (initial) { initialLayout.append(info); } } // Add sub menu void MenuFolderInfo::add(MenuFolderInfo *info, bool initial) { subFolders.append(info); if (initial) { initialLayout.append(info); } } // Remove sub menu (without deleting it) void MenuFolderInfo::take(MenuFolderInfo *info) { subFolders.removeAll(info); } // Remove sub menu (without deleting it) bool MenuFolderInfo::takeRecursive(MenuFolderInfo *info) { if (subFolders.removeAll(info) > 0) { return true; } foreach (MenuFolderInfo *subFolderInfo, subFolders) { if (subFolderInfo->takeRecursive(info)) { return true; } } return false; } // Recursively update all fullIds void MenuFolderInfo::updateFullId(const QString &parentId) { fullId = parentId + id; foreach (MenuFolderInfo *subFolderInfo, subFolders) { subFolderInfo->updateFullId(fullId); } } // Add entry void MenuFolderInfo::add(MenuEntryInfo *entry, bool initial) { entries.append(entry); if (initial) { initialLayout.append(entry); } } // Remove entry void MenuFolderInfo::take(MenuEntryInfo *entry) { entries.removeAll(entry); } // Return a unique sub-menu caption inspired by @p caption QString MenuFolderInfo::uniqueMenuCaption(const QString &caption) { QRegExp r(QStringLiteral("(.*)(?=-\\d+)")); QString cap = (r.indexIn(caption) > -1) ? r.cap(1) : caption; QString result = caption; for (int n = 1; ++n;) { bool ok = true; foreach (MenuFolderInfo *subFolderInfo, subFolders) { if (subFolderInfo->caption == result) { ok = false; break; } } if (ok) { return result; } result = cap + QStringLiteral("-%1").arg(n); } return QString(); // Never reached } // Return a unique item caption inspired by @p caption QString MenuFolderInfo::uniqueItemCaption(const QString &caption, const QString &exclude) { QRegExp r(QStringLiteral("(.*)(?=-\\d+)")); QString cap = (r.indexIn(caption) > -1) ? r.cap(1) : caption; QString result = caption; for (int n = 1; ++n;) { bool ok = true; if (result == exclude) { ok = false; } foreach (MenuEntryInfo *entryInfo, entries) { if (entryInfo->caption == result) { ok = false; break; } } if (ok) { return result; } result = cap + QStringLiteral("-%1").arg(n); } return QString(); // Never reached } // Return a list of existing submenu ids QStringList MenuFolderInfo::existingMenuIds() { QStringList result; foreach (MenuFolderInfo *subFolderInfo, subFolders) { result.append(subFolderInfo->id); } return result; } void MenuFolderInfo::setDirty() { dirty = true; } 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; } if (dirty) { QString local = KDesktopFile::locateLocal(directoryFile); KDesktopFile *df = nullptr; if (directoryFile != local) { KDesktopFile orig(QStandardPaths::ApplicationsLocation, directoryFile); df = orig.copyTo(local); } else { df = new KDesktopFile(QStandardPaths::ApplicationsLocation, directoryFile); } KConfigGroup dg(df->desktopGroup()); dg.writeEntry("Name", caption); dg.writeEntry("GenericName", genericname); dg.writeEntry("Comment", comment); dg.writeEntry("Icon", icon); dg.sync(); delete df; dirty = false; } // Save sub-menus foreach (MenuFolderInfo *subFolderInfo, subFolders) { subFolderInfo->save(menuFile); } // Save entries foreach (MenuEntryInfo *entryInfo, entries) { if (entryInfo->needInsertion()) { menuFile->addEntry(fullId, entryInfo->menuId()); } entryInfo->save(); } } bool MenuFolderInfo::hasDirt() { if (dirty) { return true; } // Check sub-menus foreach (MenuFolderInfo *subFolderInfo, subFolders) { if (subFolderInfo->hasDirt()) { return true; } } // Check entries foreach (MenuEntryInfo *entryInfo, entries) { if (entryInfo->dirty || entryInfo->shortcutDirty) { return true; } } return false; } KService::Ptr MenuFolderInfo::findServiceShortcut(const QKeySequence &cut) { KService::Ptr result; // Check sub-menus foreach (MenuFolderInfo *subFolderInfo, subFolders) { result = subFolderInfo->findServiceShortcut(cut); if (result) { return result; } } // Check entries foreach (MenuEntryInfo *entryInfo, entries) { if (entryInfo->shortCut == cut) { return entryInfo->service; } } return KService::Ptr(); } void MenuFolderInfo::setInUse(bool inUse) { // Propagate to sub-menus foreach (MenuFolderInfo *subFolderInfo, subFolders) { subFolderInfo->setInUse(inUse); } // Propagate to entries foreach (MenuEntryInfo *entryInfo, entries) { entryInfo->setInUse(inUse); } } // // MenuEntryInfo // MenuEntryInfo::~MenuEntryInfo() { m_desktopFile->markAsClean(); delete m_desktopFile; } KDesktopFile *MenuEntryInfo::desktopFile() { if (!m_desktopFile) { m_desktopFile = new KDesktopFile(service->entryPath()); } return m_desktopFile; } void MenuEntryInfo::setDirty() { if (dirty) { return; } dirty = true; QString local = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + QLatin1Char('/') + service->menuId(); if (local != service->entryPath()) { KDesktopFile *oldDf = desktopFile(); m_desktopFile = oldDf->copyTo(local); delete oldDf; } } bool MenuEntryInfo::needInsertion() { // If entry is dirty and previously stored under applnk, then we need to be added explicitly return dirty && !service->entryPath().startsWith(QLatin1Char('/')); } void MenuEntryInfo::save() { if (dirty) { 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) { if (caption == _caption) { return; } caption = _caption; setDirty(); desktopFile()->desktopGroup().writeEntry("Name", caption); } void MenuEntryInfo::setDescription(const QString &_description) { if (description == _description) { return; } description = _description; setDirty(); desktopFile()->desktopGroup().writeEntry("GenericName", description); } void MenuEntryInfo::setIcon(const QString &_icon) { if (icon == _icon) { return; } icon = _icon; setDirty(); desktopFile()->desktopGroup().writeEntry("Icon", icon); } 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; } static void freeShortcut(const QKeySequence &shortCut) { if (!shortCut.isEmpty()) { QString shortcutKey = shortCut.toString(); if (s_newShortcuts) { s_newShortcuts->removeAll(shortcutKey); } if (!s_freeShortcuts) { s_freeShortcuts = new QStringList; } s_freeShortcuts->append(shortcutKey); } } static void allocateShortcut(const QKeySequence &shortCut) { if (!shortCut.isEmpty()) { QString shortcutKey = shortCut.toString(); if (s_freeShortcuts) { s_freeShortcuts->removeAll(shortcutKey); } if (!s_newShortcuts) { s_newShortcuts = new QStringList; } s_newShortcuts->append(shortcutKey); } } void MenuEntryInfo::setShortcut(const QKeySequence &_shortcut) { if (shortCut == _shortcut) { return; } freeShortcut(shortCut); allocateShortcut(_shortcut); shortCut = _shortcut; if (shortCut.isEmpty()) { shortCut = QKeySequence(); // Normalize } shortcutLoaded = true; shortcutDirty = true; } void MenuEntryInfo::setInUse(bool inUse) { if (inUse) { QKeySequence temp = shortcut(); shortCut = QKeySequence(); if (isShortcutAvailable(temp)) { shortCut = temp; } else { shortcutDirty = true; } allocateShortcut(shortCut); if (s_deletedApps) { s_deletedApps->removeAll(service->storageId()); } } else { freeShortcut(shortcut()); // Add to list of deleted apps if (!s_deletedApps) { s_deletedApps = new QStringList; } s_deletedApps->append(service->storageId()); } } bool MenuEntryInfo::isShortcutAvailable(const QKeySequence &_shortcut) { // We only have to check agains not saved local shortcuts. // KKeySequenceWidget checks against all other registered shortcuts. if (shortCut == _shortcut) { return true; } QString shortcutKey = _shortcut.toString(); bool available = true; if (available && s_newShortcuts) { available = !s_newShortcuts->contains(shortcutKey); } if (!available && s_freeShortcuts) { available = s_freeShortcuts->contains(shortcutKey); } return available; }