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 } |