diff --git a/activities/fileitemplugin/FileItemLinkingPlugin.cpp b/activities/fileitemplugin/FileItemLinkingPlugin.cpp index 1708c029..83128543 100644 --- a/activities/fileitemplugin/FileItemLinkingPlugin.cpp +++ b/activities/fileitemplugin/FileItemLinkingPlugin.cpp @@ -1,198 +1,215 @@ /* * Copyright (C) 2012 - 2016 by Ivan Cukic * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . */ #include "FileItemLinkingPlugin.h" #include "FileItemLinkingPlugin_p.h" #include "FileItemLinkingPluginActionLoader.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include + #include "common/dbus/common.h" K_PLUGIN_FACTORY_WITH_JSON(ActivityLinkingFileItemActionFactory, "kactivitymanagerd_fileitem_linking_plugin.json", registerPlugin();) // Private FileItemLinkingPlugin::Private::Private() : shouldLoad(false) , loaded(false) { connect(&activities, &KActivities::Consumer::serviceStatusChanged, this, &Private::activitiesServiceStatusChanged); } void FileItemLinkingPlugin::Private::activitiesServiceStatusChanged( KActivities::Consumer::ServiceStatus status) { if (status != KActivities::Consumer::Unknown) { loadAllActions(); } } void FileItemLinkingPlugin::Private::rootActionHovered() { shouldLoad = true; loadAllActions(); } void FileItemLinkingPlugin::Private::actionTriggered() { QAction *action = dynamic_cast(sender()); if (!action) { return; } bool link = action->property("link").toBool(); QString activity = action->property("activity").toString(); KAMD_DBUS_DECL_INTERFACE(service, Resources/Linking, ResourcesLinking); foreach (const auto &item, items.urlList()) { service.asyncCall( link ? "LinkResourceToActivity" : "UnlinkResourceFromActivity", QString(), item.toLocalFile(), activity); } } QAction *FileItemLinkingPlugin::Private::basicAction(QWidget *parentWidget) { root = new QAction(QIcon::fromTheme("preferences-activities"), i18n("Activities"), parentWidget); rootMenu = new QMenu(); rootMenu->addAction(new QAction(i18n("Loading..."), this)); connect(root, &QAction::hovered, this, &Private::rootActionHovered); root->setMenu(rootMenu); return root; } void FileItemLinkingPlugin::Private::loadAllActions() { if (!shouldLoad || activities.serviceStatus() == KActivities::Consumer::Unknown) { return; } if (activities.serviceStatus() == KActivities::Consumer::NotRunning) { Action action = { }; action.title = i18n("The Activity Manager is not running"); setActions({ action }); } else if (!loaded) { auto loader = FileItemLinkingPluginActionLoader::create(items); static FileItemLinkingPluginActionStaticInit init; connect(loader, &FileItemLinkingPluginActionLoader::result, this, &Private::setActions, Qt::QueuedConnection); loader->start(); loaded = true; // ignore that the thread may not be finished at this time } } void FileItemLinkingPlugin::Private::setActions(const ActionList &actions) { + if (!rootMenu) { + return; + } + for (auto action: rootMenu->actions()) { rootMenu->removeAction(action); action->deleteLater(); } for (auto actionInfo: actions) { if (actionInfo.icon != "-") { auto action = new QAction(nullptr); action->setText(actionInfo.title); action->setIcon(QIcon::fromTheme(actionInfo.icon)); action->setProperty("activity", actionInfo.activity); action->setProperty("link", actionInfo.link); rootMenu->addAction(action); connect(action, &QAction::triggered, this, &Private::actionTriggered); } else { auto action = new QAction(actionInfo.title, nullptr); action->setSeparator(true); rootMenu->addAction(action); } } } FileItemLinkingPluginActionStaticInit::FileItemLinkingPluginActionStaticInit() { qRegisterMetaType("Action"); qRegisterMetaType("ActionList"); } // Main class FileItemLinkingPlugin::FileItemLinkingPlugin(QObject *parent, const QVariantList &) : KAbstractFileItemActionPlugin(parent) { } FileItemLinkingPlugin::~FileItemLinkingPlugin() { d->setActions({}); } QList FileItemLinkingPlugin::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) { + // We can only link local files, don't show the menu if there are none + // KFileItemListProperties::isLocal() is for *all* being local, we just want *any* local + const auto urlList = fileItemInfos.urlList(); + const bool hasLocalUrl = std::any_of(urlList.begin(), urlList.end(), [](const QUrl &url) { + return url.isLocalFile(); + }); + + if (!hasLocalUrl) { + return {}; + } + d->items = fileItemInfos; return { d->basicAction(parentWidget) }; } #include "FileItemLinkingPlugin.moc" diff --git a/activities/fileitemplugin/FileItemLinkingPlugin_p.h b/activities/fileitemplugin/FileItemLinkingPlugin_p.h index ebd2368e..a988346d 100644 --- a/activities/fileitemplugin/FileItemLinkingPlugin_p.h +++ b/activities/fileitemplugin/FileItemLinkingPlugin_p.h @@ -1,73 +1,73 @@ /* * Copyright (C) 2012 - 2016 by Ivan Cukic * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . */ #ifndef FILE_ITEM_LINKING_PLUGIN_P_H #define FILE_ITEM_LINKING_PLUGIN_P_H #include "FileItemLinkingPlugin.h" #include #include #include #include struct Action { QString title; QString icon; QString activity; bool link; }; typedef QList ActionList; class FileItemLinkingPlugin::Private : public QObject { Q_OBJECT public: Private(); QAction *root; - QMenu *rootMenu; + QMenu *rootMenu = nullptr; KFileItemListProperties items; QAction *basicAction(QWidget *parentWidget); KActivities::Consumer activities; public Q_SLOTS: void activitiesServiceStatusChanged(KActivities::Consumer::ServiceStatus status); void rootActionHovered(); void setActions(const ActionList &actions); void actionTriggered(); void loadAllActions(); private: bool shouldLoad : 1; bool loaded : 1; }; class FileItemLinkingPluginActionStaticInit { public: FileItemLinkingPluginActionStaticInit(); }; #endif // FILE_ITEM_LINKING_PLUGIN_P_H