Support drag & drop of plasma:// and plasma+zeroconf:// urls onto plasma containments.

svn path=/trunk/KDE/kdelibs/; revision=1026777
This commit is contained in:
Rob Scheepmaker 2009-09-22 15:29:08 +00:00
parent eedf3c47ff
commit 5b56a34dfa
5 changed files with 71 additions and 26 deletions

View File

@ -56,6 +56,9 @@
#include "svg.h" #include "svg.h"
#include "wallpaper.h" #include "wallpaper.h"
#include "remote/accessappletjob.h"
#include "remote/accessmanager.h"
#include "private/applet_p.h" #include "private/applet_p.h"
#include "private/applethandle_p.h" #include "private/applethandle_p.h"
#include "private/desktoptoolbox_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 // to create widgets out of the matching URLs, if any
const KUrl::List urls = KUrl::List::fromMimeData(mimeData); const KUrl::List urls = KUrl::List::fromMimeData(mimeData);
foreach (const KUrl &url, urls) { foreach (const KUrl &url, urls) {
KMimeType::Ptr mime = KMimeType::findByUrl(url); if (AccessManager::supportedProtocols().contains(url.protocol())) {
QString mimeName = mime->name(); AccessAppletJob *job = AccessManager::self()->accessRemoteApplet(url);
QRectF geom(pos, QSize()); dropPoints[job] = dropEvent->scenePos();
QVariantList args; QObject::connect(AccessManager::self(), SIGNAL(finished(Plasma::AccessAppletJob*)),
args << url.url(); q, SLOT(remoteAppletReady(Plasma::AccessAppletJob*)));
//kDebug() << "can decode" << mimeName << args; } else {
//kDebug() << "protocol:" << url.protocol(); KMimeType::Ptr mime = KMimeType::findByUrl(url);
KPluginInfo::List appletList = Applet::listAppletInfoForMimetype(mimeName); QString mimeName = mime->name();
KPluginInfo::List wallpaperList; QRectF geom(pos, QSize());
if (q->drawWallpaper()) { QVariantList args;
wallpaperList = Wallpaper::listWallpaperInfoForMimetype(mimeName); 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) { if (dropEvent) {
@ -1315,6 +1325,23 @@ void ContainmentPrivate::clearDataForMimeJob(KIO::Job *job)
job->kill(); 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) void ContainmentPrivate::mimeTypeRetrieved(KIO::Job * job, const QString &mimetype)
{ {
kDebug() << "Mimetype Job returns." << mimetype; kDebug() << "Mimetype Job returns." << mimetype;

View File

@ -41,6 +41,7 @@ namespace KIO
namespace Plasma namespace Plasma
{ {
class AccessAppletJob;
class AppletHandle; class AppletHandle;
class DataEngine; class DataEngine;
class Package; class Package;
@ -580,6 +581,7 @@ class PLASMA_EXPORT Containment : public Applet
Q_PRIVATE_SLOT(d, void requestConfiguration()) Q_PRIVATE_SLOT(d, void requestConfiguration())
Q_PRIVATE_SLOT(d, void updateToolBoxVisibility()) 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. * This slot is called when the 'stat' after a job event has finished.
*/ */

View File

@ -28,9 +28,12 @@ static const int TOOLBOX_MARGIN = 150;
static const int CONTAINMENT_COLUMNS = 2; static const int CONTAINMENT_COLUMNS = 2;
static const int VERTICAL_STACKING_OFFSET = 10000; static const int VERTICAL_STACKING_OFFSET = 10000;
class KJob;
namespace Plasma namespace Plasma
{ {
class AccessAppletJob;
class Containment; class Containment;
class ToolBox; class ToolBox;
@ -83,6 +86,7 @@ public:
void zoomIn(); void zoomIn();
void zoomOut(); void zoomOut();
void clearDataForMimeJob(KIO::Job *job); void clearDataForMimeJob(KIO::Job *job);
void remoteAppletReady(Plasma::AccessAppletJob *job);
void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype); void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype);
void containmentActions(KMenu &desktopMenu); void containmentActions(KMenu &desktopMenu);
void appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet); void appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet);
@ -142,8 +146,8 @@ public:
Containment::Type type; Containment::Type type;
static bool s_positioning; static bool s_positioning;
bool drawWallpaper; bool drawWallpaper;
QHash<KIO::Job*, QPointF> dropPoints; QHash<KJob*, QPointF> dropPoints;
QHash<KIO::Job*, KMenu*> dropMenus; QHash<KJob*, KMenu*> dropMenus;
}; };
} // Plasma namespace } // Plasma namespace

View File

@ -73,7 +73,7 @@ AccessAppletJob *AccessManager::accessRemoteApplet(const KUrl &location) const
AuthorizationManager::self()->d->prepareForServiceAccess(); AuthorizationManager::self()->d->prepareForServiceAccess();
KUrl resolvedLocation; KUrl resolvedLocation;
if (location.protocol() == "zeroconf") { if (location.protocol() == "plasma+zeroconf") {
if (d->zeroconfServices.contains(location.host())) { if (d->zeroconfServices.contains(location.host())) {
resolvedLocation = d->services[location.host()].remoteLocation(); resolvedLocation = d->services[location.host()].remoteLocation();
} else { } else {
@ -94,6 +94,13 @@ QList<PackageMetadata> AccessManager::remoteApplets() const
return d->services.values(); return d->services.values();
} }
QStringList AccessManager::supportedProtocols()
{
QStringList list;
list << "plasma" << "plasma+zeroconf";
return list;
}
AccessManagerPrivate::AccessManagerPrivate(AccessManager *manager) AccessManagerPrivate::AccessManagerPrivate(AccessManager *manager)
: q(manager), : q(manager),
browser(new DNSSD::ServiceBrowser("_plasma._tcp")) browser(new DNSSD::ServiceBrowser("_plasma._tcp"))

View File

@ -78,6 +78,11 @@ class PLASMA_EXPORT AccessManager : public QObject
*/ */
QList<PackageMetadata> remoteApplets() const; QList<PackageMetadata> remoteApplets() const;
/**
* @returns a list of supported protocols of urls that can be passed to accessRemoteApplet.
*/
static QStringList supportedProtocols();
Q_SIGNALS: Q_SIGNALS:
/** /**
* fires when an AccessAppletJob is finished. * fires when an AccessAppletJob is finished.