diff --git a/applets/kicker/plugin/actionlist.cpp b/applets/kicker/plugin/actionlist.cpp index 285c37adf..1fb31d69c 100644 --- a/applets/kicker/plugin/actionlist.cpp +++ b/applets/kicker/plugin/actionlist.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include #include @@ -456,6 +458,53 @@ bool handleAppstreamActions(const QString &actionId, const QVariant &argument) return false; } +static QList additionalActions(const KService::Ptr &service) +{ + QList actions; + const static auto locations = + QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("plasma/kickeractions"), QStandardPaths::LocateDirectory); + const auto files = KFileUtils::findAllUniqueFiles(locations); + for (const auto &file : files) { + KService actionsService(file); + const auto filter = actionsService.property(QStringLiteral("X-KDE-OnlyForAppIds"), QVariant::StringList).toStringList(); + if (filter.empty() || filter.contains(storageIdFromService(service))) { + actions.append(KDesktopFileActions::userDefinedServices(actionsService, true)); + } + } + return actions; +} + +QVariantList additionalAppActions(const KService::Ptr &service) +{ + QVariantList list; + const auto actions = additionalActions(service); + list.reserve(actions.size()); + for (const auto &action : actions) { + list << createActionItem(action.text(), action.icon(), action.name(), action.service()->entryPath()); + } + return list; +} + +bool handleAdditionalAppActions(const QString &actionId, const KService::Ptr &service, const QVariant &argument) +{ + const KService actionProvider(argument.toString()); + if (!actionProvider.isValid()) { + return false; + } + const auto actions = actionProvider.actions(); + auto action = std::find_if(actions.begin(), actions.end(), [&actionId](const KServiceAction &action) { + return action.name() == actionId; + }); + if (action == actions.end()) { + return false; + } + auto *job = new KIO::ApplicationLauncherJob(*action); + job->setUrls({QUrl::fromLocalFile(resolvedServiceEntryPath(service))}); + job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled)); + job->start(); + return true; +} + QString resolvedServiceEntryPath(const KService::Ptr &service) { QString path = service->entryPath(); diff --git a/applets/kicker/plugin/actionlist.h b/applets/kicker/plugin/actionlist.h index 2acbe0f5d..e8d59def0 100644 --- a/applets/kicker/plugin/actionlist.h +++ b/applets/kicker/plugin/actionlist.h @@ -56,6 +56,9 @@ bool handleEditApplicationAction(const QString &actionId, const KService::Ptr &s QVariantList appstreamActions(const KService::Ptr &service); bool handleAppstreamActions(const QString &actionId, const QVariant &argument); +QVariantList additionalAppActions(const KService::Ptr &service); +bool handleAdditionalAppActions(const QString &actionId, const KService::Ptr &service, const QVariant &argument); + QString resolvedServiceEntryPath(const KService::Ptr &service); } diff --git a/applets/kicker/plugin/appentry.cpp b/applets/kicker/plugin/appentry.cpp index 6f24d1dab..8ecdf63d7 100644 --- a/applets/kicker/plugin/appentry.cpp +++ b/applets/kicker/plugin/appentry.cpp @@ -168,6 +168,11 @@ QVariantList AppEntry::actions() const actionList << recentDocuments << Kicker::createSeparatorActionItem(); } + const QVariantList &additionalActions = Kicker::additionalAppActions(m_service); + if (!additionalActions.isEmpty()) { + actionList << additionalActions << Kicker::createSeparatorActionItem(); + } + // Don't allow adding launchers, editing, hiding, or uninstalling applications // when system is immutable. if (systemImmutable) { @@ -237,6 +242,8 @@ bool AppEntry::run(const QString &actionId, const QVariant &argument) job->setDesktopName(m_service->entryPath()); job->setIcon(m_service->icon()); return job->exec(); + } else if (Kicker::handleAdditionalAppActions(actionId, m_service, argument)) { + return true; } return Kicker::handleRecentDocumentAction(m_service, actionId, argument); diff --git a/applets/kicker/plugin/runnermatchesmodel.cpp b/applets/kicker/plugin/runnermatchesmodel.cpp index 154ab3324..8c70382ec 100644 --- a/applets/kicker/plugin/runnermatchesmodel.cpp +++ b/applets/kicker/plugin/runnermatchesmodel.cpp @@ -131,6 +131,11 @@ QVariant RunnerMatchesModel::data(const QModelIndex &index, int role) const actionList << recentDocuments << Kicker::createSeparatorActionItem(); } + const QVariantList &additionalActions = Kicker::additionalAppActions(service); + if (!additionalActions.isEmpty()) { + actionList << additionalActions << Kicker::createSeparatorActionItem(); + } + // Don't allow adding launchers, editing, hiding, or uninstalling applications // when system is immutable. if (systemImmutable) { @@ -209,6 +214,8 @@ bool RunnerMatchesModel::trigger(int row, const QString &actionId, const QVarian return job->exec(); } else if (actionId == QLatin1String("_kicker_recentDocument") || actionId == QLatin1String("_kicker_forgetRecentDocuments")) { return Kicker::handleRecentDocumentAction(service, actionId, argument); + } else if (Kicker::handleAdditionalAppActions(actionId, service, argument)) { + return true; } return false;