qtmobility/src/contacts/qcontact.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <QSet>
    42 #include <QSet>
       
    43 #include <QDebug>
    43 
    44 
    44 #include "qcontact.h"
    45 #include "qcontact.h"
    45 #include "qcontact_p.h"
    46 #include "qcontact_p.h"
    46 #include "qcontactdetail_p.h"
    47 #include "qcontactdetail_p.h"
    47 #include "qcontactmanager_p.h"
    48 #include "qcontactmanager_p.h"
    50 QTM_BEGIN_NAMESPACE
    51 QTM_BEGIN_NAMESPACE
    51 
    52 
    52 /*!
    53 /*!
    53   \class QContact
    54   \class QContact
    54  
    55  
    55   \brief The QContact class provides an addressbook contact.
    56   \brief The QContact class represents an addressbook contact.
    56 
    57 
    57   \ingroup contacts-main
    58   \ingroup contacts-main
    58  
    59  
    59   A QContact consists of zero or more details.
    60   A QContact consists of zero or more details.
    60  
    61  
    61   An instance of the QContact class represents an in-memory contact,
    62   An instance of the QContact class represents an in-memory contact,
    62   and may not reflect the state of that contact found in persistent
    63   and may not reflect the state of that contact found in persistent
    63   storage until the appropriate synchronisation method is called
    64   storage until the appropriate synchronization method is called
    64   on the QContactManager (i.e., saveContact, removeContact).
    65   on the QContactManager (i.e., saveContact, removeContact).
    65  
    66  
    66   \sa QContactManager, QContactDetail
    67   \sa QContactManager, QContactDetail
    67  */
    68  */
    68 
    69 
   231 }
   232 }
   232 
   233 
   233 /*! Returns the first detail stored in the contact which is of the given \a definitionName */
   234 /*! Returns the first detail stored in the contact which is of the given \a definitionName */
   234 QContactDetail QContact::detail(const QString& definitionName) const
   235 QContactDetail QContact::detail(const QString& definitionName) const
   235 {
   236 {
       
   237     if (definitionName.isEmpty())
       
   238         return d->m_details.first();
       
   239 
   236     // build the sub-list of matching details.
   240     // build the sub-list of matching details.
   237     for (int i = 0; i < d->m_details.size(); i++) {
   241     for (int i = 0; i < d->m_details.size(); i++) {
   238         const QContactDetail& existing = d->m_details.at(i);
   242         const QContactDetail& existing = d->m_details.at(i);
   239         if (definitionName.isEmpty() || definitionName == existing.definitionName()) {
   243         if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
   240             return existing;
   244             return existing;
   241         }
   245         }
   242     }
   246     }
   243 
   247 
   244     return QContactDetail();
   248     return QContactDetail();
   254     if (definitionName.isEmpty()) {
   258     if (definitionName.isEmpty()) {
   255         sublist = d->m_details;
   259         sublist = d->m_details;
   256     } else {
   260     } else {
   257         for (int i = 0; i < d->m_details.size(); i++) {
   261         for (int i = 0; i < d->m_details.size(); i++) {
   258             const QContactDetail& existing = d->m_details.at(i);
   262             const QContactDetail& existing = d->m_details.at(i);
   259             if (definitionName == existing.definitionName()) {
   263             if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
   260                 sublist.append(existing);
   264                 sublist.append(existing);
   261             }
   265             }
   262         }
   266         }
   263     }
   267     }
   264 
   268 
   275     if (fieldName.isEmpty()) {
   279     if (fieldName.isEmpty()) {
   276         sublist = details(definitionName);
   280         sublist = details(definitionName);
   277     } else {
   281     } else {
   278         for (int i = 0; i < d->m_details.size(); i++) {
   282         for (int i = 0; i < d->m_details.size(); i++) {
   279             const QContactDetail& existing = d->m_details.at(i);
   283             const QContactDetail& existing = d->m_details.at(i);
   280             if (definitionName == existing.definitionName() && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
   284             if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName
       
   285                 && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
       
   286                 sublist.append(existing);
       
   287             }
       
   288         }
       
   289     }
       
   290 
       
   291     return sublist;
       
   292 }
       
   293 
       
   294 /*! Returns the first detail stored in the contact which is of the given \a definitionName */
       
   295 QContactDetail QContact::detail(const char* definitionName) const
       
   296 {
       
   297     if (definitionName == 0)
       
   298         return d->m_details.first();
       
   299 
       
   300     // build the sub-list of matching details.
       
   301     for (int i = 0; i < d->m_details.size(); i++) {
       
   302         const QContactDetail& existing = d->m_details.at(i);
       
   303         if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
       
   304             return existing;
       
   305         }
       
   306     }
       
   307 
       
   308     return QContactDetail();
       
   309 }
       
   310 
       
   311 /*! Returns a list of details of the given \a definitionName */
       
   312 QList<QContactDetail> QContact::details(const char* definitionName) const
       
   313 {
       
   314     // build the sub-list of matching details.
       
   315     QList<QContactDetail> sublist;
       
   316 
       
   317     // special case
       
   318     if (definitionName == 0) {
       
   319         sublist = d->m_details;
       
   320     } else {
       
   321         for (int i = 0; i < d->m_details.size(); i++) {
       
   322             const QContactDetail& existing = d->m_details.at(i);
       
   323             if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
       
   324                 sublist.append(existing);
       
   325             }
       
   326         }
       
   327     }
       
   328 
       
   329     return sublist;
       
   330 }
       
   331 
       
   332 /*! Returns a list of details of the given \a definitionName, \a fieldName and field \a value*/
       
   333 QList<QContactDetail> QContact::details(const char* definitionName, const char* fieldName, const QString& value) const
       
   334 {
       
   335     // build the sub-list of matching details.
       
   336     QList<QContactDetail> sublist;
       
   337 
       
   338     // special case
       
   339     if (fieldName == 0) {
       
   340         sublist = details(definitionName);
       
   341     } else {
       
   342         for (int i = 0; i < d->m_details.size(); i++) {
       
   343             const QContactDetail& existing = d->m_details.at(i);
       
   344             if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName
       
   345                 && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
   281                 sublist.append(existing);
   346                 sublist.append(existing);
   282             }
   347             }
   283         }
   348         }
   284     }
   349     }
   285 
   350 
   315 
   380 
   316     if (detail->accessConstraints() & QContactDetail::ReadOnly)
   381     if (detail->accessConstraints() & QContactDetail::ReadOnly)
   317         return false;
   382         return false;
   318 
   383 
   319     /* Also handle contact type specially - only one of them. */
   384     /* Also handle contact type specially - only one of them. */
   320     if (detail->definitionName() == QContactType::DefinitionName) {
   385     if (QContactDetailPrivate::detailPrivate(*detail)->m_definitionName == QContactType::DefinitionName.latin1()) {
   321         detail->d->m_access = QContactDetail::Irremovable;
   386         detail->d->m_access = QContactDetail::Irremovable;
   322         d->m_details[1] = *detail;
   387         d->m_details[1] = *detail;
   323         return true;
   388         return true;
   324     }
   389     }
   325 
   390 
   326     /* And display label.. */
   391     /* And display label.. */
   327     if (detail->definitionName() == QContactDisplayLabel::DefinitionName) {
   392     if (QContactDetailPrivate::detailPrivate(*detail)->m_definitionName == QContactDisplayLabel::DefinitionName.latin1()) {
   328         detail->d->m_access = QContactDetail::Irremovable | QContactDetail::ReadOnly;
   393         detail->d->m_access = QContactDetail::Irremovable | QContactDetail::ReadOnly;
   329         return false;
   394         return false;
   330     }
   395     }
   331 
   396 
   332     // try to find the "old version" of this field
   397     // try to find the "old version" of this field
   404 {
   469 {
   405     return other.d->m_id == d->m_id &&
   470     return other.d->m_id == d->m_id &&
   406         other.d->m_details == d->m_details;
   471         other.d->m_details == d->m_details;
   407 }
   472 }
   408 
   473 
       
   474 /*! Returns the hash value for \a key. */
       
   475 uint qHash(const QContact &key)
       
   476 {
       
   477     uint hash = qHash(key.id());
       
   478     foreach (const QContactDetail& detail, key.details()) {
       
   479         hash += qHash(detail);
       
   480     }
       
   481     return hash;
       
   482 }
       
   483 
       
   484 QDebug operator<<(QDebug dbg, const QContact& contact)
       
   485 {
       
   486     dbg.nospace() << "QContact(" << contact.id() << ")";
       
   487     foreach (const QContactDetail& detail, contact.details()) {
       
   488         dbg.space() << '\n' << detail;
       
   489     }
       
   490     return dbg.maybeSpace();
       
   491 }
   409 
   492 
   410 /*! Retrieve the first detail for which the given \a actionName is available */
   493 /*! Retrieve the first detail for which the given \a actionName is available */
   411 QContactDetail QContact::detailWithAction(const QString& actionName) const
   494 QContactDetail QContact::detailWithAction(const QString& actionName) const
   412 {
   495 {
   413     if (actionName.isEmpty())
   496     if (actionName.isEmpty())
   432     QList<QContactActionDescriptor> descriptors = QContactManagerData::actionDescriptors(actionName);
   515     QList<QContactActionDescriptor> descriptors = QContactManagerData::actionDescriptors(actionName);
   433     for (int i = 0; i < descriptors.size(); i++) {
   516     for (int i = 0; i < descriptors.size(); i++) {
   434         QContactAction *currImpl = QContactManagerData::action(descriptors.at(i));
   517         QContactAction *currImpl = QContactManagerData::action(descriptors.at(i));
   435         for (int i = 0; i < d->m_details.size(); i++) {
   518         for (int i = 0; i < d->m_details.size(); i++) {
   436             QContactDetail detail = d->m_details.at(i);
   519             QContactDetail detail = d->m_details.at(i);
   437             if (currImpl->supportsDetail(detail)) {
   520             if (currImpl->isDetailSupported(detail, *this)) {
   438                 retn.append(detail);
   521                 retn.append(detail);
   439                 break;
   522                 break;
   440             }
   523             }
   441         }
   524         }
   442 
   525 
   468 
   551 
   469     return retn;
   552     return retn;
   470 }
   553 }
   471 
   554 
   472 /*!
   555 /*!
   473  * \preliminary
   556   Returns a list of ids of contacts which are related to this contact in a relationship of the
   474  * Returns a list of ids of contacts which are related to this contact in a relationship of the
   557   given \a relationshipType, where those other contacts participate in the relationship in the
   475  * given \a relationshipType, where those other contacts participate in the relationship in the
   558   given \a role.
   476  * given \a role
   559  */
   477  */
   560 QList<QContactId> QContact::relatedContacts(const QString& relationshipType, QContactRelationship::Role role) const
   478 QList<QContactId> QContact::relatedContacts(const QString& relationshipType, QContactRelationshipFilter::Role role) const
       
   479 {
   561 {
   480     QList<QContactId> retn;
   562     QList<QContactId> retn;
   481     for (int i = 0; i < d->m_relationshipsCache.size(); i++) {
   563     for (int i = 0; i < d->m_relationshipsCache.size(); i++) {
   482         QContactRelationship curr = d->m_relationshipsCache.at(i);
   564         QContactRelationship curr = d->m_relationshipsCache.at(i);
   483         if (curr.relationshipType() == relationshipType || relationshipType.isEmpty()) {
   565         if (relationshipType.isEmpty() || curr.relationshipType() == relationshipType) {
   484             // check that the other contacts fill the given role
   566             // check that the other contacts fill the given role
   485             if (role == QContactRelationshipFilter::First) {
   567             if (role == QContactRelationship::First) {
   486                 if (curr.first() != d->m_id) {
   568                 if (curr.first() != d->m_id) {
   487                     retn.append(curr.first());
   569                     if (!retn.contains(curr.first())) {
       
   570                         retn.append(curr.first());
       
   571                     }
   488                 }
   572                 }
   489             } else if (role == QContactRelationshipFilter::Second) {
   573             } else if (role == QContactRelationship::Second) {
   490                 if (curr.first() == d->m_id) {
   574                 if (curr.first() == d->m_id) {
   491                     retn.append(curr.second());
   575                     if (!retn.contains(curr.second())) {
       
   576                         retn.append(curr.second());
       
   577                     }
   492                 }
   578                 }
   493             } else { // role == Either.
   579             } else { // role == Either.
   494                 if (curr.first() == d->m_id) {
   580                 if (curr.first() == d->m_id) {
   495                     retn.append(curr.second());
   581                     if (!retn.contains(curr.second())) {
       
   582                         retn.append(curr.second());
       
   583                     }
   496                 } else {
   584                 } else {
   497                     retn.append(curr.first());
   585                     if (!retn.contains(curr.first())) {
       
   586                         retn.append(curr.first());
       
   587                     }
   498                 }
   588                 }
   499             }
   589             }
   500         }
   590         }
   501     }
   591     }
   502 
   592 
   503     QList<QContactId> removeDuplicates;
   593     return retn;
   504     for (int i = 0; i < retn.size(); i++) {
       
   505         QContactId curr = retn.at(i);
       
   506         if (!removeDuplicates.contains(curr)) {
       
   507             removeDuplicates.append(curr);
       
   508         }
       
   509     }
       
   510 
       
   511     return removeDuplicates;
       
   512 }
       
   513 
       
   514 /*!
       
   515  * \preliminary
       
   516  * Sets the order of importance of the relationships for this contact by saving a \a reordered list of relationships which involve the contact.
       
   517  * The list must include all of the relationships in which the contact is involved, and must not include any relationships which do
       
   518  * not involve the contact.  In order for the ordering preference to be persisted, the contact must be saved in its manager.
       
   519  *
       
   520  * It is possible that relationships will have been added or removed from the contact stored in the manager,
       
   521  * thus rendering the relationship cache of the contact in memory stale.   If this happens, attempting to save the contact after reordering
       
   522  * its relationships will result in an error occurring. The updated relationships list must be retrieved from the manager, reordered and set
       
   523  * in the contact before the contact can be saved successfully.
       
   524  *
       
   525  * \sa relationships(), relationshipOrder()
       
   526  */
       
   527 void QContact::setRelationshipOrder(const QList<QContactRelationship>& reordered)
       
   528 {
       
   529     d->m_reorderedRelationshipsCache = reordered;
       
   530 }
       
   531 
       
   532 /*!
       
   533  * \preliminary
       
   534  * Returns the ordered list of relationships in which the contact is involved.  By default, this list is equal to the cached
       
   535  * list of relationships which is available by calling relationships().
       
   536  *
       
   537  * \sa setRelationshipOrder()
       
   538  */
       
   539 QList<QContactRelationship> QContact::relationshipOrder() const
       
   540 {
       
   541     return d->m_reorderedRelationshipsCache;
       
   542 }
   594 }
   543 
   595 
   544 /*!
   596 /*!
   545  * Return a list of actions available to be performed on this contact which are offered
   597  * Return a list of actions available to be performed on this contact which are offered
   546  * by the vendor whose name is the given \a vendorName, where the action instance has
   598  * by the vendor whose name is the given \a vendorName, where the action instance has
   571 }
   623 }
   572 
   624 
   573 /*!
   625 /*!
   574  * \preliminary
   626  * \preliminary
   575  * Set a particular detail as the \a preferredDetail for a given \a actionName.  Returns
   627  * Set a particular detail as the \a preferredDetail for a given \a actionName.  Returns
   576  * true if the detail was successfully set as the preferred detail for the action
   628  * true if the detail exists in the contact and was successfully set as the preferred detail for the action
   577  * identified by \a actionName, otherwise returns false
   629  * identified by \a actionName, otherwise returns false.
       
   630  * Note that since QContact is a value class, no error checking is done on the action name
       
   631  * (to ensure that an action of that name is available) in this function.
   578  */
   632  */
   579 bool QContact::setPreferredDetail(const QString& actionName, const QContactDetail& preferredDetail)
   633 bool QContact::setPreferredDetail(const QString& actionName, const QContactDetail& preferredDetail)
   580 {
   634 {
   581     // if the given action name is empty, bad argument.
   635     // if the given action name is empty, bad argument.
   582     if (actionName.isEmpty())
   636     if (actionName.isEmpty())
   636     }
   690     }
   637 
   691 
   638     return retn;
   692     return retn;
   639 }
   693 }
   640 
   694 
       
   695 
       
   696 
       
   697 /*!
       
   698  * \preliminary
       
   699  * Returns a map of action name to the preferred detail for the action of that name.
       
   700  */
       
   701 QMap<QString, QContactDetail> QContact::preferredDetails() const
       
   702 {
       
   703     QMap<QString, QContactDetail> ret;
       
   704     QMap<QString, int>::const_iterator it = d->m_preferences.constBegin();
       
   705     while (it != d->m_preferences.constEnd()) {
       
   706         ret.insert(it.key(), d->m_details.at(it.value()));
       
   707         ++it;
       
   708     }
       
   709 
       
   710     return ret;
       
   711 }
       
   712 
   641 QTM_END_NAMESPACE
   713 QTM_END_NAMESPACE