diff --git a/applets/icon/CMakeLists.txt b/applets/icon/CMakeLists.txt --- a/applets/icon/CMakeLists.txt +++ b/applets/icon/CMakeLists.txt @@ -8,6 +8,7 @@ target_link_libraries(plasma_applet_icon KF5::I18n + KF5::KIOCore # for OpenFileManagerWindowJob KF5::KIOWidgets # for KRun KF5::Plasma) diff --git a/applets/icon/iconapplet.h b/applets/icon/iconapplet.h --- a/applets/icon/iconapplet.h +++ b/applets/icon/iconapplet.h @@ -27,6 +27,9 @@ #include +class KFileItemActions; +class QMenu; + class IconApplet : public Plasma::Applet { Q_OBJECT @@ -36,7 +39,6 @@ Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged) Q_PROPERTY(QString genericName READ genericName NOTIFY genericNameChanged) - Q_PROPERTY(QVariantList jumpListActions READ jumpListActions NOTIFY jumpListActionsChanged) public: explicit IconApplet(QObject *parent, const QVariantList &data); @@ -50,11 +52,11 @@ QString name() const; QString iconName() const; QString genericName() const; - QVariantList jumpListActions() const; + + QList contextualActions() override; Q_INVOKABLE void open(); Q_INVOKABLE void processDrop(QObject *dropEvent); - Q_INVOKABLE void execJumpList(int index); Q_INVOKABLE void configure(); signals: @@ -80,7 +82,15 @@ QString m_name; QString m_iconName; QString m_genericName; - QVariantList m_jumpListActions; + + QList m_jumpListActions; + QAction *m_separatorAction = nullptr; + QList m_openWithActions; + + QAction *m_openContainingFolderAction = nullptr; + + KFileItemActions *m_fileItemActions = nullptr; + QScopedPointer m_openWithMenu; QPointer m_configDialog; diff --git a/applets/icon/iconapplet.cpp b/applets/icon/iconapplet.cpp --- a/applets/icon/iconapplet.cpp +++ b/applets/icon/iconapplet.cpp @@ -21,25 +21,31 @@ #include "iconapplet.h" +#include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include +#include +#include #include #include +#include #include #include +#include IconApplet::IconApplet(QObject *parent, const QVariantList &data) : Plasma::Applet(parent, data) @@ -201,7 +207,39 @@ setIconName(desktopFile.readIcon()); - QVariantList jumpListActions; + delete m_openContainingFolderAction; + m_openContainingFolderAction = nullptr; + m_openWithActions.clear(); + + if (desktopFile.hasLinkType()) { + const QUrl &linkUrl = QUrl(desktopFile.readUrl()); + + if (!m_fileItemActions) { + m_fileItemActions = new KFileItemActions(this); + } + KFileItemListProperties itemProperties(KFileItemList({KFileItem(linkUrl)})); + m_fileItemActions->setItemListProperties(itemProperties); + + if (!m_openWithMenu) { + m_openWithMenu.reset(new QMenu()); + } + m_openWithMenu->clear(); + m_fileItemActions->addOpenWithActionsTo(m_openWithMenu.data()); + + m_openWithActions = m_openWithMenu->actions(); + + if (KProtocolManager::supportsListing(linkUrl)) { + if (!m_openContainingFolderAction) { + m_openContainingFolderAction = new QAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("Open Containing Folder"), this); + connect(m_openContainingFolderAction, &QAction::triggered, this, [this] { + KIO::highlightInFileManager({m_openContainingFolderAction->property("linkUrl").toUrl()}); + }); + } + m_openContainingFolderAction->setProperty("linkUrl", linkUrl); + } + } + + m_jumpListActions.clear(); foreach (const QString &actionName, desktopFile.readActions()) { const KConfigGroup &actionGroup = desktopFile.actionGroup(actionName); @@ -215,16 +253,12 @@ continue; } - jumpListActions << QVariantMap{ - {QStringLiteral("name"), name}, - {QStringLiteral("icon"), actionGroup.readEntry("Icon")}, - {QStringLiteral("exec"), exec} - }; - } + QAction *action = new QAction(QIcon::fromTheme(actionGroup.readEntry("Icon")), name, this); + connect(action, &QAction::triggered, this, [this, exec] { + KRun::run(exec, {}, nullptr, m_name, m_iconName); + }); - if (m_jumpListActions != jumpListActions) { - m_jumpListActions = jumpListActions; - emit jumpListActionsChanged(jumpListActions); + m_jumpListActions << action; } m_localPath = path; @@ -271,9 +305,26 @@ return m_genericName; } -QVariantList IconApplet::jumpListActions() const +QList IconApplet::contextualActions() { - return m_jumpListActions; + QList actions; + actions << m_jumpListActions; + + if (!actions.isEmpty()) { + if (!m_separatorAction) { + m_separatorAction = new QAction(this); + m_separatorAction->setSeparator(true); + } + actions << m_separatorAction; + } + + actions << m_openWithActions; + + if (m_openContainingFolderAction) { + actions << m_openContainingFolderAction; + } + + return actions; } void IconApplet::open() @@ -338,16 +389,6 @@ } } -void IconApplet::execJumpList(int index) -{ - const QString &exec = m_jumpListActions.at(index).toMap().value(QStringLiteral("exec")).toString(); - if (exec.isEmpty()) { - return; - } - - KRun::run(exec, {}, nullptr, m_name, m_iconName); -} - void IconApplet::configure() { KPropertiesDialog *dialog = m_configDialog.data(); diff --git a/applets/icon/package/contents/ui/main.qml b/applets/icon/package/contents/ui/main.qml --- a/applets/icon/package/contents/ui/main.qml +++ b/applets/icon/package/contents/ui/main.qml @@ -59,31 +59,13 @@ function updateActions() { plasmoid.clearActions() - var actions = plasmoid.nativeInterface.jumpListActions - var jumpListCount = actions.length - for (var i = 0; i < jumpListCount; ++i) { - var item = actions[i] - plasmoid.setAction("jumplist_" + i, item.name, item.icon) - } - - if (jumpListCount) { - plasmoid.setActionSeparator("separator0") - } - plasmoid.removeAction("configure"); if (plasmoid.immutability !== PlasmaCore.Types.SystemImmutable) { plasmoid.setAction("configure", i18n("Properties"), "document-properties"); } } - function actionTriggered(name) { - if (name.indexOf("jumplist_") === 0) { - var actionIndex = parseInt(name.substr("jumplist_".length)) - plasmoid.nativeInterface.execJumpList(actionIndex) - } - } - function action_configure() { plasmoid.nativeInterface.configure() }