plasma-framework/remote/accessmanager.cpp
Rob Scheepmaker 5b56a34dfa Support drag & drop of plasma:// and plasma+zeroconf:// urls onto plasma containments.
svn path=/trunk/KDE/kdelibs/; revision=1026777
2009-09-22 15:29:08 +00:00

182 lines
5.4 KiB
C++

/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "accessmanager.h"
#include "private/accessmanager_p.h"
#include "authorizationmanager.h"
#include "service.h"
#include "serviceaccessjob.h"
#include "private/authorizationmanager_p.h"
#include "config-plasma.h"
#include <QtCore/QMap>
#include <QtCore/QTimer>
#include <dnssd/remoteservice.h>
#include <dnssd/servicebrowser.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <ktemporaryfile.h>
#include <kurl.h>
#include <QtJolie/Message>
namespace Plasma
{
class AccessManagerSingleton
{
public:
AccessManager self;
};
K_GLOBAL_STATIC(AccessManagerSingleton, privateAccessManagerSelf)
AccessManager *AccessManager::self()
{
return &privateAccessManagerSelf->self;
}
AccessManager::AccessManager()
: QObject(),
d(new AccessManagerPrivate(this))
{
KGlobal::dirs()->addResourceType("trustedkeys", "config", "trustedkeys/");
}
AccessManager::~AccessManager()
{
delete d;
}
AccessAppletJob *AccessManager::accessRemoteApplet(const KUrl &location) const
{
AuthorizationManager::self()->d->prepareForServiceAccess();
KUrl resolvedLocation;
if (location.protocol() == "plasma+zeroconf") {
if (d->zeroconfServices.contains(location.host())) {
resolvedLocation = d->services[location.host()].remoteLocation();
} else {
kDebug() << "There's no zeroconf service with this name.";
}
} else {
resolvedLocation = location;
}
AccessAppletJob *job = new AccessAppletJob(resolvedLocation);
connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotJobFinished(KJob*)));
QTimer::singleShot(0, job, SLOT(slotStart()));
return job;
}
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"))
{
#ifdef ENABLE_REMOTE_WIDGETS
q->connect(browser, SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),
q, SLOT(slotAddService(DNSSD::RemoteService::Ptr)));
q->connect(browser, SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),
q, SLOT(slotRemoveService(DNSSD::RemoteService::Ptr)));
browser->startBrowse();
#else
kWarning() << "libplasma is compiled without support for remote widgets. not monitoring remote widgets on the network";
#endif
}
AccessManagerPrivate::~AccessManagerPrivate()
{
delete browser;
}
void AccessManagerPrivate::slotJobFinished(KJob *job)
{
emit q->finished(static_cast<AccessAppletJob*>(job));
}
void AccessManagerPrivate::slotAddService(DNSSD::RemoteService::Ptr service)
{
kDebug();
if (!service->resolve()) {
kDebug() << "Zeroconf service can't be resolved";
return;
}
if (!services.contains(service->serviceName())) {
PackageMetadata metadata;
kDebug() << "textdata = " << service->textData();
kDebug() << "hostname: " << service->hostName();
QHostAddress address = DNSSD::ServiceBrowser::resolveHostName(service->hostName());
QString ip = address.toString();
kDebug() << "result for resolve = " << ip;
KUrl url(QString("plasma://%1:%2/%3").arg(ip)
.arg(service->port())
.arg(service->serviceName()));
if (!service->textData().isEmpty()) {
kDebug() << "service has got textdata";
QMap<QString, QByteArray> textData = service->textData();
metadata.setName(textData["name"]);
metadata.setDescription(textData["description"]);
metadata.setRemoteLocation(url.prettyUrl());
} else {
kDebug() << "no textdata?";
metadata.setName(service->serviceName());
metadata.setRemoteLocation(url.prettyUrl());
}
kDebug() << "location = " << metadata.remoteLocation();
kDebug() << "name = " << metadata.name();
kDebug() << "description = " << metadata.name();
services[service->serviceName()] = metadata;
zeroconfServices[service->serviceName()] = service;
emit q->remoteAppletAnnounced(metadata);
}
}
void AccessManagerPrivate::slotRemoveService(DNSSD::RemoteService::Ptr service)
{
kDebug();
emit q->remoteAppletUnannounced(services[service->serviceName()]);
services.remove(service->serviceName());
zeroconfServices.remove(service->serviceName());
}
} // Plasma namespace
#include "accessmanager.moc"