diff -r 2b40d63a9c3d -r 90517678cc4f qtmobility/src/contacts/qcontactdetail.cpp --- a/qtmobility/src/contacts/qcontactdetail.cpp Fri Apr 16 15:51:22 2010 +0300 +++ b/qtmobility/src/contacts/qcontactdetail.cpp Mon May 03 13:18:40 2010 +0300 @@ -42,6 +42,7 @@ #include "qcontactdetail.h" #include "qcontactdetail_p.h" #include "qcontactmanager.h" +#include QTM_BEGIN_NAMESPACE @@ -49,17 +50,52 @@ QAtomicInt QContactDetailPrivate::lastDetailKey(1); /* Definitions of predefined string constants */ -Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldDetailUri, "DetailUri"); -Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldLinkedDetailUris, "LinkedDetailUris"); -Q_DEFINE_LATIN1_LITERAL(QContactDetail::FieldContext, "Context"); -Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextOther, "Other"); -Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextHome, "Home"); -Q_DEFINE_LATIN1_LITERAL(QContactDetail::ContextWork, "Work"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldDetailUri, "DetailUri"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldLinkedDetailUris, "LinkedDetailUris"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::FieldContext, "Context"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextOther, "Other"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextHome, "Home"); +Q_DEFINE_LATIN1_CONSTANT(QContactDetail::ContextWork, "Work"); + +static uint qHash(const QContactStringHolder& holder) +{ + if (!holder.m_str) + return 0; + uint h = 0; + uint g; + const register uchar*p = (const uchar*)holder.m_str; + + while (*p) { + h = (h << 4) + *p++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 23; + h &= ~g; + } + return h; +} + +/* Storage */ +QHash QContactStringHolder::s_allocated; +QHash QContactStringHolder::s_qstrings; + +/* Dtor function */ +static int qClearAllocatedStringHash() +{ + QHash::const_iterator it = QContactStringHolder::s_allocated.constBegin(); + while (it != QContactStringHolder::s_allocated.constEnd()) { + delete[] it.value(); + it++; + } + QContactStringHolder::s_allocated.clear(); + QContactStringHolder::s_qstrings.clear(); + return 1; +} +Q_DESTRUCTOR_FUNCTION(qClearAllocatedStringHash); /*! \class QContactDetail - \brief The QContactDetail class provides access to a single, complete detail about a contact. + \brief The QContactDetail class represents a single, complete detail about a contact. \ingroup contacts-main All of the information for a contact is stored in one or more QContactDetail objects. @@ -158,8 +194,18 @@ { } +/*! + Constructs a new, empty detail of the definition identified by \a thisDefinitionId. + The definitionId must be restricted to the Latin 1 character set. + */ +QContactDetail::QContactDetail(const QString& thisDefinitionId) + : d(new QContactDetailPrivate) +{ + d->m_definitionName = thisDefinitionId; +} + /*! Constructs a new, empty detail of the definition identified by \a thisDefinitionId */ -QContactDetail::QContactDetail(const QString& thisDefinitionId) +QContactDetail::QContactDetail(const char* thisDefinitionId) : d(new QContactDetailPrivate) { d->m_definitionName = thisDefinitionId; @@ -171,10 +217,29 @@ { } -/*! 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 */ +/*! + 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 +*/ +QContactDetail::QContactDetail(const QContactDetail& other, const char* expectedDefinitionId) +{ + if (other.d->m_definitionName == expectedDefinitionId) { + d = other.d; + } else { + d = new QContactDetailPrivate; + d->m_definitionName = expectedDefinitionId; + } +} + +/*! + 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 +*/ QContactDetail::QContactDetail(const QContactDetail& other, const QString& expectedDefinitionId) { - if (other.definitionName() == expectedDefinitionId) { + if (other.d->m_definitionName == expectedDefinitionId) { d = other.d; } else { d = new QContactDetailPrivate; @@ -190,11 +255,33 @@ return *this; } -/*! 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 */ +/*! + 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 +*/ +QContactDetail& QContactDetail::assign(const QContactDetail& other, const char* expectedDefinitionId) +{ + if (this != &other) { + if (other.d->m_definitionName == expectedDefinitionId) { + d = other.d; + } else { + d = new QContactDetailPrivate; + d->m_definitionName = expectedDefinitionId; + } + } + return *this; +} + +/*! + 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 +*/ QContactDetail& QContactDetail::assign(const QContactDetail& other, const QString& expectedDefinitionId) { if (this != &other) { - if (other.definitionName() == expectedDefinitionId) { + if (other.d->m_definitionName == expectedDefinitionId) { d = other.d; } else { d = new QContactDetailPrivate; @@ -220,7 +307,7 @@ be compared according to their values. */ bool QContactDetail::operator==(const QContactDetail& other) const { - if (d.constData()->m_definitionName != other.d.constData()->m_definitionName) + if (! (d.constData()->m_definitionName == other.d.constData()->m_definitionName)) return false; if (d.constData()->m_access != other.d.constData()->m_access) @@ -232,17 +319,34 @@ return true; } -/*! Sets the preferred actions for this detail to be the given list of \a preferredActions */ -void QContactDetail::setPreferredActions(const QList& preferredActions) +/*! Returns the hash value for \a key. */ +uint qHash(const QContactDetail &key) { - d->m_preferredActions = preferredActions; + const QContactDetailPrivate* dptr= QContactDetailPrivate::detailPrivate(key); + uint hash = QT_PREPEND_NAMESPACE(qHash)(dptr->m_definitionName) + + QT_PREPEND_NAMESPACE(qHash)(dptr->m_access); + QHash::const_iterator it = dptr->m_values.constBegin(); + while(it != dptr->m_values.constEnd()) { + hash += QT_PREPEND_NAMESPACE(qHash)(it.key()) + + QT_PREPEND_NAMESPACE(qHash)(it.value().toString()); + ++it; + } + return hash; } -/*! Returns the list of preferred actions for this detail */ -QList QContactDetail::preferredActions() const +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QContactDetail& detail) { - return d->m_preferredActions; + dbg.nospace() << "QContactDetail(name=" << detail.definitionName() << ", key=" << detail.key(); + QVariantMap fields = detail.variantValues(); + QVariantMap::const_iterator it; + for (it = fields.constBegin(); it != fields.constEnd(); ++it) { + dbg.nospace() << ", " << it.key() << '=' << it.value(); + } + dbg.nospace() << ')'; + return dbg.maybeSpace(); } +#endif /*! 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. */ bool QContactDetail::isEmpty() const @@ -271,9 +375,16 @@ no value for the given \a key exists */ QString QContactDetail::value(const QString& key) const { - if (d.constData()->m_values.contains(key)) - return d.constData()->m_values.value(key).toString(); - return QString(); + return d.constData()->m_values.value(key.toLatin1().constData()).toString(); +} + + +/*! \overload + Returns the value stored in this detail for the given \a key as a QString, or an empty QString if + no value for the given \a key exists */ +QString QContactDetail::value(const char* key) const +{ + return d.constData()->m_values.value(key).toString(); } // A bug in qdoc means this comment needs to appear below the comment for the other value(). @@ -285,9 +396,13 @@ /*! 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 */ QVariant QContactDetail::variantValue(const QString& key) const { - if (d.constData()->m_values.contains(key)) - return d.constData()->m_values.value(key); - return QVariant(); // returns an invalid qvariant + return d.constData()->m_values.value(key.toLatin1().constData()); +} + +/*! 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 */ +QVariant QContactDetail::variantValue(const char* key) const +{ + return d.constData()->m_values.value(key); } /*! @@ -295,9 +410,15 @@ */ bool QContactDetail::hasValue(const QString& key) const { - if (d.constData()->m_values.contains(key)) - return true; - return false; + return d.constData()->m_values.contains(key.toLatin1().constData()); +} + +/*! + Returns true if this detail has a field with the given \a key, or false otherwise. + */ +bool QContactDetail::hasValue(const char * key) const +{ + return d.constData()->m_values.contains(key); } /*! Inserts \a value into the detail for the given \a key if \a value is valid. If \a value is invalid, @@ -309,6 +430,19 @@ if (!value.isValid()) return removeValue(key); + d->m_values.insert(QContactStringHolder(key), value); + return true; +} + +/*! Inserts \a value into the detail for the given \a key if \a value is valid. If \a value is invalid, + removes the field with the given \a key from the detail. Returns true if the given \a value was set + for the \a key (if the \a value was valid), or if the given \a key was removed from detail (if the + \a value was invalid), and returns false if the key was unable to be removed (and the \a value was invalid) */ +bool QContactDetail::setValue(const char* key, const QVariant& value) +{ + if (!value.isValid()) + return removeValue(key); + d->m_values.insert(key, value); return true; } @@ -316,6 +450,13 @@ /*! 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 */ bool QContactDetail::removeValue(const QString& key) { + if(d->m_values.remove(key.toLatin1().constData())) + return true; + return false; +} +/*! 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 */ +bool QContactDetail::removeValue(const char * key) +{ if(d->m_values.remove(key)) return true; return false; @@ -326,7 +467,14 @@ */ QVariantMap QContactDetail::variantValues() const { - return d.constData()->m_values; + QVariantMap ret; + QHash::const_iterator it = d.constData()->m_values.constBegin(); + while(it != d.constData()->m_values.constEnd()) { + ret.insert(it.key(), it.value()); + ++it; + } + + return ret; } /*!