From 5b56a34dfaac42f009b15a0bc3c393283654d878 Mon Sep 17 00:00:00 2001 From: Rob Scheepmaker Date: Tue, 22 Sep 2009 15:29:08 +0000 Subject: [PATCH] Support drag & drop of plasma:// and plasma+zeroconf:// urls onto plasma containments. svn path=/trunk/KDE/kdelibs/; revision=1026777 --- containment.cpp | 73 +++++++++++++++++++++++++++------------- containment.h | 2 ++ private/containment_p.h | 8 +++-- remote/accessmanager.cpp | 9 ++++- remote/accessmanager.h | 5 +++ 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/containment.cpp b/containment.cpp index 482f35128..8aa8b5403 100644 --- a/containment.cpp +++ b/containment.cpp @@ -56,6 +56,9 @@ #include "svg.h" #include "wallpaper.h" +#include "remote/accessappletjob.h" +#include "remote/accessmanager.h" + #include "private/applet_p.h" #include "private/applethandle_p.h" #include "private/desktoptoolbox_p.h" @@ -1207,30 +1210,37 @@ void ContainmentPrivate::dropData(QPointF scenePos, QPoint screenPos, QGraphicsS // to create widgets out of the matching URLs, if any const KUrl::List urls = KUrl::List::fromMimeData(mimeData); foreach (const KUrl &url, urls) { - KMimeType::Ptr mime = KMimeType::findByUrl(url); - QString mimeName = mime->name(); - QRectF geom(pos, QSize()); - QVariantList args; - args << url.url(); - //kDebug() << "can decode" << mimeName << args; - //kDebug() << "protocol:" << url.protocol(); - KPluginInfo::List appletList = Applet::listAppletInfoForMimetype(mimeName); - KPluginInfo::List wallpaperList; - if (q->drawWallpaper()) { - wallpaperList = Wallpaper::listWallpaperInfoForMimetype(mimeName); + if (AccessManager::supportedProtocols().contains(url.protocol())) { + AccessAppletJob *job = AccessManager::self()->accessRemoteApplet(url); + dropPoints[job] = dropEvent->scenePos(); + QObject::connect(AccessManager::self(), SIGNAL(finished(Plasma::AccessAppletJob*)), + q, SLOT(remoteAppletReady(Plasma::AccessAppletJob*))); + } else { + KMimeType::Ptr mime = KMimeType::findByUrl(url); + QString mimeName = mime->name(); + QRectF geom(pos, QSize()); + QVariantList args; + args << url.url(); + kDebug() << "can decode" << mimeName << args; + kDebug() << "protocol:" << url.protocol(); + KPluginInfo::List appletList = Applet::listAppletInfoForMimetype(mimeName); + KPluginInfo::List wallpaperList; + if (q->drawWallpaper()) { + wallpaperList = Wallpaper::listWallpaperInfoForMimetype(mimeName); + } + + // It may be a directory or a file, let's stat + KIO::JobFlags flags = KIO::HideProgressInfo; + KIO::TransferJob *job = KIO::get(url, KIO::NoReload, flags); + dropPoints[job] = dropEvent->scenePos(); + QObject::connect(job, SIGNAL(mimetype(KIO::Job *, const QString&)), + q, SLOT(mimeTypeRetrieved(KIO::Job *, const QString&))); + + KMenu *choices = new KMenu("Content dropped"); + choices->addAction(KIcon("process-working"), i18n("Fetching file type...")); + choices->popup(dropEvent->screenPos()); + dropMenus[job] = choices; } - - // It may be a directory or a file, let's stat - KIO::JobFlags flags = KIO::HideProgressInfo; - KIO::TransferJob *job = KIO::get(url, KIO::NoReload, flags); - dropPoints[job] = dropEvent->scenePos(); - QObject::connect(job, SIGNAL(mimetype(KIO::Job *, const QString&)), - q, SLOT(mimeTypeRetrieved(KIO::Job *, const QString&))); - - KMenu *choices = new KMenu("Content dropped"); - choices->addAction(KIcon("process-working"), i18n("Fetching file type...")); - choices->popup(dropEvent->screenPos()); - dropMenus[job] = choices; } if (dropEvent) { @@ -1315,6 +1325,23 @@ void ContainmentPrivate::clearDataForMimeJob(KIO::Job *job) job->kill(); } +void ContainmentPrivate::remoteAppletReady(Plasma::AccessAppletJob *job) +{ + QPointF pos = dropPoints.take(job); + if (job->error()) { + //TODO: nice user visible error handling (knotification probably?) + kDebug() << "remote applet access failed: " << job->errorText(); + return; + } + + if (!job->applet()) { + kDebug() << "how did we end up here? if applet is null, the job->error should be nonzero"; + return; + } + + q->addApplet(job->applet(), pos); +} + void ContainmentPrivate::mimeTypeRetrieved(KIO::Job * job, const QString &mimetype) { kDebug() << "Mimetype Job returns." << mimetype; diff --git a/containment.h b/containment.h index abaabb50c..f45f85791 100644 --- a/containment.h +++ b/containment.h @@ -41,6 +41,7 @@ namespace KIO namespace Plasma { +class AccessAppletJob; class AppletHandle; class DataEngine; class Package; @@ -580,6 +581,7 @@ class PLASMA_EXPORT Containment : public Applet Q_PRIVATE_SLOT(d, void requestConfiguration()) Q_PRIVATE_SLOT(d, void updateToolBoxVisibility()) + Q_PRIVATE_SLOT(d, void remoteAppletReady(Plasma::AccessAppletJob *)); /** * This slot is called when the 'stat' after a job event has finished. */ diff --git a/private/containment_p.h b/private/containment_p.h index 913e6d469..243ba0b3e 100644 --- a/private/containment_p.h +++ b/private/containment_p.h @@ -28,9 +28,12 @@ static const int TOOLBOX_MARGIN = 150; static const int CONTAINMENT_COLUMNS = 2; static const int VERTICAL_STACKING_OFFSET = 10000; +class KJob; + namespace Plasma { +class AccessAppletJob; class Containment; class ToolBox; @@ -83,6 +86,7 @@ public: void zoomIn(); void zoomOut(); void clearDataForMimeJob(KIO::Job *job); + void remoteAppletReady(Plasma::AccessAppletJob *job); void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype); void containmentActions(KMenu &desktopMenu); void appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet); @@ -142,8 +146,8 @@ public: Containment::Type type; static bool s_positioning; bool drawWallpaper; - QHash dropPoints; - QHash dropMenus; + QHash dropPoints; + QHash dropMenus; }; } // Plasma namespace diff --git a/remote/accessmanager.cpp b/remote/accessmanager.cpp index 6f60ce86e..0a4f66af8 100644 --- a/remote/accessmanager.cpp +++ b/remote/accessmanager.cpp @@ -73,7 +73,7 @@ AccessAppletJob *AccessManager::accessRemoteApplet(const KUrl &location) const AuthorizationManager::self()->d->prepareForServiceAccess(); KUrl resolvedLocation; - if (location.protocol() == "zeroconf") { + if (location.protocol() == "plasma+zeroconf") { if (d->zeroconfServices.contains(location.host())) { resolvedLocation = d->services[location.host()].remoteLocation(); } else { @@ -94,6 +94,13 @@ QList AccessManager::remoteApplets() const return d->services.values(); } +QStringList AccessManager::supportedProtocols() +{ + QStringList list; + list << "plasma" << "plasma+zeroconf"; + return list; +} + AccessManagerPrivate::AccessManagerPrivate(AccessManager *manager) : q(manager), browser(new DNSSD::ServiceBrowser("_plasma._tcp")) diff --git a/remote/accessmanager.h b/remote/accessmanager.h index 7ecd4f5b1..6e6107331 100644 --- a/remote/accessmanager.h +++ b/remote/accessmanager.h @@ -78,6 +78,11 @@ class PLASMA_EXPORT AccessManager : public QObject */ QList remoteApplets() const; + /** + * @returns a list of supported protocols of urls that can be passed to accessRemoteApplet. + */ + static QStringList supportedProtocols(); + Q_SIGNALS: /** * fires when an AccessAppletJob is finished.