[Icon Applet] Add "Open With" and "Open Containing Folder" actions

This adds the "Open With..." option known from Dolphin to the icon applet when it points to a file.
Also adds a "Open Containing Folder".
While at it, moves the action logic for jump list actions to C++ side

Differential Revision: https://phabricator.kde.org/D3905
wilder-5.14
Kai Uwe Broulik 9 years ago
parent f22a9b5fe8
commit 036b545baa
  1. 1
      applets/icon/CMakeLists.txt
  2. 85
      applets/icon/iconapplet.cpp
  3. 18
      applets/icon/iconapplet.h
  4. 18
      applets/icon/package/contents/ui/main.qml

@ -8,6 +8,7 @@ kcoreaddons_desktop_to_json(plasma_applet_icon package/metadata.desktop)
target_link_libraries(plasma_applet_icon
KF5::I18n
KF5::KIOCore # for OpenFileManagerWindowJob
KF5::KIOWidgets # for KRun
KF5::Plasma)

@ -21,6 +21,7 @@
#include "iconapplet.h"
#include <QAction>
#include <QApplication>
#include <QCryptographicHash>
#include <QDesktopWidget>
@ -29,17 +30,22 @@
#include <QFileInfo>
#include <QIcon>
#include <QJsonArray>
#include <QMenu>
#include <QMimeData>
#include <QMimeDatabase>
#include <QProcess>
#include <KAuthorized>
#include <KDesktopFile>
#include <KFileItemActions>
#include <KFileItemListProperties>
#include <KJobWidgets>
#include <KLocalizedString>
#include <KProtocolManager>
#include <KRun>
#include <KIO/DropJob>
#include <KIO/OpenFileManagerWindowJob>
IconApplet::IconApplet(QObject *parent, const QVariantList &data)
: Plasma::Applet(parent, data)
@ -201,7 +207,39 @@ void IconApplet::populateFromDesktopFile(const QString &path)
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 @@ void IconApplet::populateFromDesktopFile(const QString &path)
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 @@ QString IconApplet::genericName() const
return m_genericName;
}
QVariantList IconApplet::jumpListActions() const
QList<QAction *> IconApplet::contextualActions()
{
return m_jumpListActions;
QList<QAction *> 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::processDrop(QObject *dropEvent)
}
}
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();

@ -27,6 +27,9 @@
#include <KPropertiesDialog>
class KFileItemActions;
class QMenu;
class IconApplet : public Plasma::Applet
{
Q_OBJECT
@ -36,7 +39,6 @@ class IconApplet : public Plasma::Applet
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 @@ public:
QString name() const;
QString iconName() const;
QString genericName() const;
QVariantList jumpListActions() const;
QList<QAction *> 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 @@ private:
QString m_name;
QString m_iconName;
QString m_genericName;
QVariantList m_jumpListActions;
QList<QAction *> m_jumpListActions;
QAction *m_separatorAction = nullptr;
QList<QAction *> m_openWithActions;
QAction *m_openContainingFolderAction = nullptr;
KFileItemActions *m_fileItemActions = nullptr;
QScopedPointer<QMenu> m_openWithMenu;
QPointer<KPropertiesDialog> m_configDialog;

@ -59,17 +59,6 @@ MouseArea {
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) {
@ -77,13 +66,6 @@ MouseArea {
}
}
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()
}

Loading…
Cancel
Save