diff --git a/applets/quicklaunch/package/contents/ui/IconItem.qml b/applets/quicklaunch/package/contents/ui/IconItem.qml --- a/applets/quicklaunch/package/contents/ui/IconItem.qml +++ b/applets/quicklaunch/package/contents/ui/IconItem.qml @@ -74,6 +74,7 @@ if (mouse.button == Qt.LeftButton) { logic.openUrl(url) } else if (mouse.button == Qt.RightButton) { + contextMenu.refreshActions(); contextMenu.open(mouse.x, mouse.y); } } @@ -122,9 +123,17 @@ PlasmaComponents.ContextMenu { id: contextMenu + + property var jumpListItems : [] + visualParent: mouseArea PlasmaComponents.MenuItem { + id: jumpListSeparator + separator: true + } + + PlasmaComponents.MenuItem { text: i18n("Add Launcher...") icon: "list-add" onClicked: addLauncher() @@ -153,6 +162,34 @@ PlasmaComponents.MenuItem { action: plasmoid.action("remove") } + + function refreshActions() { + for (var i = 0; i < jumpListItems.length; ++i) { + var item = jumpListItems[i]; + removeMenuItem(item); + item.destroy(); + } + jumpListItems = []; + + for (var i = 0; i < launcher.jumpListActions.length; ++i) { + var action = launcher.jumpListActions[i]; + var item = menuItemComponent.createObject(iconItem, { + "text": action.name, + "icon": action.icon + }); + item.clicked.connect(function() { + logic.openExec(this.exec); + }.bind(action)); + + addMenuItem(item, jumpListSeparator); + jumpListItems.push(item); + } + } + } + + Component { + id: menuItemComponent + PlasmaComponents.MenuItem { } } } } diff --git a/applets/quicklaunch/plugin/quicklaunch_p.h b/applets/quicklaunch/plugin/quicklaunch_p.h --- a/applets/quicklaunch/plugin/quicklaunch_p.h +++ b/applets/quicklaunch/plugin/quicklaunch_p.h @@ -23,17 +23,18 @@ #include #include -#include +#include class QuicklaunchPrivate : public QObject { Q_OBJECT public: explicit QuicklaunchPrivate(QObject *parent = Q_NULLPTR); - Q_INVOKABLE QJsonObject launcherData(const QUrl &url); + Q_INVOKABLE QVariantMap launcherData(const QUrl &url); Q_INVOKABLE void openUrl(const QUrl &url); + Q_INVOKABLE void openExec(const QString &exec); Q_INVOKABLE void addLauncher(bool isPopup = false); Q_INVOKABLE void editLauncher(QUrl url, int index, bool isPopup = false); diff --git a/applets/quicklaunch/plugin/quicklaunch_p.cpp b/applets/quicklaunch/plugin/quicklaunch_p.cpp --- a/applets/quicklaunch/plugin/quicklaunch_p.cpp +++ b/applets/quicklaunch/plugin/quicklaunch_p.cpp @@ -44,11 +44,12 @@ { } -QJsonObject QuicklaunchPrivate::launcherData(const QUrl &url) +QVariantMap QuicklaunchPrivate::launcherData(const QUrl &url) { QString name; QString icon; QString genericName; + QVariantList jumpListActions; if (url.scheme() == QLatin1String("quicklaunch")) { // Ignore internal scheme @@ -64,6 +65,28 @@ if (name.isEmpty()) { name = QFileInfo(url.toLocalFile()).fileName(); } + + const QStringList &actions = f.readActions(); + + foreach (const QString &actionName, actions) { + const KConfigGroup &actionGroup = f.actionGroup(actionName); + + if (!actionGroup.isValid() || !actionGroup.exists()) { + continue; + } + + const QString &name = actionGroup.readEntry("Name"); + const QString &exec = actionGroup.readEntry("Exec"); + if (name.isEmpty() || exec.isEmpty()) { + continue; + } + + jumpListActions << QVariantMap{ + {QStringLiteral("name"), name}, + {QStringLiteral("icon"), actionGroup.readEntry("Icon")}, + {QStringLiteral("exec"), exec} + }; + } } else { QMimeDatabase db; name = fi.baseName(); @@ -82,18 +105,24 @@ icon = KIO::iconNameForUrl(url); } - QJsonObject data; - data[QStringLiteral("applicationName")] = name; - data[QStringLiteral("iconName")] = icon; - data[QStringLiteral("genericName")] = genericName; - return data; + return QVariantMap{ + {QStringLiteral("applicationName"), name}, + {QStringLiteral("iconName"), icon}, + {QStringLiteral("genericName"), genericName}, + {QStringLiteral("jumpListActions"), jumpListActions} + }; } void QuicklaunchPrivate::openUrl(const QUrl &url) { new KRun(url, Q_NULLPTR); } +void QuicklaunchPrivate::openExec(const QString &exec) +{ + KRun::run(exec, {}, Q_NULLPTR); +} + void QuicklaunchPrivate::addLauncher(bool isPopup) { KOpenWithDialog *dialog = new KOpenWithDialog(); @@ -151,8 +180,8 @@ bool desktopFileCreated = false; if (!url.isLocalFile() || !KDesktopFile::isDesktopFile(url.toLocalFile())) { - QString desktopFilePath = determineNewDesktopFilePath(QStringLiteral("launcher")); - QJsonObject data = launcherData(url); + const QString desktopFilePath = determineNewDesktopFilePath(QStringLiteral("launcher")); + const QVariantMap data = launcherData(url); KConfig desktopFile(desktopFilePath); KConfigGroup desktopEntry(&desktopFile, "Desktop Entry");