Implement drag and drop support for icon widget

CHANGELOG: Dropping file(s) onto an icon widget will now open them in the given application

REVIEW: 124472
wilder-5.14
Kai Uwe Broulik 11 years ago
parent 0524b4d45a
commit 5f80513249
  1. 28
      applets/icon/package/contents/ui/main.qml
  2. 124
      applets/icon/plugin/icon_p.cpp
  3. 10
      applets/icon/plugin/icon_p.h

@ -24,11 +24,13 @@ import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as Components
import org.kde.kquickcontrolsaddons 2.0
import org.kde.draganddrop 2.0 as DragDrop
import org.kde.plasma.private.icon 1.0
MouseArea {
id: root
id:root
property bool containsAcceptableDrag: false
height: units.iconSizes.desktop + theme.mSize(theme.defaultFont).height
width: units.iconSizes.desktop
@ -39,29 +41,43 @@ MouseArea {
property bool constrained: formFactor == PlasmaCore.Types.Vertical || formFactor == PlasmaCore.Types.Horizontal
hoverEnabled: true
onClicked: logic.open();
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.icon: plasmoid.configuration.iconName
Plasmoid.title: plasmoid.configuration.applicationName
Plasmoid.backgroundHints: PlasmaCore.Types.TranslucentBackground
Component.onCompleted: {
plasmoid.backgroundHints = 2;
plasmoid.popupIcon = plasmoid.configuration.iconName;
plasmoid.activated.connect(logic.open);
}
DragDrop.DropArea {
id: dropArea
anchors.fill: parent
preventStealing: true
onDragEnter: root.containsAcceptableDrag = event.mimeData.hasUrls
onDragLeave: root.containsAcceptableDrag = false
onDrop: {
logic.processDroppedUrls(event.mimeData.urls)
root.containsAcceptableDrag = false
}
}
PlasmaCore.IconItem {
id:icon
source: plasmoid.configuration.iconName
source: plasmoid.icon
anchors{
left : parent.left
right : parent.right
top : parent.top
bottom : constrained ? parent.bottom : text.top
}
active: root.containsMouse
active: root.containsMouse || root.containsAcceptableDrag
}
Components.Label {
id : text
text : plasmoid.configuration.applicationName
text : plasmoid.title
anchors {
left : parent.left
bottom : parent.bottom

@ -21,10 +21,13 @@
#include "icon_p.h"
#include <QFileInfo>
#include <QJsonArray>
#include <KFileItem>
#include <KDesktopFile>
#include <KRun>
#include <KService>
#include <KShell>
#include <QMimeType>
#include <QMimeDatabase>
@ -36,46 +39,44 @@ IconPrivate::IconPrivate() {
IconPrivate::~IconPrivate() {
}
void IconPrivate::setUrl(QUrl& url) {
void IconPrivate::setUrl(const QUrl &url)
{
m_url = url;
if (m_url.isLocalFile()) {
const KFileItem fileItem(m_url);
const QFileInfo fi(m_url.toLocalFile());
if (fileItem.isDesktopFile()) {
const KDesktopFile f(m_url.toLocalFile());
m_name = f.readName();
m_icon = f.readIcon();
m_genericName = f.readGenericName();
if (m_name.isNull()) {
m_name = QFileInfo(m_url.toLocalFile()).fileName();
}
} else {
QMimeDatabase db;
m_name = fi.baseName();
m_icon = db.mimeTypeForUrl(m_url).iconName();
m_genericName = fi.baseName();
}
const KFileItem fileItem(m_url);
const QFileInfo fi(m_url.toLocalFile());
if (fileItem.isDesktopFile()) {
const KDesktopFile f(m_url.toLocalFile());
m_name = f.readName();
m_icon = f.readIcon();
m_genericName = f.readGenericName();
if (m_name.isNull()) {
m_name = QFileInfo(m_url.toLocalFile()).fileName();
}
} else {
QMimeDatabase db;
m_name = fi.baseName();
m_icon = db.mimeTypeForUrl(m_url).iconName();
m_genericName = fi.baseName();
}
} else {
if (m_url.scheme().contains("http")) {
m_name = m_url.host();
} else if (m_name.isEmpty()) {
m_name = m_url.toString();
if (m_name.endsWith(QLatin1String(":/"))) {
m_name = m_url.scheme();
}
}
m_icon = KIO::iconNameForUrl(url);
if (m_url.scheme().contains("http")) {
m_name = m_url.host();
} else if (m_name.isEmpty()) {
m_name = m_url.toString();
if (m_name.endsWith(QLatin1String(":/"))) {
m_name = m_url.scheme();
}
}
m_icon = KIO::iconNameForUrl(url);
}
emit urlChanged(m_url);
emit nameChanged(m_name);
emit iconChanged(m_icon);
emit genericNameChanged(m_genericName);
}
QUrl IconPrivate::url() const
@ -98,6 +99,69 @@ QString IconPrivate::genericName() const
return m_genericName;
}
bool IconPrivate::processDroppedUrls(const QJsonArray &droppedUrls)
{
if (!m_url.isLocalFile()) {
return false;
}
QList<QUrl> urls;
foreach (const QJsonValue &droppedUrl, droppedUrls) {
// TODO fromLocalFile / user input?
const QUrl url(droppedUrl.toString());
if (url.isValid()) {
urls.append(url);
}
}
if (urls.isEmpty()) {
return false;
}
const QString stringUrl = m_url.toLocalFile();
QMimeDatabase db;
const QMimeType mimeType = db.mimeTypeForFile(m_url.toLocalFile());
if (KDesktopFile::isDesktopFile(stringUrl)) {
const KDesktopFile desktopFile(stringUrl);
const QStringList &supportedMimeTypes = desktopFile.readMimeTypes();
// if no mime types are given just execute the command in the Desktop file
if (supportedMimeTypes.isEmpty()) {
KService service(stringUrl);
KRun::runService(service, urls, nullptr);
return true;
}
// otherwise check if the applicaton supports the dropped type
foreach (const QString &supportedType, supportedMimeTypes) {
if (mimeType.inherits(supportedType)) {
KService service(stringUrl);
KRun::runService(service, urls, nullptr);
return true;
}
}
return false;
}
if (mimeType.inherits("application/x-executable") || mimeType.inherits("application/x-shellscript")) {
QString params;
foreach (const QUrl &url, urls) {
// TODO toEncoded?
params += QLatin1Char(' ') + KShell::quoteArg(url.isLocalFile() ? url.toLocalFile() : url.toEncoded());
}
KRun::runCommand(KShell::quoteArg(m_url.path()) + QLatin1Char(' ') + params, nullptr);
return true;
} else if (mimeType.inherits("inode/directory")) {
// TODO drop urls thingie from konq/dolphin
}
return false;
}
void IconPrivate::open()
{
new KRun(m_url, 0);

@ -24,6 +24,8 @@
#include <QObject>
#include <QUrl>
class QJsonArray;
class IconPrivate : public QObject
{
Q_OBJECT
@ -33,7 +35,6 @@ class IconPrivate : public QObject
Q_PROPERTY(QString genericName READ genericName NOTIFY genericNameChanged)
public:
IconPrivate();
~IconPrivate();
@ -41,19 +42,18 @@ public:
QString name() const;
QString icon() const;
QString genericName() const;
void setUrl(QUrl& url);
void setUrl(const QUrl &url);
Q_INVOKABLE void open();
Q_INVOKABLE bool processDroppedUrls(const QJsonArray &droppedUrls);
Q_SIGNALS:
void urlChanged(QUrl newUrl);
void nameChanged(QString newName);
void iconChanged(QString newIcon);
void genericNameChanged(QString newGenericName);
private:
QUrl m_url;
QString m_name;
QString m_icon;
@ -61,4 +61,4 @@ private:
};
#endif
#endif

Loading…
Cancel
Save