qtmobility/src/contacts/qcontact.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 <QSet>
       
    43 
       
    44 #include "qcontact.h"
       
    45 #include "qcontact_p.h"
       
    46 #include "qcontactdetail_p.h"
       
    47 #include "qcontactmanager_p.h"
       
    48 #include "qcontactaction.h"
       
    49 
       
    50 QTM_BEGIN_NAMESPACE
       
    51 
       
    52 /*!
       
    53   \class QContact
       
    54  
       
    55   \brief The QContact class provides an addressbook contact.
       
    56 
       
    57   \ingroup contacts-main
       
    58  
       
    59   A QContact consists of zero or more details.
       
    60  
       
    61   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   storage until the appropriate synchronisation method is called
       
    64   on the QContactManager (i.e., saveContact, removeContact).
       
    65  
       
    66   \sa QContactManager, QContactDetail
       
    67  */
       
    68 
       
    69 /*!
       
    70  * \fn QList<T> QContact::details() const
       
    71  * Returns a list of details of the template type
       
    72  */
       
    73 
       
    74 /*!
       
    75  * \fn QList<T> QContact::details(const QString& fieldName, const QString& value) const
       
    76  * Returns a list of details of the template type which match the \a fieldName and \a value criteria
       
    77  */
       
    78 
       
    79 /*!
       
    80  * \fn T QContact::detail() const
       
    81  * Returns the first detail of the template type
       
    82  */
       
    83 
       
    84 /*!
       
    85  * \fn QContact::operator!=(const QContact &other) const
       
    86  * Returns true if this contacts Id or details are different to those of the \a other contact
       
    87  */
       
    88 
       
    89 /*! Construct an empty contact. */
       
    90 QContact::QContact()
       
    91     : d(new QContactData)
       
    92 {
       
    93     clearDetails();
       
    94 }
       
    95 
       
    96 /*! Initializes this QContact from \a other */
       
    97 QContact::QContact(const QContact& other)
       
    98     : d(other.d)
       
    99 {
       
   100 }
       
   101 
       
   102 /*!
       
   103  * Returns true if this QContact is empty, false if not.
       
   104  *
       
   105  * An empty QContact has an empty label and no extra details.
       
   106  * The type of the contact is irrelevant.
       
   107  */
       
   108 bool QContact::isEmpty() const
       
   109 {
       
   110     /* Every contact has a display label field.. */
       
   111     if (d->m_details.count() > 2)
       
   112         return false;
       
   113 
       
   114     /* We know we have two details (a display label and a type) */
       
   115     const QContactDisplayLabel& label = d->m_details.at(0);
       
   116     return label.label().isEmpty();
       
   117 }
       
   118 
       
   119 /*!
       
   120  * Removes all details of the contact.
       
   121  * This function does not modify the id or type of the contact.
       
   122  * Calling isEmpty() after calling this function will return true.
       
   123  */
       
   124 void QContact::clearDetails()
       
   125 {
       
   126     d->m_details.clear();
       
   127 
       
   128     // insert the contact's display label detail.
       
   129     QContactDisplayLabel contactLabel;
       
   130     contactLabel.setValue(QContactDisplayLabel::FieldLabel, QString());
       
   131     contactLabel.d->m_id = 1;
       
   132     contactLabel.d->m_access = QContactDetail::Irremovable | QContactDetail::ReadOnly;
       
   133     d->m_details.insert(0, contactLabel);
       
   134 
       
   135     // and the contact type detail.
       
   136     QContactType contactType;
       
   137     contactType.setType(QContactType::TypeContact);
       
   138     contactType.d->m_id = 2;
       
   139     contactType.d->m_access = QContactDetail::Irremovable;
       
   140     d->m_details.insert(1, contactType);
       
   141 }
       
   142 
       
   143 /*! Replace the contents of this QContact with \a other */
       
   144 QContact& QContact::operator=(const QContact& other)
       
   145 {
       
   146     d = other.d;
       
   147     return *this;
       
   148 }
       
   149 
       
   150 /*! Frees the memory used by this QContact */
       
   151 QContact::~QContact()
       
   152 {
       
   153 }
       
   154 
       
   155 /*! Returns the QContactId that identifies this contact */
       
   156 QContactId QContact::id() const
       
   157 {
       
   158     return d->m_id;
       
   159 }
       
   160 
       
   161 /*! Returns the QContactLocalId that identifies this contact within its manager */
       
   162 QContactLocalId QContact::localId() const
       
   163 {
       
   164     return d->m_id.localId();
       
   165 }
       
   166 
       
   167 /*!
       
   168  * Returns the type of the contact.  Every contact has exactly one type which
       
   169  * is either set manually (by saving a modified copy of the QContactType
       
   170  * in the contact, or by calling \l setType()) or synthesized automatically.
       
   171  *
       
   172  * \sa setType()
       
   173  */
       
   174 QString QContact::type() const
       
   175 {
       
   176     // type is detail 1
       
   177     QString type = d->m_details.at(1).value(QContactType::FieldType);
       
   178     if (type.isEmpty())
       
   179         return QString(QLatin1String(QContactType::TypeContact));
       
   180     return type;
       
   181 }
       
   182 
       
   183 /*!
       
   184  * Sets the type of the contact to the given \a type.
       
   185  */
       
   186 void QContact::setType(const QString& type)
       
   187 {
       
   188     // type is detail 1
       
   189     QContactType newType;
       
   190     newType.setType(type);
       
   191     newType.d->m_access = QContactDetail::Irremovable;
       
   192 
       
   193     d->m_details[1] = newType;
       
   194 }
       
   195 
       
   196 /*!
       
   197  * Sets the type of the contact to the given \a type.
       
   198  */
       
   199 void QContact::setType(const QContactType& type)
       
   200 {
       
   201     // type is detail 1
       
   202     d->m_details[1] = type;
       
   203     d->m_details[1].d->m_access = QContactDetail::Irremovable;
       
   204 }
       
   205 
       
   206 /*!
       
   207  * Returns the read-only display label of this contact.
       
   208  * A contact which has been retrieved from a manager will have a display label synthesized for it.
       
   209  */
       
   210 QString QContact::displayLabel() const
       
   211 {
       
   212     return d->m_details.at(0).value(QContactDisplayLabel::FieldLabel);
       
   213 }
       
   214 
       
   215 /*!
       
   216  * Sets the id of this contact to \a id.  Note that this only affects
       
   217  * this structure, not any corresponding structures stored
       
   218  * by a QContactManager.
       
   219  *
       
   220  * If you change the id of a contact and save the contact
       
   221  * in a manager, the previously existing contact will still
       
   222  * exist.  You can do this to create copies (possibly modified)
       
   223  * of an existing contact.
       
   224  *
       
   225  * Returns true if the \a id was set successfully, otherwise
       
   226  * returns false.
       
   227  */
       
   228 void QContact::setId(const QContactId& id)
       
   229 {
       
   230     d->m_id = id;
       
   231 }
       
   232 
       
   233 /*! Returns the first detail stored in the contact which is of the given \a definitionName */
       
   234 QContactDetail QContact::detail(const QString& definitionName) const
       
   235 {
       
   236     // build the sub-list of matching details.
       
   237     for (int i = 0; i < d->m_details.size(); i++) {
       
   238         const QContactDetail& existing = d->m_details.at(i);
       
   239         if (definitionName.isEmpty() || definitionName == existing.definitionName()) {
       
   240             return existing;
       
   241         }
       
   242     }
       
   243 
       
   244     return QContactDetail();
       
   245 }
       
   246 
       
   247 /*! Returns a list of details of the given \a definitionName */
       
   248 QList<QContactDetail> QContact::details(const QString& definitionName) const
       
   249 {
       
   250     // build the sub-list of matching details.
       
   251     QList<QContactDetail> sublist;
       
   252 
       
   253     // special case
       
   254     if (definitionName.isEmpty()) {
       
   255         sublist = d->m_details;
       
   256     } else {
       
   257         for (int i = 0; i < d->m_details.size(); i++) {
       
   258             const QContactDetail& existing = d->m_details.at(i);
       
   259             if (definitionName == existing.definitionName()) {
       
   260                 sublist.append(existing);
       
   261             }
       
   262         }
       
   263     }
       
   264 
       
   265     return sublist;
       
   266 }
       
   267 
       
   268 /*! Returns a list of details of the given \a definitionName, \a fieldName and field \a value*/
       
   269 QList<QContactDetail> QContact::details(const QString& definitionName, const QString& fieldName, const QString& value) const
       
   270 {
       
   271     // build the sub-list of matching details.
       
   272     QList<QContactDetail> sublist;
       
   273 
       
   274     // special case
       
   275     if (fieldName.isEmpty()) {
       
   276         sublist = details(definitionName);
       
   277     } else {
       
   278         for (int i = 0; i < d->m_details.size(); i++) {
       
   279             const QContactDetail& existing = d->m_details.at(i);
       
   280             if (definitionName == existing.definitionName() && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
       
   281                 sublist.append(existing);
       
   282             }
       
   283         }
       
   284     }
       
   285 
       
   286     return sublist;
       
   287 }
       
   288 
       
   289 /*!
       
   290  * Saves the given \a detail in the list of stored details, and sets its Id.
       
   291  * If another detail of the same type and Id has been previously saved in
       
   292  * this contact, that detail is overwritten.  Otherwise, a new Id is generated
       
   293  * and set in the detail, and the detail is added to the list.
       
   294  *
       
   295  * If the detail's access constraint includes \c QContactDetail::ReadOnly,
       
   296  * this function will return false.
       
   297  *
       
   298  * If \a detail is a contact type, the existing contact type will
       
   299  * be overwritten with \a detail.  There is never more than one contact type
       
   300  * in a contact.  The supplied \a detail will have its accessConstraint set to
       
   301  * QContactDetail::Irremovable.
       
   302  *
       
   303  * If \a detail is a display label, the supplied \a detail will have its
       
   304  * accessConstraint set to QContactDetail::Irremovable | QContactDetail::ReadOnly,
       
   305  * and the function will return false.
       
   306  *
       
   307  * Returns true if the detail was saved successfully, otherwise returns false.
       
   308  *
       
   309  * Note that the caller retains ownership of the detail.
       
   310  */
       
   311 bool QContact::saveDetail(QContactDetail* detail)
       
   312 {
       
   313     if (!detail)
       
   314         return false;
       
   315 
       
   316     if (detail->accessConstraints() & QContactDetail::ReadOnly)
       
   317         return false;
       
   318 
       
   319     /* Also handle contact type specially - only one of them. */
       
   320     if (detail->definitionName() == QContactType::DefinitionName) {
       
   321         detail->d->m_access = QContactDetail::Irremovable;
       
   322         d->m_details[1] = *detail;
       
   323         return true;
       
   324     }
       
   325 
       
   326     /* And display label.. */
       
   327     if (detail->definitionName() == QContactDisplayLabel::DefinitionName) {
       
   328         detail->d->m_access = QContactDetail::Irremovable | QContactDetail::ReadOnly;
       
   329         return false;
       
   330     }
       
   331 
       
   332     // try to find the "old version" of this field
       
   333     // ie, the one with the same type and id, but different value or attributes.
       
   334     for (int i = 0; i < d->m_details.size(); i++) {
       
   335         const QContactDetail& curr = d->m_details.at(i);
       
   336         if (detail->d->m_definitionName == curr.d->m_definitionName && detail->d->m_id == curr.d->m_id) {
       
   337             // update the detail constraints of the supplied detail
       
   338             detail->d->m_access = d->m_details[i].accessConstraints();
       
   339             // Found the old version.  Replace it with this one.
       
   340             d->m_details[i] = *detail;
       
   341             return true;
       
   342         }
       
   343     }
       
   344 
       
   345     // this is a new detail!  add it to the contact.
       
   346     d->m_details.append(*detail);
       
   347     return true;
       
   348 }
       
   349 
       
   350 /*!
       
   351  * Removes the \a detail from the contact.
       
   352  *
       
   353  * The detail in the contact which has the same key as that of the given \a detail
       
   354  * will be removed if it exists.  That is, the information in the detail may be different.
       
   355  * Any preference for the given field is also removed.
       
   356  *
       
   357  * If the detail's access constraint includes \c QContactDetail::Irremovable,
       
   358  * this function will return false.
       
   359  *
       
   360  * Returns true if the detail was removed successfully, false if an error occurred.
       
   361  *
       
   362  * Note that the caller retains ownership of the detail.
       
   363  */
       
   364 bool QContact::removeDetail(QContactDetail* detail)
       
   365 {
       
   366     if (!detail)
       
   367         return false;
       
   368 
       
   369     // find the detail stored in the contact which has the same key as the detail argument
       
   370     int removeIndex = -1;
       
   371     for (int i = 0; i < d->m_details.size(); i++) {
       
   372         if (d->m_details.at(i).key() == detail->key()) {
       
   373             removeIndex = i;
       
   374             break;
       
   375         }
       
   376     }
       
   377 
       
   378     // make sure the detail exists (in some form) in the contact.
       
   379     if (removeIndex < 0)
       
   380         return false;
       
   381 
       
   382     if (detail->accessConstraints() & QContactDetail::Irremovable)
       
   383         return false;
       
   384 
       
   385     if (!d->m_details.contains(*detail))
       
   386         return false;
       
   387 
       
   388     // remove any preferences we may have stored for the detail.
       
   389     QStringList keys = d->m_preferences.keys();
       
   390     for (int i = 0; i < keys.size(); i++) {
       
   391         QString prefKey = keys.at(i);
       
   392         if (d->m_preferences.value(prefKey) == detail->d->m_id) {
       
   393             d->m_preferences.remove(prefKey);
       
   394         }
       
   395     }
       
   396 
       
   397     // then remove the detail.  // OLD BEHAVIOUR (24/12/2009): d->m_details.removeOne(*detail);
       
   398     d->m_details.removeAt(removeIndex);
       
   399     return true;
       
   400 }
       
   401 
       
   402 /*! Returns true if this contact is equal to the \a other contact, false if either the id or stored details are not the same */
       
   403 bool QContact::operator==(const QContact& other) const
       
   404 {
       
   405     return other.d->m_id == d->m_id &&
       
   406         other.d->m_details == d->m_details;
       
   407 }
       
   408 
       
   409 
       
   410 /*! Retrieve the first detail for which the given \a actionName is available */
       
   411 QContactDetail QContact::detailWithAction(const QString& actionName) const
       
   412 {
       
   413     if (actionName.isEmpty())
       
   414         return QContactDetail();
       
   415 
       
   416     QList<QContactDetail> dets = detailsWithAction(actionName);
       
   417     if (dets.isEmpty())
       
   418         return QContactDetail();
       
   419 
       
   420     QContactDetail retn = dets.first();
       
   421     return retn;
       
   422 }
       
   423 
       
   424 /*! Retrieve any details for which the given \a actionName is available */
       
   425 QList<QContactDetail> QContact::detailsWithAction(const QString& actionName) const
       
   426 {
       
   427     if (actionName.isEmpty())
       
   428         return QList<QContactDetail>();
       
   429 
       
   430     // ascertain which details are supported by any implementation of the given action
       
   431     QList<QContactDetail> retn;
       
   432     QList<QContactActionDescriptor> descriptors = QContactManagerData::actionDescriptors(actionName);
       
   433     for (int i = 0; i < descriptors.size(); i++) {
       
   434         QContactAction *currImpl = QContactManagerData::action(descriptors.at(i));
       
   435         for (int i = 0; i < d->m_details.size(); i++) {
       
   436             QContactDetail detail = d->m_details.at(i);
       
   437             if (currImpl->supportsDetail(detail)) {
       
   438                 retn.append(detail);
       
   439                 break;
       
   440             }
       
   441         }
       
   442 
       
   443         // clean up
       
   444         delete currImpl;
       
   445     }
       
   446 
       
   447     return retn;
       
   448 }
       
   449 
       
   450 /*!
       
   451  * \preliminary
       
   452  * Returns a list of relationships of the given \a relationshipType in which the contact was a participant at the time that it was retrieved from the manager
       
   453  */
       
   454 QList<QContactRelationship> QContact::relationships(const QString& relationshipType) const
       
   455 {
       
   456     // if empty, then they want all relationships
       
   457     if (relationshipType.isEmpty())
       
   458         return d->m_relationshipsCache;
       
   459 
       
   460     // otherwise, filter on type.
       
   461     QList<QContactRelationship> retn;
       
   462     for (int i = 0; i < d->m_relationshipsCache.size(); i++) {
       
   463         QContactRelationship curr = d->m_relationshipsCache.at(i);
       
   464         if (curr.relationshipType() == relationshipType) {
       
   465             retn.append(curr);
       
   466         }
       
   467     }
       
   468 
       
   469     return retn;
       
   470 }
       
   471 
       
   472 /*!
       
   473  * \preliminary
       
   474  * Returns a list of ids of contacts which are related to this contact in a relationship of the
       
   475  * given \a relationshipType, where those other contacts participate in the relationship in the
       
   476  * given \a role
       
   477  */
       
   478 QList<QContactId> QContact::relatedContacts(const QString& relationshipType, QContactRelationshipFilter::Role role) const
       
   479 {
       
   480     QList<QContactId> retn;
       
   481     for (int i = 0; i < d->m_relationshipsCache.size(); i++) {
       
   482         QContactRelationship curr = d->m_relationshipsCache.at(i);
       
   483         if (curr.relationshipType() == relationshipType || relationshipType.isEmpty()) {
       
   484             // check that the other contacts fill the given role
       
   485             if (role == QContactRelationshipFilter::First) {
       
   486                 if (curr.first() != d->m_id) {
       
   487                     retn.append(curr.first());
       
   488                 }
       
   489             } else if (role == QContactRelationshipFilter::Second) {
       
   490                 if (curr.first() == d->m_id) {
       
   491                     retn.append(curr.second());
       
   492                 }
       
   493             } else { // role == Either.
       
   494                 if (curr.first() == d->m_id) {
       
   495                     retn.append(curr.second());
       
   496                 } else {
       
   497                     retn.append(curr.first());
       
   498                 }
       
   499             }
       
   500         }
       
   501     }
       
   502 
       
   503     QList<QContactId> removeDuplicates;
       
   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 }
       
   543 
       
   544 /*!
       
   545  * 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
       
   547  * the implementation version given by \a implementationVersion.
       
   548  * If \a vendorName is empty, actions from any vendor are supplied; if \a implementationVersion
       
   549  * is \c -1, action implementations of any version will be returned.
       
   550  */
       
   551 QList<QContactActionDescriptor> QContact::availableActions(const QString& vendorName, int implementationVersion) const
       
   552 {
       
   553     // check every action implementation to see if it supports me.
       
   554     QSet<QContactActionDescriptor> retn;
       
   555     QList<QContactActionDescriptor> descriptors = QContactManagerData::actionDescriptors();
       
   556     for (int i = 0; i < descriptors.size(); i++) {
       
   557         QContactActionDescriptor currDescriptor = descriptors.at(i);
       
   558         QContactAction *currImpl = QContactManagerData::action(currDescriptor);
       
   559         if (QContactManagerEngine::testFilter(currImpl->contactFilter(), *this)) {
       
   560             if ((vendorName.isEmpty() || currDescriptor.vendorName() == vendorName) &&
       
   561                     (implementationVersion == -1 || currDescriptor.implementationVersion() == implementationVersion)) {
       
   562                 retn.insert(currDescriptor);
       
   563             }
       
   564         }
       
   565 
       
   566         // clean up the implementation to avoid leak.
       
   567         delete currImpl;
       
   568     }
       
   569 
       
   570     return retn.toList();
       
   571 }
       
   572 
       
   573 /*!
       
   574  * \preliminary
       
   575  * 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
       
   577  * identified by \a actionName, otherwise returns false
       
   578  */
       
   579 bool QContact::setPreferredDetail(const QString& actionName, const QContactDetail& preferredDetail)
       
   580 {
       
   581     // if the given action name is empty, bad argument.
       
   582     if (actionName.isEmpty())
       
   583         return false;
       
   584 
       
   585     // check to see whether the the given preferredDetail is saved in this contact
       
   586     if (!d->m_details.contains(preferredDetail))
       
   587         return false;
       
   588 
       
   589     // otherwise, save the preference.
       
   590     d->m_preferences.insert(actionName, preferredDetail.d->m_id);
       
   591     return true;
       
   592 }
       
   593 
       
   594 /*!
       
   595  * \preliminary
       
   596  *
       
   597  * Returns true if the given \a detail is a preferred detail for the given \a actionName, or for any action if the \a actionName is empty
       
   598  */
       
   599 bool QContact::isPreferredDetail(const QString& actionName, const QContactDetail& detail) const
       
   600 {
       
   601     if (!d->m_details.contains(detail))
       
   602         return false;
       
   603 
       
   604     if (actionName.isEmpty())
       
   605          return d->m_preferences.values().contains(detail.d->m_id);
       
   606 
       
   607     QMap<QString, int>::const_iterator it = d->m_preferences.find(actionName);
       
   608     if (it != d->m_preferences.end() && it.value() == detail.d->m_id)
       
   609         return true;
       
   610 
       
   611     return false;
       
   612 }
       
   613 
       
   614 /*!
       
   615  * \preliminary
       
   616  * Returns the preferred detail for a given \a actionName
       
   617  */
       
   618 QContactDetail QContact::preferredDetail(const QString& actionName) const
       
   619 {
       
   620     // if the given action name is empty, bad argument.
       
   621     if (actionName.isEmpty())
       
   622         return QContactDetail();
       
   623 
       
   624     if (!d->m_preferences.contains(actionName))
       
   625         return QContactDetail();
       
   626 
       
   627     QContactDetail retn;
       
   628     int detId = d->m_preferences.value(actionName);
       
   629     for (int i = 0; i < d->m_details.size(); i++) {
       
   630         QContactDetail det = d->m_details.at(i);
       
   631         if (det.d->m_id == detId) {
       
   632             // found it.
       
   633             retn = det;
       
   634             break;
       
   635         }
       
   636     }
       
   637 
       
   638     return retn;
       
   639 }
       
   640 
       
   641 QTM_END_NAMESPACE