qtmobility/src/contacts/qcontactdetail.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "qcontactdetail.h"
    42 #include "qcontactdetail.h"
    43 #include "qcontactdetail_p.h"
    43 #include "qcontactdetail_p.h"
    44 #include "qcontactmanager.h"
    44 #include "qcontactmanager.h"
       
    45 #include <QDebug>
    45 
    46 
    46 QTM_BEGIN_NAMESPACE
    47 QTM_BEGIN_NAMESPACE
    47 
    48 
    48 /* Initialise our static private data member */
    49 /* Initialise our static private data member */
    49 QAtomicInt QContactDetailPrivate::lastDetailKey(1);
    50 QAtomicInt QContactDetailPrivate::lastDetailKey(1);
    50 
    51 
    51 /* Definitions of predefined string constants */
    52 /* Definitions of predefined string constants */
    52 Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldDetailUri, "DetailUri");
    53 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldDetailUri, "DetailUri");
    53 Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldLinkedDetailUris, "LinkedDetailUris");
    54 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldLinkedDetailUris, "LinkedDetailUris");
    54 Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldContext, "Context");
    55 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldContext, "Context");
    55 Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextOther, "Other");
    56 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextOther, "Other");
    56 Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextHome, "Home");
    57 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextHome, "Home");
    57 Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextWork, "Work");
    58 Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextWork, "Work");
       
    59 
       
    60 static uint qHash(const QContactStringHolder& holder)
       
    61 {
       
    62     if (!holder.m_str)
       
    63         return 0;
       
    64     uint h = 0;
       
    65     uint g;
       
    66     const register uchar*p = (const uchar*)holder.m_str;
       
    67 
       
    68     while (*p) {
       
    69         h = (h << 4) + *p++;
       
    70         if ((g = (h & 0xf0000000)) != 0)
       
    71             h ^= g >> 23;
       
    72         h &= ~g;
       
    73     }
       
    74     return h;
       
    75 }
       
    76 
       
    77 /* Storage */
       
    78 QHash<QString, char*> QContactStringHolder::s_allocated;
       
    79 QHash<const char *, QString> QContactStringHolder::s_qstrings;
       
    80 
       
    81 /* Dtor function */
       
    82 static int qClearAllocatedStringHash()
       
    83 {
       
    84     QHash<QString, char*>::const_iterator it = QContactStringHolder::s_allocated.constBegin();
       
    85     while (it != QContactStringHolder::s_allocated.constEnd()) {
       
    86         delete[] it.value();
       
    87         it++;
       
    88     }
       
    89     QContactStringHolder::s_allocated.clear();
       
    90     QContactStringHolder::s_qstrings.clear();
       
    91     return 1;
       
    92 }
       
    93 Q_DESTRUCTOR_FUNCTION(qClearAllocatedStringHash);
    58 
    94 
    59 /*!
    95 /*!
    60   \class QContactDetail
    96   \class QContactDetail
    61  
    97  
    62   \brief The QContactDetail class provides access to a single, complete detail about a contact.
    98   \brief The QContactDetail class represents a single, complete detail about a contact.
    63   \ingroup contacts-main
    99   \ingroup contacts-main
    64  
   100  
    65   All of the information for a contact is stored in one or more QContactDetail objects.
   101   All of the information for a contact is stored in one or more QContactDetail objects.
    66  
   102  
    67   A detail is a group of logically related bits of data - for example, a street address is a single
   103   A detail is a group of logically related bits of data - for example, a street address is a single
   156 QContactDetail::QContactDetail()
   192 QContactDetail::QContactDetail()
   157     : d(new QContactDetailPrivate)
   193     : d(new QContactDetailPrivate)
   158 {
   194 {
   159 }
   195 }
   160 
   196 
       
   197 /*!
       
   198     Constructs a new, empty detail of the definition identified by \a thisDefinitionId.
       
   199     The definitionId must be restricted to the Latin 1 character set.
       
   200  */
       
   201 QContactDetail::QContactDetail(const QString& thisDefinitionId)
       
   202     : d(new QContactDetailPrivate)
       
   203 {
       
   204     d->m_definitionName = thisDefinitionId;
       
   205 }
       
   206 
   161 /*! Constructs a new, empty detail of the definition identified by \a thisDefinitionId */
   207 /*! Constructs a new, empty detail of the definition identified by \a thisDefinitionId */
   162 QContactDetail::QContactDetail(const QString& thisDefinitionId)
   208 QContactDetail::QContactDetail(const char* thisDefinitionId)
   163     : d(new QContactDetailPrivate)
   209     : d(new QContactDetailPrivate)
   164 {
   210 {
   165     d->m_definitionName = thisDefinitionId;
   211     d->m_definitionName = thisDefinitionId;
   166 }
   212 }
   167 
   213 
   169 QContactDetail::QContactDetail(const QContactDetail& other)
   215 QContactDetail::QContactDetail(const QContactDetail& other)
   170     : d(other.d)
   216     : d(other.d)
   171 {
   217 {
   172 }
   218 }
   173 
   219 
   174 /*! Constructs a detail that is a copy of \a other if \a other is of the expected definition identified by \a expectedDefinitionId, else constructs a new, empty detail of the definition identified by the \a expectedDefinitionId */
   220 /*!
   175 QContactDetail::QContactDetail(const QContactDetail& other, const QString& expectedDefinitionId)
   221     Constructs a detail that is a copy of \a other if \a other is of the expected definition
   176 {
   222     identified by \a expectedDefinitionId, else constructs a new, empty detail of the
   177     if (other.definitionName() == expectedDefinitionId) {
   223     definition identified by the \a expectedDefinitionId
       
   224 */
       
   225 QContactDetail::QContactDetail(const QContactDetail& other, const char* expectedDefinitionId)
       
   226 {
       
   227     if (other.d->m_definitionName == expectedDefinitionId) {
   178         d = other.d;
   228         d = other.d;
   179     } else {
   229     } else {
   180         d = new QContactDetailPrivate;
   230         d = new QContactDetailPrivate;
   181         d->m_definitionName = expectedDefinitionId;
   231         d->m_definitionName = expectedDefinitionId;
   182     }
   232     }
   183 }
   233 }
   184 
   234 
       
   235 /*!
       
   236     Constructs a detail that is a copy of \a other if \a other is of the expected definition
       
   237     identified by \a expectedDefinitionId, else constructs a new, empty detail of the
       
   238     definition identified by the \a expectedDefinitionId
       
   239 */
       
   240 QContactDetail::QContactDetail(const QContactDetail& other, const QString& expectedDefinitionId)
       
   241 {
       
   242     if (other.d->m_definitionName == expectedDefinitionId) {
       
   243         d = other.d;
       
   244     } else {
       
   245         d = new QContactDetailPrivate;
       
   246         d->m_definitionName = expectedDefinitionId;
       
   247     }
       
   248 }
       
   249 
   185 /*! Assigns this detail to \a other */
   250 /*! Assigns this detail to \a other */
   186 QContactDetail& QContactDetail::operator=(const QContactDetail& other)
   251 QContactDetail& QContactDetail::operator=(const QContactDetail& other)
   187 {
   252 {
   188     if (this != &other)
   253     if (this != &other)
   189         d = other.d;
   254         d = other.d;
   190     return *this;
   255     return *this;
   191 }
   256 }
   192 
   257 
   193 /*! Assigns this detail to \a other if the definition of \a other is that identified by the given \a expectedDefinitionId, else assigns this detail to be a new, empty detail of the definition identified by the given \a expectedDefinitionId */
   258 /*!
   194 QContactDetail& QContactDetail::assign(const QContactDetail& other, const QString& expectedDefinitionId)
   259     Assigns this detail to \a other if the definition of \a other is that identified
       
   260     by the given \a expectedDefinitionId, else assigns this detail to be a new, empty
       
   261     detail of the definition identified by the given \a expectedDefinitionId
       
   262 */
       
   263 QContactDetail& QContactDetail::assign(const QContactDetail& other, const char* expectedDefinitionId)
   195 {
   264 {
   196     if (this != &other) {
   265     if (this != &other) {
   197         if (other.definitionName() == expectedDefinitionId) {
   266         if (other.d->m_definitionName == expectedDefinitionId) {
   198             d = other.d;
   267             d = other.d;
   199         } else {
   268         } else {
   200             d = new QContactDetailPrivate;
   269             d = new QContactDetailPrivate;
   201             d->m_definitionName = expectedDefinitionId;
   270             d->m_definitionName = expectedDefinitionId;
   202         }
   271         }
   203     }
   272     }
   204     return *this;
   273     return *this;
   205 }
   274 }
   206 
   275 
       
   276 /*!
       
   277     Assigns this detail to \a other if the definition of \a other is that identified
       
   278     by the given \a expectedDefinitionId, else assigns this detail to be a new, empty
       
   279     detail of the definition identified by the given \a expectedDefinitionId
       
   280 */
       
   281 QContactDetail& QContactDetail::assign(const QContactDetail& other, const QString& expectedDefinitionId)
       
   282 {
       
   283     if (this != &other) {
       
   284         if (other.d->m_definitionName == expectedDefinitionId) {
       
   285             d = other.d;
       
   286         } else {
       
   287             d = new QContactDetailPrivate;
       
   288             d->m_definitionName = expectedDefinitionId;
       
   289         }
       
   290     }
       
   291     return *this;
       
   292 }
       
   293 
   207 /*! Frees the memory used by this detail */
   294 /*! Frees the memory used by this detail */
   208 QContactDetail::~QContactDetail()
   295 QContactDetail::~QContactDetail()
   209 {
   296 {
   210 }
   297 }
   211 
   298 
   218 /*! Compares this detail to \a other.  Returns true if the definition and values of \a other are equal to those of this detail.
   305 /*! Compares this detail to \a other.  Returns true if the definition and values of \a other are equal to those of this detail.
   219     The keys of each detail are not considered during the comparison, in order to allow details from different contacts to
   306     The keys of each detail are not considered during the comparison, in order to allow details from different contacts to
   220     be compared according to their values. */
   307     be compared according to their values. */
   221 bool QContactDetail::operator==(const QContactDetail& other) const
   308 bool QContactDetail::operator==(const QContactDetail& other) const
   222 {
   309 {
   223     if (d.constData()->m_definitionName != other.d.constData()->m_definitionName)
   310     if (! (d.constData()->m_definitionName == other.d.constData()->m_definitionName))
   224         return false;
   311         return false;
   225 
   312 
   226     if (d.constData()->m_access != other.d.constData()->m_access)
   313     if (d.constData()->m_access != other.d.constData()->m_access)
   227         return false;
   314         return false;
   228 
   315 
   230         return false;
   317         return false;
   231 
   318 
   232     return true;
   319     return true;
   233 }
   320 }
   234 
   321 
   235 /*! Sets the preferred actions for this detail to be the given list of \a preferredActions */
   322 /*! Returns the hash value for \a key. */
   236 void QContactDetail::setPreferredActions(const QList<QContactActionDescriptor>& preferredActions)
   323 uint qHash(const QContactDetail &key)
   237 {
   324 {
   238     d->m_preferredActions = preferredActions;
   325     const QContactDetailPrivate* dptr= QContactDetailPrivate::detailPrivate(key);
   239 }
   326     uint hash = QT_PREPEND_NAMESPACE(qHash)(dptr->m_definitionName)
   240 
   327                 + QT_PREPEND_NAMESPACE(qHash)(dptr->m_access);
   241 /*! Returns the list of preferred actions for this detail */
   328     QHash<QContactStringHolder, QVariant>::const_iterator it = dptr->m_values.constBegin();
   242 QList<QContactActionDescriptor> QContactDetail::preferredActions() const
   329     while(it != dptr->m_values.constEnd()) {
   243 {
   330         hash += QT_PREPEND_NAMESPACE(qHash)(it.key())
   244     return d->m_preferredActions;
   331                 + QT_PREPEND_NAMESPACE(qHash)(it.value().toString());
   245 }
   332         ++it;
       
   333     }
       
   334     return hash;
       
   335 }
       
   336 
       
   337 #ifndef QT_NO_DEBUG_STREAM
       
   338 QDebug operator<<(QDebug dbg, const QContactDetail& detail)
       
   339 {
       
   340     dbg.nospace() << "QContactDetail(name=" << detail.definitionName() << ", key=" << detail.key();
       
   341     QVariantMap fields = detail.variantValues();
       
   342     QVariantMap::const_iterator it;
       
   343     for (it = fields.constBegin(); it != fields.constEnd(); ++it) {
       
   344         dbg.nospace() << ", " << it.key() << '=' << it.value();
       
   345     }
       
   346     dbg.nospace() << ')';
       
   347     return dbg.maybeSpace();
       
   348 }
       
   349 #endif
   246 
   350 
   247 /*! Returns true if no values are contained in this detail.  Note that context is stored as a value; hence, if a context is set, this function will return false. */
   351 /*! Returns true if no values are contained in this detail.  Note that context is stored as a value; hence, if a context is set, this function will return false. */
   248 bool QContactDetail::isEmpty() const
   352 bool QContactDetail::isEmpty() const
   249 {
   353 {
   250     if (!d.constData()->m_values.isEmpty())
   354     if (!d.constData()->m_values.isEmpty())
   269 /*! \overload
   373 /*! \overload
   270   Returns the value stored in this detail for the given \a key as a QString, or an empty QString if
   374   Returns the value stored in this detail for the given \a key as a QString, or an empty QString if
   271   no value for the given \a key exists */
   375   no value for the given \a key exists */
   272 QString QContactDetail::value(const QString& key) const
   376 QString QContactDetail::value(const QString& key) const
   273 {
   377 {
   274     if (d.constData()->m_values.contains(key))
   378     return d.constData()->m_values.value(key.toLatin1().constData()).toString();
   275         return d.constData()->m_values.value(key).toString();
   379 }
   276     return QString();
   380 
       
   381 
       
   382 /*! \overload
       
   383   Returns the value stored in this detail for the given \a key as a QString, or an empty QString if
       
   384   no value for the given \a key exists */
       
   385 QString QContactDetail::value(const char* key) const
       
   386 {
       
   387     return d.constData()->m_values.value(key).toString();
   277 }
   388 }
   278 
   389 
   279 // A bug in qdoc means this comment needs to appear below the comment for the other value().
   390 // A bug in qdoc means this comment needs to appear below the comment for the other value().
   280 /*!
   391 /*!
   281   \fn T QContactDetail::value(const QString& key) const
   392   \fn T QContactDetail::value(const QString& key) const
   283  */
   394  */
   284 
   395 
   285 /*! Returns the value stored in this detail for the given \a key as a QVariant, or an invalid QVariant if no value for the given \a key exists */
   396 /*! Returns the value stored in this detail for the given \a key as a QVariant, or an invalid QVariant if no value for the given \a key exists */
   286 QVariant QContactDetail::variantValue(const QString& key) const
   397 QVariant QContactDetail::variantValue(const QString& key) const
   287 {
   398 {
   288     if (d.constData()->m_values.contains(key))
   399     return d.constData()->m_values.value(key.toLatin1().constData());
   289         return d.constData()->m_values.value(key);
   400 }
   290     return QVariant(); // returns an invalid qvariant
   401 
       
   402 /*! Returns the value stored in this detail for the given \a key as a QVariant, or an invalid QVariant if no value for the given \a key exists */
       
   403 QVariant QContactDetail::variantValue(const char* key) const
       
   404 {
       
   405     return d.constData()->m_values.value(key);
   291 }
   406 }
   292 
   407 
   293 /*!
   408 /*!
   294   Returns true if this detail has a field with the given \a key, or false otherwise.
   409   Returns true if this detail has a field with the given \a key, or false otherwise.
   295  */
   410  */
   296 bool QContactDetail::hasValue(const QString& key) const
   411 bool QContactDetail::hasValue(const QString& key) const
   297 {
   412 {
   298     if (d.constData()->m_values.contains(key))
   413     return d.constData()->m_values.contains(key.toLatin1().constData());
   299         return true;
   414 }
   300     return false;
   415 
       
   416 /*!
       
   417   Returns true if this detail has a field with the given \a key, or false otherwise.
       
   418  */
       
   419 bool QContactDetail::hasValue(const char * key) const
       
   420 {
       
   421     return d.constData()->m_values.contains(key);
   301 }
   422 }
   302 
   423 
   303 /*! Inserts \a value into the detail for the given \a key if \a value is valid.  If \a value is invalid,
   424 /*! Inserts \a value into the detail for the given \a key if \a value is valid.  If \a value is invalid,
   304     removes the field with the given \a key from the detail.  Returns true if the given \a value was set
   425     removes the field with the given \a key from the detail.  Returns true if the given \a value was set
   305     for the \a key (if the \a value was valid), or if the given \a key was removed from detail (if the
   426     for the \a key (if the \a value was valid), or if the given \a key was removed from detail (if the
   307 bool QContactDetail::setValue(const QString& key, const QVariant& value)
   428 bool QContactDetail::setValue(const QString& key, const QVariant& value)
   308 {
   429 {
   309     if (!value.isValid())
   430     if (!value.isValid())
   310         return removeValue(key);
   431         return removeValue(key);
   311 
   432 
       
   433     d->m_values.insert(QContactStringHolder(key), value);
       
   434     return true;
       
   435 }
       
   436 
       
   437 /*! Inserts \a value into the detail for the given \a key if \a value is valid.  If \a value is invalid,
       
   438     removes the field with the given \a key from the detail.  Returns true if the given \a value was set
       
   439     for the \a key (if the \a value was valid), or if the given \a key was removed from detail (if the
       
   440     \a value was invalid), and returns false if the key was unable to be removed (and the \a value was invalid) */
       
   441 bool QContactDetail::setValue(const char* key, const QVariant& value)
       
   442 {
       
   443     if (!value.isValid())
       
   444         return removeValue(key);
       
   445 
   312     d->m_values.insert(key, value);
   446     d->m_values.insert(key, value);
   313     return true;
   447     return true;
   314 }
   448 }
   315 
   449 
   316 /*! Removes the value stored in this detail for the given \a key.  Returns true if a value was stored for the given \a key and the operation succeeded, and false otherwise */
   450 /*! Removes the value stored in this detail for the given \a key.  Returns true if a value was stored for the given \a key and the operation succeeded, and false otherwise */
   317 bool QContactDetail::removeValue(const QString& key)
   451 bool QContactDetail::removeValue(const QString& key)
       
   452 {
       
   453     if(d->m_values.remove(key.toLatin1().constData()))
       
   454         return true;
       
   455     return false;
       
   456 }
       
   457 /*! Removes the value stored in this detail for the given \a key.  Returns true if a value was stored for the given \a key and the operation succeeded, and false otherwise */
       
   458 bool QContactDetail::removeValue(const char * key)
   318 {
   459 {
   319     if(d->m_values.remove(key))
   460     if(d->m_values.remove(key))
   320         return true;
   461         return true;
   321     return false;
   462     return false;
   322 }
   463 }
   324 /*!
   465 /*!
   325   Returns the values stored in this detail as a map from value key to value
   466   Returns the values stored in this detail as a map from value key to value
   326  */
   467  */
   327 QVariantMap QContactDetail::variantValues() const
   468 QVariantMap QContactDetail::variantValues() const
   328 {
   469 {
   329     return d.constData()->m_values;
   470     QVariantMap ret;
       
   471     QHash<QContactStringHolder, QVariant>::const_iterator it = d.constData()->m_values.constBegin();
       
   472     while(it != d.constData()->m_values.constEnd()) {
       
   473         ret.insert(it.key(), it.value());
       
   474         ++it;
       
   475     }
       
   476 
       
   477     return ret;
   330 }
   478 }
   331 
   479 
   332 /*!
   480 /*!
   333   \enum QContactDetail::AccessConstraint
   481   \enum QContactDetail::AccessConstraint
   334 
   482