Branch 'kolab/integration/4.13.0' - 4 commits - korganizer/akonadicollectionview.cpp korganizer/CMakeLists.txt korganizer/views libkdepim/CMakeLists.txt libkdepim/job
Christian Mollekopf
mollekopf at kolabsys.com
Mon Jan 19 17:32:29 CET 2015
korganizer/CMakeLists.txt | 2
korganizer/akonadicollectionview.cpp | 2
korganizer/views/collectionview/collectionsearchjob.cpp | 129 --------
korganizer/views/collectionview/collectionsearchjob.h | 51 ---
korganizer/views/collectionview/controller.cpp | 32 +-
korganizer/views/collectionview/controller.h | 2
korganizer/views/collectionview/person.h | 46 --
korganizer/views/collectionview/personsearchjob.cpp | 253 ----------------
korganizer/views/collectionview/personsearchjob.h | 65 ----
libkdepim/CMakeLists.txt | 2
libkdepim/job/collectionsearchjob.cpp | 132 ++++++++
libkdepim/job/collectionsearchjob.h | 55 +++
libkdepim/job/person.h | 48 +++
libkdepim/job/personsearchjob.cpp | 253 ++++++++++++++++
libkdepim/job/personsearchjob.h | 67 ++++
15 files changed, 575 insertions(+), 564 deletions(-)
New commits:
commit 3ae28f4648eb1cb9c8cdee778fd25aac0408bf25
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date: Mon Jan 19 17:31:40 2015 +0100
KOrganizer: show all personal folder when searching for *
diff --git a/korganizer/akonadicollectionview.cpp b/korganizer/akonadicollectionview.cpp
index 170fad6..2e85995 100644
--- a/korganizer/akonadicollectionview.cpp
+++ b/korganizer/akonadicollectionview.cpp
@@ -569,7 +569,7 @@ AkonadiCollectionView::AkonadiCollectionView( CalendarView *view, bool hasContex
filterTreeViewModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
// filterTreeViewModel->setObjectName( "Recursive filtering, for the search bar" );
connect( searchCol, SIGNAL(textChanged(QString)),
- filterTreeViewModel, SLOT(setFilterFixedString(QString)) );
+ filterTreeViewModel, SLOT(setFilterWildcard(QString)) );
SortProxyModel *searchSortProxy = new SortProxyModel( this );
searchSortProxy->setSourceModel(filterTreeViewModel);
diff --git a/korganizer/views/collectionview/controller.cpp b/korganizer/views/collectionview/controller.cpp
index 5bcc0e5..b89d221 100644
--- a/korganizer/views/collectionview/controller.cpp
+++ b/korganizer/views/collectionview/controller.cpp
@@ -297,43 +297,44 @@ void Controller::setSearchString(const QString &searchString)
//TODO: Delay and abort when results are found
mSearchModel->clear();
emit searchIsActive(!searchString.isEmpty());
- if (searchString.size() < 2) {
+ const bool showAllPersonalFolders = (searchString == QLatin1String("*"));
+ if (searchString.size() < 2 && !showAllPersonalFolders) {
emit searching(false);
return;
}
- emit searching(true);
+ if (!showAllPersonalFolders) {
+ emit searching(true);
- mPersonSearchJob = new PersonSearchJob(searchString, this);
- connect(mPersonSearchJob, SIGNAL(personsFound(QList<Person>)), this, SLOT(onPersonsFound(QList<Person>)));
- connect(mPersonSearchJob, SIGNAL(personUpdate(Person)), this, SLOT(onPersonUpdate(Person)));
- connect(mPersonSearchJob, SIGNAL(result(KJob*)), this, SLOT(onPersonsFound(KJob*)));
- mPersonSearchJob->start();
+ mPersonSearchJob = new PersonSearchJob(searchString, this);
+ connect(mPersonSearchJob, SIGNAL(personsFound(QList<Person>)), this, SLOT(onPersonsFound(QList<Person>)));
+ connect(mPersonSearchJob, SIGNAL(personUpdate(Person)), this, SLOT(onPersonUpdate(Person)));
+ connect(mPersonSearchJob, SIGNAL(result(KJob*)), this, SLOT(onPersonsFound(KJob*)));
+ mPersonSearchJob->start();
+ }
- mCollectionSearchJob = new CollectionSearchJob(searchString, QStringList(), this);
+ mCollectionSearchJob = new CollectionSearchJob(searchString, QStringList() << QLatin1String("text/calendar"), this);
connect(mCollectionSearchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFound(KJob*)));
mCollectionSearchJob->start();
}
void Controller::onCollectionsFound(KJob* job)
{
+ mCollectionSearchJob = 0;
if (!mPersonSearchJob) {
emit searching(false);
}
if (job->error()) {
kWarning() << job->errorString();
- mCollectionSearchJob = 0;
return;
}
- Q_ASSERT(mCollectionSearchJob == static_cast<CollectionSearchJob*>(job));
- Q_FOREACH(const Akonadi::Collection &col, mCollectionSearchJob->matchingCollections()) {
+ Q_FOREACH(const Akonadi::Collection &col, static_cast<CollectionSearchJob*>(job)->matchingCollections()) {
CollectionNode *collectionNode = new CollectionNode(*mSearchModel, col);
collectionNode->isSearchNode = true;
//toggled by the checkbox, results in collection getting monitored
// connect(&collectionNode->emitter, SIGNAL(enabled(bool, Akonadi::Collection)), this, SLOT(onCollectionEnabled(bool, Akonadi::Collection)));
mSearchModel->addNode(ReparentingModel::Node::Ptr(collectionNode));
}
- mCollectionSearchJob = 0;
}
void Controller::onPersonsFound(const QList<Person> &persons)
@@ -356,15 +357,14 @@ void Controller::onPersonUpdate(const Person &person)
void Controller::onPersonsFound(KJob* job)
{
+ mPersonSearchJob = 0;
if (!mCollectionSearchJob) {
emit searching(false);
}
if (job->error()) {
kWarning() << job->errorString();
- mPersonSearchJob = 0;
return;
}
- mPersonSearchJob = 0;
}
static Akonadi::EntityTreeModel *findEtm(QAbstractItemModel *model)
commit c382227777ac9c8bfa18e3787434dc260a2be862
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date: Mon Jan 19 14:00:03 2015 +0100
Use personsearchjob and collectionsearchjob from libkdepim.
diff --git a/korganizer/CMakeLists.txt b/korganizer/CMakeLists.txt
index 07218db..5c7645e 100644
--- a/korganizer/CMakeLists.txt
+++ b/korganizer/CMakeLists.txt
@@ -175,8 +175,6 @@ set(korganizerprivate_LIB_SRCS
akonadicollectionview.cpp
views/collectionview/reparentingmodel.cpp
views/collectionview/controller.cpp
- views/collectionview/collectionsearchjob.cpp
- views/collectionview/personsearchjob.cpp
views/collectionview/calendardelegate.cpp
views/collectionview/quickview.cpp
calendarview.cpp
diff --git a/korganizer/views/collectionview/collectionsearchjob.cpp b/korganizer/views/collectionview/collectionsearchjob.cpp
deleted file mode 100644
index 0f17ab2..0000000
--- a/korganizer/views/collectionview/collectionsearchjob.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
-
-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.
-
-As a special exception, permission is given to link this program
-with any edition of Qt, and distribute the resulting executable,
-without including the source code for Qt in the source distribution.
-*/
-#include "collectionsearchjob.h"
-
-#include <Akonadi/CollectionFetchJob>
-#include <Akonadi/CollectionFetchScope>
-#include <baloo/pim/collectionquery.h>
-
-CollectionSearchJob::CollectionSearchJob(const QString& searchString, QObject* parent)
- : KJob(parent),
- mSearchString(searchString)
-{
-}
-
-void CollectionSearchJob::start()
-{
- Baloo::PIM::CollectionQuery query;
- //We exclude the other users namespace
- query.setNamespace(QStringList() << QLatin1String("shared") << QLatin1String(""));
- query.pathMatches(mSearchString);
- query.setMimetype(QStringList() << QLatin1String("text/calendar"));
- query.setLimit(200);
- Baloo::PIM::ResultIterator it = query.exec();
- Akonadi::Collection::List collections;
- while (it.next()) {
- collections << Akonadi::Collection(it.id());
- }
- kDebug() << "Found collections " << collections.size();
-
- if (collections.isEmpty()) {
- //We didn't find anything
- emitResult();
- return;
- }
-
- Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(collections, Akonadi::CollectionFetchJob::Base, this);
- fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
- fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
- fetchJob->fetchScope().setIgnoreRetrievalErrors(true);
- connect(fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), this, SLOT(onCollectionsReceived(Akonadi::Collection::List)));
- connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetched(KJob*)));
-}
-
-void CollectionSearchJob::onCollectionsReceived(const Akonadi::Collection::List &list)
-{
- Q_FOREACH(const Akonadi::Collection &col, list) {
- if (col.name().contains(mSearchString)) {
- mMatchingCollections << col;
- Akonadi::Collection ancestor = col.parentCollection();
- while (ancestor.isValid() && (ancestor != Akonadi::Collection::root())) {
- if (!mAncestors.contains(ancestor)) {
- mAncestors << ancestor;
- }
- ancestor = ancestor.parentCollection();
- }
- }
- }
-}
-
-void CollectionSearchJob::onCollectionsFetched(KJob *job)
-{
- if (job->error()) {
- kWarning() << job->errorString();
- }
- if (!mAncestors.isEmpty()) {
- Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(mAncestors, Akonadi::CollectionFetchJob::Base, this);
- fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
- connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onAncestorsFetched(KJob*)));
- } else {
- //We didn't find anything
- emitResult();
- }
-}
-
-static Akonadi::Collection replaceParent(Akonadi::Collection col, const Akonadi::Collection::List &ancestors)
-{
- if (!col.isValid()) {
- return col;
- }
- const Akonadi::Collection parent = replaceParent(col.parentCollection(), ancestors);
- Q_FOREACH (const Akonadi::Collection &c, ancestors) {
- if (col == c) {
- col = c;
- break;
- }
- }
- col.setParentCollection(parent);
- return col;
-}
-
-void CollectionSearchJob::onAncestorsFetched(KJob *job)
-{
- if (job->error()) {
- kWarning() << job->errorString();
- }
- Akonadi::CollectionFetchJob *fetchJob = static_cast<Akonadi::CollectionFetchJob*>(job);
- Akonadi::Collection::List matchingCollections;
- Q_FOREACH (const Akonadi::Collection &c, mMatchingCollections) {
- //We need to replace the parents with the version that contains the name, so we can display it accordingly
- matchingCollections << replaceParent(c, fetchJob->collections());
- }
- mMatchingCollections = matchingCollections;
- emitResult();
-}
-
-Akonadi::Collection::List CollectionSearchJob::matchingCollections() const
-{
- return mMatchingCollections;
-}
-
diff --git a/korganizer/views/collectionview/collectionsearchjob.h b/korganizer/views/collectionview/collectionsearchjob.h
deleted file mode 100644
index 30b0c07..0000000
--- a/korganizer/views/collectionview/collectionsearchjob.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
-
- 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.
-
- As a special exception, permission is given to link this program
- with any edition of Qt, and distribute the resulting executable,
- without including the source code for Qt in the source distribution.
-*/
-
-#ifndef KORG_COLLECTIONSEARCHJOB_H
-#define KORG_COLLECTIONSEARCHJOB_H
-
-#include <KJob>
-#include <Akonadi/Collection>
-
-class CollectionSearchJob : public KJob
-{
- Q_OBJECT
-public:
- explicit CollectionSearchJob(const QString &searchString, QObject* parent = 0);
-
- virtual void start();
-
- Akonadi::Collection::List matchingCollections() const;
-
-private Q_SLOTS:
- void onCollectionsReceived(const Akonadi::Collection::List &);
- void onCollectionsFetched(KJob *);
- void onAncestorsFetched(KJob *);
-
-private:
- QString mSearchString;
- Akonadi::Collection::List mMatchingCollections;
- Akonadi::Collection::List mAncestors;
-};
-
-#endif
-
diff --git a/korganizer/views/collectionview/controller.cpp b/korganizer/views/collectionview/controller.cpp
index d6f294d..5bcc0e5 100644
--- a/korganizer/views/collectionview/controller.cpp
+++ b/korganizer/views/collectionview/controller.cpp
@@ -35,8 +35,8 @@
#include <baloo/pim/collectionquery.h>
#include <akonadi/collectionidentificationattribute.h>
-#include "collectionsearchjob.h"
-#include "personsearchjob.h"
+#include <libkdepim/job/collectionsearchjob.h>
+#include <libkdepim/job/personsearchjob.h>
CollectionNode::CollectionNode(ReparentingModel& personModel, const Akonadi::Collection& col)
: Node(personModel),
@@ -310,7 +310,7 @@ void Controller::setSearchString(const QString &searchString)
connect(mPersonSearchJob, SIGNAL(result(KJob*)), this, SLOT(onPersonsFound(KJob*)));
mPersonSearchJob->start();
- mCollectionSearchJob = new CollectionSearchJob(searchString, this);
+ mCollectionSearchJob = new CollectionSearchJob(searchString, QStringList(), this);
connect(mCollectionSearchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFound(KJob*)));
mCollectionSearchJob->start();
}
diff --git a/korganizer/views/collectionview/controller.h b/korganizer/views/collectionview/controller.h
index e54b4ff..259ac61 100644
--- a/korganizer/views/collectionview/controller.h
+++ b/korganizer/views/collectionview/controller.h
@@ -28,7 +28,7 @@
#include <Akonadi/EntityTreeModel>
#include <Akonadi/Collection>
#include "reparentingmodel.h"
-#include "person.h"
+#include <libkdepim/job/person.h>
#include <libkdepim/ldap/ldapclientsearch.h>
diff --git a/korganizer/views/collectionview/person.h b/korganizer/views/collectionview/person.h
deleted file mode 100644
index 8fe979b..0000000
--- a/korganizer/views/collectionview/person.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
-
- 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.
-
- As a special exception, permission is given to link this program
- with any edition of Qt, and distribute the resulting executable,
- without including the source code for Qt in the source distribution.
-*/
-
-#ifndef KORG_PERSON_H
-#define KORG_PERSON_H
-
-#include <QStringList>
-#include <Akonadi/Collection>
-
-struct Person
-{
- Person(): rootCollection(-1), updateDisplayName(false) {};
- QString name;
- QString uid;
- QString ou;
- QString mail;
- Akonadi::Collection::Id rootCollection;
- bool updateDisplayName;
-
- //FIXME not sure we actually require those two
- QStringList folderPaths;
- QList<Akonadi::Collection::Id> collections;
-};
-
-Q_DECLARE_METATYPE(Person);
-
-#endif
diff --git a/korganizer/views/collectionview/personsearchjob.cpp b/korganizer/views/collectionview/personsearchjob.cpp
deleted file mode 100644
index 9fcda4e..0000000
--- a/korganizer/views/collectionview/personsearchjob.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
-
- 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.
-
- As a special exception, permission is given to link this program
- with any edition of Qt, and distribute the resulting executable,
- without including the source code for Qt in the source distribution.
-*/
-#include "personsearchjob.h"
-
-#include <Akonadi/EntityDisplayAttribute>
-#include <Akonadi/CollectionModifyJob>
-#include <Akonadi/CollectionFetchJob>
-#include <Akonadi/CollectionFetchScope>
-#include <KLocale>
-#include <baloo/pim/collectionquery.h>
-#include <akonadi/collectionidentificationattribute.h>
-
-PersonSearchJob::PersonSearchJob(const QString& searchString, QObject* parent)
- : KJob(parent),
- mSearchString(searchString)
-{
- connect(&mLdapSearch, SIGNAL(searchData(const QList<KLDAP::LdapResultObject> &)),
- SLOT(onLDAPSearchData(const QList<KLDAP::LdapResultObject> &)));
-
- connect(&mLdapSearch, SIGNAL(searchDone()),
- SLOT(onLDAPSearchDone()));
-}
-
-PersonSearchJob::~PersonSearchJob()
-{
- mLdapSearch.cancelSearch();
-}
-
-bool PersonSearchJob::kill(KJob::KillVerbosity verbosity)
-{
- mLdapSearch.cancelSearch();
- return KJob::kill(verbosity);
-}
-
-void PersonSearchJob::start()
-{
- Baloo::PIM::CollectionQuery query;
- query.setNamespace(QStringList() << QLatin1String("usertoplevel"));
- query.nameMatches(mSearchString);
- query.setLimit(200);
- Baloo::PIM::ResultIterator it = query.exec();
- Akonadi::Collection::List collections;
- while (it.next()) {
- collections << Akonadi::Collection(it.id());
- }
- kDebug() << "Found persons " << collections.size();
-
- mCollectionSearchDone = false;
- mLdapSearchDone = false;
-
- mLdapSearch.startSearch(QLatin1String("*") + mSearchString);
-
- if (collections.isEmpty()) {
- //We didn't find anything
- mCollectionSearchDone = true;
- return;
- }
-
- Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(collections, Akonadi::CollectionFetchJob::Base, this);
- fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
- fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
- connect(fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), this, SLOT(onCollectionsReceived(Akonadi::Collection::List)));
- connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetched(KJob*)));
-
- //The IMAP resource should add a "Person" attribute to the collections in the person namespace,
- //the ldap query can then be used to update the name (entitydisplayattribute) for the person.
-}
-
-void PersonSearchJob::onLDAPSearchData(const QList< KLDAP::LdapResultObject > &list)
-{
- QList<Person> persons;
- Q_FOREACH(const KLDAP::LdapResultObject &item, list) {
- Person person;
- person.name = QString::fromUtf8(item.object.value(QLatin1String("cn")));
- person.mail = QString::fromUtf8(item.object.value(QLatin1String("mail")));
-
- const int depth = item.object.dn().depth();
- for ( int i = 0; i < depth; ++i ) {
- const QString rdnStr = item.object.dn().rdnString(i);
- if ( rdnStr.startsWith(QLatin1String("ou="), Qt::CaseInsensitive) ) {
- person.ou = rdnStr.mid(3);
- break;
- }
- }
- const QStringList &parts = person.mail.split(QLatin1Char('@'));
- if (parts.count() == 2) {
- const QString &uid = parts.at(0);
- person.uid = uid;
- if (mMatches.contains(uid)) {
- const Person &p = mMatches.value(uid);
- if (p.mail != person.mail ) {
- if (p.rootCollection > -1) {
- person.rootCollection = p.rootCollection;
- person.updateDisplayName = p.updateDisplayName;
- updatePersonCollection(person);
- mMatches.insert(uid, person);
- } else {
- kWarning() << "That should not happen: we found two times persons with the same uid ("<< uid << "), but differnet name:" << p.name << "vs" << person.name;
- }
- }
- } else { //New person found
- mMatches.insert(uid, person);
- persons << person;
- }
- } else {
- kWarning() << item.object.dn().toString() << ": invalid email address" << person.mail;
- }
- }
- if (persons.count() > 0) {
- emit personsFound(persons);
- }
-}
-
-void PersonSearchJob::onLDAPSearchDone()
-{
- mLdapSearchDone = true;
- if (mCollectionSearchDone) {
- emitResult();
- }
-}
-
-void PersonSearchJob::onCollectionsReceived(const Akonadi::Collection::List &list)
-{
- QList<Person> persons;
- Q_FOREACH(const Akonadi::Collection &col, list) {
- Person person;
- const QString &uid = col.name();
- const CollectionIdentificationAttribute *const attr = col.attribute<CollectionIdentificationAttribute>();
- const Akonadi::EntityDisplayAttribute *const displayname = col.attribute<Akonadi::EntityDisplayAttribute>();
- person.rootCollection = col.id();
- person.uid = uid;
- if (attr) {
- person.ou = QString::fromUtf8(attr->ou());
- person.mail = QString::fromUtf8(attr->mail());
- person.name = QString::fromUtf8(attr->identifier());
- if (!displayname || displayname->displayName().isEmpty() || displayname->displayName() == person.name) {
- person.updateDisplayName = true;
- }
- } else {
- person.name = col.displayName();
- if (!displayname || displayname->displayName().isEmpty()) {
- person.updateDisplayName = true;
- }
- }
- if (mMatches.contains(uid)) {
- Person p = mMatches.value(uid);
- if (p.rootCollection > -1) {
- //two collection with the same uid ?!
- kWarning() << "Two collections match to same person" << p.rootCollection << person.rootCollection;
- } else if (p.mail != person.mail) {
- p.rootCollection = person.rootCollection;
- p.updateDisplayName = person.updateDisplayName;
- updatePersonCollection(p);
- } else {
- mMatches.insert(uid, person);
- emit personUpdate(person);
- }
- } else {
- mMatches.insert(uid, person);
- persons << person;
- }
- }
-
- if (persons.count() > 0) {
- emit personsFound(persons);
- }
-}
-
-void PersonSearchJob::updatePersonCollection(const Person &person)
-{
- Akonadi::Collection c(person.rootCollection);
- CollectionIdentificationAttribute *identification = c.attribute<CollectionIdentificationAttribute>(Akonadi::Entity::AddIfMissing);
-
- if (person.updateDisplayName) {
- Akonadi::EntityDisplayAttribute *displayname = c.attribute<Akonadi::EntityDisplayAttribute >(Akonadi::Entity::AddIfMissing);
- displayname->setDisplayName(person.name);
- }
-
- //identification->setIdentifier("Other Users/" + person.uid);
- identification->setIdentifier(person.name.toUtf8());
- identification->setName(person.name.toUtf8());
- identification->setCollectionNamespace("usertoplevel");
- identification->setMail(person.mail.toUtf8());
- identification->setOu(person.ou.toUtf8());
-
- Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( c, this );
- connect(job, SIGNAL(result(KJob*)), this, SLOT(modifyResult(KJob*)));
-}
-
-void PersonSearchJob::onCollectionsFetched(KJob *job)
-{
- if (job->error()) {
- kWarning() << job->errorString();
- }
- mCollectionSearchDone = true;
- if (mLdapSearchDone) {
- emitResult();
- }
-}
-
-QList<Person> PersonSearchJob::matches() const
-{
- return mMatches.values();
-}
-
-void PersonSearchJob::modifyResult(KJob *job)
-{
- if (job->error()) {
- kWarning() << job->errorString();
- return;
- }
-
- const Akonadi::CollectionModifyJob *modifyJob = static_cast<Akonadi::CollectionModifyJob*>(job);
- const Akonadi::Collection &col = modifyJob->collection();
-
- const CollectionIdentificationAttribute *const attr = col.attribute<CollectionIdentificationAttribute>();
- const Akonadi::EntityDisplayAttribute *const displayname = col.attribute<Akonadi::EntityDisplayAttribute>();
- const QString &uid = col.name();
- Person &person = mMatches[col.name()];
- person.rootCollection = col.id();
- person.uid = uid;
- if (attr) {
- person.ou = QString::fromUtf8(attr->ou());
- person.mail = QString::fromUtf8(attr->mail());
- person.name = QString::fromUtf8(attr->identifier());
- if (!displayname || displayname->displayName().isEmpty() || displayname->displayName() == person.name) {
- person.updateDisplayName = true;
- }
- }
- kDebug() << "modified person to" << person.uid << person.name << person.rootCollection;
-
- mMatches.insert(person.uid, person);
- emit personUpdate(person);
-}
diff --git a/korganizer/views/collectionview/personsearchjob.h b/korganizer/views/collectionview/personsearchjob.h
deleted file mode 100644
index 43d8350..0000000
--- a/korganizer/views/collectionview/personsearchjob.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
-
- 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.
-
- As a special exception, permission is given to link this program
- with any edition of Qt, and distribute the resulting executable,
- without including the source code for Qt in the source distribution.
-*/
-
-#ifndef KORG_PERSONSEARCHJOB_H
-#define KORG_PERSONSEARCHJOB_H
-
-#include <KJob>
-#include <Akonadi/Collection>
-#include <libkdepim/ldap/ldapclientsearch.h>
-#include "person.h"
-
-class PersonSearchJob : public KJob
-{
- Q_OBJECT
-public:
- explicit PersonSearchJob(const QString &searchString, QObject* parent = 0);
- virtual ~PersonSearchJob();
-
- virtual void start();
-
- QList<Person> matches() const;
-
-Q_SIGNALS:
- void personsFound(const QList<Person> &persons);
- void personUpdate(const Person &person);
-
-public Q_SLOTS:
- bool kill(KillVerbosity verbosity=Quietly);
-
-private Q_SLOTS:
- void onCollectionsReceived(const Akonadi::Collection::List &);
- void onCollectionsFetched(KJob *);
- void onLDAPSearchData(const QList<KLDAP::LdapResultObject> &);
- void onLDAPSearchDone();
- void updatePersonCollection(const Person &person);
- void modifyResult(KJob *job);
-
-private:
- QString mSearchString;
- QHash<QString, Person> mMatches;
- KLDAP::LdapClientSearch mLdapSearch;
- bool mCollectionSearchDone;
- bool mLdapSearchDone;
-};
-
-#endif
diff --git a/libkdepim/job/collectionsearchjob.h b/libkdepim/job/collectionsearchjob.h
index 18092fe..e23de74 100644
--- a/libkdepim/job/collectionsearchjob.h
+++ b/libkdepim/job/collectionsearchjob.h
@@ -23,11 +23,13 @@
#ifndef KORG_COLLECTIONSEARCHJOB_H
#define KORG_COLLECTIONSEARCHJOB_H
+#include "kdepim_export.h"
+
#include <KJob>
#include <Akonadi/Collection>
#include <QStringList>
-class CollectionSearchJob : public KJob
+class KDEPIM_EXPORT CollectionSearchJob : public KJob
{
Q_OBJECT
public:
diff --git a/libkdepim/job/person.h b/libkdepim/job/person.h
index 8fe979b..e11729b 100644
--- a/libkdepim/job/person.h
+++ b/libkdepim/job/person.h
@@ -23,10 +23,12 @@
#ifndef KORG_PERSON_H
#define KORG_PERSON_H
+#include "kdepim_export.h"
+
#include <QStringList>
#include <Akonadi/Collection>
-struct Person
+struct KDEPIM_EXPORT Person
{
Person(): rootCollection(-1), updateDisplayName(false) {};
QString name;
diff --git a/libkdepim/job/personsearchjob.h b/libkdepim/job/personsearchjob.h
index 43d8350..8924e83 100644
--- a/libkdepim/job/personsearchjob.h
+++ b/libkdepim/job/personsearchjob.h
@@ -23,12 +23,14 @@
#ifndef KORG_PERSONSEARCHJOB_H
#define KORG_PERSONSEARCHJOB_H
+#include "kdepim_export.h"
+
#include <KJob>
#include <Akonadi/Collection>
#include <libkdepim/ldap/ldapclientsearch.h>
#include "person.h"
-class PersonSearchJob : public KJob
+class KDEPIM_EXPORT PersonSearchJob : public KJob
{
Q_OBJECT
public:
commit 720ea7a504dbf097312fb75fa67313ee321bf15d
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date: Fri Jan 16 18:40:53 2015 +0100
Re-importet modified personsearchjob from zanshin.
diff --git a/libkdepim/CMakeLists.txt b/libkdepim/CMakeLists.txt
index b51d976..17bda53 100644
--- a/libkdepim/CMakeLists.txt
+++ b/libkdepim/CMakeLists.txt
@@ -39,6 +39,7 @@ set(kdepim_LIB_SRCS
job/openemailaddressjob.cpp
job/addemaildisplayjob.cpp
job/collectionsearchjob.cpp
+ job/personsearchjob.cpp
addressline/completionordereditor.cpp
addressline/addresseelineedit.cpp
addressline/recentaddresses.cpp
diff --git a/libkdepim/job/person.h b/libkdepim/job/person.h
new file mode 100644
index 0000000..8fe979b
--- /dev/null
+++ b/libkdepim/job/person.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KORG_PERSON_H
+#define KORG_PERSON_H
+
+#include <QStringList>
+#include <Akonadi/Collection>
+
+struct Person
+{
+ Person(): rootCollection(-1), updateDisplayName(false) {};
+ QString name;
+ QString uid;
+ QString ou;
+ QString mail;
+ Akonadi::Collection::Id rootCollection;
+ bool updateDisplayName;
+
+ //FIXME not sure we actually require those two
+ QStringList folderPaths;
+ QList<Akonadi::Collection::Id> collections;
+};
+
+Q_DECLARE_METATYPE(Person);
+
+#endif
diff --git a/libkdepim/job/personsearchjob.cpp b/libkdepim/job/personsearchjob.cpp
new file mode 100644
index 0000000..39838a2
--- /dev/null
+++ b/libkdepim/job/personsearchjob.cpp
@@ -0,0 +1,253 @@
+/*
+ Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+#include "personsearchjob.h"
+
+#include <Akonadi/EntityDisplayAttribute>
+#include <Akonadi/CollectionModifyJob>
+#include <Akonadi/CollectionFetchJob>
+#include <Akonadi/CollectionFetchScope>
+#include <KLocale>
+#include <baloo/pim/collectionquery.h>
+#include <akonadi/collectionidentificationattribute.h>
+
+PersonSearchJob::PersonSearchJob(const QString& searchString, QObject* parent)
+ : KJob(parent),
+ mSearchString(searchString)
+{
+ connect(&mLdapSearch, SIGNAL(searchData(const QList<KLDAP::LdapResultObject> &)),
+ SLOT(onLDAPSearchData(const QList<KLDAP::LdapResultObject> &)));
+
+ connect(&mLdapSearch, SIGNAL(searchDone()),
+ SLOT(onLDAPSearchDone()));
+}
+
+PersonSearchJob::~PersonSearchJob()
+{
+ mLdapSearch.cancelSearch();
+}
+
+bool PersonSearchJob::kill(KJob::KillVerbosity verbosity)
+{
+ mLdapSearch.cancelSearch();
+ return KJob::kill(verbosity);
+}
+
+void PersonSearchJob::start()
+{
+ Baloo::PIM::CollectionQuery query;
+ query.setNamespace(QStringList() << QLatin1String("usertoplevel"));
+ query.nameMatches(mSearchString);
+ query.setLimit(200);
+ Baloo::PIM::ResultIterator it = query.exec();
+ Akonadi::Collection::List collections;
+ while (it.next()) {
+ collections << Akonadi::Collection(it.id());
+ }
+ kDebug() << "Found persons " << collections.size();
+
+ mCollectionSearchDone = false;
+ mLdapSearchDone = false;
+ if (collections.isEmpty()) {
+ //We didn't find anything
+ mCollectionSearchDone = true;
+ }
+
+ mLdapSearch.startSearch(QLatin1String("*") + mSearchString);
+
+ if (!collections.isEmpty()) {
+ Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(collections, Akonadi::CollectionFetchJob::Base, this);
+ fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
+ fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
+ connect(fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), this, SLOT(onCollectionsReceived(Akonadi::Collection::List)));
+ connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetched(KJob*)));
+ }
+
+ //The IMAP resource should add a "Person" attribute to the collections in the person namespace,
+ //the ldap query can then be used to update the name (entitydisplayattribute) for the person.
+}
+
+void PersonSearchJob::onLDAPSearchData(const QList< KLDAP::LdapResultObject > &list)
+{
+ QList<Person> persons;
+ Q_FOREACH(const KLDAP::LdapResultObject &item, list) {
+ Person person;
+ person.name = QString::fromUtf8(item.object.value(QLatin1String("cn")));
+ person.mail = QString::fromUtf8(item.object.value(QLatin1String("mail")));
+
+ const int depth = item.object.dn().depth();
+ for ( int i = 0; i < depth; ++i ) {
+ const QString rdnStr = item.object.dn().rdnString(i);
+ if ( rdnStr.startsWith(QLatin1String("ou="), Qt::CaseInsensitive) ) {
+ person.ou = rdnStr.mid(3);
+ break;
+ }
+ }
+ const QStringList &parts = person.mail.split(QLatin1Char('@'));
+ if (parts.count() == 2) {
+ const QString &uid = parts.at(0);
+ person.uid = uid;
+ if (mMatches.contains(uid)) {
+ const Person &p = mMatches.value(uid);
+ if (p.mail != person.mail ) {
+ if (p.rootCollection > -1) {
+ person.rootCollection = p.rootCollection;
+ person.updateDisplayName = p.updateDisplayName;
+ updatePersonCollection(person);
+ mMatches.insert(uid, person);
+ } else {
+ kWarning() << "That should not happen: we found two times persons with the same uid ("<< uid << "), but differnet name:" << p.name << "vs" << person.name;
+ }
+ }
+ } else { //New person found
+ mMatches.insert(uid, person);
+ persons << person;
+ }
+ } else {
+ kWarning() << item.object.dn().toString() << ": invalid email address" << person.mail;
+ }
+ }
+ if (persons.count() > 0) {
+ emit personsFound(persons);
+ }
+}
+
+void PersonSearchJob::onLDAPSearchDone()
+{
+ mLdapSearchDone = true;
+ if (mCollectionSearchDone) {
+ emitResult();
+ }
+}
+
+void PersonSearchJob::onCollectionsReceived(const Akonadi::Collection::List &list)
+{
+ QList<Person> persons;
+ Q_FOREACH(const Akonadi::Collection &col, list) {
+ Person person;
+ const QString &uid = col.name();
+ const CollectionIdentificationAttribute *const attr = col.attribute<CollectionIdentificationAttribute>();
+ const Akonadi::EntityDisplayAttribute *const displayname = col.attribute<Akonadi::EntityDisplayAttribute>();
+ person.rootCollection = col.id();
+ person.uid = uid;
+ if (attr) {
+ person.ou = QString::fromUtf8(attr->ou());
+ person.mail = QString::fromUtf8(attr->mail());
+ person.name = QString::fromUtf8(attr->identifier());
+ if (!displayname || displayname->displayName().isEmpty() || displayname->displayName() == person.name) {
+ person.updateDisplayName = true;
+ }
+ } else {
+ person.name = col.displayName();
+ if (!displayname || displayname->displayName().isEmpty()) {
+ person.updateDisplayName = true;
+ }
+ }
+ if (mMatches.contains(uid)) {
+ Person p = mMatches.value(uid);
+ if (p.rootCollection > -1) {
+ //two collection with the same uid ?!
+ kWarning() << "Two collections match to same person" << p.rootCollection << person.rootCollection;
+ } else if (p.mail != person.mail) {
+ p.rootCollection = person.rootCollection;
+ p.updateDisplayName = person.updateDisplayName;
+ updatePersonCollection(p);
+ } else {
+ mMatches.insert(uid, person);
+ emit personUpdate(person);
+ }
+ } else {
+ mMatches.insert(uid, person);
+ persons << person;
+ }
+ }
+
+ if (persons.count() > 0) {
+ emit personsFound(persons);
+ }
+}
+
+void PersonSearchJob::updatePersonCollection(const Person &person)
+{
+ Akonadi::Collection c(person.rootCollection);
+ CollectionIdentificationAttribute *identification = c.attribute<CollectionIdentificationAttribute>(Akonadi::Entity::AddIfMissing);
+
+ if (person.updateDisplayName) {
+ Akonadi::EntityDisplayAttribute *displayname = c.attribute<Akonadi::EntityDisplayAttribute >(Akonadi::Entity::AddIfMissing);
+ displayname->setDisplayName(person.name);
+ }
+
+ //identification->setIdentifier("Other Users/" + person.uid);
+ identification->setIdentifier(person.name.toUtf8());
+ identification->setName(person.name.toUtf8());
+ identification->setCollectionNamespace("usertoplevel");
+ identification->setMail(person.mail.toUtf8());
+ identification->setOu(person.ou.toUtf8());
+
+ Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( c, this );
+ connect(job, SIGNAL(result(KJob*)), this, SLOT(modifyResult(KJob*)));
+}
+
+void PersonSearchJob::onCollectionsFetched(KJob *job)
+{
+ if (job->error()) {
+ kWarning() << job->errorString();
+ }
+ mCollectionSearchDone = true;
+ if (mLdapSearchDone) {
+ emitResult();
+ }
+}
+
+QList<Person> PersonSearchJob::matches() const
+{
+ return mMatches.values();
+}
+
+void PersonSearchJob::modifyResult(KJob *job)
+{
+ if (job->error()) {
+ kWarning() << job->errorString();
+ return;
+ }
+
+ const Akonadi::CollectionModifyJob *modifyJob = static_cast<Akonadi::CollectionModifyJob*>(job);
+ const Akonadi::Collection &col = modifyJob->collection();
+
+ const CollectionIdentificationAttribute *const attr = col.attribute<CollectionIdentificationAttribute>();
+ const Akonadi::EntityDisplayAttribute *const displayname = col.attribute<Akonadi::EntityDisplayAttribute>();
+ const QString &uid = col.name();
+ Person &person = mMatches[col.name()];
+ person.rootCollection = col.id();
+ person.uid = uid;
+ if (attr) {
+ person.ou = QString::fromUtf8(attr->ou());
+ person.mail = QString::fromUtf8(attr->mail());
+ person.name = QString::fromUtf8(attr->identifier());
+ if (!displayname || displayname->displayName().isEmpty() || displayname->displayName() == person.name) {
+ person.updateDisplayName = true;
+ }
+ }
+ kDebug() << "modified person to" << person.uid << person.name << person.rootCollection;
+
+ mMatches.insert(person.uid, person);
+ emit personUpdate(person);
+}
diff --git a/libkdepim/job/personsearchjob.h b/libkdepim/job/personsearchjob.h
new file mode 100644
index 0000000..43d8350
--- /dev/null
+++ b/libkdepim/job/personsearchjob.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KORG_PERSONSEARCHJOB_H
+#define KORG_PERSONSEARCHJOB_H
+
+#include <KJob>
+#include <Akonadi/Collection>
+#include <libkdepim/ldap/ldapclientsearch.h>
+#include "person.h"
+
+class PersonSearchJob : public KJob
+{
+ Q_OBJECT
+public:
+ explicit PersonSearchJob(const QString &searchString, QObject* parent = 0);
+ virtual ~PersonSearchJob();
+
+ virtual void start();
+
+ QList<Person> matches() const;
+
+Q_SIGNALS:
+ void personsFound(const QList<Person> &persons);
+ void personUpdate(const Person &person);
+
+public Q_SLOTS:
+ bool kill(KillVerbosity verbosity=Quietly);
+
+private Q_SLOTS:
+ void onCollectionsReceived(const Akonadi::Collection::List &);
+ void onCollectionsFetched(KJob *);
+ void onLDAPSearchData(const QList<KLDAP::LdapResultObject> &);
+ void onLDAPSearchDone();
+ void updatePersonCollection(const Person &person);
+ void modifyResult(KJob *job);
+
+private:
+ QString mSearchString;
+ QHash<QString, Person> mMatches;
+ KLDAP::LdapClientSearch mLdapSearch;
+ bool mCollectionSearchDone;
+ bool mLdapSearchDone;
+};
+
+#endif
commit 30e818f9f6eddb3822f62f1aafabbd39029f1a51
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date: Fri Jan 16 18:32:25 2015 +0100
Re-imported modified collectionsearchjob from zanshin to be shared.
diff --git a/libkdepim/CMakeLists.txt b/libkdepim/CMakeLists.txt
index f8b1725..b51d976 100644
--- a/libkdepim/CMakeLists.txt
+++ b/libkdepim/CMakeLists.txt
@@ -38,6 +38,7 @@ set(kdepim_LIB_SRCS
job/addcontactjob.cpp
job/openemailaddressjob.cpp
job/addemaildisplayjob.cpp
+ job/collectionsearchjob.cpp
addressline/completionordereditor.cpp
addressline/addresseelineedit.cpp
addressline/recentaddresses.cpp
diff --git a/libkdepim/job/collectionsearchjob.cpp b/libkdepim/job/collectionsearchjob.cpp
new file mode 100644
index 0000000..066bcff
--- /dev/null
+++ b/libkdepim/job/collectionsearchjob.cpp
@@ -0,0 +1,132 @@
+/*
+Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
+
+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.
+
+As a special exception, permission is given to link this program
+with any edition of Qt, and distribute the resulting executable,
+without including the source code for Qt in the source distribution.
+*/
+#include "collectionsearchjob.h"
+
+#include <Akonadi/CollectionFetchJob>
+#include <Akonadi/CollectionFetchScope>
+#include <baloo/pim/collectionquery.h>
+
+CollectionSearchJob::CollectionSearchJob(const QString& searchString, const QStringList &mimetypeFilter, QObject* parent)
+ : KJob(parent),
+ mSearchString(searchString),
+ mMimeTypeFilter(mimetypeFilter)
+{
+}
+
+void CollectionSearchJob::start()
+{
+ Baloo::PIM::CollectionQuery query;
+ if (mSearchString == QLatin1String("*")) {
+ query.setNamespace(QStringList() << QLatin1String(""));
+ } else {
+ //We exclude the other users namespace
+ query.setNamespace(QStringList() << QLatin1String("shared") << QLatin1String(""));
+ query.pathMatches(mSearchString);
+ }
+ query.setMimetype(mMimeTypeFilter);
+ query.setLimit(200);
+ Baloo::PIM::ResultIterator it = query.exec();
+ Akonadi::Collection::List collections;
+ while (it.next()) {
+ collections << Akonadi::Collection(it.id());
+ }
+ kDebug() << "Found collections " << collections.size();
+
+ if (collections.isEmpty()) {
+ //We didn't find anything
+ emitResult();
+ return;
+ }
+
+ Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(collections, Akonadi::CollectionFetchJob::Base, this);
+ fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
+ fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
+ fetchJob->fetchScope().setIgnoreRetrievalErrors(true);
+ connect(fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), this, SLOT(onCollectionsReceived(Akonadi::Collection::List)));
+ connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetched(KJob*)));
+}
+
+void CollectionSearchJob::onCollectionsReceived(const Akonadi::Collection::List &list)
+{
+ Q_FOREACH(const Akonadi::Collection &col, list) {
+ mMatchingCollections << col;
+ Akonadi::Collection ancestor = col.parentCollection();
+ while (ancestor.isValid() && (ancestor != Akonadi::Collection::root())) {
+ if (!mAncestors.contains(ancestor)) {
+ mAncestors << ancestor;
+ }
+ ancestor = ancestor.parentCollection();
+ }
+ }
+}
+
+void CollectionSearchJob::onCollectionsFetched(KJob *job)
+{
+ if (job->error()) {
+ kWarning() << job->errorString();
+ }
+ if (!mAncestors.isEmpty()) {
+ Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(mAncestors, Akonadi::CollectionFetchJob::Base, this);
+ fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter);
+ connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onAncestorsFetched(KJob*)));
+ } else {
+ //We didn't find anything
+ emitResult();
+ }
+}
+
+static Akonadi::Collection replaceParent(Akonadi::Collection col, const Akonadi::Collection::List &ancestors)
+{
+ if (!col.isValid()) {
+ return col;
+ }
+ const Akonadi::Collection parent = replaceParent(col.parentCollection(), ancestors);
+ Q_FOREACH (const Akonadi::Collection &c, ancestors) {
+ if (col == c) {
+ col = c;
+ break;
+ }
+ }
+ col.setParentCollection(parent);
+ return col;
+}
+
+void CollectionSearchJob::onAncestorsFetched(KJob *job)
+{
+ if (job->error()) {
+ kWarning() << job->errorString();
+ }
+ Akonadi::CollectionFetchJob *fetchJob = static_cast<Akonadi::CollectionFetchJob*>(job);
+ Akonadi::Collection::List matchingCollections;
+ Q_FOREACH (const Akonadi::Collection &c, mMatchingCollections) {
+ //We need to replace the parents with the version that contains the name, so we can display it accordingly
+ matchingCollections << replaceParent(c, fetchJob->collections());
+ }
+ mMatchingCollections = matchingCollections;
+ emitResult();
+}
+
+Akonadi::Collection::List CollectionSearchJob::matchingCollections() const
+{
+ return mMatchingCollections;
+}
+
diff --git a/libkdepim/job/collectionsearchjob.h b/libkdepim/job/collectionsearchjob.h
new file mode 100644
index 0000000..18092fe
--- /dev/null
+++ b/libkdepim/job/collectionsearchjob.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2014 Christian Mollekopf <mollekopf at kolabsys.com>
+
+ 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.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#ifndef KORG_COLLECTIONSEARCHJOB_H
+#define KORG_COLLECTIONSEARCHJOB_H
+
+#include <KJob>
+#include <Akonadi/Collection>
+#include <QStringList>
+
+class CollectionSearchJob : public KJob
+{
+ Q_OBJECT
+public:
+ explicit CollectionSearchJob(const QString &searchString, const QStringList &mimetypeFilter, QObject* parent = 0);
+
+ virtual void start();
+
+ Akonadi::Collection::List matchingCollections() const;
+
+private Q_SLOTS:
+ void onCollectionsReceived(const Akonadi::Collection::List &);
+ void onCollectionsFetched(KJob *);
+ void onAncestorsFetched(KJob *);
+
+private:
+ QString mSearchString;
+ QStringList mMimeTypeFilter;
+ Akonadi::Collection::List mMatchingCollections;
+ Akonadi::Collection::List mAncestors;
+};
+
+#endif
+
More information about the commits
mailing list