qtmobility/src/contacts/qcontact.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
--- a/qtmobility/src/contacts/qcontact.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/contacts/qcontact.cpp	Mon May 03 13:18:40 2010 +0300
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include <QSet>
+#include <QDebug>
 
 #include "qcontact.h"
 #include "qcontact_p.h"
@@ -52,7 +53,7 @@
 /*!
   \class QContact
  
-  \brief The QContact class provides an addressbook contact.
+  \brief The QContact class represents an addressbook contact.
 
   \ingroup contacts-main
  
@@ -60,7 +61,7 @@
  
   An instance of the QContact class represents an in-memory contact,
   and may not reflect the state of that contact found in persistent
-  storage until the appropriate synchronisation method is called
+  storage until the appropriate synchronization method is called
   on the QContactManager (i.e., saveContact, removeContact).
  
   \sa QContactManager, QContactDetail
@@ -233,10 +234,13 @@
 /*! Returns the first detail stored in the contact which is of the given \a definitionName */
 QContactDetail QContact::detail(const QString& definitionName) const
 {
+    if (definitionName.isEmpty())
+        return d->m_details.first();
+
     // build the sub-list of matching details.
     for (int i = 0; i < d->m_details.size(); i++) {
         const QContactDetail& existing = d->m_details.at(i);
-        if (definitionName.isEmpty() || definitionName == existing.definitionName()) {
+        if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
             return existing;
         }
     }
@@ -256,7 +260,7 @@
     } else {
         for (int i = 0; i < d->m_details.size(); i++) {
             const QContactDetail& existing = d->m_details.at(i);
-            if (definitionName == existing.definitionName()) {
+            if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
                 sublist.append(existing);
             }
         }
@@ -277,7 +281,68 @@
     } else {
         for (int i = 0; i < d->m_details.size(); i++) {
             const QContactDetail& existing = d->m_details.at(i);
-            if (definitionName == existing.definitionName() && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
+            if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName
+                && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
+                sublist.append(existing);
+            }
+        }
+    }
+
+    return sublist;
+}
+
+/*! Returns the first detail stored in the contact which is of the given \a definitionName */
+QContactDetail QContact::detail(const char* definitionName) const
+{
+    if (definitionName == 0)
+        return d->m_details.first();
+
+    // build the sub-list of matching details.
+    for (int i = 0; i < d->m_details.size(); i++) {
+        const QContactDetail& existing = d->m_details.at(i);
+        if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
+            return existing;
+        }
+    }
+
+    return QContactDetail();
+}
+
+/*! Returns a list of details of the given \a definitionName */
+QList<QContactDetail> QContact::details(const char* definitionName) const
+{
+    // build the sub-list of matching details.
+    QList<QContactDetail> sublist;
+
+    // special case
+    if (definitionName == 0) {
+        sublist = d->m_details;
+    } else {
+        for (int i = 0; i < d->m_details.size(); i++) {
+            const QContactDetail& existing = d->m_details.at(i);
+            if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName) {
+                sublist.append(existing);
+            }
+        }
+    }
+
+    return sublist;
+}
+
+/*! Returns a list of details of the given \a definitionName, \a fieldName and field \a value*/
+QList<QContactDetail> QContact::details(const char* definitionName, const char* fieldName, const QString& value) const
+{
+    // build the sub-list of matching details.
+    QList<QContactDetail> sublist;
+
+    // special case
+    if (fieldName == 0) {
+        sublist = details(definitionName);
+    } else {
+        for (int i = 0; i < d->m_details.size(); i++) {
+            const QContactDetail& existing = d->m_details.at(i);
+            if (QContactDetailPrivate::detailPrivate(existing)->m_definitionName == definitionName
+                && existing.hasValue(fieldName) && value == existing.value(fieldName)) {
                 sublist.append(existing);
             }
         }
@@ -317,14 +382,14 @@
         return false;
 
     /* Also handle contact type specially - only one of them. */
-    if (detail->definitionName() == QContactType::DefinitionName) {
+    if (QContactDetailPrivate::detailPrivate(*detail)->m_definitionName == QContactType::DefinitionName.latin1()) {
         detail->d->m_access = QContactDetail::Irremovable;
         d->m_details[1] = *detail;
         return true;
     }
 
     /* And display label.. */
-    if (detail->definitionName() == QContactDisplayLabel::DefinitionName) {
+    if (QContactDetailPrivate::detailPrivate(*detail)->m_definitionName == QContactDisplayLabel::DefinitionName.latin1()) {
         detail->d->m_access = QContactDetail::Irremovable | QContactDetail::ReadOnly;
         return false;
     }
@@ -406,6 +471,24 @@
         other.d->m_details == d->m_details;
 }
 
+/*! Returns the hash value for \a key. */
+uint qHash(const QContact &key)
+{
+    uint hash = qHash(key.id());
+    foreach (const QContactDetail& detail, key.details()) {
+        hash += qHash(detail);
+    }
+    return hash;
+}
+
+QDebug operator<<(QDebug dbg, const QContact& contact)
+{
+    dbg.nospace() << "QContact(" << contact.id() << ")";
+    foreach (const QContactDetail& detail, contact.details()) {
+        dbg.space() << '\n' << detail;
+    }
+    return dbg.maybeSpace();
+}
 
 /*! Retrieve the first detail for which the given \a actionName is available */
 QContactDetail QContact::detailWithAction(const QString& actionName) const
@@ -434,7 +517,7 @@
         QContactAction *currImpl = QContactManagerData::action(descriptors.at(i));
         for (int i = 0; i < d->m_details.size(); i++) {
             QContactDetail detail = d->m_details.at(i);
-            if (currImpl->supportsDetail(detail)) {
+            if (currImpl->isDetailSupported(detail, *this)) {
                 retn.append(detail);
                 break;
             }
@@ -470,75 +553,44 @@
 }
 
 /*!
- * \preliminary
- * Returns a list of ids of contacts which are related to this contact in a relationship of the
- * given \a relationshipType, where those other contacts participate in the relationship in the
- * given \a role
+  Returns a list of ids of contacts which are related to this contact in a relationship of the
+  given \a relationshipType, where those other contacts participate in the relationship in the
+  given \a role.
  */
-QList<QContactId> QContact::relatedContacts(const QString& relationshipType, QContactRelationshipFilter::Role role) const
+QList<QContactId> QContact::relatedContacts(const QString& relationshipType, QContactRelationship::Role role) const
 {
     QList<QContactId> retn;
     for (int i = 0; i < d->m_relationshipsCache.size(); i++) {
         QContactRelationship curr = d->m_relationshipsCache.at(i);
-        if (curr.relationshipType() == relationshipType || relationshipType.isEmpty()) {
+        if (relationshipType.isEmpty() || curr.relationshipType() == relationshipType) {
             // check that the other contacts fill the given role
-            if (role == QContactRelationshipFilter::First) {
+            if (role == QContactRelationship::First) {
                 if (curr.first() != d->m_id) {
-                    retn.append(curr.first());
+                    if (!retn.contains(curr.first())) {
+                        retn.append(curr.first());
+                    }
                 }
-            } else if (role == QContactRelationshipFilter::Second) {
+            } else if (role == QContactRelationship::Second) {
                 if (curr.first() == d->m_id) {
-                    retn.append(curr.second());
+                    if (!retn.contains(curr.second())) {
+                        retn.append(curr.second());
+                    }
                 }
             } else { // role == Either.
                 if (curr.first() == d->m_id) {
-                    retn.append(curr.second());
+                    if (!retn.contains(curr.second())) {
+                        retn.append(curr.second());
+                    }
                 } else {
-                    retn.append(curr.first());
+                    if (!retn.contains(curr.first())) {
+                        retn.append(curr.first());
+                    }
                 }
             }
         }
     }
 
-    QList<QContactId> removeDuplicates;
-    for (int i = 0; i < retn.size(); i++) {
-        QContactId curr = retn.at(i);
-        if (!removeDuplicates.contains(curr)) {
-            removeDuplicates.append(curr);
-        }
-    }
-
-    return removeDuplicates;
-}
-
-/*!
- * \preliminary
- * Sets the order of importance of the relationships for this contact by saving a \a reordered list of relationships which involve the contact.
- * The list must include all of the relationships in which the contact is involved, and must not include any relationships which do
- * not involve the contact.  In order for the ordering preference to be persisted, the contact must be saved in its manager.
- *
- * It is possible that relationships will have been added or removed from the contact stored in the manager,
- * thus rendering the relationship cache of the contact in memory stale.   If this happens, attempting to save the contact after reordering
- * its relationships will result in an error occurring. The updated relationships list must be retrieved from the manager, reordered and set
- * in the contact before the contact can be saved successfully.
- *
- * \sa relationships(), relationshipOrder()
- */
-void QContact::setRelationshipOrder(const QList<QContactRelationship>& reordered)
-{
-    d->m_reorderedRelationshipsCache = reordered;
-}
-
-/*!
- * \preliminary
- * Returns the ordered list of relationships in which the contact is involved.  By default, this list is equal to the cached
- * list of relationships which is available by calling relationships().
- *
- * \sa setRelationshipOrder()
- */
-QList<QContactRelationship> QContact::relationshipOrder() const
-{
-    return d->m_reorderedRelationshipsCache;
+    return retn;
 }
 
 /*!
@@ -573,8 +625,10 @@
 /*!
  * \preliminary
  * Set a particular detail as the \a preferredDetail for a given \a actionName.  Returns
- * true if the detail was successfully set as the preferred detail for the action
- * identified by \a actionName, otherwise returns false
+ * true if the detail exists in the contact and was successfully set as the preferred detail for the action
+ * identified by \a actionName, otherwise returns false.
+ * Note that since QContact is a value class, no error checking is done on the action name
+ * (to ensure that an action of that name is available) in this function.
  */
 bool QContact::setPreferredDetail(const QString& actionName, const QContactDetail& preferredDetail)
 {
@@ -638,4 +692,22 @@
     return retn;
 }
 
+
+
+/*!
+ * \preliminary
+ * Returns a map of action name to the preferred detail for the action of that name.
+ */
+QMap<QString, QContactDetail> QContact::preferredDetails() const
+{
+    QMap<QString, QContactDetail> ret;
+    QMap<QString, int>::const_iterator it = d->m_preferences.constBegin();
+    while (it != d->m_preferences.constEnd()) {
+        ret.insert(it.key(), d->m_details.at(it.value()));
+        ++it;
+    }
+
+    return ret;
+}
+
 QTM_END_NAMESPACE