--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/src/contacts/qcontactmanagerengine.cpp Fri Apr 16 15:51:22 2010 +0300
@@ -0,0 +1,2022 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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 "qcontactmanagerengine.h"
+
+#include "qcontactdetaildefinition.h"
+#include "qcontactdetailfielddefinition.h"
+#include "qcontactdetails.h"
+#include "qcontactsortorder.h"
+#include "qcontactfilters.h"
+#include "qcontactaction.h"
+#include "qcontactactiondescriptor.h"
+#include "qcontactabstractrequest.h"
+#include "qcontactabstractrequest_p.h"
+#include "qcontactrequests.h"
+#include "qcontactrequests_p.h"
+
+#include "qcontact_p.h"
+#include "qcontactdetail_p.h"
+QTM_BEGIN_NAMESPACE
+
+/*!
+ \class QContactManagerEngine
+ \preliminary
+ \brief The QContactManagerEngine class provides the interface for all
+ implementations of the contact manager backend functionality.
+
+ Instances of this class are usually provided by a
+ \l QContactManagerEngineFactory, which is loaded from a plugin.
+
+ The default implementation of this interface provides a basic
+ level of functionality for some functions so that specific engines
+ can simply implement the functionality that is supported by
+ the specific contacts engine that is being adapted.
+
+ More information on writing a contacts engine plugin is TODO.
+
+ \sa QContactManager, QContactManagerEngineFactory
+ */
+
+/*!
+ \fn QContactManagerEngine::QContactManagerEngine()
+
+ A default, empty constructor.
+ */
+
+/*!
+ \fn QContactManagerEngine::deref()
+
+ Notifies the engine that it is no longer required. If this
+ engine can not be shared between managers, it is safe for the
+ engine to delete itself in this function.
+
+ If the engine implementation can be shared, this function can use a
+ reference count and track lifetime that way. The factory that
+ returns an instance of this engine should increment the reference
+ count in this case.
+ */
+
+/*!
+ \fn QContactManagerEngine::dataChanged()
+
+ This signal is emitted some time after changes occur to the data managed by this
+ engine, and the engine is unable to determine which changes occurred, or if the
+ engine considers the changes to be radical enough to require clients to reload all data.
+
+ If this signal is emitted, no other signals may be emitted for the associated changes.
+
+ As it is possible that other processes (or other devices) may have caused the
+ changes, the timing can not be determined.
+
+ \sa contactsAdded(), contactsChanged(), contactsRemoved()
+ */
+
+/*!
+ \fn QContactManagerEngine::contactsAdded(const QList<QContactLocalId>& contactIds);
+
+ This signal is emitted some time after a set of contacts has been added to
+ this engine where the \l dataChanged() signal was not emitted for those changes.
+ As it is possible that other processes (or other devices) may
+ have added the contacts, the timing cannot be determined.
+
+ The list of ids of contacts added is given by \a contactIds. There may be one or more
+ ids in the list.
+
+ \sa dataChanged()
+ */
+
+/*!
+ \fn QContactManagerEngine::contactsChanged(const QList<QContactLocalId>& contactIds);
+
+ This signal is emitted some time after a set of contacts has been modified in
+ this engine where the \l dataChanged() signal was not emitted for those changes.
+ As it is possible that other processes (or other devices) may
+ have modified the contacts, the timing cannot be determined.
+
+ The list of ids of changed contacts is given by \a contactIds. There may be one or more
+ ids in the list.
+
+ \sa dataChanged()
+ */
+
+/*!
+ \fn QContactManagerEngine::contactsRemoved(const QList<QContactLocalId>& contactIds);
+
+ This signal is emitted some time after a set of contacts has been removed from
+ this engine where the \l dataChanged() signal was not emitted for those changes.
+ As it is possible that other processes (or other devices) may
+ have removed the contacts, the timing cannot be determined.
+
+ The list of ids of removed contacts is given by \a contactIds. There may be one or more
+ ids in the list.
+
+ \sa dataChanged()
+ */
+
+/*!
+ \fn QContactManagerEngine::relationshipsAdded(const QList<QContactLocalId>& affectedContactIds);
+
+ This signal is emitted some time after a set of contacts has been added to
+ this engine where the \l dataChanged() signal was not emitted for those changes.
+ As it is possible that other processes (or other devices) may
+ have added the contacts, the timing cannot be determined.
+
+ The list of ids of affected contacts is given by \a affectedContactIds. There may be one or more
+ ids in the list.
+
+ \sa dataChanged()
+ */
+
+/*!
+ \fn QContactManagerEngine::relationshipsRemoved(const QList<QContactLocalId>& affectedContactIds);
+
+ This signal is emitted some time after a set of relationships has been removed from
+ this engine where the \l dataChanged() signal was not emitted for those changes.
+ As it is possible that other processes (or other devices) may
+ have removed the relationships, the timing cannot be determined.
+
+ The list of ids of affected contacts is given by \a affectedContactIds. There may be one or more
+ ids in the list.
+
+ \sa dataChanged()
+ */
+
+/*!
+ \fn QContactManagerEngine::selfContactIdChanged(const QContactLocalId& oldId, const QContactLocalId& newId)
+
+ This signal is emitted at some point after the id of the self-contact is changed from \a oldId to \a newId in the manager.
+ If the \a newId is the invalid, zero id, then the self contact was deleted or no self contact exists.
+ This signal must not be emitted if the dataChanged() signal was previously emitted for this change.
+ As it is possible that other processes (or other devices) may
+ have removed or changed the self contact, the timing cannot be determined.
+
+ \sa dataChanged()
+ */
+
+/*! Returns the manager name for this QContactManagerEngine */
+QString QContactManagerEngine::managerName() const
+{
+ return QString(QLatin1String("base"));
+}
+
+/*!
+ Returns the parameters with which this engine was constructed. Note that
+ the engine may have discarded unused or invalid parameters at the time of
+ construction, and these will not be returned.
+ */
+QMap<QString, QString> QContactManagerEngine::managerParameters() const
+{
+ return QMap<QString, QString>(); // default implementation requires no parameters.
+}
+
+/*!
+ Returns the unique URI of this manager, which is built from the manager name and the parameters
+ used to construct it.
+ */
+QString QContactManagerEngine::managerUri() const
+{
+ return QContactManager::buildUri(managerName(), managerParameters());
+}
+
+/*!
+ Returns a list of contact ids sorted according to the given list of \a sortOrders.
+ Depending on the backend, this operation may involve retrieving all the contacts.
+ Any error which occurs will be saved in \a error.
+ */
+QList<QContactLocalId> QContactManagerEngine::contactIds(const QList<QContactSortOrder>& sortOrders, QContactManager::Error& error) const
+{
+ Q_UNUSED(sortOrders);
+ error = QContactManager::NotSupportedError;
+ return QList<QContactLocalId>();
+}
+
+/*!
+ Returns a list of contact ids that match the given \a filter, sorted according to the given list of \a sortOrders.
+ Depending on the backend, this filtering operation may involve retrieving all the contacts.
+ Any error which occurs will be saved in \a error.
+ */
+QList<QContactLocalId> QContactManagerEngine::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error& error) const
+{
+ /* Slow way */
+ QList<QContactLocalId> ret;
+
+ /* If the filter matches all ids, then return the list of all ids */
+ if (filter.type() == QContactFilter::DefaultFilter) {
+ const QList<QContactLocalId>& allIds = contactIds(sortOrders, error);
+ if (error != QContactManager::NoError)
+ return ret;
+ return allIds;
+ }
+
+ /* Otherwise, retrieve all contacts, test and return matching */
+ const QList<QContact>& all = contacts(sortOrders, QStringList(), error);
+
+ if (error != QContactManager::NoError)
+ return ret;
+
+ for (int j = 0; j < all.count(); j++) {
+ if (testFilter(filter, all.at(j)))
+ ret << all.at(j).localId();
+ }
+
+ return ret;
+}
+
+/*!
+ Returns the list of contacts stored in the manager sorted according to the given list of \a sortOrders.
+ If the given list of detail definition names \a definitionRestrictions is empty, each contact returned will include
+ all of the details which are stored in it, otherwise only those details which are of a definition whose name is included
+ in the \a definitionRestrictions list will be included.
+ Any error which occurs will be saved in \a error.
+ */
+QList<QContact> QContactManagerEngine::contacts(const QList<QContactSortOrder>& sortOrders, const QStringList& definitionRestrictions, QContactManager::Error& error) const
+{
+ Q_UNUSED(sortOrders);
+ Q_UNUSED(definitionRestrictions);
+ error = QContactManager::NotSupportedError;
+ return QList<QContact>();
+}
+
+/*!
+ Returns a list of contacs that match the given \a filter, sorted according to the given list of \a sortOrders.
+ Depending on the backend, this filtering operation may involve retrieving all the contacts.
+ If the given list of detail definition names \a definitionRestrictions is empty, each contact returned will include
+ all of the details which are stored in it, otherwise only those details which are of a definition whose name is included
+ in the \a definitionRestrictions list will be included.
+ Any error which occurs will be saved in \a error.
+ */
+QList<QContact> QContactManagerEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QStringList& definitionRestrictions, QContactManager::Error& error) const
+{
+ /* Slow way */
+ QList<QContact> ret;
+
+ /* Retrieve each contact.. . . */
+ const QList<QContact>& all = contacts(sortOrders, definitionRestrictions, error);
+ if (error != QContactManager::NoError)
+ return ret;
+
+ if (filter.type() == QContactFilter::DefaultFilter)
+ return all;
+
+ for (int j = 0; j < all.count(); j++) {
+ if (testFilter(filter, all.at(j))) {
+ ret << all.at(j);
+ }
+ }
+
+ return ret;
+}
+
+/*!
+ Returns the contact in the database identified by \a contactId.
+ If the list of detail definition names \a definitionRestrictions given is non-empty,
+ the contact returned will contain at least those details which are of a definition whose name is
+ contained in the \a definitionRestrictions list.
+ Note that the returned contact may also contain other details, but this function guarantees that
+ all details whose definition name is included in the given list of definition names \a definitionRestrictions
+ will be included in the returned contact.
+
+ The default implementation returns the entire contact.
+
+ Any errors encountered should be stored to \a error.
+ */
+QContact QContactManagerEngine::contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions, QContactManager::Error& error) const
+{
+ Q_UNUSED(contactId);
+ Q_UNUSED(definitionRestrictions);
+ error = QContactManager::NotSupportedError;
+ return QContact();
+}
+
+/*!
+ Sets the id of the "self" contact to the given \a contactId.
+ Returns true if the "self" contact id was set successfully.
+ If the given \a contactId does not identify a contact
+ stored in this manager, the \a error will be set to
+ \c QContactManager::DoesNotExistError and the function will
+ return false; if the backend does not support the
+ concept of a "self" contact, the \a error will be set to
+ \c QContactManager::NotSupportedError and the function will
+ return false.
+ */
+bool QContactManagerEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error& error)
+{
+ Q_UNUSED(contactId);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Returns the id of the "self" contact which has previously been set.
+ If no "self" contact has been set, or if the self contact was removed
+ from the manager after being set, or if the backend does not support
+ the concept of a "self" contact, an invalid id will be returned
+ and the \a error will be set to \c QContactManager::DoesNotExistError.
+ */
+QContactLocalId QContactManagerEngine::selfContactId(QContactManager::Error& error) const
+{
+ error = QContactManager::DoesNotExistError;
+ return QContactLocalId();
+}
+
+/*!
+ Returns a list of relationships of the given \a relationshipType in which the contact identified by the given \a participantId participates in the given \a role.
+ If \a participantId is the default-constructed id, \a role is ignored and all relationships of the given \a relationshipType are returned.
+ If \a relationshipType is empty, relationships of any type are returned.
+ If no relationships of the given \a relationshipType in which the contact identified by the given \a participantId is involved in the given \a role exists,
+ \a error is set to QContactManager::DoesNotExistError.
+ */
+QList<QContactRelationship> QContactManagerEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationshipFilter::Role role, QContactManager::Error& error) const
+{
+ Q_UNUSED(relationshipType);
+ Q_UNUSED(participantId);
+ Q_UNUSED(role);
+ error = QContactManager::NotSupportedError;
+ return QList<QContactRelationship>();
+}
+
+/*!
+ Saves the given \a relationship in the database. If the relationship already exists in the database, this function will
+ return \c false and the \a error will be set to \c QContactManager::AlreadyExistsError.
+ If the relationship is saved successfully, this function will return \c true and \a error will be set
+ to \c QContactManager::NoError. Note that relationships cannot be updated directly using this function; in order
+ to update a relationship, you must remove the old relationship, make the required modifications, and then save it.
+
+ The given relationship is invalid if it is circular (one of the destination contacts is also the source contact), or
+ if it references a non-existent local contact (either source or destination). If the given \a relationship is invalid,
+ the function will return \c false and the \a error will be set to \c QContactManager::InvalidRelationshipError.
+ If the given \a relationship could not be saved in the database (due to backend limitations)
+ the function will return \c false and \a error will be set to \c QContactManager::NotSupportedError.
+
+ If any destination contact manager URI is not set in the \a relationship, these will be
+ automatically set to the URI of this manager, before the relationship is saved.
+ */
+bool QContactManagerEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error& error)
+{
+ Q_UNUSED(relationship);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Saves the given \a relationships in the database and returns a list of error codes. Any error which occurs will be saved in \a error.
+ */
+QList<QContactManager::Error> QContactManagerEngine::saveRelationships(QList<QContactRelationship>* relationships, QContactManager::Error& error)
+{
+ Q_UNUSED(relationships);
+ error = QContactManager::NotSupportedError;
+ return QList<QContactManager::Error>();
+}
+
+/*!
+ Removes the given \a relationship from the manager. If the relationship exists in the manager, the relationship
+ will be removed, the \a error will be set to \c QContactManager::NoError and this function will return true. If no such
+ relationship exists in the manager, the \a error will be set to \c QContactManager::DoesNotExistError and this function
+ will return false.
+
+ The priority of the relationship is ignored when determining existence of the relationship.
+ */
+bool QContactManagerEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error& error)
+{
+ Q_UNUSED(relationship);
+ error = QContactManager::DoesNotExistError;
+ return false;
+}
+
+/*!
+ Removes the given \a relationships from the database and returns a list of error codes. Any error which occurs will be saved in \a error.
+ */
+QList<QContactManager::Error> QContactManagerEngine::removeRelationships(const QList<QContactRelationship>& relationships, QContactManager::Error& error)
+{
+ Q_UNUSED(relationships);
+ error = QContactManager::DoesNotExistError;
+ return QList<QContactManager::Error>();
+}
+
+/*!
+ Synthesizes the display label of the given \a contact in a platform specific manner.
+ Any error that occurs will be stored in \a error.
+ Returns the synthesized display label.
+ */
+QString QContactManagerEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error& error) const
+{
+ // synthesize the display name from the name of the contact, or, failing that, the organisation of the contact.
+ error = QContactManager::NoError;
+ QList<QContactDetail> allNames = contact.details(QContactName::DefinitionName);
+
+ const QLatin1String space(" ");
+
+ // synthesize the display label from the name.
+ for (int i=0; i < allNames.size(); i++) {
+ const QContactName& name = allNames.at(i);
+
+ if (!name.customLabel().isEmpty()) {
+ // default behaviour is to allow the user to define a custom display label.
+ return name.customLabel();
+ }
+
+ QString result;
+ if (!name.value(QContactName::FieldPrefix).trimmed().isEmpty()) {
+ result += name.value(QContactName::FieldPrefix);
+ }
+
+ if (!name.value(QContactName::FieldFirstName).trimmed().isEmpty()) {
+ if (!result.isEmpty())
+ result += space;
+ result += name.value(QContactName::FieldFirstName);
+ }
+
+ if (!name.value(QContactName::FieldMiddleName).trimmed().isEmpty()) {
+ if (!result.isEmpty())
+ result += space;
+ result += name.value(QContactName::FieldMiddleName);
+ }
+
+ if (!name.value(QContactName::FieldLastName).trimmed().isEmpty()) {
+ if (!result.isEmpty())
+ result += space;
+ result += name.value(QContactName::FieldLastName);
+ }
+
+ if (!name.value(QContactName::FieldSuffix).trimmed().isEmpty()) {
+ if (!result.isEmpty())
+ result += space;
+ result += name.value(QContactName::FieldSuffix);
+ }
+
+ if (!result.isEmpty()) {
+ return result;
+ }
+ }
+
+ /* Well, we had no non empty names. if we have orgs, fall back to those */
+ QList<QContactDetail> allOrgs = contact.details(QContactOrganization::DefinitionName);
+ for (int i=0; i < allOrgs.size(); i++) {
+ const QContactOrganization& org = allOrgs.at(i);
+ if (!org.name().isEmpty()) {
+ return org.name();
+ }
+ }
+
+ error = QContactManager::UnspecifiedError;
+ return QString();
+}
+
+/*!
+ Returns a copy of the given contact \a contact with its display label set to \a displayLabel.
+ This function does not touch the database in any way, and is purely a convenience to allow engine implementations to set the display label.
+ */
+QContact QContactManagerEngine::setContactDisplayLabel(const QString& displayLabel, const QContact& contact) const
+{
+ QContact retn = contact;
+ QContactDisplayLabel dl;
+ dl.setValue(QContactDisplayLabel::FieldLabel, displayLabel);
+ setDetailAccessConstraints(&dl, QContactDetail::Irremovable);
+ retn.d->m_details.replace(0, dl);
+ return retn;
+}
+
+/*!
+ Returns true if the given \a feature is supported by this engine for contacts of the given \a contactType
+ */
+bool QContactManagerEngine::hasFeature(QContactManager::ManagerFeature feature, const QString& contactType) const
+{
+ Q_UNUSED(feature);
+ Q_UNUSED(contactType);
+ return false;
+}
+
+/*!
+ Returns a whether the supplied \a filter can be implemented
+ natively by this engine. If not, the base class implementation
+ will emulate the functionality.
+ */
+bool QContactManagerEngine::isFilterSupported(const QContactFilter& filter) const
+{
+ Q_UNUSED(filter);
+ return false;
+}
+
+/*!
+ Returns the list of data types supported by this engine.
+ */
+QList<QVariant::Type> QContactManagerEngine::supportedDataTypes() const
+{
+ return QList<QVariant::Type>();
+}
+
+/*!
+ Returns the list of relationship types supported by this engine for contacts whose type is the given \a contactType.
+ */
+QStringList QContactManagerEngine::supportedRelationshipTypes(const QString& contactType) const
+{
+ Q_UNUSED(contactType);
+ return QStringList();
+}
+
+/*!
+ Returns the list of contact types which are supported by this engine.
+ This is a convenience function, equivalent to retrieving the allowable values
+ for the \c QContactType::FieldType field of the QContactType definition
+ which is valid in this engine.
+ */
+QStringList QContactManagerEngine::supportedContactTypes() const
+{
+ QContactManager::Error error;
+ QList<QVariant> allowableVals = detailDefinition(QContactType::DefinitionName, QContactType::TypeContact, error).fields().value(QContactType::FieldType).allowableValues();
+ QStringList retn;
+ for (int i = 0; i < allowableVals.size(); i++)
+ retn += allowableVals.at(i).toString();
+ return retn;
+}
+
+/*!
+ Returns the engine backend implementation version number
+ */
+int QContactManagerEngine::managerVersion() const
+{
+ return 0;
+}
+
+
+/*! Returns the base schema definitions */
+QMap<QString, QMap<QString, QContactDetailDefinition> > QContactManagerEngine::schemaDefinitions()
+{
+ // This implementation provides the base schema.
+ // The schema documentation (contactsschema.qdoc)
+ // MUST BE KEPT UP TO DATE as definitions are added here.
+
+ // the map we will eventually return
+ QMap<QString, QContactDetailDefinition> retn;
+
+ // local variables for reuse
+ QMap<QString, QContactDetailFieldDefinition> fields;
+ QContactDetailFieldDefinition f;
+ QContactDetailDefinition d;
+ QVariantList contexts;
+ contexts << QString(QLatin1String(QContactDetail::ContextHome)) << QString(QLatin1String(QContactDetail::ContextWork)) << QString(QLatin1String(QContactDetail::ContextOther));
+ QVariantList subTypes;
+
+ // sync target
+ d.setName(QContactSyncTarget::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactSyncTarget::FieldSyncTarget, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(true);
+ retn.insert(d.name(), d);
+
+ // timestamp
+ d.setName(QContactTimestamp::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::DateTime);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactTimestamp::FieldModificationTimestamp, f);
+ fields.insert(QContactTimestamp::FieldCreationTimestamp, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(true);
+ retn.insert(d.name(), d);
+
+ // type
+ d.setName(QContactType::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactType::TypeContact)) << QString(QLatin1String(QContactType::TypeGroup));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactType::FieldType, f); // note: NO CONTEXT!!
+ d.setFields(fields);
+ d.setUnique(true);
+ retn.insert(d.name(), d);
+
+ // guid
+ d.setName(QContactGuid::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactGuid::FieldGuid, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // display label
+ d.setName(QContactDisplayLabel::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactDisplayLabel::FieldLabel, f);
+ d.setFields(fields);
+ d.setUnique(true);
+ retn.insert(d.name(), d);
+
+ // email address
+ d.setName(QContactEmailAddress::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactEmailAddress::FieldEmailAddress, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // organisation
+ d.setName(QContactOrganization::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactOrganization::FieldName, f);
+ fields.insert(QContactOrganization::FieldLogo, f);
+ fields.insert(QContactOrganization::FieldLocation, f);
+ fields.insert(QContactOrganization::FieldTitle, f);
+ f.setDataType(QVariant::StringList);
+ fields.insert(QContactOrganization::FieldDepartment, f);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // phone number
+ d.setName(QContactPhoneNumber::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactPhoneNumber::FieldNumber, f);
+ f.setDataType(QVariant::StringList); // can implement multiple subtypes
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeAssistant));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeBulletinBoardSystem));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeCar));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeDtmfMenu));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeFacsimile));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeLandline));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeMessagingCapable));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeMobile));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeModem));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypePager));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeVideo));
+ subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeVoice));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactPhoneNumber::FieldSubTypes, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // anniversary
+ d.setName(QContactAnniversary::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::Date);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAnniversary::FieldOriginalDate, f);
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAnniversary::FieldCalendarId, f);
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAnniversary::FieldEvent, f);
+ f.setDataType(QVariant::String); // only allowed to be a single subtype.
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactAnniversary::SubTypeEmployment));
+ subTypes << QString(QLatin1String(QContactAnniversary::SubTypeEngagement));
+ subTypes << QString(QLatin1String(QContactAnniversary::SubTypeHouse));
+ subTypes << QString(QLatin1String(QContactAnniversary::SubTypeMemorial));
+ subTypes << QString(QLatin1String(QContactAnniversary::SubTypeWedding));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactAnniversary::FieldSubType, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // birthday
+ d.setName(QContactBirthday::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::Date);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactBirthday::FieldBirthday, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(true);
+ retn.insert(d.name(), d);
+
+ // nickname
+ d.setName(QContactNickname::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactNickname::FieldNickname, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // note
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ d.setName(QContactNote::DefinitionName);
+ fields.insert(QContactNote::FieldNote, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // url
+ d.setName(QContactUrl::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactUrl::FieldUrl, f);
+ f.setDataType(QVariant::String); // only allowed to be a single subtype
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactUrl::SubTypeFavourite));
+ subTypes << QString(QLatin1String(QContactUrl::SubTypeHomePage));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactUrl::FieldSubType, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // gender
+ d.setName(QContactGender::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList() << QString(QLatin1String(QContactGender::GenderMale)) << QString(QLatin1String(QContactGender::GenderFemale)) << QString(QLatin1String(QContactGender::GenderUnspecified)));
+ fields.insert(QContactGender::FieldGender, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // online account
+ d.setName(QContactOnlineAccount::DefinitionName);
+ fields.clear();
+ f.setAllowableValues(QVariantList());
+ f.setDataType(QVariant::String);
+ fields.insert(QContactOnlineAccount::FieldAccountUri, f);
+ f.setDataType(QVariant::StringList);
+ fields.insert(QContactOnlineAccount::FieldCapabilities, f);
+ f.setDataType(QVariant::String);
+ fields.insert(QContactOnlineAccount::FieldAccountUri, f);
+ fields.insert(QContactOnlineAccount::FieldServiceProvider, f);
+ fields.insert(QContactOnlineAccount::FieldNickname, f);
+ fields.insert(QContactOnlineAccount::FieldStatusMessage, f);
+ QVariantList presenceValues;
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceAvailable));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceHidden));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceBusy));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceAway));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceExtendedAway));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceUnknown));
+ presenceValues << QString(QLatin1String(QContactOnlineAccount::PresenceOffline));
+ f.setAllowableValues(presenceValues);
+ fields.insert(QContactOnlineAccount::FieldPresence, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ f.setAllowableValues(QVariantList()); // allow any subtypes!
+ fields.insert(QContactOnlineAccount::FieldSubTypes, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // avatar
+ d.setName(QContactAvatar::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAvatar::FieldAvatar, f);
+
+ f.setDataType(QVariant::Pixmap);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAvatar::FieldAvatarPixmap, f);
+
+ f.setDataType(QVariant::String); // only allowed to be a single subtype
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactAvatar::SubTypeImage));
+ subTypes << QString(QLatin1String(QContactAvatar::SubTypeTexturedMesh));
+ subTypes << QString(QLatin1String(QContactAvatar::SubTypeVideo));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactAvatar::FieldSubType, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // GeoLocation
+ d.setName(QContactGeoLocation::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactGeoLocation::FieldLabel, f);
+ f.setDataType(QVariant::Double);
+ fields.insert(QContactGeoLocation::FieldLatitude, f);
+ fields.insert(QContactGeoLocation::FieldLongitude, f);
+ fields.insert(QContactGeoLocation::FieldAccuracy, f);
+ fields.insert(QContactGeoLocation::FieldAltitude, f);
+ fields.insert(QContactGeoLocation::FieldAltitudeAccuracy, f);
+ fields.insert(QContactGeoLocation::FieldSpeed, f);
+ fields.insert(QContactGeoLocation::FieldHeading, f);
+ f.setDataType(QVariant::DateTime);
+ fields.insert(QContactGeoLocation::FieldTimestamp, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // street address
+ d.setName(QContactAddress::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactAddress::FieldPostOfficeBox, f);
+ fields.insert(QContactAddress::FieldStreet, f);
+ fields.insert(QContactAddress::FieldLocality, f);
+ fields.insert(QContactAddress::FieldRegion, f);
+ fields.insert(QContactAddress::FieldPostcode, f);
+ fields.insert(QContactAddress::FieldCountry, f);
+ f.setDataType(QVariant::StringList); // can implement multiple subtypes
+ subTypes.clear();
+ subTypes << QString(QLatin1String(QContactAddress::SubTypeDomestic));
+ subTypes << QString(QLatin1String(QContactAddress::SubTypeInternational));
+ subTypes << QString(QLatin1String(QContactAddress::SubTypeParcel));
+ subTypes << QString(QLatin1String(QContactAddress::SubTypePostal));
+ f.setAllowableValues(subTypes);
+ fields.insert(QContactAddress::FieldSubTypes, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // name
+ d.setName(QContactName::DefinitionName);
+ fields.clear();
+ f.setDataType(QVariant::String);
+ f.setAllowableValues(QVariantList());
+ fields.insert(QContactName::FieldPrefix, f);
+ fields.insert(QContactName::FieldFirstName, f);
+ fields.insert(QContactName::FieldMiddleName, f);
+ fields.insert(QContactName::FieldLastName, f);
+ fields.insert(QContactName::FieldSuffix, f);
+ fields.insert(QContactName::FieldCustomLabel, f);
+ f.setDataType(QVariant::StringList);
+ f.setAllowableValues(contexts);
+ fields.insert(QContactDetail::FieldContext, f);
+ d.setFields(fields);
+ d.setUnique(false);
+ retn.insert(d.name(), d);
+
+ // in the default schema, we have two contact types: TypeContact, TypeGroup.
+ // the entire default schema is valid for both types.
+ QMap<QString, QMap<QString, QContactDetailDefinition> > retnSchema;
+ retnSchema.insert(QContactType::TypeContact, retn);
+ retnSchema.insert(QContactType::TypeGroup, retn);
+
+ return retnSchema;
+}
+
+
+/*!
+ Adds the given \a contact to the database if \a contact has a
+ default-constructed id, or an id with the manager URI set to the URI of
+ this manager and a local id of zero.
+
+ If the manager URI of the id of the \a contact is neither empty nor equal to the URI of
+ this manager, or local id of the \a contact is non-zero but does not exist in the
+ manager, the operation will fail and \a error will be set to
+ \c QContactManager::DoesNotExistError.
+
+ Alternatively, the function will update the existing contact in the database if \a contact
+ has a non-zero id and currently exists in the database.
+
+ If the \a contact contains one or more details whose definitions have
+ not yet been saved with the manager, the operation will fail and \a error will be
+ set to \c QContactManager::UnsupportedError.
+
+ If the \a contact has had its relationships reordered, the manager
+ will check to make sure that every relationship that the contact is currently
+ involved in is included in the reordered list, and that no relationships which
+ either do not involve the contact, or have not been saved in the manager are
+ included in the list. If these conditions are not met, the function will
+ return \c false and \a error will be set to \c QContactManager::InvalidRelationshipError.
+
+ The engine must automatically synthesize the display label of the contact when it is saved,
+ by either using the built in \l synthesizedDisplayLabel() function or overriding it, and
+ then calling \l setContactDisplayLabel().
+
+ Returns false on failure, or true on
+ success. On successful save of a contact with an id of zero, its
+ id will be set to a new, valid id with the manager URI set to the URI of
+ this manager, and the local id set to a new, valid local id.
+
+ This function is called by the contacts framework in both the
+ single contact save and batch contact save, if the saveContacts
+ function is not overridden.
+
+ The backend must emit the appropriate signals to inform clients of changes
+ to the database resulting from this operation.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::saveContact(QContact* contact, QContactManager::Error& error)
+{
+ Q_UNUSED(contact);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Checks that the given contact \a contact does not have details which
+ don't conform to a valid definition, violate uniqueness constraints,
+ or contain values for nonexistent fields, and that the values contained are
+ of the correct type for each field, and are allowable values for that field.
+
+ Note that this function is unable to ensure that the access constraints
+ (such as CreateOnly and ReadOnly) are observed; backend specific code
+ must be written if you wish to enforce these constraints.
+
+ Returns true if the \a contact is valid according to the definitions for
+ its details, otherwise returns false.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::validateContact(const QContact& contact, QContactManager::Error& error) const
+{
+ QList<QString> uniqueDefinitionIds;
+
+ // check that each detail conforms to its definition as supported by this manager.
+ for (int i=0; i < contact.details().count(); i++) {
+ const QContactDetail& d = contact.details().at(i);
+ QVariantMap values = d.variantValues();
+ QContactDetailDefinition def = detailDefinition(d.definitionName(), contact.type(), error);
+ // check that the definition is supported
+ if (error != QContactManager::NoError) {
+ error = QContactManager::InvalidDetailError;
+ return false; // this definition is not supported.
+ }
+
+ // check uniqueness
+ if (def.isUnique()) {
+ if (uniqueDefinitionIds.contains(def.name())) {
+ error = QContactManager::AlreadyExistsError;
+ return false; // can't have two of a unique detail.
+ }
+ uniqueDefinitionIds.append(def.name());
+ }
+
+ QList<QString> keys = values.keys();
+ for (int i=0; i < keys.count(); i++) {
+ const QString& key = keys.at(i);
+ // check that no values exist for nonexistent fields.
+ if (!def.fields().contains(key)) {
+ error = QContactManager::InvalidDetailError;
+ return false; // value for nonexistent field.
+ }
+
+ QContactDetailFieldDefinition field = def.fields().value(key);
+ // check that the type of each value corresponds to the allowable field type
+ if (static_cast<int>(field.dataType()) != values.value(key).userType()) {
+ error = QContactManager::InvalidDetailError;
+ return false; // type doesn't match.
+ }
+
+ // check that the value is allowable
+ // if the allowable values is an empty list, any are allowed.
+ if (!field.allowableValues().isEmpty()) {
+ // if the field datatype is a list, check that it contains only allowable values
+ if (field.dataType() == QVariant::List || field.dataType() == QVariant::StringList) {
+ QList<QVariant> innerValues = values.value(key).toList();
+ for (int i = 0; i < innerValues.size(); i++) {
+ if (!field.allowableValues().contains(innerValues.at(i))) {
+ error = QContactManager::InvalidDetailError;
+ return false; // value not allowed.
+ }
+ }
+ } else if (!field.allowableValues().contains(values.value(key))) {
+ // the datatype is not a list; the value wasn't allowed.
+ error = QContactManager::InvalidDetailError;
+ return false; // value not allowed.
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+/*!
+ Checks that the given detail definition \a definition seems valid,
+ with a correct id, defined fields, and any specified value types
+ are supported by this engine. This function is called before
+ trying to save a definition.
+
+ Returns true if the \a definition seems valid, otherwise returns
+ false.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::validateDefinition(const QContactDetailDefinition& definition, QContactManager::Error& error) const
+{
+ if (definition.name().isEmpty()) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ if (definition.fields().count() == 0) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ // Check each field now
+ QList<QVariant::Type> types = supportedDataTypes();
+ QMapIterator<QString, QContactDetailFieldDefinition> it(definition.fields());
+ while(it.hasNext()) {
+ it.next();
+ if (it.key().isEmpty()) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ if (!types.contains(it.value().dataType())) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ // Check that each allowed value is the same type
+ for (int i=0; i < it.value().allowableValues().count(); i++) {
+ if (it.value().allowableValues().at(i).type() != it.value().dataType()) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+ }
+ }
+ error = QContactManager::NoError;
+ return true;
+}
+
+/*!
+ Remove the contact identified by \a contactId from the database,
+ and removes the contact from any relationships in which it was involved.
+ Returns true if the contact was removed successfully, otherwise
+ returns false.
+
+ The backend must emit the appropriate signals to inform clients of changes
+ to the database resulting from this operation.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error& error)
+{
+ Q_UNUSED(contactId);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Returns the registered detail definitions which are valid for contacts whose type is of the given \a contactType in this engine.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+QMap<QString, QContactDetailDefinition> QContactManagerEngine::detailDefinitions(const QString& contactType, QContactManager::Error& error) const
+{
+ Q_UNUSED(contactType);
+ error = QContactManager::NotSupportedError;
+ return QMap<QString, QContactDetailDefinition>();
+}
+
+/*!
+ Returns the definition identified by the given \a definitionName that
+ is valid for contacts whose type is of the given \a contactType in this store, or a default-constructed QContactDetailDefinition
+ if no such definition exists
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+QContactDetailDefinition QContactManagerEngine::detailDefinition(const QString& definitionName, const QString& contactType, QContactManager::Error& error) const
+{
+ Q_UNUSED(definitionName);
+
+ QMap<QString, QContactDetailDefinition> definitions = detailDefinitions(contactType, error);
+ if (definitions.contains(definitionName)) {
+ error = QContactManager::NoError;
+ return definitions.value(definitionName);
+ } else {
+ error = QContactManager::DoesNotExistError;
+ return QContactDetailDefinition();
+ }
+}
+
+/*!
+ Persists the given definition \a def in the database, which is valid for contacts whose type is the given \a contactType.
+
+ Returns true if the definition was saved successfully, and otherwise returns false.
+
+ The backend must emit the appropriate signals to inform clients of changes
+ to the database resulting from this operation.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error& error)
+{
+ Q_UNUSED(def);
+ Q_UNUSED(contactType);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Removes the definition identified by the given \a definitionName from the database, where it was valid for contacts whose type was the given \a contactType.
+
+ Returns true if the definition was removed successfully, otherwise returns false.
+
+ The backend must emit the appropriate signals to inform clients of changes
+ to the database resulting from this operation.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+ */
+bool QContactManagerEngine::removeDetailDefinition(const QString& definitionName, const QString& contactType, QContactManager::Error& error)
+{
+ Q_UNUSED(definitionName);
+ Q_UNUSED(contactType);
+ error = QContactManager::NotSupportedError;
+ return false;
+}
+
+/*!
+ Sets the access constraints of \a detail to the supplied \a constraints.
+
+ This function is provided to allow engine implementations to report the
+ access constraints of retrieved details, without generally allowing the
+ access constraints to be modified after retrieval.
+
+ Application code should not call this function, since validation of the
+ detail will happen in the engine in any case.
+ */
+void QContactManagerEngine::setDetailAccessConstraints(QContactDetail *detail, QContactDetail::AccessConstraints constraints) const
+{
+ if (detail) {
+ QContactDetailPrivate::setAccessConstraints(detail, constraints);
+ }
+}
+
+/*!
+ Adds the list of contacts given by \a contacts list to the database.
+ Returns true if the contacts were saved successfully, otherwise false.
+
+ The manager might populate \a errorMap (the map of indices of the \a contacts list to
+ the error which occurred when saving the contact at that index) for
+ every index for which the contact could not be saved, if it is able.
+ The \l QContactManager::error() function will only return \c QContactManager::NoError
+ if all contacts were saved successfully.
+
+ For each newly saved contact that was successful, the id of the contact
+ in the \a contacts list will be updated with the new value. If a failure occurs
+ when saving a new contact, the id will be cleared.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+
+ \sa QContactManager::saveContact()
+ */
+bool QContactManagerEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error)
+{
+ if(errorMap) {
+ errorMap->clear();
+ }
+
+ if (!contacts) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ QContactManager::Error functionError = QContactManager::NoError;
+ for (int i = 0; i < contacts->count(); i++) {
+ QContact current = contacts->at(i);
+ if (!saveContact(¤t, error)) {
+ functionError = error;
+ if (errorMap) {
+ errorMap->insert(i, functionError);
+ }
+ } else {
+ (*contacts)[i] = current;
+ }
+ }
+
+ error = functionError;
+ return (functionError == QContactManager::NoError);
+}
+
+/*!
+ Remove every contact whose id is contained in the list of contacts ids
+ \a contactIds. Returns true if all contacts were removed successfully,
+ otherwise false.
+
+ The manager might populate \a errorMap (the map of indices of the \a contactIds list to
+ the error which occurred when saving the contact at that index) for every
+ index for which the contact could not be removed, if it is able.
+ The \l QContactManager::error() function will
+ only return \c QContactManager::NoError if all contacts were removed
+ successfully.
+
+ For each contact that was removed succesfully, the corresponding
+ id in the \a contactIds list will be retained but set to zero. The id of contacts
+ that were not successfully removed will be left alone.
+
+ Any contact that was removed successfully will have the relationships
+ in which it was involved removed also.
+
+ Any errors encountered during this operation should be stored to
+ \a error.
+
+ \sa QContactManager::removeContact()
+ */
+bool QContactManagerEngine::removeContacts(QList<QContactLocalId>* contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error)
+{
+ if(errorMap) {
+ errorMap->clear();
+ }
+
+ if (!contactIds) {
+ error = QContactManager::BadArgumentError;
+ return false;
+ }
+
+ QContactManager::Error functionError = QContactManager::NoError;
+ for (int i = 0; i < contactIds->count(); i++) {
+ QContactLocalId current = contactIds->at(i);
+ if (!removeContact(current, error)) {
+ functionError = error;
+ if (errorMap) {
+ errorMap->insert(i, functionError);
+ }
+ } else {
+ (*contactIds)[i] = 0;
+ }
+ }
+
+ error = functionError;
+ return (functionError == QContactManager::NoError);
+}
+
+/*!
+ Compares \a first against \a second. If the types are
+ strings (QVariant::String), the \a sensitivity argument controls
+ case sensitivity when comparing.
+
+ Returns:
+ <0 if \a first is less than \a second
+ 0 if \a first is equal to \a second
+ >0 if \a first is greater than \a second.
+
+ The results are undefined if the variants are different types, or
+ cannot be compared.
+ */
+int QContactManagerEngine::compareVariant(const QVariant& first, const QVariant& second, Qt::CaseSensitivity sensitivity)
+{
+ switch(first.type()) {
+ case QVariant::Int:
+ return first.toInt() - second.toInt();
+
+ case QVariant::LongLong:
+ return first.toLongLong() - second.toLongLong();
+
+ case QVariant::Bool:
+ case QVariant::Char:
+ case QVariant::UInt:
+ return first.toUInt() - second.toUInt();
+
+ case QVariant::ULongLong:
+ return first.toULongLong() - second.toULongLong();
+
+ case QVariant::String:
+ return first.toString().compare(second.toString(), sensitivity);
+
+ case QVariant::Double:
+ {
+ const double a = first.toDouble();
+ const double b = second.toDouble();
+ return (a < b) ? -1 : ((a == b) ? 0 : 1);
+ }
+
+ case QVariant::DateTime:
+ {
+ const QDateTime a = first.toDateTime();
+ const QDateTime b = second.toDateTime();
+ return (a < b) ? -1 : ((a == b) ? 0 : 1);
+ }
+
+ case QVariant::Date:
+ return first.toDate().toJulianDay() - second.toDate().toJulianDay();
+
+ case QVariant::Time:
+ {
+ const QTime a = first.toTime();
+ const QTime b = second.toTime();
+ return (a < b) ? -1 : ((a == b) ? 0 : 1);
+ }
+
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns true if the supplied contact \a contact matches the supplied filter \a filter.
+
+ This function will test each condition in the filter, possibly recursing.
+ */
+bool QContactManagerEngine::testFilter(const QContactFilter &filter, const QContact &contact)
+{
+ switch(filter.type()) {
+ case QContactFilter::InvalidFilter:
+ return false;
+
+ case QContactFilter::DefaultFilter:
+ return true;
+
+ case QContactFilter::LocalIdFilter:
+ {
+ const QContactLocalIdFilter idf(filter);
+ if (idf.ids().contains(contact.id().localId()))
+ return true;
+ }
+ // Fall through to end
+ break;
+
+ case QContactFilter::ContactDetailFilter:
+ {
+ const QContactDetailFilter cdf(filter);
+ if (cdf.detailDefinitionName().isEmpty())
+ return false;
+
+ /* See if this contact has one of these details in it */
+ const QList<QContactDetail>& details = contact.details(cdf.detailDefinitionName());
+
+ if (details.count() == 0)
+ return false; /* can't match */
+
+ /* See if we need to check the values */
+ if (cdf.detailFieldName().isEmpty())
+ return true; /* just testing for the presence of a detail of the specified definition */
+
+ /* Now figure out what tests we are doing */
+ const bool valueTest = cdf.value().isValid();
+ const bool presenceTest = !valueTest;
+
+ /* See if we need to test any values at all */
+ if (presenceTest) {
+ for(int j=0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+
+ /* Check that the field is present and has a non-empty value */
+ if (detail.variantValues().contains(cdf.detailFieldName()) && !detail.value(cdf.detailFieldName()).isEmpty())
+ return true;
+ }
+ return false;
+ }
+
+ /* Case sensitivity, for those parts that use it */
+ Qt::CaseSensitivity cs = (cdf.matchFlags() & QContactFilter::MatchCaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ /* See what flags are requested, since we're looking at a value */
+ if (cdf.matchFlags() & (QContactFilter::MatchEndsWith | QContactFilter::MatchStartsWith | QContactFilter::MatchContains | QContactFilter::MatchFixedString)) {
+ /* We're strictly doing string comparisons here */
+ bool matchStarts = (cdf.matchFlags() & 7) == QContactFilter::MatchStartsWith;
+ bool matchEnds = (cdf.matchFlags() & 7) == QContactFilter::MatchEndsWith;
+ bool matchContains = (cdf.matchFlags() & 7) == QContactFilter::MatchContains;
+
+ /* Value equality test */
+ for(int j=0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+ const QString& var = detail.value(cdf.detailFieldName());
+ const QString& needle = cdf.value().toString();
+ if (matchStarts && var.startsWith(needle, cs))
+ return true;
+ if (matchEnds && var.endsWith(needle, cs))
+ return true;
+ if (matchContains && var.contains(needle, cs))
+ return true;
+ if (QString::compare(var, needle, cs) == 0)
+ return true;
+ }
+ return false;
+ } else {
+ /* Nope, testing the values as a variant */
+ /* Value equality test */
+ for(int j = 0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+ const QVariant& var = detail.variantValue(cdf.detailFieldName());
+ if (!var.isNull() && compareVariant(var, cdf.value(), cs) == 0)
+ return true;
+ }
+ }
+ }
+ break;
+
+ case QContactFilter::ContactDetailRangeFilter:
+ {
+ const QContactDetailRangeFilter cdf(filter);
+ if (cdf.detailDefinitionName().isEmpty())
+ return false; /* we do not know which field to check */
+
+ /* See if this contact has one of these details in it */
+ const QList<QContactDetail>& details = contact.details(cdf.detailDefinitionName());
+
+ if (details.count() == 0)
+ return false; /* can't match */
+
+ /* Check for a detail presence test */
+ if (cdf.detailFieldName().isEmpty())
+ return true;
+
+ /* See if this is a field presence test */
+ if (!cdf.minValue().isValid() && !cdf.maxValue().isValid()) {
+ for(int j=0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+ if (detail.variantValues().contains(cdf.detailFieldName()))
+ return true;
+ }
+ return false;
+ }
+
+ /* open or closed interval testing support */
+ const int minComp = cdf.rangeFlags() & QContactDetailRangeFilter::ExcludeLower ? 1 : 0;
+ const int maxComp = cdf.rangeFlags() & QContactDetailRangeFilter::IncludeUpper ? 1 : 0;
+
+ const bool testMin = cdf.minValue().isValid();
+ const bool testMax = cdf.maxValue().isValid();
+
+ /* At this point we know that at least of testMin & testMax is true */
+
+ /* Case sensitivity, for those parts that use it */
+ Qt::CaseSensitivity cs = (cdf.matchFlags() & QContactFilter::MatchCaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ /* See what flags are requested, since we're looking at a value */
+ if (cdf.matchFlags() & (QContactFilter::MatchEndsWith | QContactFilter::MatchStartsWith | QContactFilter::MatchContains | QContactFilter::MatchFixedString)) {
+ /* We're strictly doing string comparisons here */
+ //bool matchStarts = (cdf.matchFlags() & 7) == QContactFilter::MatchStartsWith;
+ bool matchEnds = (cdf.matchFlags() & 7) == QContactFilter::MatchEndsWith;
+ bool matchContains = (cdf.matchFlags() & 7) == QContactFilter::MatchContains;
+
+ /* Min/Max and contains do not make sense */
+ if (matchContains)
+ return false;
+
+ QString minVal = cdf.minValue().toString();
+ QString maxVal = cdf.maxValue().toString();
+
+ /* Starts with is the normal compare case, endsWith is a bit trickier */
+ for(int j=0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+ const QString& var = detail.value(cdf.detailFieldName());
+ if (!matchEnds) {
+ // MatchStarts or MatchFixedString
+ if (testMin && QString::compare(var, minVal, cs) < minComp)
+ continue;
+ if (testMax && QString::compare(var, maxVal, cs) >= maxComp)
+ continue;
+ return true;
+ } else {
+ /* Have to test the length of min & max */
+ // using refs means the parameter order is backwards, so negate the result of compare
+ if (testMin && -QString::compare(minVal, var.rightRef(minVal.length()), cs) < minComp)
+ continue;
+ if (testMax && -QString::compare(maxVal, var.rightRef(maxVal.length()), cs) >= maxComp)
+ continue;
+ return true;
+ }
+ }
+ // Fall through to end
+ } else {
+ /* Nope, testing the values as a variant */
+ for(int j=0; j < details.count(); j++) {
+ const QContactDetail& detail = details.at(j);
+ const QVariant& var = detail.variantValue(cdf.detailFieldName());
+
+ if (testMin && compareVariant(var, cdf.minValue(), cs) < minComp)
+ continue;
+ if (testMax && compareVariant(var, cdf.maxValue(), cs) >= maxComp)
+ continue;
+ return true;
+ }
+ // Fall through to end
+ }
+ }
+ break;
+
+ case QContactFilter::RelationshipFilter:
+ {
+ // matches any contact that plays the specified role in a relationship
+ // of the specified type with the specified other participant.
+ const QContactRelationshipFilter rf(filter);
+
+ // first, retrieve contact uris
+ QContactId contactUri = contact.id();
+ QContactId relatedContactId = rf.relatedContactId();
+
+ // get the relationships in which this contact is involved.
+ QList<QContactRelationship> allRelationships;
+ allRelationships = contact.relationships();
+
+// simplify the comparison of two contact id's depending on their fields.
+#define CONTACT_IDS_MATCH(specific, other) \
+ ((specific == QContactId()) \
+ || (specific.managerUri().isEmpty() && specific.localId() == other.localId()) \
+ || (specific.managerUri() == other.managerUri() && specific.localId() == QContactLocalId(0)) \
+ || (specific.managerUri() == other.managerUri() && specific.localId() == other.localId()))
+
+ // now check to see if we have a match.
+ foreach (const QContactRelationship& rel, allRelationships) {
+ // perform the matching.
+ if (rf.relatedContactRole() == QContactRelationshipFilter::Second) { // this is the role of the related contact; ie, to match, contact.id() must be the first in the relationship.
+ if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType())
+ && CONTACT_IDS_MATCH(rel.first(), contact.id()) && CONTACT_IDS_MATCH(relatedContactId, rel.second())) {
+ return true;
+ }
+ } else if (rf.relatedContactRole() == QContactRelationshipFilter::First) { // this is the role of the related contact; ie, to match, contact.id() must be the second in the relationship.
+ if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType())
+ && CONTACT_IDS_MATCH(rel.second(), contact.id()) && CONTACT_IDS_MATCH(relatedContactId, rel.first())) {
+ return true;
+ }
+ } else { // QContactRelationshipFilter::Either
+ if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType())
+ && ((CONTACT_IDS_MATCH(relatedContactId, rel.first()) && !CONTACT_IDS_MATCH(contactUri, relatedContactId)) || (CONTACT_IDS_MATCH(relatedContactId, rel.second()) && !CONTACT_IDS_MATCH(contactUri, relatedContactId)))) {
+ return true;
+ }
+ }
+ }
+
+ // if not found by now, it doesn't match the filter.
+ return false;
+ }
+ //break; // unreachable.
+
+ case QContactFilter::ChangeLogFilter:
+ {
+ QContactChangeLogFilter ccf(filter);
+
+ // See what we can do...
+ QContactTimestamp ts = contact.detail(QContactTimestamp::DefinitionName);
+
+ // See if timestamps are even supported
+ if (ts.isEmpty())
+ break;
+
+ if (ccf.eventType() == QContactChangeLogFilter::EventAdded)
+ return ccf.since() <= ts.created();
+ if (ccf.eventType() == QContactChangeLogFilter::EventChanged)
+ return ccf.since() <= ts.lastModified();
+
+ // You can't emulate a removed..
+ // Fall through to end
+ }
+ break;
+
+ case QContactFilter::ActionFilter:
+ {
+ // Find any matching actions, and do a union filter on their filter objects
+ QContactActionFilter af(filter);
+ QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion());
+
+ // There's a small wrinkle if there's a value specified in the action filter
+ // we have to adjust any contained QContactDetailFilters to have that value
+ // or test if a QContactDetailRangeFilter contains this value already
+ for (int j = 0; j < descriptors.count(); j++) {
+ QContactAction* action = QContactAction::action(descriptors.at(j));
+
+ // Action filters are not allowed to return action filters, at all
+ // it's too annoying to check for recursion
+ QContactFilter d = action->contactFilter(af.value());
+ delete action; // clean up.
+ if (!validateActionFilter(d))
+ return false;
+
+ // Check for values etc...
+ if (testFilter(d, contact))
+ return true;
+ }
+ // Fall through to end
+ }
+ break;
+
+ case QContactFilter::IntersectionFilter:
+ {
+ /* XXX In theory we could reorder the terms to put the native tests first */
+ const QContactIntersectionFilter bf(filter);
+ const QList<QContactFilter>& terms = bf.filters();
+ if (terms.count() > 0) {
+ for(int j = 0; j < terms.count(); j++) {
+ if (!testFilter(terms.at(j), contact)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // Fall through to end
+ }
+ break;
+
+ case QContactFilter::UnionFilter:
+ {
+ /* XXX In theory we could reorder the terms to put the native tests first */
+ const QContactUnionFilter bf(filter);
+ const QList<QContactFilter>& terms = bf.filters();
+ if (terms.count() > 0) {
+ for(int j = 0; j < terms.count(); j++) {
+ if (testFilter(terms.at(j), contact)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Fall through to end
+ }
+ break;
+ }
+ return false;
+}
+
+/*!
+ Given a QContactFilter \a filter retrieved from a QContactAction,
+ check that it is valid and cannot cause infinite recursion.
+
+ In particular, a filter from a QContactAction cannot contain
+ any instances of a QContactActionFilter.
+
+ Returns true if \a filter seems ok, or false otherwise.
+ */
+
+bool QContactManagerEngine::validateActionFilter(const QContactFilter& filter)
+{
+ QList<QContactFilter> toVerify;
+ toVerify << filter;
+
+ while(toVerify.count() > 0) {
+ QContactFilter f = toVerify.takeFirst();
+ if (f.type() == QContactFilter::ActionFilter)
+ return false;
+ if (f.type() == QContactFilter::IntersectionFilter)
+ toVerify.append(QContactIntersectionFilter(f).filters());
+ if (f.type() == QContactFilter::UnionFilter)
+ toVerify.append(QContactUnionFilter(f).filters());
+ }
+
+ return true;
+}
+
+/*!
+ Sets the cached relationships in the given \a contact to \a relationships
+ */
+void QContactManagerEngine::setContactRelationships(QContact* contact, const QList<QContactRelationship>& relationships)
+{
+ contact->d->m_relationshipsCache = relationships;
+ contact->d->m_reorderedRelationshipsCache = relationships;
+}
+
+
+/*!
+ Compares two contacts (\a a and \a b) using the given list of \a sortOrders. Returns a negative number if \a a should appear
+ before \a b according to the sort order, a positive number if \a a should appear after \a b according to the sort order,
+ and zero if the two are unable to be sorted.
+ */
+int QContactManagerEngine::compareContact(const QContact& a, const QContact& b, const QList<QContactSortOrder>& sortOrders)
+{
+ QList<QContactSortOrder> copy = sortOrders;
+ while (copy.size()) {
+ // retrieve the next sort order in the list
+ QContactSortOrder sortOrder = copy.takeFirst();
+ if (!sortOrder.isValid())
+ break;
+
+ // obtain the values which this sort order concerns
+ const QVariant& aVal = a.detail(sortOrder.detailDefinitionName()).variantValue(sortOrder.detailFieldName());
+ const QVariant& bVal = b.detail(sortOrder.detailDefinitionName()).variantValue(sortOrder.detailFieldName());
+
+ // early exit error checking
+ if (aVal.isNull())
+ return (sortOrder.blankPolicy() == QContactSortOrder::BlanksFirst ? -1 : 1);
+ if (bVal.isNull())
+ return (sortOrder.blankPolicy() == QContactSortOrder::BlanksFirst ? 1 : -1);
+
+ // real comparison
+ int comparison = compareVariant(aVal, bVal, sortOrder.caseSensitivity()) * (sortOrder.direction() == Qt::AscendingOrder ? 1 : -1);
+ if (comparison == 0)
+ continue;
+ return comparison;
+ }
+
+ return 0; // or according to id? return (a.id() < b.id() ? -1 : 1);
+}
+
+
+/*!
+ Performs insertion sort of the contact \a toAdd into the \a sorted list, according to the provided \a sortOrders list.
+ The first QContactSortOrder in the list has the highest priority; if the contact \a toAdd is deemed equal to another
+ in the \a sorted list, the second QContactSortOrder in the list is used (and so on until either the contact is inserted
+ or there are no more sort order objects in the list).
+ */
+void QContactManagerEngine::addSorted(QList<QContact>* sorted, const QContact& toAdd, const QList<QContactSortOrder>& sortOrders)
+{
+ for (int i = 0; i < sorted->size(); i++) {
+ // check to see if the new contact should be inserted here
+ int comparison = compareContact(sorted->at(i), toAdd, sortOrders);
+ if (comparison > 0) {
+ sorted->insert(i, toAdd);
+ return;
+ }
+ }
+
+ // hasn't been inserted yet? append to the list.
+ sorted->append(toAdd);
+}
+
+/*! Sorts the given list of contacts \a cs according to the provided \a sortOrders */
+QList<QContactLocalId> QContactManagerEngine::sortContacts(const QList<QContact>& cs, const QList<QContactSortOrder>& sortOrders)
+{
+ QList<QContactLocalId> sortedIds;
+ QList<QContact> sortedContacts;
+ if (!sortOrders.isEmpty()) {
+ foreach (const QContact& c, cs) {
+ QContactManagerEngine::addSorted(&sortedContacts, c, sortOrders);
+ }
+
+ foreach(const QContact c, sortedContacts) {
+ sortedIds.append(c.localId());
+ }
+ } else {
+ foreach(const QContact c, cs) {
+ sortedIds.append(c.localId());
+ }
+ }
+ return sortedIds;
+}
+
+/*!
+ Notifies the manager engine that the given request \a req has been destroyed
+ */
+void QContactManagerEngine::requestDestroyed(QContactAbstractRequest* req)
+{
+ Q_UNUSED(req);
+}
+
+/*!
+ Asks the manager engine to begin the given request \a req which
+ is currently in a (re)startable state.
+ Returns true if the request was started successfully, else returns false.
+
+ \sa QContactAbstractRequest::start()
+ */
+bool QContactManagerEngine::startRequest(QContactAbstractRequest* req)
+{
+ Q_UNUSED(req);
+ return false;
+}
+
+/*!
+ Asks the manager engine to cancel the given request \a req which was
+ previously started and is currently in a cancellable state.
+ Returns true if cancellation of the request was started successfully,
+ otherwise returns false.
+
+ \sa startRequest(), QContactAbstractRequest::cancel()
+ */
+bool QContactManagerEngine::cancelRequest(QContactAbstractRequest* req)
+{
+ Q_UNUSED(req);
+ return false;
+}
+
+/*!
+ Blocks until the manager engine has completed the given request \a req
+ which was previously started, or until \a msecs milliseconds have passed.
+ Returns true if the request was completed, and false if the request was not in the
+ \c QContactAbstractRequest::Active state or no progress could be reported.
+
+ \sa startRequest()
+ */
+bool QContactManagerEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs)
+{
+ Q_UNUSED(req);
+ Q_UNUSED(msecs);
+ return false;
+}
+
+/*!
+ Updates the given asynchronous request \a req by setting the new \a state
+ of the request. It then causes the stateChanged() signal to be emitted by the request.
+ */
+void QContactManagerEngine::updateRequestState(QContactAbstractRequest* req, QContactAbstractRequest::State state)
+{
+ req->d_ptr->m_state = state;
+ emit req->stateChanged(state);
+}
+
+/*!
+ Updates the given QContactLocalIdFetchRequest \a req with the latest results \a result, and operation error \a error.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateContactLocalIdFetchRequest(QContactLocalIdFetchRequest* req, const QList<QContactLocalId>& result, QContactManager::Error error)
+{
+ QContactLocalIdFetchRequestPrivate* rd = static_cast<QContactLocalIdFetchRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_ids = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactFetchRequest \a req with the latest results \a result, and operation error \a error.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateContactFetchRequest(QContactFetchRequest* req, const QList<QContact>& result, QContactManager::Error error)
+{
+ QContactFetchRequestPrivate* rd = static_cast<QContactFetchRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_contacts = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateContactRemoveRequest(QContactRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactRemoveRequestPrivate* rd = static_cast<QContactRemoveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateContactSaveRequest(QContactSaveRequest* req, const QList<QContact>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactSaveRequestPrivate* rd = static_cast<QContactSaveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ rd->m_contacts = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactDetailDefinitionSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateDefinitionSaveRequest(QContactDetailDefinitionSaveRequest* req, const QList<QContactDetailDefinition>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactDetailDefinitionSaveRequestPrivate* rd = static_cast<QContactDetailDefinitionSaveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ rd->m_definitions = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactDetailDefinitionRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateDefinitionRemoveRequest(QContactDetailDefinitionRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactDetailDefinitionRemoveRequestPrivate* rd = static_cast<QContactDetailDefinitionRemoveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactDetailDefinitionFetchRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateDefinitionFetchRequest(QContactDetailDefinitionFetchRequest* req, const QMap<QString, QContactDetailDefinition>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactDetailDefinitionFetchRequestPrivate* rd = static_cast<QContactDetailDefinitionFetchRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ rd->m_definitions = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactRelationshipSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateRelationshipSaveRequest(QContactRelationshipSaveRequest* req, const QList<QContactRelationship>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactRelationshipSaveRequestPrivate* rd = static_cast<QContactRelationshipSaveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ rd->m_relationships = result;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactRelationshipRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateRelationshipRemoveRequest(QContactRelationshipRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap)
+{
+ QContactRelationshipRemoveRequestPrivate* rd = static_cast<QContactRelationshipRemoveRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_errors = errorMap;
+ emit req->resultsAvailable();
+}
+
+/*!
+ Updates the given QContactRelationshipFetchRequest \a req with the latest results \a result, and operation error \a error.
+ It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress.
+ */
+void QContactManagerEngine::updateRelationshipFetchRequest(QContactRelationshipFetchRequest* req, const QList<QContactRelationship>& result, QContactManager::Error error)
+{
+ QContactRelationshipFetchRequestPrivate* rd = static_cast<QContactRelationshipFetchRequestPrivate*>(req->d_ptr);
+ req->d_ptr->m_error = error;
+ rd->m_relationships = result;
+ emit req->resultsAvailable();
+}
+
+#include "moc_qcontactmanagerengine.cpp"
+
+QTM_END_NAMESPACE