mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
660 lines
21 KiB
C++
660 lines
21 KiB
C++
/*
|
|
Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 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 Library General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
*/
|
|
|
|
#include "specialcollectionshelperjobs_p.h"
|
|
|
|
#include "dbusconnectionpool.h"
|
|
#include "specialcollectionattribute_p.h"
|
|
#include "specialcollections.h"
|
|
#include "servermanager.h"
|
|
|
|
#include <akonadi/agentinstance.h>
|
|
#include <akonadi/agentinstancecreatejob.h>
|
|
#include <akonadi/agentmanager.h>
|
|
#include <akonadi/collectionfetchjob.h>
|
|
#include <akonadi/collectionfetchscope.h>
|
|
#include <akonadi/collectionmodifyjob.h>
|
|
#include <akonadi/entitydisplayattribute.h>
|
|
#include <akonadi/resourcesynchronizationjob.h>
|
|
|
|
#include <KDebug>
|
|
#include <KLocalizedString>
|
|
#include <kcoreconfigskeleton.h>
|
|
|
|
#include <QtDBus/QDBusConnectionInterface>
|
|
#include <QtDBus/QDBusInterface>
|
|
#include <QtDBus/QDBusServiceWatcher>
|
|
#include <QtCore/QMetaMethod>
|
|
#include <QtCore/QTime>
|
|
#include <QtCore/QTimer>
|
|
|
|
#define LOCK_WAIT_TIMEOUT_SECONDS 10
|
|
|
|
using namespace Akonadi;
|
|
|
|
// convenient methods to get/set the default resource id
|
|
static void setDefaultResourceId(KCoreConfigSkeleton *settings, const QString &value)
|
|
{
|
|
KConfigSkeletonItem *item = settings->findItem(QLatin1String("DefaultResourceId"));
|
|
Q_ASSERT(item);
|
|
item->setProperty(value);
|
|
}
|
|
|
|
static QString defaultResourceId(KCoreConfigSkeleton *settings)
|
|
{
|
|
const KConfigSkeletonItem *item = settings->findItem(QLatin1String("DefaultResourceId"));
|
|
Q_ASSERT(item);
|
|
return item->property().toString();
|
|
}
|
|
|
|
static QString dbusServiceName()
|
|
{
|
|
QString service = QString::fromLatin1("org.kde.pim.SpecialCollections");
|
|
if (ServerManager::hasInstanceIdentifier()) {
|
|
return service + ServerManager::instanceIdentifier();
|
|
}
|
|
return service;
|
|
}
|
|
|
|
static QVariant::Type argumentType(const QMetaObject *mo, const QString &method)
|
|
{
|
|
QMetaMethod m;
|
|
for (int i = 0; i < mo->methodCount(); ++i) {
|
|
const QString signature = QString::fromLatin1(mo->method(i).signature());
|
|
if (signature.startsWith(method)) {
|
|
m = mo->method(i);
|
|
}
|
|
}
|
|
|
|
if (!m.signature()) {
|
|
return QVariant::Invalid;
|
|
}
|
|
|
|
const QList<QByteArray> argTypes = m.parameterTypes();
|
|
if (argTypes.count() != 1) {
|
|
return QVariant::Invalid;
|
|
}
|
|
|
|
return QVariant::nameToType(argTypes.first());
|
|
}
|
|
|
|
// ===================== ResourceScanJob ============================
|
|
|
|
/**
|
|
@internal
|
|
*/
|
|
class Akonadi::ResourceScanJob::Private
|
|
{
|
|
public:
|
|
Private(KCoreConfigSkeleton *settings, ResourceScanJob *qq);
|
|
|
|
void fetchResult(KJob *job); // slot
|
|
|
|
ResourceScanJob *const q;
|
|
|
|
// Input:
|
|
QString mResourceId;
|
|
KCoreConfigSkeleton *mSettings;
|
|
|
|
// Output:
|
|
Collection mRootCollection;
|
|
Collection::List mSpecialCollections;
|
|
};
|
|
|
|
ResourceScanJob::Private::Private(KCoreConfigSkeleton *settings, ResourceScanJob *qq)
|
|
: q(qq)
|
|
, mSettings(settings)
|
|
{
|
|
}
|
|
|
|
void ResourceScanJob::Private::fetchResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
return;
|
|
}
|
|
|
|
CollectionFetchJob *fetchJob = qobject_cast<CollectionFetchJob *>(job);
|
|
Q_ASSERT(fetchJob);
|
|
|
|
Q_ASSERT(!mRootCollection.isValid());
|
|
Q_ASSERT(mSpecialCollections.isEmpty());
|
|
foreach (const Collection &collection, fetchJob->collections()) {
|
|
if (collection.parentCollection() == Collection::root()) {
|
|
if (mRootCollection.isValid()) {
|
|
kWarning() << "Resource has more than one root collection. I don't know what to do.";
|
|
} else {
|
|
mRootCollection = collection;
|
|
}
|
|
}
|
|
|
|
if (collection.hasAttribute<SpecialCollectionAttribute>()) {
|
|
mSpecialCollections.append(collection);
|
|
}
|
|
}
|
|
|
|
kDebug() << "Fetched root collection" << mRootCollection.id()
|
|
<< "and" << mSpecialCollections.count() << "local folders"
|
|
<< "(total" << fetchJob->collections().count() << "collections).";
|
|
|
|
if (!mRootCollection.isValid()) {
|
|
q->setError(Unknown);
|
|
q->setErrorText(i18n("Could not fetch root collection of resource %1.", mResourceId));
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
|
|
// We are done!
|
|
q->emitResult();
|
|
}
|
|
|
|
ResourceScanJob::ResourceScanJob(const QString &resourceId, KCoreConfigSkeleton *settings, QObject *parent)
|
|
: Job(parent)
|
|
, d(new Private(settings, this))
|
|
{
|
|
setResourceId(resourceId);
|
|
}
|
|
|
|
ResourceScanJob::~ResourceScanJob()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
QString ResourceScanJob::resourceId() const
|
|
{
|
|
return d->mResourceId;
|
|
}
|
|
|
|
void ResourceScanJob::setResourceId(const QString &resourceId)
|
|
{
|
|
d->mResourceId = resourceId;
|
|
}
|
|
|
|
Akonadi::Collection ResourceScanJob::rootResourceCollection() const
|
|
{
|
|
return d->mRootCollection;
|
|
}
|
|
|
|
Akonadi::Collection::List ResourceScanJob::specialCollections() const
|
|
{
|
|
return d->mSpecialCollections;
|
|
}
|
|
|
|
void ResourceScanJob::doStart()
|
|
{
|
|
if (d->mResourceId.isEmpty()) {
|
|
if(!qobject_cast<DefaultResourceJob *>(this)) {
|
|
kError() << "No resource ID given.";
|
|
setError(Job::Unknown);
|
|
setErrorText(i18n("No resource ID given."));
|
|
}
|
|
emitResult();
|
|
return;
|
|
}
|
|
|
|
CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(),
|
|
CollectionFetchJob::Recursive, this);
|
|
fetchJob->fetchScope().setResource(d->mResourceId);
|
|
fetchJob->fetchScope().setIncludeStatistics(true);
|
|
connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(fetchResult(KJob*)));
|
|
}
|
|
|
|
// ===================== DefaultResourceJob ============================
|
|
|
|
/**
|
|
@internal
|
|
*/
|
|
class Akonadi::DefaultResourceJobPrivate
|
|
{
|
|
public:
|
|
DefaultResourceJobPrivate(KCoreConfigSkeleton *settings, DefaultResourceJob *qq);
|
|
|
|
void tryFetchResource();
|
|
void resourceCreateResult(KJob *job); // slot
|
|
void resourceSyncResult(KJob *job); // slot
|
|
void collectionFetchResult(KJob *job); // slot
|
|
void collectionModifyResult(KJob *job); // slot
|
|
|
|
DefaultResourceJob *const q;
|
|
KCoreConfigSkeleton *mSettings;
|
|
bool mResourceWasPreexisting;
|
|
int mPendingModifyJobs;
|
|
QString mDefaultResourceType;
|
|
QVariantMap mDefaultResourceOptions;
|
|
QList<QByteArray> mKnownTypes;
|
|
QMap<QByteArray, QString> mNameForTypeMap;
|
|
QMap<QByteArray, QString> mIconForTypeMap;
|
|
};
|
|
|
|
DefaultResourceJobPrivate::DefaultResourceJobPrivate(KCoreConfigSkeleton *settings, DefaultResourceJob *qq)
|
|
: q(qq)
|
|
, mSettings(settings)
|
|
, mResourceWasPreexisting(true /* for safety, so as not to accidentally delete data */)
|
|
, mPendingModifyJobs(0)
|
|
{
|
|
}
|
|
|
|
void DefaultResourceJobPrivate::tryFetchResource()
|
|
{
|
|
// Get the resourceId from config. Another instance might have changed it in the meantime.
|
|
mSettings->readConfig();
|
|
|
|
const QString resourceId = defaultResourceId(mSettings);
|
|
|
|
kDebug() << "Read defaultResourceId" << resourceId << "from config.";
|
|
|
|
const AgentInstance resource = AgentManager::self()->instance(resourceId);
|
|
if (resource.isValid()) {
|
|
// The resource exists; scan it.
|
|
mResourceWasPreexisting = true;
|
|
kDebug() << "Found resource" << resourceId;
|
|
q->setResourceId(resourceId);
|
|
|
|
CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, q);
|
|
fetchJob->fetchScope().setResource(resourceId);
|
|
fetchJob->fetchScope().setIncludeStatistics(true);
|
|
q->connect(fetchJob, SIGNAL(result(KJob*)), q, SLOT(collectionFetchResult(KJob*)));
|
|
} else {
|
|
// Try harder: maybe the default resource has been removed and another one added
|
|
// without updating the config file, in this case search for a resource
|
|
// of the same type and the default name
|
|
const AgentInstance::List resources = AgentManager::self()->instances();
|
|
foreach (const AgentInstance &resource, resources) {
|
|
if (resource.type().identifier() == mDefaultResourceType) {
|
|
if (resource.name() == mDefaultResourceOptions.value(QLatin1String("Name")).toString()) {
|
|
// found a matching one...
|
|
setDefaultResourceId(mSettings, resource.identifier());
|
|
mSettings->writeConfig();
|
|
mResourceWasPreexisting = true;
|
|
kDebug() << "Found resource" << resource.identifier();
|
|
q->setResourceId(resource.identifier());
|
|
q->ResourceScanJob::doStart();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create the resource.
|
|
mResourceWasPreexisting = false;
|
|
kDebug() << "Creating maildir resource.";
|
|
const AgentType type = AgentManager::self()->type(mDefaultResourceType);
|
|
AgentInstanceCreateJob *job = new AgentInstanceCreateJob(type, q);
|
|
QObject::connect(job, SIGNAL(result(KJob*)), q, SLOT(resourceCreateResult(KJob*)));
|
|
job->start(); // non-Akonadi::Job
|
|
}
|
|
}
|
|
|
|
void DefaultResourceJobPrivate::resourceCreateResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
//fail( i18n( "Failed to create the default resource (%1).", job->errorString() ) );
|
|
q->setError(job->error());
|
|
q->setErrorText(job->errorText());
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
|
|
AgentInstance agent;
|
|
|
|
// Get the resource instance.
|
|
{
|
|
AgentInstanceCreateJob *createJob = qobject_cast<AgentInstanceCreateJob *>(job);
|
|
Q_ASSERT(createJob);
|
|
agent = createJob->instance();
|
|
setDefaultResourceId(mSettings, agent.identifier());
|
|
kDebug() << "Created maildir resource with id" << defaultResourceId(mSettings);
|
|
}
|
|
|
|
const QString defaultId = defaultResourceId(mSettings);
|
|
|
|
// Configure the resource.
|
|
{
|
|
agent.setName(mDefaultResourceOptions.value(QLatin1String("Name")).toString());
|
|
|
|
QDBusInterface conf(QString::fromLatin1("org.freedesktop.Akonadi.Resource.") + defaultId,
|
|
QString::fromLatin1("/Settings"), QString());
|
|
|
|
if (!conf.isValid()) {
|
|
q->setError(-1);
|
|
q->setErrorText(i18n("Invalid resource identifier '%1'", defaultId));
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
|
|
QMapIterator<QString, QVariant> it(mDefaultResourceOptions);
|
|
while (it.hasNext()) {
|
|
it.next();
|
|
|
|
if (it.key() == QLatin1String("Name")) {
|
|
continue;
|
|
}
|
|
|
|
const QString methodName = QString::fromLatin1("set%1").arg(it.key());
|
|
const QVariant::Type argType = argumentType(conf.metaObject(), methodName);
|
|
if (argType == QVariant::Invalid) {
|
|
q->setError(Job::Unknown);
|
|
q->setErrorText(i18n("Failed to configure default resource via D-Bus."));
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
|
|
QDBusReply<void> reply = conf.call(methodName, it.value());
|
|
if (!reply.isValid()) {
|
|
q->setError(Job::Unknown);
|
|
q->setErrorText(i18n("Failed to configure default resource via D-Bus."));
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
}
|
|
|
|
conf.call(QLatin1String("writeConfig"));
|
|
|
|
agent.reconfigure();
|
|
}
|
|
|
|
// Sync the resource.
|
|
{
|
|
ResourceSynchronizationJob *syncJob = new ResourceSynchronizationJob(agent, q);
|
|
QObject::connect(syncJob, SIGNAL(result(KJob*)), q, SLOT(resourceSyncResult(KJob*)));
|
|
syncJob->start(); // non-Akonadi
|
|
}
|
|
}
|
|
|
|
void DefaultResourceJobPrivate::resourceSyncResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
//fail( i18n( "ResourceSynchronizationJob failed (%1).", job->errorString() ) );
|
|
return;
|
|
}
|
|
|
|
// Fetch the collections of the resource.
|
|
kDebug() << "Fetching maildir collections.";
|
|
CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, q);
|
|
fetchJob->fetchScope().setResource(defaultResourceId(mSettings));
|
|
QObject::connect(fetchJob, SIGNAL(result(KJob*)), q, SLOT(collectionFetchResult(KJob*)));
|
|
}
|
|
|
|
void DefaultResourceJobPrivate::collectionFetchResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
//fail( i18n( "Failed to fetch the root maildir collection (%1).", job->errorString() ) );
|
|
return;
|
|
}
|
|
|
|
CollectionFetchJob *fetchJob = qobject_cast<CollectionFetchJob *>(job);
|
|
Q_ASSERT(fetchJob);
|
|
|
|
const Collection::List collections = fetchJob->collections();
|
|
kDebug() << "Fetched" << collections.count() << "collections.";
|
|
|
|
// Find the root maildir collection.
|
|
Collection::List toRecover;
|
|
Collection resourceCollection;
|
|
foreach (const Collection &collection, collections) {
|
|
if (collection.parentCollection() == Collection::root()) {
|
|
resourceCollection = collection;
|
|
toRecover.append(collection);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!resourceCollection.isValid()) {
|
|
q->setError(Job::Unknown);
|
|
q->setErrorText(i18n("Failed to fetch the resource collection."));
|
|
q->emitResult();
|
|
return;
|
|
}
|
|
|
|
// Find all children of the resource collection.
|
|
foreach (const Collection &collection, collections) {
|
|
if (collection.parentCollection() == resourceCollection) {
|
|
toRecover.append(collection);
|
|
}
|
|
}
|
|
|
|
QHash<QString, QByteArray> typeForName;
|
|
foreach (const QByteArray &type, mKnownTypes) {
|
|
const QString displayName = mNameForTypeMap.value(type);
|
|
typeForName[displayName] = type;
|
|
}
|
|
|
|
// These collections have been created by the maildir resource, when it
|
|
// found the folders on disk. So give them the necessary attributes now.
|
|
Q_ASSERT(mPendingModifyJobs == 0);
|
|
foreach (Collection collection, toRecover) { // krazy:exclude=foreach
|
|
|
|
if (collection.hasAttribute<SpecialCollectionAttribute>()) {
|
|
continue;
|
|
}
|
|
|
|
// Find the type for the collection.
|
|
const QString name = collection.displayName();
|
|
const QByteArray type = typeForName.value(name);
|
|
|
|
if (!type.isEmpty()) {
|
|
kDebug() << "Recovering collection" << name;
|
|
setCollectionAttributes(collection, type, mNameForTypeMap, mIconForTypeMap);
|
|
|
|
CollectionModifyJob *modifyJob = new CollectionModifyJob(collection, q);
|
|
QObject::connect(modifyJob, SIGNAL(result(KJob*)), q, SLOT(collectionModifyResult(KJob*)));
|
|
mPendingModifyJobs++;
|
|
} else {
|
|
kDebug() << "Searching for names: " << typeForName.keys();
|
|
kDebug() << "Unknown collection name" << name << "-- not recovering.";
|
|
}
|
|
}
|
|
|
|
if (mPendingModifyJobs == 0) {
|
|
// Scan the resource.
|
|
q->setResourceId(defaultResourceId(mSettings));
|
|
q->ResourceScanJob::doStart();
|
|
}
|
|
}
|
|
|
|
void DefaultResourceJobPrivate::collectionModifyResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
//fail( i18n( "Failed to modify the root maildir collection (%1).", job->errorString() ) );
|
|
return;
|
|
}
|
|
|
|
Q_ASSERT(mPendingModifyJobs > 0);
|
|
mPendingModifyJobs--;
|
|
kDebug() << "pendingModifyJobs now" << mPendingModifyJobs;
|
|
if (mPendingModifyJobs == 0) {
|
|
// Write the updated config.
|
|
kDebug() << "Writing defaultResourceId" << defaultResourceId(mSettings) << "to config.";
|
|
mSettings->writeConfig();
|
|
|
|
// Scan the resource.
|
|
q->setResourceId(defaultResourceId(mSettings));
|
|
q->ResourceScanJob::doStart();
|
|
}
|
|
}
|
|
|
|
DefaultResourceJob::DefaultResourceJob(KCoreConfigSkeleton *settings, QObject *parent)
|
|
: ResourceScanJob(QString(), settings, parent)
|
|
, d(new DefaultResourceJobPrivate(settings, this))
|
|
{
|
|
}
|
|
|
|
DefaultResourceJob::~DefaultResourceJob()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void DefaultResourceJob::setDefaultResourceType(const QString &type)
|
|
{
|
|
d->mDefaultResourceType = type;
|
|
}
|
|
|
|
void DefaultResourceJob::setDefaultResourceOptions(const QVariantMap &options)
|
|
{
|
|
d->mDefaultResourceOptions = options;
|
|
}
|
|
|
|
void DefaultResourceJob::setTypes(const QList<QByteArray> &types)
|
|
{
|
|
d->mKnownTypes = types;
|
|
}
|
|
|
|
void DefaultResourceJob::setNameForTypeMap(const QMap<QByteArray, QString> &map)
|
|
{
|
|
d->mNameForTypeMap = map;
|
|
}
|
|
|
|
void DefaultResourceJob::setIconForTypeMap(const QMap<QByteArray, QString> &map)
|
|
{
|
|
d->mIconForTypeMap = map;
|
|
}
|
|
|
|
void DefaultResourceJob::doStart()
|
|
{
|
|
d->tryFetchResource();
|
|
}
|
|
|
|
void DefaultResourceJob::slotResult(KJob *job)
|
|
{
|
|
if (job->error()) {
|
|
kWarning() << job->errorText();
|
|
// Do some cleanup.
|
|
if (!d->mResourceWasPreexisting) {
|
|
// We only removed the resource instance if we have created it.
|
|
// Otherwise we might lose the user's data.
|
|
const AgentInstance resource = AgentManager::self()->instance(defaultResourceId(d->mSettings));
|
|
kDebug() << "Removing resource" << resource.identifier();
|
|
AgentManager::self()->removeInstance(resource);
|
|
}
|
|
}
|
|
|
|
Job::slotResult(job);
|
|
}
|
|
|
|
// ===================== GetLockJob ============================
|
|
|
|
class Akonadi::GetLockJob::Private
|
|
{
|
|
public:
|
|
Private(GetLockJob *qq);
|
|
|
|
void doStart(); // slot
|
|
void serviceOwnerChanged(const QString &name, const QString &oldOwner,
|
|
const QString &newOwner); // slot
|
|
void timeout(); // slot
|
|
|
|
GetLockJob *const q;
|
|
QTimer *mSafetyTimer;
|
|
};
|
|
|
|
GetLockJob::Private::Private(GetLockJob *qq)
|
|
: q(qq)
|
|
, mSafetyTimer(0)
|
|
{
|
|
}
|
|
|
|
void GetLockJob::Private::doStart()
|
|
{
|
|
// Just doing registerService() and checking its return value is not sufficient,
|
|
// since we may *already* own the name, and then registerService() returns true.
|
|
|
|
QDBusConnection bus = DBusConnectionPool::threadConnection();
|
|
const bool alreadyLocked = bus.interface()->isServiceRegistered(dbusServiceName());
|
|
const bool gotIt = bus.registerService(dbusServiceName());
|
|
|
|
if (gotIt && !alreadyLocked) {
|
|
//kDebug() << "Got lock immediately.";
|
|
q->emitResult();
|
|
} else {
|
|
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(dbusServiceName(), DBusConnectionPool::threadConnection(),
|
|
QDBusServiceWatcher::WatchForOwnerChange, q);
|
|
//kDebug() << "Waiting for lock.";
|
|
connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
|
|
q, SLOT(serviceOwnerChanged(QString,QString,QString)));
|
|
|
|
mSafetyTimer = new QTimer(q);
|
|
mSafetyTimer->setSingleShot(true);
|
|
mSafetyTimer->setInterval(LOCK_WAIT_TIMEOUT_SECONDS * 1000);
|
|
mSafetyTimer->start();
|
|
connect(mSafetyTimer, SIGNAL(timeout()), q, SLOT(timeout()));
|
|
}
|
|
}
|
|
|
|
void GetLockJob::Private::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
|
|
{
|
|
if (newOwner.isEmpty()) {
|
|
const bool gotIt = DBusConnectionPool::threadConnection().registerService(dbusServiceName());
|
|
if (gotIt) {
|
|
mSafetyTimer->stop();
|
|
q->emitResult();
|
|
}
|
|
}
|
|
}
|
|
|
|
void GetLockJob::Private::timeout()
|
|
{
|
|
kWarning() << "Timeout trying to get lock. Check who has acquired the name" << dbusServiceName() << "on DBus, using qdbus or qdbusviewer.";
|
|
q->setError(Job::Unknown);
|
|
q->setErrorText(i18n("Timeout trying to get lock."));
|
|
q->emitResult();
|
|
}
|
|
|
|
GetLockJob::GetLockJob(QObject *parent)
|
|
: KJob(parent)
|
|
, d(new Private(this))
|
|
{
|
|
}
|
|
|
|
GetLockJob::~GetLockJob()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void GetLockJob::start()
|
|
{
|
|
QTimer::singleShot(0, this, SLOT(doStart()));
|
|
}
|
|
|
|
void Akonadi::setCollectionAttributes(Akonadi::Collection &collection, const QByteArray &type,
|
|
const QMap<QByteArray, QString> &nameForType,
|
|
const QMap<QByteArray, QString> &iconForType)
|
|
{
|
|
{
|
|
EntityDisplayAttribute *attr = new EntityDisplayAttribute;
|
|
attr->setIconName(iconForType.value(type));
|
|
attr->setDisplayName(nameForType.value(type));
|
|
collection.addAttribute(attr);
|
|
}
|
|
|
|
{
|
|
SpecialCollectionAttribute *attr = new SpecialCollectionAttribute;
|
|
attr->setCollectionType(type);
|
|
collection.addAttribute(attr);
|
|
}
|
|
}
|
|
|
|
bool Akonadi::releaseLock()
|
|
{
|
|
return DBusConnectionPool::threadConnection().unregisterService(dbusServiceName());
|
|
}
|
|
|
|
#include "moc_specialcollectionshelperjobs_p.cpp"
|