[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [plasma-desktop] applets/kicker/plugin: Support edit and appstream actions also for application sear
From:       Eike Hein <null () kde ! org>
Date:       2017-08-31 20:13:28
Message-ID: E1dnVqC-0000AB-3s () code ! kde ! org
[Download RAW message or body]

Git commit ee7078864b750b91812269b7cbc43bd4544c98f8 by Eike Hein.
Committed on 31/08/2017 at 20:12.
Pushed by hein into branch 'master'.

Support edit and appstream actions also for application search results

Summary: BUG:384036

Reviewers: #plasma, broulik, davidedmundson

Reviewed By: #plasma, broulik

Subscribers: mak, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7567

M  +94   -0    applets/kicker/plugin/actionlist.cpp
M  +8    -0    applets/kicker/plugin/actionlist.h
M  +6    -63   applets/kicker/plugin/appentry.cpp
M  +23   -3    applets/kicker/plugin/runnermatchesmodel.cpp

https://commits.kde.org/plasma-desktop/ee7078864b750b91812269b7cbc43bd4544c98f8

diff --git a/applets/kicker/plugin/actionlist.cpp \
b/applets/kicker/plugin/actionlist.cpp index 16661da0..54a5a1c2 100644
--- a/applets/kicker/plugin/actionlist.cpp
+++ b/applets/kicker/plugin/actionlist.cpp
@@ -19,12 +19,17 @@
  ***************************************************************************/
 
 #include "actionlist.h"
+#include "menuentryeditor.h"
+
+#include <config-appstream.h>
 
 #include <QApplication>
+#include <QDesktopServices>
 
 #include <KLocalizedString>
 #include <KMimeTypeTrader>
 #include <KPropertiesDialog>
+#include <KProtocolInfo>
 #include <KRun>
 
 #include <KActivities/Stats/Cleaning>
@@ -33,6 +38,10 @@
 
 #include "containmentinterface.h"
 
+#ifdef HAVE_APPSTREAMQT
+#include <AppStreamQt/pool.h>
+#endif
+
 namespace KAStats = KActivities::Stats;
 
 using namespace KAStats;
@@ -308,4 +317,89 @@ bool handleRecentDocumentAction(KService::Ptr service, const \
                QString &actionId,
     return (KRun::runService(*service, QList<QUrl>() << QUrl(argument), \
QApplication::activeWindow()) != 0);  }
 
+Q_GLOBAL_STATIC(MenuEntryEditor, menuEntryEditor)
+
+bool canEditApplication(const QString &entryPath)
+{
+    return menuEntryEditor->canEdit(entryPath);
+}
+
+void editApplication(const QString &entryPath, const QString &menuId)
+{
+    menuEntryEditor->edit(entryPath, menuId);
+}
+
+QVariantList editApplicationAction(const KService::Ptr &service)
+{
+    QVariantList actionList;
+
+    if (canEditApplication(service->entryPath())) {
+        QVariantMap editAction = Kicker::createActionItem(i18n("Edit \
Application..."), "editApplication"); +        editAction["icon"] = "kmenuedit"; // \
TODO: Using the KMenuEdit icon might be misleading. +        actionList << \
editAction; +    }
+
+    return actionList;
+}
+
+bool handleEditApplicationAction(const QString &actionId, const KService::Ptr \
&service) +{
+
+    if (service && actionId == "editApplication" && \
canEditApplication(service->entryPath())) { +        \
Kicker::editApplication(service->entryPath(), service->menuId()); +
+        return true;
+    }
+
+    return false;
+}
+
+#ifdef HAVE_APPSTREAMQT
+Q_GLOBAL_STATIC(AppStream::Pool, appstreamPool)
+#endif
+
+QVariantList appstreamActions(const KService::Ptr &service)
+{
+    QVariantList ret;
+
+#ifdef HAVE_APPSTREAMQT
+    const KService::Ptr appStreamHandler = \
KMimeTypeTrader::self()->preferredService(QStringLiteral("x-scheme-handler/appstream"));
 +
+    // Don't show action if we can't find any app to handle appstream:// URLs.
+    if (!appStreamHandler) {
+        if (!KProtocolInfo::isHelperProtocol(QStringLiteral("appstream"))
+            || KProtocolInfo::exec(QStringLiteral("appstream")).isEmpty()) {
+            return ret;
+        }
+    }
+
+    if (!appstreamPool.exists()) {
+        appstreamPool->load();
+    }
+
+    const auto components = \
appstreamPool->componentsById(service->desktopEntryName()+QLatin1String(".desktop")); \
+    for(const auto &component: components) { +        const QString componentId = \
component.id(); +
+        QVariantMap appstreamAction = Kicker::createActionItem(i18nc("@action opens \
a software center with the application", "Manage '%1'...", component.name()), \
"manageApplication", QVariant(QStringLiteral("appstream://") + componentId)); +       \
appstreamAction[QStringLiteral("icon")] = QStringLiteral("applications-other"); +     \
ret << appstreamAction; +    }
+#else
+    Q_UNUSED(service)
+#endif
+
+    return ret;
+}
+
+bool handleAppstreamActions(const QString &actionId, const QVariant &argument)
+{
+    if (actionId == "manageApplication") {
+        return QDesktopServices::openUrl(QUrl(argument.toString()));
+    }
+
+    return false;
+}
+
+
 }
diff --git a/applets/kicker/plugin/actionlist.h b/applets/kicker/plugin/actionlist.h
index 869354c9..85fac255 100644
--- a/applets/kicker/plugin/actionlist.h
+++ b/applets/kicker/plugin/actionlist.h
@@ -57,4 +57,12 @@ QVariantList jumpListActions(KService::Ptr service);
 QVariantList recentDocumentActions(KService::Ptr service);
 bool handleRecentDocumentAction(KService::Ptr service, const QString &actionId, \
const QVariant &argument);  
+bool canEditApplication(const QString &entryPath);
+void editApplication(const QString &entryPath, const QString &menuId);
+QVariantList editApplicationAction(const KService::Ptr &service);
+bool handleEditApplicationAction(const QString &actionId, const KService::Ptr \
&service); +
+QVariantList appstreamActions(const KService::Ptr &service);
+bool handleAppstreamActions(const QString &actionId, const QVariant &argument);
+
 }
diff --git a/applets/kicker/plugin/appentry.cpp b/applets/kicker/plugin/appentry.cpp
index ee58657e..6f2cc8f8 100644
--- a/applets/kicker/plugin/appentry.cpp
+++ b/applets/kicker/plugin/appentry.cpp
@@ -22,15 +22,12 @@
 #include "actionlist.h"
 #include "appsmodel.h"
 #include "containmentinterface.h"
-#include "menuentryeditor.h"
 
 #include <config-X11.h>
-#include <config-appstream.h>
 
 #include <QProcess>
 #include <QQmlPropertyMap>
 #include <QStandardPaths>
-#include <QDesktopServices>
 #if HAVE_X11
 #include <QX11Info>
 #endif
@@ -40,7 +37,6 @@
 #include <KJob>
 #include <KLocalizedString>
 #include <KMimeTypeTrader>
-#include <KProtocolInfo>
 #include <KRun>
 #include <KSycoca>
 #include <KShell>
@@ -49,12 +45,6 @@
 
 #include <Plasma/Plasma>
 
-#ifdef HAVE_APPSTREAMQT
-#include <AppStreamQt/pool.h>
-#endif
-
-MenuEntryEditor *AppEntry::m_menuEntryEditor = nullptr;
-
 AppEntry::AppEntry(AbstractModel *owner, KService::Ptr service, NameFormat \
nameFormat)  : AbstractEntry(owner)
 , m_service(service)
@@ -89,10 +79,6 @@ void AppEntry::init(NameFormat nameFormat)
     } else {
         m_description = nameFromService(m_service, GenericNameOnly);
     }
-
-    if (!m_menuEntryEditor) {
-        m_menuEntryEditor = new MenuEntryEditor();
-    }
 }
 
 bool AppEntry::isValid() const
@@ -142,39 +128,6 @@ bool AppEntry::hasActions() const
     return true;
 }
 
-#ifdef HAVE_APPSTREAMQT
-Q_GLOBAL_STATIC(AppStream::Pool, appstreamPool)
-
-QVariantList appstreamActions(const KService::Ptr &service)
-{
-    QVariantList ret;
-
-    const KService::Ptr appStreamHandler = \
KMimeTypeTrader::self()->preferredService(QStringLiteral("x-scheme-handler/appstream"));
                
-
-    // Don't show action if we can't find any app to handle appstream:// URLs.
-    if (!appStreamHandler) {
-        if (!KProtocolInfo::isHelperProtocol(QStringLiteral("appstream"))
-            || KProtocolInfo::exec(QStringLiteral("appstream")).isEmpty()) {
-            return ret;
-        }
-    }
-
-    if (!appstreamPool.exists()) {
-        appstreamPool->load();
-    }
-
-    const auto components = \
                appstreamPool->componentsById(service->desktopEntryName()+QLatin1String(".desktop"));
                
-    for(const auto &component: components) {
-        const QString componentId = component.id();
-
-        QVariantMap appstreamAction = Kicker::createActionItem(i18nc("@action opens \
a software center with the application", "Manage '%1'...", component.name()), \
                "manageApplication", QVariant(QStringLiteral("appstream://") + \
                componentId));
-        appstreamAction[QStringLiteral("icon")] = \
                QStringLiteral("applications-other");
-        ret << appstreamAction;
-    }
-    return ret;
-}
-#endif
-
 QVariantList AppEntry::actions() const
 {
     QVariantList actionList;
@@ -205,19 +158,11 @@ QVariantList AppEntry::actions() const
         return actionList;
     }
 
-    if (m_menuEntryEditor->canEdit(m_service->entryPath())) {
-        actionList << Kicker::createSeparatorActionItem();
-
-        QVariantMap editAction = Kicker::createActionItem(i18n("Edit \
                Application..."), "editApplication");
-        editAction["icon"] = "kmenuedit"; // TODO: Using the KMenuEdit icon might be \
                misleading.
-        actionList << editAction;
-    }
-
-#ifdef HAVE_APPSTREAMQT
     if (m_service->isApplication()) {
-        actionList << appstreamActions(m_service);
+        actionList << Kicker::createSeparatorActionItem();
+        actionList << Kicker::editApplicationAction(m_service);
+        actionList << Kicker::appstreamActions(m_service);
     }
-#endif
 
     QQmlPropertyMap *appletConfig = qobject_cast<QQmlPropertyMap \
*>(appletInterface->property("configuration").value<QObject *>());  
@@ -260,12 +205,10 @@ bool AppEntry::run(const QString& actionId, const QVariant \
&argument)  
     if (Kicker::handleAddLauncherAction(actionId, appletInterface, m_service)) {
         return true;
-    } else if (actionId == "editApplication" && \
                m_menuEntryEditor->canEdit(m_service->entryPath())) {
-        m_menuEntryEditor->edit(m_service->entryPath(), m_service->menuId());
-
+    } else if (Kicker::handleEditApplicationAction(actionId, m_service)) {
+        return true;
+    } else if (Kicker::handleAppstreamActions(actionId, argument)) {
         return true;
-    } else if (actionId == "manageApplication") {
-        return QDesktopServices::openUrl(QUrl(argument.toString()));
     } else if (actionId == "_kicker_jumpListAction") {
         return KRun::run(argument.toString(), {}, nullptr, m_service->name(), \
m_service->icon());  }
diff --git a/applets/kicker/plugin/runnermatchesmodel.cpp \
b/applets/kicker/plugin/runnermatchesmodel.cpp index 504d8da6..03911b94 100644
--- a/applets/kicker/plugin/runnermatchesmodel.cpp
+++ b/applets/kicker/plugin/runnermatchesmodel.cpp
@@ -29,6 +29,8 @@
 #include <KRunner/RunnerManager>
 #include <KRun>
 
+#include <Plasma/Plasma>
+
 RunnerMatchesModel::RunnerMatchesModel(const QString &runnerId, const QString &name,
     Plasma::RunnerManager *manager, QObject *parent)
 : AbstractModel(parent)
@@ -104,7 +106,8 @@ QVariant RunnerMatchesModel::data(const QModelIndex &index, int \
role) const  actionList << Kicker::createSeparatorActionItem();
         }
 
-        KService::Ptr service = \
KService::serviceByStorageId(match.data().toString()); +        const KService::Ptr \
service = KService::serviceByStorageId(match.data().toString()); +
         if (service) {
             const QVariantList &jumpListActions = Kicker::jumpListActions(service);
             if (!jumpListActions.isEmpty()) {
@@ -113,8 +116,10 @@ QVariant RunnerMatchesModel::data(const QModelIndex &index, int \
role) const  
             QObject *appletInterface = static_cast<RunnerModel \
*>(parent())->appletInterface();  
+            const bool systemImmutable = \
appletInterface->property("immutability").toInt() == Plasma::Types::SystemImmutable; \
                +
             const QVariantList &addLauncherActions = \
                Kicker::createAddLauncherActionList(appletInterface, service);
-            if (!addLauncherActions.isEmpty()) {
+            if (!systemImmutable && !addLauncherActions.isEmpty()) {
                 actionList << addLauncherActions << \
Kicker::createSeparatorActionItem();  }
 
@@ -122,6 +127,17 @@ QVariant RunnerMatchesModel::data(const QModelIndex &index, int \
role) const  if (!recentDocuments.isEmpty()) {
                 actionList << recentDocuments << \
Kicker::createSeparatorActionItem();  }
+
+            // Don't allow adding launchers, editing, hiding, or uninstalling \
applications +            // when system is immutable.
+            if (systemImmutable) {
+                return actionList;
+            }
+
+            if (service->isApplication()) {
+                actionList << Kicker::editApplicationAction(service);
+                actionList << Kicker::appstreamActions(service);
+            }
         }
 
         return actionList;
@@ -149,10 +165,14 @@ bool RunnerMatchesModel::trigger(int row, const QString \
&actionId, const QVarian  
     QObject *appletInterface = static_cast<RunnerModel \
*>(parent())->appletInterface();  
-    KService::Ptr service = KService::serviceByStorageId(match.data().toString());
+    const KService::Ptr service = \
KService::serviceByStorageId(match.data().toString());  
     if (Kicker::handleAddLauncherAction(actionId, appletInterface, service)) {
         return true;
+    } else if (Kicker::handleEditApplicationAction(actionId, service)) {
+        return true;
+    } else if (Kicker::handleAppstreamActions(actionId, argument)) {
+        return true;
     } else if (actionId == QLatin1String("_kicker_jumpListAction")) {
         return KRun::run(argument.toString(), {}, nullptr, service ? service->name() \
: QString(), service ? service->icon() : QString());  } else if (actionId == \
QLatin1String("_kicker_recentDocument")


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic