src/contacts/qcontactmanager.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qcontactmanager.h"
       
    43 
       
    44 #include "qcontact_p.h"
       
    45 #include "qcontactfilter.h"
       
    46 #include "qcontactdetaildefinition.h"
       
    47 #include "qcontactmanager_p.h"
       
    48 #include "qcontactfetchhint.h"
       
    49 
       
    50 #include <QSharedData>
       
    51 #include <QPair>
       
    52 #include <QSet>
       
    53 
       
    54 QTM_BEGIN_NAMESPACE
       
    55 /*!
       
    56   \class QContactManager
       
    57   \brief The QContactManager class provides an interface which allows clients with access to contact information stored in a particular backend.
       
    58   \ingroup contacts-main
       
    59  
       
    60   This class provides an abstraction of a datastore or aggregation of datastores which contains contact information.
       
    61   It provides methods to retrieve and manipulate contact information, contact relationship information, and
       
    62   supported schema definitions.  It also provides metadata and error information reporting.
       
    63 
       
    64   The functions provided by QContactManager are purely synchronous; to access the same functionality in an
       
    65   asynchronous manner, clients should use the use-case-specific classes derived from QContactAbstractRequest.
       
    66 
       
    67   Some functionality provided by QContactManager directly is not accessible using the asynchronous API; see
       
    68   the \l{Contacts Synchronous API}{synchronous} and \l{Contacts Asynchronous API}{asynchronous} API
       
    69   information from the \l{Contacts}{contacts module} API documentation.
       
    70  */
       
    71 
       
    72 /*!
       
    73   \fn QContactManager::dataChanged()
       
    74   This signal is emitted by the manager if its internal state changes, and it is unable to determine the changes
       
    75   which occurred, or if the manager considers the changes to be radical enough to require clients to reload all data.
       
    76   If this signal is emitted, no other signals will be emitted for the associated changes.
       
    77  */
       
    78 
       
    79 /*!
       
    80   \fn QContactManager::contactsAdded(const QList<QContactLocalId>& contactIds)
       
    81   This signal is emitted at some point once the contacts identified by \a contactIds have been added to a datastore managed by this manager.
       
    82   This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
       
    83  */
       
    84 
       
    85 /*!
       
    86   \fn QContactManager::contactsChanged(const QList<QContactLocalId>& contactIds)
       
    87   This signal is emitted at some point once the contacts identified by \a contactIds have been modified in a datastore managed by this manager.
       
    88   This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
       
    89  */
       
    90 
       
    91 /*!
       
    92   \fn QContactManager::contactsRemoved(const QList<QContactLocalId>& contactIds)
       
    93   This signal is emitted at some point once the contacts identified by \a contactIds have been removed from a datastore managed by this manager.
       
    94   This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
       
    95  */
       
    96 
       
    97 /*!
       
    98   \fn QContactManager::relationshipsAdded(const QList<QContactLocalId>& affectedContactIds)
       
    99   This signal is emitted at some point after relationships have been added to the manager which involve the contacts identified by \a affectedContactIds.
       
   100   This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
       
   101  */
       
   102 
       
   103 /*!
       
   104   \fn QContactManager::relationshipsRemoved(const QList<QContactLocalId>& affectedContactIds)
       
   105   This signal is emitted at some point after relationships have eben removed from the manager which involve the contacts identified by \a affectedContactIds.
       
   106   This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
       
   107  */
       
   108 
       
   109 /*!
       
   110   \fn QContactManager::selfContactIdChanged(const QContactLocalId& oldId, const QContactLocalId& newId)
       
   111   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.
       
   112   If the \a newId is the invalid, zero id, then the self contact was deleted or no self contact exists.
       
   113   This signal must not be emitted if the dataChanged() signal was previously emitted for this change.
       
   114  */
       
   115 
       
   116 
       
   117 
       
   118 #define makestr(x) (#x)
       
   119 #define makename(x) makestr(x)
       
   120 
       
   121 /*!
       
   122     Returns a list of available manager ids that can be used when constructing
       
   123     a QContactManager.  If an empty id is specified to the constructor, the
       
   124     first value in this list will be used instead.
       
   125   */
       
   126 QStringList QContactManager::availableManagers()
       
   127 {
       
   128     QStringList ret;
       
   129     ret << QLatin1String("memory") << QLatin1String("invalid");
       
   130     QContactManagerData::loadFactories();
       
   131     ret.append(QContactManagerData::m_engines.keys());
       
   132 
       
   133     // now swizzle the default engine to pole position
       
   134 #if defined(Q_CONTACTS_DEFAULT_ENGINE)
       
   135     if (ret.removeAll(QLatin1String(makename(Q_CONTACTS_DEFAULT_ENGINE)))) {
       
   136         ret.prepend(QLatin1String(makename(Q_CONTACTS_DEFAULT_ENGINE)));
       
   137     }
       
   138 #endif
       
   139 
       
   140     return ret;
       
   141 }
       
   142 
       
   143 /*!
       
   144   Splits the given \a uri into the manager, store, and parameters that it describes, and places the information into the memory addressed by \a pManagerId and \a pParams respectively.  Returns true if \a uri could be split successfully, otherwise returns false
       
   145  */
       
   146 bool QContactManager::parseUri(const QString& uri, QString* pManagerId, QMap<QString, QString>* pParams)
       
   147 {
       
   148     // Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value>
       
   149     // 1) parameters are currently a qstringlist.. should they be a map?
       
   150     // 2) is the uri going to be escaped?  my guess would be "probably not"
       
   151     // 3) hence, do we assume that the prefix, managerid and storeid cannot contain `:'
       
   152     // 4) similarly, that neither keys nor values can contain `=' or `&'
       
   153 
       
   154     QStringList colonSplit = uri.split(QLatin1Char(':'));
       
   155     QString prefix = colonSplit.value(0);
       
   156 
       
   157     if (prefix != QLatin1String("qtcontacts"))
       
   158         return false;
       
   159 
       
   160     QString managerName = colonSplit.value(1);
       
   161 
       
   162     if (managerName.trimmed().isEmpty())
       
   163         return false;
       
   164 
       
   165     QString firstParts = prefix + QLatin1Char(':') + managerName + QLatin1Char(':');
       
   166     QString paramString = uri.mid(firstParts.length());
       
   167 
       
   168     QMap<QString, QString> outParams;
       
   169 
       
   170     // Now we have to decode each parameter
       
   171     if (!paramString.isEmpty()) {
       
   172         QStringList params = paramString.split(QRegExp(QLatin1String("&(?!(amp;|equ;))")), QString::KeepEmptyParts);
       
   173         // If we have an empty string for paramstring, we get one entry in params,
       
   174         // so skip that case.
       
   175         for(int i = 0; i < params.count(); i++) {
       
   176             /* This should be something like "foo&amp;bar&equ;=grob&amp;" */
       
   177             QStringList paramChunk = params.value(i).split(QLatin1String("="), QString::KeepEmptyParts);
       
   178 
       
   179             if (paramChunk.count() != 2)
       
   180                 return false;
       
   181 
       
   182             QString arg = paramChunk.value(0);
       
   183             QString param = paramChunk.value(1);
       
   184             arg.replace(QLatin1String("&equ;"), QLatin1String("="));
       
   185             arg.replace(QLatin1String("&amp;"), QLatin1String("&"));
       
   186             param.replace(QLatin1String("&equ;"), QLatin1String("="));
       
   187             param.replace(QLatin1String("&amp;"), QLatin1String("&"));
       
   188             if (arg.isEmpty())
       
   189                 return false;
       
   190             outParams.insert(arg, param);
       
   191         }
       
   192     }
       
   193 
       
   194     if (pParams)
       
   195         *pParams = outParams;
       
   196     if (pManagerId)
       
   197         *pManagerId = managerName;
       
   198     return true;
       
   199 }
       
   200 
       
   201 /*!
       
   202    Returns a URI that completely describes a manager implementation, datastore, and the parameters
       
   203    with which to instantiate the manager, from the given \a managerName, \a params and an optional
       
   204    \a implementationVersion.  This function is generally useful only if you intend to construct a
       
   205    manager with the \l fromUri() function, or wish to set the manager URI field in a QContactId
       
   206    manually (for synchronization or other purposes).  Most clients will not need to use this function. */
       
   207 QString QContactManager::buildUri(const QString& managerName, const QMap<QString, QString>& params, int implementationVersion) 
       
   208 {
       
   209     QString ret(QLatin1String("qtcontacts:%1:%2"));
       
   210     // we have to escape each param
       
   211     QStringList escapedParams;
       
   212     QStringList keys = params.keys();
       
   213     for (int i=0; i < keys.size(); i++) {
       
   214         QString key = keys.at(i);
       
   215         QString arg = params.value(key);
       
   216         arg = arg.replace(QLatin1Char('&'), QLatin1String("&amp;"));
       
   217         arg = arg.replace(QLatin1Char('='), QLatin1String("&equ;"));
       
   218         key = key.replace(QLatin1Char('&'), QLatin1String("&amp;"));
       
   219         key = key.replace(QLatin1Char('='), QLatin1String("&equ;"));
       
   220         key = key + QLatin1Char('=') + arg;
       
   221         escapedParams.append(key);
       
   222     }
       
   223 
       
   224     if (implementationVersion != -1) {
       
   225         QString versionString = QString(QLatin1String(QTCONTACTS_IMPLEMENTATION_VERSION_NAME));
       
   226         versionString += QString::fromAscii("=");
       
   227         versionString += QString::number(implementationVersion);
       
   228         escapedParams.append(versionString);
       
   229     }
       
   230 
       
   231     return ret.arg(managerName, escapedParams.join(QLatin1String("&")));
       
   232 }
       
   233 
       
   234 /*!
       
   235   Constructs a QContactManager whose implementation version, manager name and specific parameters
       
   236   are specified in the given \a managerUri, and whose parent object is \a parent.
       
   237  */
       
   238 QContactManager* QContactManager::fromUri(const QString& managerUri, QObject* parent)
       
   239 {
       
   240     if (managerUri.isEmpty()) {
       
   241         return new QContactManager(QString(), QMap<QString, QString>(), parent);
       
   242     } else {
       
   243         QString id;
       
   244         QMap<QString, QString> parameters;
       
   245         if (parseUri(managerUri, &id, &parameters)) {
       
   246             return new QContactManager(id, parameters, parent);
       
   247         } else {
       
   248             // invalid
       
   249             return new QContactManager(QLatin1String("invalid"), QMap<QString, QString>(), parent);
       
   250         }
       
   251     }
       
   252 }
       
   253 
       
   254 /*!
       
   255   Constructs a QContactManager whose parent QObject is \a parent.
       
   256   The default implementation for the platform will be created.
       
   257  */
       
   258 QContactManager::QContactManager(QObject* parent)
       
   259     : QObject(parent)
       
   260 {
       
   261     createEngine(QString(), QMap<QString, QString>());
       
   262 }
       
   263 
       
   264 /*!
       
   265   Constructs a QContactManager whose implementation is identified by \a managerName with the given \a parameters.
       
   266 
       
   267   The \a parent QObject will be used as the parent of this QContactManager.
       
   268 
       
   269   If an empty \a managerName is specified, the default implementation for the platform will
       
   270   be used.
       
   271  */
       
   272 QContactManager::QContactManager(const QString& managerName, const QMap<QString, QString>& parameters, QObject* parent)
       
   273     : QObject(parent),
       
   274     d(new QContactManagerData)
       
   275 {
       
   276     createEngine(managerName, parameters); 
       
   277 } 
       
   278 
       
   279 void QContactManager::createEngine(const QString& managerName, const QMap<QString, QString>& parameters) 
       
   280 { 
       
   281     d->createEngine(managerName, parameters);
       
   282     connect(d->m_engine, SIGNAL(dataChanged()), this, SIGNAL(dataChanged()));
       
   283     connect(d->m_engine, SIGNAL(contactsAdded(QList<QContactLocalId>)), this, SIGNAL(contactsAdded(QList<QContactLocalId>)));
       
   284     connect(d->m_engine, SIGNAL(contactsChanged(QList<QContactLocalId>)), this, SIGNAL(contactsChanged(QList<QContactLocalId>)));
       
   285     connect(d->m_engine, SIGNAL(contactsRemoved(QList<QContactLocalId>)), this, SIGNAL(contactsRemoved(QList<QContactLocalId>)));
       
   286     connect(d->m_engine, SIGNAL(relationshipsAdded(QList<QContactLocalId>)), this, SIGNAL(relationshipsAdded(QList<QContactLocalId>)));
       
   287     connect(d->m_engine, SIGNAL(relationshipsRemoved(QList<QContactLocalId>)), this, SIGNAL(relationshipsRemoved(QList<QContactLocalId>)));
       
   288     connect(d->m_engine, SIGNAL(selfContactIdChanged(QContactLocalId,QContactLocalId)), this, SIGNAL(selfContactIdChanged(QContactLocalId,QContactLocalId)));
       
   289 }
       
   290 
       
   291 /*!
       
   292   Constructs a QContactManager whose backend has the name \a managerName and version \a implementationVersion, where the manager
       
   293   is constructed with the provided \a parameters.
       
   294 
       
   295   The \a parent QObject will be used as the parent of this QContactManager.
       
   296 
       
   297   If an empty \a managerName is specified, the default implementation for the platform will be instantiated.
       
   298   If the specified implementation version is not available, the manager with the name \a managerName with the default implementation version is instantiated.
       
   299  */
       
   300 QContactManager::QContactManager(const QString& managerName, int implementationVersion, const QMap<QString, QString>& parameters, QObject* parent) 
       
   301     : QObject(parent), 
       
   302     d(new QContactManagerData) 
       
   303 { 
       
   304     QMap<QString, QString> params = parameters; 
       
   305     params[QString(QLatin1String(QTCONTACTS_IMPLEMENTATION_VERSION_NAME))] = QString::number(implementationVersion);
       
   306     createEngine(managerName, params); 
       
   307 } 
       
   308  
       
   309 /*! Frees the memory used by the QContactManager */
       
   310 QContactManager::~QContactManager()
       
   311 {
       
   312     delete d;
       
   313 }
       
   314 
       
   315 /*!
       
   316   \enum QContactManager::Error
       
   317 
       
   318   This enum specifies an error that occurred during the most recent operation:
       
   319 
       
   320   \value NoError The most recent operation was successful
       
   321   \value DoesNotExistError The most recent operation failed because the requested contact or detail definition does not exist
       
   322   \value AlreadyExistsError The most recent operation failed because the specified contact or detail definition already exists
       
   323   \value InvalidDetailError The most recent operation failed because the specified contact contains details which do not conform to their definition
       
   324   \value InvalidRelationshipError The most recent operation failed because the specified relationship is circular or references an invalid local contact
       
   325   \value InvalidContactTypeError The most recent operation failed because the contact type specified was not valid for the operation
       
   326   \value LockedError The most recent operation failed because the datastore specified is currently locked
       
   327   \value DetailAccessError The most recent operation failed because a detail was modified or removed and its access method does not allow that
       
   328   \value PermissionsError The most recent operation failed because the caller does not have permission to perform the operation
       
   329   \value OutOfMemoryError The most recent operation failed due to running out of memory
       
   330   \value VersionMismatchError The most recent operation failed because the backend of the manager is not of the required version
       
   331   \value LimitReachedError The most recent operation failed because the limit for that type of object has been reached
       
   332   \value NotSupportedError The most recent operation failed because the requested operation is not supported in the specified store
       
   333   \value BadArgumentError The most recent operation failed because one or more of the parameters to the operation were invalid
       
   334   \value UnspecifiedError The most recent operation failed for an undocumented reason
       
   335  */
       
   336 
       
   337 /*! Return the error code of the most recent operation */
       
   338 QContactManager::Error QContactManager::error() const
       
   339 {
       
   340     return d->m_error;
       
   341 }
       
   342 
       
   343 /*!
       
   344   Return the list of contact ids, sorted according to the given list of \a sortOrders
       
   345  */
       
   346 QList<QContactLocalId> QContactManager::contactIds(const QList<QContactSortOrder>& sortOrders) const
       
   347 {
       
   348     d->m_error = QContactManager::NoError;
       
   349     return d->m_engine->contactIds(QContactFilter(), sortOrders, &d->m_error);
       
   350 }
       
   351 
       
   352 /*!
       
   353   Returns a list of contact ids that match the given \a filter, sorted according to the given list of \a sortOrders.
       
   354   Depending on the backend, this filtering operation may involve retrieving all the contacts.
       
   355  */
       
   356 QList<QContactLocalId> QContactManager::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders) const
       
   357 {
       
   358     d->m_error = QContactManager::NoError;
       
   359     return d->m_engine->contactIds(filter, sortOrders, &d->m_error);
       
   360 }
       
   361 
       
   362 /*!
       
   363   Returns the list of contacts stored in the manager sorted according to the given list of \a sortOrders.
       
   364 
       
   365   The \a fetchHint parameter describes the optimization hints that a manager may take.
       
   366   If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences
       
   367   in the matching contacts will be returned.  A client should not make changes to a contact which has
       
   368   been retrieved using a fetch hint other than the default fetch hint.  Doing so will result in information
       
   369   loss when saving the contact back to the manager (as the "new" restricted contact will
       
   370   replace the previously saved contact in the backend).
       
   371 
       
   372   \sa QContactFetchHint
       
   373  */
       
   374 QList<QContact> QContactManager::contacts(const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint) const
       
   375 {
       
   376     d->m_error = QContactManager::NoError;
       
   377     return d->m_engine->contacts(QContactFilter(), sortOrders, fetchHint, &d->m_error);
       
   378 }
       
   379 
       
   380 /*!
       
   381   Returns a list of contacts that match the given \a filter, sorted according to the given list of \a sortOrders.
       
   382 
       
   383   Depending on the manager implementation, this filtering operation might be slow and involve retrieving all the
       
   384   contacts and testing them against the supplied filter - see the \l isFilterSupported() function.
       
   385 
       
   386   The \a fetchHint parameter describes the optimization hints that a manager may take.
       
   387   If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences
       
   388   in the matching contacts will be returned.  A client should not make changes to a contact which has
       
   389   been retrieved using a fetch hint other than the default fetch hint.  Doing so will result in information
       
   390   loss when saving the contact back to the manager (as the "new" restricted contact will
       
   391   replace the previously saved contact in the backend).
       
   392 
       
   393   \sa QContactFetchHint
       
   394  */
       
   395 QList<QContact> QContactManager::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint) const
       
   396 {
       
   397     d->m_error = QContactManager::NoError;
       
   398     return d->m_engine->contacts(filter, sortOrders, fetchHint, &d->m_error);
       
   399 }
       
   400 
       
   401 /*!
       
   402   Returns the contact in the database identified by \a contactId.
       
   403 
       
   404   If the contact does not exist, an empty, default constructed QContact will be returned,
       
   405   and the error returned by \l error() will be \c QContactManager::DoesNotExistError.
       
   406 
       
   407   The \a fetchHint parameter describes the optimization hints that a manager may take.
       
   408   If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences
       
   409   in the matching contact will be returned.  A client should not make changes to a contact which has
       
   410   been retrieved using a fetch hint other than the default fetch hint.  Doing so will result in information
       
   411   loss when saving the contact back to the manager (as the "new" restricted contact will
       
   412   replace the previously saved contact in the backend).
       
   413 
       
   414   \sa QContactFetchHint
       
   415  */
       
   416 QContact QContactManager::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint) const
       
   417 {
       
   418     d->m_error = QContactManager::NoError;
       
   419     return d->m_engine->contact(contactId, fetchHint, &d->m_error);
       
   420 }
       
   421 
       
   422 /*!
       
   423   Adds the given \a contact to the database if \a contact has a
       
   424   default-constructed id, or an id with the manager URI set to the URI of
       
   425   this manager and a local id of zero.
       
   426 
       
   427   If the manager URI of the id of the \a contact is neither empty nor equal to the URI of
       
   428   this manager, or local id of the \a contact is non-zero but does not exist in the
       
   429   manager, the operation will fail and calling error() will return
       
   430   \c QContactManager::DoesNotExistError.
       
   431 
       
   432   Alternatively, the function will update the existing contact in the database if \a contact
       
   433   has a non-zero id and currently exists in the database.
       
   434 
       
   435   If the \a contact contains one or more details whose definitions have
       
   436   not yet been saved with the manager, the operation will fail and calling
       
   437   error() will return \c QContactManager::UnsupportedError.
       
   438 
       
   439   If the \a contact has had its relationships reordered, the manager
       
   440   will check to make sure that every relationship that the contact is currently
       
   441   involved in is included in the reordered list, and that no relationships which
       
   442   either do not involve the contact, or have not been saved in the manager are
       
   443   included in the list.  If these conditions are not met, the function will
       
   444   return \c false and calling error() will return
       
   445   \c QContactManager::InvalidRelationshipError.
       
   446 
       
   447   Returns false on failure, or true on
       
   448   success.  On successful save of a contact with an id of zero, its
       
   449   id will be set to a new, valid id with the manager URI set to the URI of
       
   450   this manager, and the local id set to a new, valid local id.
       
   451   The manager will automatically synthesize the display label of the contact when it is saved.
       
   452   The manager is not required to fetch updated details of the contact on save,
       
   453   and as such, clients should fetch a contact if they want the most up-to-date information
       
   454   by calling \l QContactManager::contact().
       
   455 
       
   456   \sa managerUri()
       
   457  */
       
   458 bool QContactManager::saveContact(QContact* contact)
       
   459 {
       
   460     if (contact) {
       
   461         d->m_error = QContactManager::NoError;
       
   462         return d->m_engine->saveContact(contact, &d->m_error);
       
   463     } else {
       
   464         d->m_error = QContactManager::BadArgumentError;
       
   465         return false;
       
   466     }
       
   467 }
       
   468 
       
   469 /*!
       
   470   Remove the contact identified by \a contactId from the database,
       
   471   and also removes any relationships in which the contact was involved.
       
   472   Returns true if the contact was removed successfully, otherwise
       
   473   returns false.
       
   474  */
       
   475 bool QContactManager::removeContact(const QContactLocalId& contactId)
       
   476 {
       
   477     d->m_error = QContactManager::NoError;
       
   478     return d->m_engine->removeContact(contactId, &d->m_error);
       
   479 }
       
   480 
       
   481 /*!
       
   482   Adds the list of contacts given by \a contacts list to the database.
       
   483   Returns true if the contacts were saved successfully, otherwise false.
       
   484 
       
   485   The manager might populate \a errorMap (the map of indices of the \a contacts list to
       
   486   the error which occurred when saving the contact at that index) for
       
   487   every index for which the contact could not be saved, if it is able.
       
   488   The \l QContactManager::error() function will only return \c QContactManager::NoError
       
   489   if all contacts were saved successfully.
       
   490 
       
   491   For each newly saved contact that was successful, the id of the contact
       
   492   in the \a contacts list will be updated with the new value.  If a failure occurs
       
   493   when saving a new contact, the id will be cleared.
       
   494 
       
   495   \sa QContactManager::saveContact()
       
   496  */
       
   497 bool QContactManager::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap)
       
   498 {
       
   499     if (errorMap)
       
   500         errorMap->clear();
       
   501     if (!contacts) {
       
   502         d->m_error =QContactManager::BadArgumentError;
       
   503         return false;
       
   504     }
       
   505 
       
   506     d->m_error = QContactManager::NoError;
       
   507     return d->m_engine->saveContacts(contacts, errorMap, &d->m_error);
       
   508 }
       
   509 
       
   510 /*!
       
   511   Remove every contact whose id is contained in the list of contacts ids
       
   512   \a contactIds.  Returns true if all contacts were removed successfully,
       
   513   otherwise false.
       
   514 
       
   515   Any contact that was removed successfully will have the relationships
       
   516   in which it was involved removed also.
       
   517 
       
   518   The manager might populate \a errorMap (the map of indices of the \a contactIds list to
       
   519   the error which occurred when saving the contact at that index) for every
       
   520   index for which the contact could not be removed, if it is able.
       
   521   The \l QContactManager::error() function will
       
   522   only return \c QContactManager::NoError if all contacts were removed
       
   523   successfully.
       
   524 
       
   525   If the given list of contact ids \a contactIds is empty, the function will return false
       
   526   and calling error() will return \c QContactManager::BadArgumentError.  If the list is non-empty
       
   527   and contains ids which do not identify a valid contact in the manager, the function will
       
   528   remove any contacts which are identified by ids in the \a contactIds list, insert
       
   529   \c QContactManager::DoesNotExist entries into the \a errorMap for the indices of invalid ids
       
   530   in the \a contactIds list, return false, and set the overall operation error to
       
   531   \c QContactManager::DoesNotExistError.
       
   532 
       
   533   \sa QContactManager::removeContact()
       
   534  */
       
   535 bool QContactManager::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap)
       
   536 {
       
   537     if (errorMap)
       
   538         errorMap->clear();
       
   539     if (contactIds.isEmpty()) {
       
   540         d->m_error = QContactManager::BadArgumentError;
       
   541         return false;
       
   542     }
       
   543 
       
   544     d->m_error = QContactManager::NoError;
       
   545     return d->m_engine->removeContacts(contactIds, errorMap, &d->m_error);
       
   546 }
       
   547 
       
   548 /*!
       
   549   Returns a pruned or modified version of the \a original contact which is valid and can be saved in the manager.
       
   550   The returned contact might have entire details removed or arbitrarily changed.  The cache of relationships
       
   551   in the contact are ignored entirely when considering compatibility with the backend, as they are
       
   552   saved and validated separately.
       
   553  */
       
   554 QContact QContactManager::compatibleContact(const QContact& original)
       
   555 {
       
   556     d->m_error = QContactManager::NoError;
       
   557     return d->m_engine->compatibleContact(original, &d->m_error);
       
   558 }
       
   559 
       
   560 /*!
       
   561   \deprecated
       
   562 */
       
   563 QString QContactManager::synthesizedDisplayLabel(const QContact& contact) const
       
   564 {
       
   565     d->m_error = QContactManager::NoError;
       
   566     return d->m_engine->synthesizedDisplayLabel(contact, &d->m_error);
       
   567 }
       
   568 
       
   569 /*!
       
   570   Returns a display label for a \a contact which is synthesized from its details in a manager specific
       
   571   manner.
       
   572 
       
   573   If you want to update the display label stored in the contact, use the synthesizeContactDisplayLabel()
       
   574   function instead.
       
   575 
       
   576   \sa synthesizeContactDisplayLabel()
       
   577  */
       
   578 QString QContactManager::synthesizedContactDisplayLabel(const QContact& contact) const
       
   579 {
       
   580     d->m_error = QContactManager::NoError;
       
   581     return d->m_engine->synthesizedDisplayLabel(contact, &d->m_error);
       
   582 }
       
   583 
       
   584 /*!
       
   585  * Updates the display label of the supplied \a contact, according to the formatting rules
       
   586  * of this manager.
       
   587  *
       
   588  * Different managers can format the display label of a contact in different ways -
       
   589  * some managers may only consider first or last name, or might put them in different
       
   590  * orders.  Others might consider an organization, a nickname, or a freeform label.
       
   591  *
       
   592  * This function will update the QContactDisplayLabel of this contact, and the string
       
   593  * returned by QContact::displayLabel().
       
   594  *
       
   595  * If \a contact is null, nothing will happen.
       
   596  *
       
   597  * See the following example for more information:
       
   598  * \snippet doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Updating the display label of a contact
       
   599  *
       
   600  * \sa synthesizedContactDisplayLabel(), QContact::displayLabel()
       
   601  */
       
   602 void QContactManager::synthesizeContactDisplayLabel(QContact *contact) const
       
   603 {
       
   604     if (contact) {
       
   605         d->m_error = QContactManager::NoError;
       
   606         QContactManagerEngine::setContactDisplayLabel(contact, d->m_engine->synthesizedDisplayLabel(*contact, &d->m_error));
       
   607     } else {
       
   608         d->m_error = QContactManager::BadArgumentError;
       
   609     }
       
   610 }
       
   611 
       
   612 /*!
       
   613   Sets the id of the "self" contact to the given \a contactId.
       
   614   Returns true if the "self" contact id was set successfully.
       
   615   If the given \a contactId does not identify a contact
       
   616   stored in this manager, the error will be set to
       
   617   \c QContactManager::DoesNotExistError and the function will
       
   618   return false; if the backend does not support the
       
   619   concept of a "self" contact then the error will be set to
       
   620   \c QContactManager::NotSupportedError and the function will
       
   621   return false.
       
   622  */
       
   623 bool QContactManager::setSelfContactId(const QContactLocalId& contactId)
       
   624 {
       
   625     d->m_error = QContactManager::NoError;
       
   626     return d->m_engine->setSelfContactId(contactId, &d->m_error);
       
   627 }
       
   628 
       
   629 /*!
       
   630   Returns the id of the "self" contact which has previously been set.
       
   631   If no "self" contact has been set, or if the self contact was removed
       
   632   from the manager after being set, or if the backend does not support
       
   633   the concept of a "self" contact, an invalid id will be returned
       
   634   and the error will be set to \c QContactManager::DoesNotExistError.
       
   635  */
       
   636 QContactLocalId QContactManager::selfContactId() const
       
   637 {
       
   638     d->m_error = QContactManager::NoError;
       
   639     return d->m_engine->selfContactId(&d->m_error);
       
   640 }
       
   641 
       
   642 /*!
       
   643   Returns a list of relationships in which the contact identified by the given \a participantId participates in the given \a role.
       
   644   If \a participantId is the default-constructed id, \a role is ignored and all relationships are returned.
       
   645  */
       
   646 QList<QContactRelationship> QContactManager::relationships(const QContactId& participantId, QContactRelationship::Role role) const
       
   647 {
       
   648     d->m_error = QContactManager::NoError;
       
   649     return d->m_engine->relationships(QString(), participantId, role, &d->m_error);
       
   650 }
       
   651 
       
   652 /*!
       
   653   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.
       
   654   If \a participantId is the default-constructed id, \a role is ignored and all relationships of the given \a relationshipType are returned.
       
   655   If \a relationshipType is empty, relationships of any type are returned.
       
   656  */
       
   657 QList<QContactRelationship> QContactManager::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role) const
       
   658 {
       
   659     d->m_error = QContactManager::NoError;
       
   660     return d->m_engine->relationships(relationshipType, participantId, role, &d->m_error);
       
   661 }
       
   662 
       
   663 /*!
       
   664   Saves the given \a relationship in the database.  If the relationship already exists in the database, this function will
       
   665   return \c false and the error will be set to \c QContactManager::AlreadyExistsError.
       
   666   If the relationship is saved successfully, this function will return \c true and error will be set
       
   667   to \c QContactManager::NoError.  Note that relationships cannot be updated directly using this function; in order
       
   668   to update a relationship, you must remove the old relationship, make the required modifications, and then save it.
       
   669 
       
   670   The given relationship is invalid if it is circular (the first contact is the second contact), or
       
   671   if it references a non-existent local contact (either the first or second contact).  If the given \a relationship is invalid,
       
   672   the function will return \c false and the error will be set to \c QContactManager::InvalidRelationshipError.
       
   673   If the given \a relationship could not be saved in the database (due to backend limitations)
       
   674   the function will return \c false and error will be set to \c QContactManager::NotSupportedError.
       
   675  */
       
   676 bool QContactManager::saveRelationship(QContactRelationship* relationship)
       
   677 {
       
   678     if (relationship) {
       
   679         d->m_error = QContactManager::NoError;
       
   680         return d->m_engine->saveRelationship(relationship, &d->m_error);
       
   681     } else {
       
   682         d->m_error =QContactManager::BadArgumentError;
       
   683         return false;
       
   684     }
       
   685 }
       
   686 
       
   687 /*!
       
   688   Saves the given \a relationships in the database and returns true if the operation was successful.
       
   689   For any relationship which was unable to be saved, an entry into the \a errorMap will be created,
       
   690   with the key being the index into the input relationships list, and the value being the error which
       
   691   occurred for that index.
       
   692  */
       
   693 bool QContactManager::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap)
       
   694 {
       
   695     if (errorMap)
       
   696         errorMap->clear();
       
   697     if (!relationships) {
       
   698         d->m_error =QContactManager::BadArgumentError;
       
   699         return false;
       
   700     }
       
   701 
       
   702     d->m_error = QContactManager::NoError;
       
   703     return d->m_engine->saveRelationships(relationships, errorMap, &d->m_error);
       
   704 }
       
   705 
       
   706 /*!
       
   707   Removes the given \a relationship from the manager.  If the relationship exists in the manager, the relationship
       
   708   will be removed, the error will be set to \c QContactManager::NoError and this function will return true.  If no such
       
   709   relationship exists in the manager, the error will be set to \c QContactManager::DoesNotExistError and this function
       
   710   will return false.
       
   711  */
       
   712 bool QContactManager::removeRelationship(const QContactRelationship& relationship)
       
   713 {
       
   714     d->m_error = QContactManager::NoError;
       
   715     return d->m_engine->removeRelationship(relationship, &d->m_error);
       
   716 }
       
   717 
       
   718 /*!
       
   719   Removes the given \a relationships from the database and returns true if the operation was successful.
       
   720   For any relationship which was unable to be removed, an entry into the \a errorMap will be created,
       
   721   with the key being the index into the input relationships list, and the value being the error which
       
   722   occurred for that index.
       
   723  */
       
   724 bool QContactManager::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap)
       
   725 {
       
   726     if (errorMap)
       
   727         errorMap->clear();
       
   728     d->m_error = QContactManager::NoError;
       
   729     return d->m_engine->removeRelationships(relationships, errorMap, &d->m_error);
       
   730 }
       
   731 
       
   732 /*!
       
   733   Returns a map of identifier to detail definition for the registered detail definitions which are valid for contacts whose type is the given \a contactType
       
   734   which are valid for the contacts in this store
       
   735  */
       
   736 QMap<QString, QContactDetailDefinition> QContactManager::detailDefinitions(const QString& contactType) const
       
   737 {
       
   738     if (!supportedContactTypes().contains(contactType)) {
       
   739         d->m_error =QContactManager::InvalidContactTypeError;
       
   740         return QMap<QString, QContactDetailDefinition>();
       
   741     }
       
   742 
       
   743     d->m_error = QContactManager::NoError;
       
   744     return d->m_engine->detailDefinitions(contactType, &d->m_error);
       
   745 }
       
   746 
       
   747 /*! Returns the definition identified by the given \a definitionName that is valid for the contacts whose type is the given \a contactType in this store, or a default-constructed QContactDetailDefinition if no such definition exists */
       
   748 QContactDetailDefinition QContactManager::detailDefinition(const QString& definitionName, const QString& contactType) const
       
   749 {
       
   750     if (!supportedContactTypes().contains(contactType)) {
       
   751         d->m_error =QContactManager::InvalidContactTypeError;
       
   752         return QContactDetailDefinition();
       
   753     }
       
   754 
       
   755     d->m_error = QContactManager::NoError;
       
   756     return d->m_engine->detailDefinition(definitionName, contactType, &d->m_error);
       
   757 }
       
   758 
       
   759 /*! 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, otherwise returns false */
       
   760 bool QContactManager::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType)
       
   761 {
       
   762     if (!supportedContactTypes().contains(contactType)) {
       
   763         d->m_error =QContactManager::InvalidContactTypeError;
       
   764         return false;
       
   765     }
       
   766 
       
   767     d->m_error = QContactManager::NoError;
       
   768     return d->m_engine->saveDetailDefinition(def, contactType, &d->m_error);
       
   769 }
       
   770 
       
   771 /*! Removes the detail definition identified by \a definitionName from the database, which is valid for contacts whose type is the given \a contactType.  Returns true if the definition was removed successfully, otherwise returns false */
       
   772 bool QContactManager::removeDetailDefinition(const QString& definitionName, const QString& contactType)
       
   773 {
       
   774     if (!supportedContactTypes().contains(contactType)) {
       
   775         d->m_error =QContactManager::InvalidContactTypeError;
       
   776         return false;
       
   777     }
       
   778 
       
   779     d->m_error = QContactManager::NoError;
       
   780     return d->m_engine->removeDetailDefinition(definitionName, contactType, &d->m_error);
       
   781 }
       
   782 
       
   783 /*!
       
   784   \enum QContactManager::ManagerFeature
       
   785   This enum describes the possible features that a particular manager may support
       
   786   \value Groups The manager supports saving contacts of the \c QContactType::TypeGroup type
       
   787   \value ActionPreferences The manager supports saving preferred details per action per contact
       
   788   \value DetailOrdering When a contact is retrieved, the manager will return the details in the same order in which they were saved
       
   789   \value Relationships The manager supports at least some types of relationships between contacts
       
   790   \value ArbitraryRelationshipTypes The manager supports relationships of arbitrary types between contacts
       
   791   \value MutableDefinitions The manager supports saving, updating or removing detail definitions.  Some built-in definitions may still be immutable
       
   792   \value SelfContact The manager supports the concept of saving a contact which represents the current user
       
   793   \value ChangeLogs The manager supports reporting of timestamps of changes, and filtering and sorting by those timestamps
       
   794   \value Anonymous The manager is isolated from other managers
       
   795  */
       
   796 
       
   797 /*!
       
   798   Returns true if the given feature \a feature is supported by the manager, for the specified type of contact \a contactType
       
   799  */
       
   800 bool QContactManager::hasFeature(QContactManager::ManagerFeature feature, const QString& contactType) const
       
   801 {
       
   802     return d->m_engine->hasFeature(feature, contactType);
       
   803 }
       
   804 
       
   805 /*!
       
   806   Returns the list of data types supported by the manager
       
   807  */
       
   808 QList<QVariant::Type> QContactManager::supportedDataTypes() const
       
   809 {
       
   810     return d->m_engine->supportedDataTypes();
       
   811 }
       
   812 
       
   813 /*!
       
   814   Returns true if the given \a filter is supported natively by the
       
   815   manager, and false if the filter behaviour would be emulated.
       
   816 
       
   817   Note: In some cases, the behaviour of an unsupported filter
       
   818   cannot be emulated.  For example, a filter that requests contacts
       
   819   that have changed since a given time depends on having that information
       
   820   available.  In these cases, the filter will fail.
       
   821  */
       
   822 bool QContactManager::isFilterSupported(const QContactFilter& filter) const
       
   823 {
       
   824     return d->m_engine->isFilterSupported(filter);
       
   825 }
       
   826 
       
   827 /*!
       
   828   Returns true if the manager supports the relationship type specified in \a relationshipType for
       
   829   contacts whose type is the given \a contactType.
       
   830 
       
   831   Note that some managers may support the relationship type for a contact in a limited manner
       
   832   (for example, only as the first contact in the relationship, or only as the second contact
       
   833   in the relationship).  In this case, it will still return true.  It will only return false
       
   834   if the relationship is entirely unsupported for the given type of contact.
       
   835  */
       
   836 bool QContactManager::isRelationshipTypeSupported(const QString& relationshipType, const QString& contactType) const
       
   837 {
       
   838     return d->m_engine->isRelationshipTypeSupported(relationshipType, contactType);
       
   839 }
       
   840 
       
   841 /*!
       
   842   Returns the list of contact types which are supported by this manager.
       
   843   This is a convenience function, equivalent to retrieving the allowable values
       
   844   for the \c QContactType::FieldType field of the QContactType definition
       
   845   which is valid in this manager.
       
   846  */
       
   847 QStringList QContactManager::supportedContactTypes() const
       
   848 {
       
   849     return d->m_engine->supportedContactTypes();
       
   850 }
       
   851 
       
   852 /*!
       
   853   Returns the engine backend implementation version number
       
   854  */
       
   855 int QContactManager::managerVersion() const
       
   856 {
       
   857     return d->m_engine->managerVersion();
       
   858 }
       
   859 
       
   860 /*! Returns the manager name for this QContactManager */
       
   861 QString QContactManager::managerName() const
       
   862 {
       
   863     return d->m_engine->managerName();
       
   864 }
       
   865 
       
   866 /*! Return the parameters relevant to the creation of this QContactManager */
       
   867 QMap<QString, QString> QContactManager::managerParameters() const
       
   868 {
       
   869     QMap<QString, QString> params = d->m_engine->managerParameters();
       
   870     
       
   871     params.remove(QString::fromAscii(QTCONTACTS_VERSION_NAME));
       
   872     params.remove(QString::fromAscii(QTCONTACTS_IMPLEMENTATION_VERSION_NAME));
       
   873     return params;
       
   874 }
       
   875 
       
   876 /*!
       
   877   Return the uri describing this QContactManager, consisting of the manager name and any parameters.
       
   878  */
       
   879 QString QContactManager::managerUri() const
       
   880 {
       
   881     return d->m_engine->managerUri();
       
   882 }
       
   883 
       
   884 #include "moc_qcontactmanager.cpp"
       
   885 
       
   886 QTM_END_NAMESPACE