--- a/qtmobility/plugins/contacts/qtcontacts-tracker/qcontacttrackerbackend.cpp Fri Jun 11 14:26:25 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,609 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcontacttrackerbackend_p.h"
-
-#include <QtTracker/Tracker>
-#include <QtTracker/ontologies/nco.h>
-#include <QtTracker/ontologies/nie.h>
-#include <QtTracker/ontologies/nao.h>
-#include <QRegExp>
-#include <QDir>
-#include <QFile>
-#include <QSet>
-#include <QList>
-
-#include "qtcontacts.h"
-
-#include "trackerchangelistener.h"
-#include "qtrackercontactsaverequest.h"
-#include <qtrackerrelationshipfetchrequest.h>
-#include <qtrackerrelationshipsaverequest.h>
-#include <qtrackercontactidfetchrequest.h>
-
-
-QContactManagerEngine* ContactTrackerFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
-{
- Q_UNUSED(error);
- QString version = QLatin1String(VERSION_INFO);
- return new QContactTrackerEngine(managerName(), version.toInt(), parameters);
-}
-
-QString ContactTrackerFactory::managerName() const
-{
- return QString("tracker");
-}
-Q_EXPORT_PLUGIN2(qtcontacts_tracker, ContactTrackerFactory);
-
-QContactTrackerEngine::QContactTrackerEngine(const QString& engineName, int engineVersion, const QMap<QString, QString>& parameters)
- : d(new QContactTrackerEngineData),
- contactArchiveFile("removed"),
- contactArchiveDir(QDir::homePath()+"/.contacts")
-{
- Q_UNUSED(parameters);
- d->m_engineName = engineName;
- d->m_engineVersion = engineVersion;
- connectToSignals();
-}
-
-QContactTrackerEngine::QContactTrackerEngine(const QMap<QString, QString>& parameters)
- : d(new QContactTrackerEngineData),
- contactArchiveFile("removed"),
- contactArchiveDir(QDir::homePath()+"/.contacts")
-{
- Q_UNUSED(parameters);
- connectToSignals();
-}
-
-QContactTrackerEngine::QContactTrackerEngine(const QContactTrackerEngine& other)
- : QContactManagerEngine(), d(other.d)
-{
- Q_UNUSED(other);
- connectToSignals();
-}
-
-void QContactTrackerEngine::connectToSignals()
-{
- TrackerChangeListener *listener = new TrackerChangeListener(this, this);
- connect(listener, SIGNAL(contactsAdded(const QList<QContactLocalId>&)), SIGNAL(contactsAdded(const QList<QContactLocalId>&)));
- connect(listener, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), SIGNAL(contactsChanged(const QList<QContactLocalId>&)));
- connect(listener, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), SIGNAL(contactsRemoved(const QList<QContactLocalId>&)));
-}
-
-QContactTrackerEngine& QContactTrackerEngine::operator=(const QContactTrackerEngine& other)
-{
- d = other.d;
- return *this;
-}
-
-QContactTrackerEngine::~QContactTrackerEngine()
-{
-}
-
-QContactManagerEngine* QContactTrackerEngine::clone()
-{
- // this engine allows sharing - so we increase the reference count.
- d->m_refCount.ref();
- return this;
-}
-
-void QContactTrackerEngine::deref()
-{
- if (!d->m_refCount.deref())
- delete this;
-}
-
-QList<QContactLocalId> QContactTrackerEngine::contactIds(const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const
-{
- return contactIds(QContactFilter(), sortOrders, error);
-}
-
-QList<QContactLocalId> QContactTrackerEngine::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const
-{
- QContactLocalIdFetchRequest request;
- request.setFilter(filter);
- request.setSorting(sortOrders);
-
- QContactTrackerEngine engine(*this);
- engine.startRequest(&request);
- // 10 seconds should be enough
- engine.waitForRequestFinished(&request, 10000);
- if(!request.isFinished()) {
- *error = QContactManager::UnspecifiedError;
- }
- else {
- // leave the code for now while not all other code is fixed
- *error = request.error();
- }
- return request.ids();
-}
-
-QList<QContact> QContactTrackerEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
-{
- // the rest of the code is for internal usage, unit tests etc.
- QContactFetchRequest request;
- request.setFetchHint(fetchHint);
- request.setFilter(filter);
- request.setSorting(sortOrders);
-
- QContactTrackerEngine engine(*this);
- engine.startRequest(&request);
- // 10 seconds should be enough
- engine.waitForRequestFinished(&request, 10000);
-
- if( !request.isFinished()) {
- *error = QContactManager::UnspecifiedError;
- }
- else {
- // leave the code for now while not all other code is fixed
- *error = request.error();
- }
- return request.contacts();
-}
-
-QContact QContactTrackerEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
-{
- // plan to keep this warning for a while - as message to customers using the API
- qWarning() << "QContactManager::contact()" << "api is blocking on dbus roundtrip while accessing tracker. Please, consider using asynchronous API QContactFetchRequest and not fetching contacts by id \n"
- "- reading 100 ids and 100 contact by ids is ~100 times slower then reading 100 contacts at once with QContactFetchRequest.";
- return contact_impl(contactId, fetchHint, error);
-}
-
-QContactLocalId QContactTrackerEngine::selfContactId(QContactManager::Error* error) const
-{
- *error = QContactManager::NoError;
- return QContactLocalId(0xFFFFFFFF);
-}
-
-// used in tests, removed warning while decided if to provide sync api. Until then customers are advised to use async
-QContact QContactTrackerEngine::contact_impl(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error ) const
-{
- QContactLocalIdFilter idlist;
- QList<QContactLocalId> ids; ids << contactId;
- idlist.setIds(ids);
- QContactFetchRequest request;
- QStringList definitionNames = fetchHint.detailDefinitionsHint();
- if (fetchHint.detailDefinitionsHint().isEmpty())
- {
- definitionNames << QContactAvatar::DefinitionName
- << QContactBirthday::DefinitionName
- << QContactAddress::DefinitionName
- << QContactEmailAddress::DefinitionName
- << QContactDisplayLabel::DefinitionName
- << QContactGender::DefinitionName
- << QContactAnniversary::DefinitionName
- << QContactName::DefinitionName
- << QContactOnlineAccount::DefinitionName
- << QContactOrganization::DefinitionName
- << QContactPhoneNumber::DefinitionName
- << QContactOnlineAccount::DefinitionName
- << QContactUrl::DefinitionName;
- }
-
- QContactFetchHint modifiedHint;
- modifiedHint.setDetailDefinitionsHint(definitionNames);
- request.setFetchHint(modifiedHint);
- request.setFilter(idlist);
-
- QContactTrackerEngine engine(*this);
- engine.startRequest(&request);
- // 10 seconds should be enough
- engine.waitForRequestFinished(&request, 10000);
-
- if( !request.isFinished()) {
- *error = QContactManager::UnspecifiedError;
- return QContact();
- }
- else if(request.contacts().size() == 0)
- {
- *error = QContactManager::DoesNotExistError;
- return QContact();
- }
- else {
- // leave the code for now while not all other code is fixed
- *error = request.error();
- return request.contacts()[0];
- }
-
-}
-
-bool QContactTrackerEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs)
-{
- Q_ASSERT(req);
- if(!req->isActive())
- {
- return req->isFinished(); // might be already finished
- }
- QTime t;
- t.start();
- while(t.elapsed() < msecs || msecs == 0) // 0 for infinite
- {
- usleep(10000);
- QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- if(req->isFinished())
- return true;
- }
- qDebug() << Q_FUNC_INFO <<"Status Finished" << req->isFinished();
- return req->isFinished();
-
-}
-
-bool QContactTrackerEngine::saveContact( QContact* contact, QContactManager::Error* error)
-{
- // Signal emitted from TrackerChangeListener
- QContactSaveRequest request;
- QList<QContact> contacts(QList<QContact>()<<*contact);
- request.setContacts(contacts);
- QContactTrackerEngine engine(*this);
- engine.startRequest(&request);
- // 10 seconds should be enough
- engine.waitForRequestFinished(&request, 10000);
- *error = request.error();
- Q_ASSERT(request.contacts().size() == 1);
- *contact = request.contacts()[0];
-
- if( request.isFinished() && *error == QContactManager::NoError)
- return true;
- else
- return false;
-}
-
-bool QContactTrackerEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error)
-{
- *error = QContactManager::NoError;
-
- // TODO: Do with LiveNodes when they support strict querying.
- RDFVariable RDFContact = RDFVariable::fromType<nco::PersonContact>();
- RDFContact.property<nco::contactUID>() = LiteralValue(QString::number(contactId));
- RDFSelect query;
-
- query.addColumn("contact_uri", RDFContact);
- LiveNodes ncoContacts = ::tracker()->modelQuery(query);
- if(ncoContacts->rowCount() == 0) {
- *error = QContactManager::DoesNotExistError;
- return false;
- }
-
-
- Live< nco::PersonContact> ncoContact = ncoContacts->liveNode(0);
- LiveNodes contactMediums = ncoContact->getHasContactMediums();
- foreach(Live<nco::ContactMedium> media, contactMediums) {
- media->remove();
- }
- ncoContact->remove();
-
- //Temporary workaround to get removed- signal
- QList<QContactLocalId> removed;
- removed << contactId;
- emit contactsRemoved(removed);
-
- return true;
-}
-
-bool QContactTrackerEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
-{
- // @todo: Handle errors per saved contact.
- Q_UNUSED(errorMap)
-
- *error = QContactManager::NoError;
-
- if(contacts == 0) {
- *error = QContactManager::BadArgumentError;
- return false;
- }
-
- // Signal emitted from TrackerChangeListener
- QContactSaveRequest request;
- QList<QContact> contactList;
- for (int i = 0; i < contacts->size(); ++i) {
- contactList.append(contacts->at(i));
- }
- request.setContacts(contactList);
- QContactTrackerEngine engine(*this);
- engine.startRequest(&request);
- /// @todo what should be the delay
- engine.waitForRequestFinished(&request, 1000*contacts->size());
- /// @todo what should we do in case request.isFinished() == false
- if (request.isFinished() == false) {
- qWarning() << "QContactTrackerEngine::saveContacts:" << "request not finished";
- }
- *error = request.error();
- for (int i = 0; i < contacts->size(); ++i) {
- (*contacts)[i] = request.contacts().at(i);
- }
-
- // Returns false if we have any errors - true if everything went ok.
- return (request.errorMap().isEmpty() && *error == QContactManager::NoError);
-}
-
-bool QContactTrackerEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
-{
- // Cannot report errors - giving up.
- if(!errorMap) {
- *error = QContactManager::BadArgumentError;
- return false;
- }
-
- // let's clear the error hash so there is nothing old haunting us.
- errorMap->clear();
-
- for (int i = 0; i < contactIds.count(); i++) {
- QContactManager::Error lastError;
- removeContact(contactIds.at(i), &lastError);
- if (lastError != QContactManager::NoError) {
- errorMap->insert(i, lastError);
- }
- }
-
- // Returns true if no errors were encountered - false if there was errors.
- // emit signals removed as they are fired from QContactManager
- return (errorMap->isEmpty());
-}
-
-QMap<QString, QContactDetailDefinition> QContactTrackerEngine::detailDefinitions(const QString& contactType,
- QContactManager::Error* error) const
-{
- if (contactType != QContactType::TypeContact) {
- *error = QContactManager::InvalidContactTypeError;
- return QMap<QString, QContactDetailDefinition>();
- }
-
- // lazy initialisation of schema definitions.
- if (d->m_definitions.isEmpty()) {
- // none in the list? get the schema definitions, and modify them to match our capabilities.
- d->m_definitions = QContactManagerEngine::schemaDefinitions().value(QContactType::TypeContact);
-
- // modification: name is unique
- QContactDetailDefinition nameDef = d->m_definitions.value(QContactName::DefinitionName);
- nameDef.setUnique(true);
- d->m_definitions.insert(QContactName::DefinitionName, nameDef);
-
- // modification: avatar is unique.
- QContactDetailDefinition avatarDef = d->m_definitions.value(QContactAvatar::DefinitionName);
- avatarDef.setUnique(true);
- d->m_definitions.insert(QContactAvatar::DefinitionName, avatarDef);
-
- // modification: url is unique.
- {
- const QContactDetailDefinition urlDef = d->m_definitions.value(
- QContactUrl::DefinitionName);
- QContactDetailDefinition newUrlDef;
-
- QMap<QString, QContactDetailFieldDefinition> urlFieldNames = urlDef.fields();
- QMap<QString, QContactDetailFieldDefinition> &fields(urlFieldNames);
- QContactDetailFieldDefinition f;
-
- f.setDataType(QVariant::String);
- QVariantList subTypes;
- // removing social networking url
- subTypes << QString(QLatin1String(QContactUrl::SubTypeFavourite));
- subTypes << QString(QLatin1String(QContactUrl::SubTypeHomePage));
- f.setAllowableValues(subTypes);
- fields.insert(QContactUrl::FieldSubType, f);
- newUrlDef.setFields(fields);
- newUrlDef.setUnique(true);
- newUrlDef.setName(QContactUrl::DefinitionName);
- d->m_definitions.insert(QContactUrl::DefinitionName, newUrlDef);
- }
-
- // QContactOnlineAccount custom fields
- {
- const QContactDetailDefinition accDef = d->m_definitions.value(QContactOnlineAccount::DefinitionName);
- QContactDetailDefinition newAccountDefinition;
-
- QMap<QString, QContactDetailFieldDefinition> accountFieldName = accDef.fields();
- QMap<QString, QContactDetailFieldDefinition> &fields(accountFieldName);
- QContactDetailFieldDefinition f;
-
- f.setDataType(QVariant::String);
- fields.insert("Account", f);
- fields.insert("AccountPath", f);
- newAccountDefinition.setFields(fields);
- newAccountDefinition.setName(QContactOnlineAccount::DefinitionName);
- d->m_definitions.insert(QContactOnlineAccount::DefinitionName, newAccountDefinition);
- }
- }
-
- *error = QContactManager::NoError;
- return d->m_definitions;
-}
-
-/*!
- * \reimp
- */
-bool QContactTrackerEngine::hasFeature(QContactManager::ManagerFeature feature, const QString& contactType) const
-{
- if (!supportedContactTypes().contains(contactType)) {
- return false;
- }
-
- switch (feature) {
- case QContactManager::Groups:
- case QContactManager::ActionPreferences:
- case QContactManager::Relationships:
- case QContactManager::SelfContact:
- return true;
- case QContactManager::ArbitraryRelationshipTypes:
- return true;
- case QContactManager::MutableDefinitions:
- return true;
- case QContactManager::ChangeLogs:
- return true;
- default:
- return false;
- }
-}
-
-
-/*!
- * \reimp
- */
-/*!
- * Definition identifiers which are natively (fast) filterable
- * on the default backend store managed by the manager from which the capabilities object was accessed
- */
-bool QContactTrackerEngine::isFilterSupported(const QContactFilter& filter) const
-{
- switch (filter.type()) {
- case QContactFilter::InvalidFilter:
- case QContactFilter::DefaultFilter:
- case QContactFilter::LocalIdFilter:
- case QContactFilter::ContactDetailFilter:
- case QContactFilter::ContactDetailRangeFilter:
- case QContactFilter::ActionFilter:
- case QContactFilter::ChangeLogFilter:
- case QContactFilter::RelationshipFilter:
-
-// not yet done
-// case QContactFilter::IntersectionFilter:
-// case QContactFilter::UnionFilter:
- return true;
- default:
- return false;
- }
-}
-
-/*!
- * Returns the list of data types supported by the Tracker engine
- */
-QList<QVariant::Type> QContactTrackerEngine::supportedDataTypes() const
-{
- // TODO: Check supported datatypes for Tracker backend.
- QList<QVariant::Type> st;
- st.append(QVariant::String);
- st.append(QVariant::Date);
- st.append(QVariant::DateTime);
- return st;
-}
-
-/*!
- * Returns the name of the Tracker engine
- */
-QString QContactTrackerEngine::managerName() const
-{
- return d->m_engineName;
-}
-
-/*!
- * Returns the manager version of this engine
- */
-int QContactTrackerEngine::managerVersion() const
-{
- return d->m_engineVersion;
-}
-
-RDFVariable QContactTrackerEngine::contactDetail2Rdf(const RDFVariable& rdfContact, const QString& definitionName,
- const QString& fieldName) const
-{
- if (definitionName == QContactName::DefinitionName) {
- if (fieldName == QContactName::FieldFirstName) {
- return rdfContact.property<nco::nameGiven>();
- }
- else if (fieldName == QContactName::FieldLastName) {
- return rdfContact.property<nco::nameFamily>();
- }
- else if (fieldName == QContactName::FieldMiddleName) {
- return rdfContact.property<nco::nameAdditional>();
- }
- else if (fieldName == QContactName::FieldPrefix) {
- return rdfContact.property<nco::nameHonorificPrefix>();
- }
- else if (fieldName == QContactName::FieldSuffix) {
- return rdfContact.property<nco::nameHonorificSuffix>();
- }
- else if (fieldName == QContactNickname::FieldNickname) {
- return rdfContact.property<nco::nickname>();
- }
- }
- return RDFVariable();
-}
-
-/*! \reimp */
-void QContactTrackerEngine::requestDestroyed(QContactAbstractRequest* req)
-{
- if( d->m_requests.contains(req) )
- {
- QTrackerContactAsyncRequest *request = d->m_requests.take(req);
- delete request;
- }
-}
-
-/*! \reimp */
-bool QContactTrackerEngine::startRequest(QContactAbstractRequest* req)
-{
- QTrackerContactAsyncRequest *request = 0;
- switch (req->type())
- {
- case QContactAbstractRequest::ContactLocalIdFetchRequest:
- request = new QTrackerContactIdFetchRequest(req, this);
- break;
- case QContactAbstractRequest::ContactFetchRequest:
- request = new QTrackerContactFetchRequest(req, this);
- break;
- case QContactAbstractRequest::ContactSaveRequest:
- request = new QTrackerContactSaveRequest(req, this);
- break;
- case QContactAbstractRequest::RelationshipFetchRequest:
- request = new QTrackerRelationshipFetchRequest(req, this);
- break;
- case QContactAbstractRequest::RelationshipSaveRequest:
- request = new QTrackerRelationshipSaveRequest(req, this);
- break;
- default:
- return false;
- }
- d->m_requests[req] = request;
- return true;
-}
-
-/*! \reimp */
-QString QContactTrackerEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const
-{
- QString label = QContactManagerEngine::synthesizedDisplayLabel(contact, error);
- if (label.isEmpty())
- label = contact.detail<QContactNickname>().nickname();
- //XXX TODO: FIXME - take the nickname from the presence field associated with the online account
- //if(label.isEmpty())
- // label = contact.detail<QContactOnlineAccount>().nickname();
-
- qDebug() << Q_FUNC_INFO << label;
- return label;
-}