kde-playground/kdepim/kalarm/collectionsearch.cpp

180 lines
6.2 KiB
C++
Raw Normal View History

/*
* collectionsearch.cpp - Search Akonadi Collections
* Program: kalarm
* Copyright © 2014 by David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// kdepimlibs and kdepim-runtime 4.12.4 minimum are required
#include <kdeversion.h>
#if defined(USE_AKONADI) && KDE_IS_VERSION(4,12,4)
#include "collectionsearch.h"
#include <akonadi/agentinstance.h>
#include <akonadi/agentmanager.h>
#include <akonadi/collectionfetchjob.h>
#include <akonadi/collectionfetchscope.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemdeletejob.h>
#include <QStringList>
#include <QTimer>
using namespace Akonadi;
/******************************************************************************
* Constructor.
* Creates jobs to fetch all collections for resources containing the mime type.
* Its subsequent actions depend on the parameters:
* - If 'remove' is true, it will locate all Items with the specified 'gid' and
* delete them. The deleted() signal will be emitted.
* - Otherwise, if 'gid' is specified, it will emit the signal items() to
* notify all Items with that GID.
* - Otherwise, it will emit the signal collections() to notify all Collections.
*/
CollectionSearch::CollectionSearch(const QString& mimeType, const QString& gid, bool remove)
: mMimeType(mimeType),
mGid(gid),
mDeleteCount(0),
mDelete(remove && !mGid.isEmpty())
{
const AgentInstance::List agents = AgentManager::self()->instances();
foreach (const AgentInstance& agent, agents)
{
if (agent.type().mimeTypes().contains(mimeType))
{
{
CollectionFetchJob* job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel);
job->fetchScope().setResource(agent.identifier());
mCollectionJobs << job;
connect(job, SIGNAL(result(KJob*)), SLOT(collectionFetchResult(KJob*)));
}
}
}
if (mCollectionJobs.isEmpty())
{
// There are no resources containing the mime type, so ensure that a
// signal is emitted after construction.
QTimer::singleShot(0, this, SLOT(finish()));
}
}
/******************************************************************************
* Called when a CollectionFetchJob has completed.
*/
void CollectionSearch::collectionFetchResult(KJob* j)
{
CollectionFetchJob* job = static_cast<CollectionFetchJob*>(j);
if (j->error())
kError() << "CollectionFetchJob" << job->fetchScope().resource() << "error: " << j->errorString();
else
{
const Collection::List collections = job->collections();
foreach (const Collection& c, collections)
{
if (c.contentMimeTypes().contains(mMimeType))
{
if (mGid.isEmpty())
mCollections << c;
else
{
// Search for all Items with the specified GID
Item item;
item.setGid(mGid);
ItemFetchJob* ijob = new ItemFetchJob(item, this);
ijob->setCollection(c);
mItemFetchJobs[ijob] = c.id();
connect(ijob, SIGNAL(result(KJob*)), SLOT(itemFetchResult(KJob*)));
}
}
}
}
mCollectionJobs.removeAll(job);
if (mCollectionJobs.isEmpty())
{
// All collections have now been fetched
if (mGid.isEmpty())
finish();
}
}
/******************************************************************************
* Called when an ItemFetchJob has completed.
*/
void CollectionSearch::itemFetchResult(KJob* j)
{
ItemFetchJob* job = static_cast<ItemFetchJob*>(j);
if (j->error())
kDebug() << "ItemFetchJob: collection" << mItemFetchJobs[job] << "GID" << mGid << "error: " << j->errorString();
else
{
if (mDelete)
{
Item::List items = job->items();
foreach (const Item& item, items)
{
ItemDeleteJob* djob = new ItemDeleteJob(item, this);
mItemDeleteJobs[djob] = mItemFetchJobs[job];
connect(djob, SIGNAL(result(KJob*)), SLOT(itemDeleteResult(KJob*)));
}
}
else
mItems << job->items();
}
mItemFetchJobs.remove(job);
if (mItemFetchJobs.isEmpty() && mItemDeleteJobs.isEmpty() && mCollectionJobs.isEmpty())
finish(); // all Items have now been fetched or deleted, so notify the result
}
/******************************************************************************
* Called when an ItemDeleteJob has completed.
*/
void CollectionSearch::itemDeleteResult(KJob* j)
{
ItemDeleteJob* job = static_cast<ItemDeleteJob*>(j);
if (j->error())
kDebug() << "ItemDeleteJob: resource" << mItemDeleteJobs[job] << "GID" << mGid << "error: " << j->errorString();
else
++mDeleteCount;
mItemDeleteJobs.remove(job);
if (mItemFetchJobs.isEmpty() && mItemDeleteJobs.isEmpty() && mCollectionJobs.isEmpty())
finish(); // all Items have now been deleted, so notify the result
}
/******************************************************************************
* Notify the result of the search/delete operation, and delete this instance.
*/
void CollectionSearch::finish()
{
if (mDelete)
emit deleted(mDeleteCount);
else if (mGid.isEmpty())
emit collections(mCollections);
else
emit items(mItems);
deleteLater();
}
#include "moc_collectionsearch.cpp"
#endif
// vim: et sw=4: