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 "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;

View File

@ -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.
*/

View File

@ -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<KIO::Job*, QPointF> dropPoints;
QHash<KIO::Job*, KMenu*> dropMenus;
QHash<KJob*, QPointF> dropPoints;
QHash<KJob*, KMenu*> dropMenus;
};
} // Plasma namespace

View File

@ -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<PackageMetadata> 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"))

View File

@ -78,6 +78,11 @@ class PLASMA_EXPORT AccessManager : public QObject
*/
QList<PackageMetadata> 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.