diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/dolphincontextmenu.cpp | 2 | ||||
| -rw-r--r-- | src/dolphinmainwindow.cpp | 22 | ||||
| -rw-r--r-- | src/dolphinmainwindow.h | 2 | ||||
| -rw-r--r-- | src/servicemenushortcutmanager.cpp | 81 | ||||
| -rw-r--r-- | src/servicemenushortcutmanager.h | 42 |
6 files changed, 152 insertions, 4 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cf10f486..4faabe9d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -457,6 +457,13 @@ if(HAVE_KUSERFEEDBACK) ) endif() +if(KF6KIO_VERSION VERSION_GREATER_EQUAL "6.24.0") + target_sources(dolphinstatic PRIVATE + servicemenushortcutmanager.cpp + servicemenushortcutmanager.h + ) +endif() + kconfig_add_kcfg_files(dolphinstatic panels/folders/dolphin_folderspanelsettings.kcfgc panels/places/dolphin_placespanelsettings.kcfgc diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index 577990e19..6fb362039 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -268,8 +268,6 @@ void DolphinContextMenu::addItemContextMenu() const KFileItemListProperties &selectedItemsProps = selectedItemsProperties(); - m_fileItemActions->setItemListProperties(selectedItemsProps); - if (m_selectedItems.count() == 1) { // single files if (m_fileInfo.isDir()) { diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 62ff2fa45..110bef2f3 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -28,6 +28,9 @@ #include "panels/terminal/terminalpanel.h" #include "search/dolphinquery.h" #include "selectionmode/actiontexthelper.h" +#if KIO_VERSION >= QT_VERSION_CHECK(6, 24, 0) +#include "servicemenushortcutmanager.h" +#endif #include "settings/dolphinsettingsdialog.h" #include "statusbar/diskspaceusagemenu.h" #include "statusbar/dolphinstatusbar.h" @@ -206,6 +209,11 @@ DolphinMainWindow::DolphinMainWindow() setupDockWidgets(); +#if KIO_VERSION >= QT_VERSION_CHECK(6, 24, 0) + m_serviceMenuShortcutManager = new ServiceMenuShortcutManager(actionCollection(), this); +#endif + setupFileItemActions(); + const bool usePhoneUi{KRuntimePlatform::runtimePlatform().contains(QLatin1String("phone"))}; setupGUI(Save | Create | ToolBar, usePhoneUi ? QStringLiteral("dolphinuiforphones.rc") : QString() /* load the default dolphinui.rc file */); stateChanged(QStringLiteral("new_file")); @@ -256,8 +264,6 @@ DolphinMainWindow::DolphinMainWindow() QTimer::singleShot(0, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction); - setupFileItemActions(); - m_serviceMenuConfigWatcher = KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kservicemenurc"))); connect(m_serviceMenuConfigWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup & /*group*/, const QByteArrayList & /*names*/) { setupFileItemActions(); @@ -431,6 +437,10 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList &selection) { updateFileAndEditActions(); + if (m_fileItemActions) { + m_fileItemActions->setItemListProperties(KFileItemListProperties(selection)); + } + const int selectedUrlsCount = m_tabWidget->currentTabPage()->selectedItemsCount(); QAction *compareFilesAction = actionCollection()->action(QStringLiteral("compare_files")); @@ -1783,6 +1793,10 @@ void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString &mo void DolphinMainWindow::slotKeyBindings() { +#if KIO_VERSION >= QT_VERSION_CHECK(6, 24, 0) + m_serviceMenuShortcutManager->cleanupStaleShortcuts(this); +#endif + KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this); dialog.addCollection(actionCollection()); if (m_terminalPanel) { @@ -2624,6 +2638,10 @@ void DolphinMainWindow::setupFileItemActions() connect(m_fileItemActions, &KFileItemActions::error, this, [this](const QString &errorMessage) { showErrorMessage(errorMessage); }); + +#if KIO_VERSION >= QT_VERSION_CHECK(6, 24, 0) + m_serviceMenuShortcutManager->refresh(m_fileItemActions); +#endif } void DolphinMainWindow::updateFileAndEditActions() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index a03d566d0..cd9f238aa 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -49,6 +49,7 @@ class KToolBarPopupAction; class QToolButton; class PlacesPanel; class TerminalPanel; +class ServiceMenuShortcutManager; /** Used to identify that a custom command should be triggered on a view background double-click.*/ constexpr QLatin1String customCommand{"CUSTOM_COMMAND"}; @@ -801,6 +802,7 @@ private: QMenu m_searchTools; KConfigWatcher::Ptr m_serviceMenuConfigWatcher; KFileItemActions *m_fileItemActions = nullptr; + ServiceMenuShortcutManager *m_serviceMenuShortcutManager = nullptr; QTimer *m_sessionSaveTimer; QFutureWatcher<void> *m_sessionSaveWatcher; diff --git a/src/servicemenushortcutmanager.cpp b/src/servicemenushortcutmanager.cpp new file mode 100644 index 000000000..ea13fc5f8 --- /dev/null +++ b/src/servicemenushortcutmanager.cpp @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2026 Albert Mkhitaryan <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <servicemenushortcutmanager.h> + +#include <KActionCategory> +#include <KActionCollection> +#include <KDesktopFileAction> +#include <KFileItemActions> +#include <KLocalizedString> +#include <KXMLGUIClient> +#include <KXMLGUIFactory> + +#include <QAction> +#include <QDomDocument> +#include <QFileInfo> + +static constexpr QLatin1String serviceMenuNamePrefix("servicemenu_"); + +ServiceMenuShortcutManager::ServiceMenuShortcutManager(KActionCollection *actionCollection, QObject *parent) + : QObject(parent) + , m_actionCollection(actionCollection) + , m_category(new KActionCategory(i18nc("@title:group", "Context Menu Actions"), actionCollection)) +{ +} + +void ServiceMenuShortcutManager::refresh(KFileItemActions *fileItemActions) +{ + // Uses takeAction() to remove without deleting. Actions are owned by KFileItemActions + // and are deleted when called createServiceMenuActions() or destroyed + for (const QString &name : std::as_const(m_actionNames)) { + m_actionCollection->takeAction(m_actionCollection->action(name)); + } + m_actionNames.clear(); + + // Get action->execution mapping from KIO + const QList<QAction *> actions = fileItemActions->createServiceMenuActions(); + + for (QAction *action : actions) { + const auto desktopAction = action->data().value<KDesktopFileAction>(); + const QString fileName = QFileInfo(desktopAction.desktopFilePath()).fileName(); + const QString name = serviceMenuNamePrefix + fileName + QLatin1String("::") + desktopAction.actionsKey(); + m_category->addAction(name, action); + m_actionNames.append(name); + } +} + +void ServiceMenuShortcutManager::cleanupStaleShortcuts(KXMLGUIClient *client) +{ + const QString file = client->localXMLFile(); + if (file.isEmpty()) { + return; + } + + const QString xml = KXMLGUIFactory::readConfigFile(file, client->componentName()); + if (xml.isEmpty()) { + return; + } + + QDomDocument doc; + doc.setContent(xml); + QDomElement actionPropElement = KXMLGUIFactory::actionPropertiesElement(doc); + + bool modified = false; + for (QDomElement e = actionPropElement.firstChildElement(); !e.isNull();) { + QDomElement next = e.nextSiblingElement(); + const QString name = e.attribute(QStringLiteral("name")); + if (name.startsWith(serviceMenuNamePrefix) && !m_actionNames.contains(name)) { + actionPropElement.removeChild(e); + modified = true; + } + e = next; + } + + if (modified) { + KXMLGUIFactory::saveConfigFile(doc, file, client->componentName()); + } +}
\ No newline at end of file diff --git a/src/servicemenushortcutmanager.h b/src/servicemenushortcutmanager.h new file mode 100644 index 000000000..10502c341 --- /dev/null +++ b/src/servicemenushortcutmanager.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Albert Mkhitaryan <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef SERVICEMENUSHORTCUTMANAGER_H +#define SERVICEMENUSHORTCUTMANAGER_H + +#include <QObject> +#include <QStringList> + +class KActionCategory; +class KActionCollection; +class KFileItemActions; +class KXMLGUIClient; + +/** + * @brief Registers service menu actions with KActionCollection for keyboard shortcuts. + * + * This lightweight manager bridges KIO's service menu actions with Dolphin's + * shortcut system. Actions are obtained from KFileItemActions and registered + * with the action collection. Execution is handled entirely by KFileItemActions. + * + */ +class ServiceMenuShortcutManager : public QObject +{ + Q_OBJECT + +public: + explicit ServiceMenuShortcutManager(KActionCollection *actionCollection, QObject *parent = nullptr); + + void refresh(KFileItemActions *fileItemaActions); + void cleanupStaleShortcuts(KXMLGUIClient *client); + +private: + KActionCollection *m_actionCollection; + KActionCategory *m_category; + QStringList m_actionNames; +}; + +#endif // SERVICEMENUSHORTCUTMANAGER_H |
