|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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 "qcontactmanagerengine.h" |
|
43 |
|
44 #include "qcontactdetaildefinition.h" |
|
45 #include "qcontactdetailfielddefinition.h" |
|
46 #include "qcontactdetails.h" |
|
47 #include "qcontactsortorder.h" |
|
48 #include "qcontactfilters.h" |
|
49 #include "qcontactaction.h" |
|
50 #include "qcontactactiondescriptor.h" |
|
51 #include "qcontactabstractrequest.h" |
|
52 #include "qcontactabstractrequest_p.h" |
|
53 #include "qcontactrequests.h" |
|
54 #include "qcontactrequests_p.h" |
|
55 #include "qcontact.h" |
|
56 #include "qcontactfetchhint.h" |
|
57 |
|
58 #include "qcontact_p.h" |
|
59 #include "qcontactdetail_p.h" |
|
60 |
|
61 #include <QMutex> |
|
62 #include <QMutexLocker> |
|
63 #include <QWeakPointer> |
|
64 |
|
65 QTM_BEGIN_NAMESPACE |
|
66 |
|
67 /*! |
|
68 \class QContactManagerEngine |
|
69 \brief The QContactManagerEngine class provides the interface for all |
|
70 implementations of the contact manager backend functionality. |
|
71 \ingroup contacts-backends |
|
72 |
|
73 Instances of this class are usually provided by a |
|
74 \l QContactManagerEngineFactory, which is loaded from a plugin. |
|
75 |
|
76 The default implementation of this interface provides a basic |
|
77 level of functionality for some functions so that specific engines |
|
78 can simply implement the functionality that is supported by |
|
79 the specific contacts engine that is being adapted. |
|
80 |
|
81 More information on writing a contacts engine plugin is available in |
|
82 the \l{Qt Contacts Manager Engines} documentation. |
|
83 |
|
84 \sa QContactManager, QContactManagerEngineFactory |
|
85 */ |
|
86 |
|
87 /*! |
|
88 \fn QContactManagerEngine::QContactManagerEngine() |
|
89 |
|
90 A default, empty constructor. |
|
91 */ |
|
92 |
|
93 /*! |
|
94 \fn QContactManagerEngine::dataChanged() |
|
95 |
|
96 This signal is emitted some time after changes occur to the data managed by this |
|
97 engine, and the engine is unable to determine which changes occurred, or if the |
|
98 engine considers the changes to be radical enough to require clients to reload all data. |
|
99 |
|
100 If this signal is emitted, no other signals may be emitted for the associated changes. |
|
101 |
|
102 As it is possible that other processes (or other devices) may have caused the |
|
103 changes, the timing can not be determined. |
|
104 |
|
105 \sa contactsAdded(), contactsChanged(), contactsRemoved() |
|
106 */ |
|
107 |
|
108 /*! |
|
109 \fn QContactManagerEngine::contactsAdded(const QList<QContactLocalId>& contactIds); |
|
110 |
|
111 This signal is emitted some time after a set of contacts has been added to |
|
112 this engine where the \l dataChanged() signal was not emitted for those changes. |
|
113 As it is possible that other processes (or other devices) may |
|
114 have added the contacts, the timing cannot be determined. |
|
115 |
|
116 The list of ids of contacts added is given by \a contactIds. There may be one or more |
|
117 ids in the list. |
|
118 |
|
119 \sa dataChanged() |
|
120 */ |
|
121 |
|
122 /*! |
|
123 \fn QContactManagerEngine::contactsChanged(const QList<QContactLocalId>& contactIds); |
|
124 |
|
125 This signal is emitted some time after a set of contacts has been modified in |
|
126 this engine where the \l dataChanged() signal was not emitted for those changes. |
|
127 As it is possible that other processes (or other devices) may |
|
128 have modified the contacts, the timing cannot be determined. |
|
129 |
|
130 The list of ids of changed contacts is given by \a contactIds. There may be one or more |
|
131 ids in the list. |
|
132 |
|
133 \sa dataChanged() |
|
134 */ |
|
135 |
|
136 /*! |
|
137 \fn QContactManagerEngine::contactsRemoved(const QList<QContactLocalId>& contactIds); |
|
138 |
|
139 This signal is emitted some time after a set of contacts has been removed from |
|
140 this engine where the \l dataChanged() signal was not emitted for those changes. |
|
141 As it is possible that other processes (or other devices) may |
|
142 have removed the contacts, the timing cannot be determined. |
|
143 |
|
144 The list of ids of removed contacts is given by \a contactIds. There may be one or more |
|
145 ids in the list. |
|
146 |
|
147 \sa dataChanged() |
|
148 */ |
|
149 |
|
150 /*! |
|
151 \fn QContactManagerEngine::relationshipsAdded(const QList<QContactLocalId>& affectedContactIds); |
|
152 |
|
153 This signal is emitted some time after a set of contacts has been added to |
|
154 this engine where the \l dataChanged() signal was not emitted for those changes. |
|
155 As it is possible that other processes (or other devices) may |
|
156 have added the contacts, the timing cannot be determined. |
|
157 |
|
158 The list of ids of affected contacts is given by \a affectedContactIds. There may be one or more |
|
159 ids in the list. |
|
160 |
|
161 \sa dataChanged() |
|
162 */ |
|
163 |
|
164 /*! |
|
165 \fn QContactManagerEngine::relationshipsRemoved(const QList<QContactLocalId>& affectedContactIds); |
|
166 |
|
167 This signal is emitted some time after a set of relationships has been removed from |
|
168 this engine where the \l dataChanged() signal was not emitted for those changes. |
|
169 As it is possible that other processes (or other devices) may |
|
170 have removed the relationships, the timing cannot be determined. |
|
171 |
|
172 The list of ids of affected contacts is given by \a affectedContactIds. There may be one or more |
|
173 ids in the list. |
|
174 |
|
175 \sa dataChanged() |
|
176 */ |
|
177 |
|
178 /*! |
|
179 \fn QContactManagerEngine::selfContactIdChanged(const QContactLocalId& oldId, const QContactLocalId& newId) |
|
180 |
|
181 This signal is emitted at some point after the id of the self-contact is changed from \a oldId to \a newId in the manager. |
|
182 If the \a newId is the invalid, zero id, then the self contact was deleted or no self contact exists. |
|
183 This signal must not be emitted if the dataChanged() signal was previously emitted for this change. |
|
184 As it is possible that other processes (or other devices) may |
|
185 have removed or changed the self contact, the timing cannot be determined. |
|
186 |
|
187 \sa dataChanged() |
|
188 */ |
|
189 |
|
190 /*! Returns the manager name for this QContactManagerEngine */ |
|
191 QString QContactManagerEngine::managerName() const |
|
192 { |
|
193 return QString(QLatin1String("base")); |
|
194 } |
|
195 |
|
196 /*! |
|
197 Returns the parameters with which this engine was constructed. Note that |
|
198 the engine may have discarded unused or invalid parameters at the time of |
|
199 construction, and these will not be returned. |
|
200 */ |
|
201 QMap<QString, QString> QContactManagerEngine::managerParameters() const |
|
202 { |
|
203 return QMap<QString, QString>(); // default implementation requires no parameters. |
|
204 } |
|
205 |
|
206 /*! |
|
207 Returns the unique URI of this manager, which is built from the manager name and the parameters |
|
208 used to construct it. |
|
209 */ |
|
210 QString QContactManagerEngine::managerUri() const |
|
211 { |
|
212 return QContactManager::buildUri(managerName(), managerParameters()); |
|
213 } |
|
214 |
|
215 /*! |
|
216 Returns a list of contact ids that match the given \a filter, sorted according to the given list of \a sortOrders. |
|
217 Depending on the backend, this filtering operation may involve retrieving all the contacts. |
|
218 Any error which occurs will be saved in \a error. |
|
219 */ |
|
220 QList<QContactLocalId> QContactManagerEngine::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const |
|
221 { |
|
222 Q_UNUSED(filter); |
|
223 Q_UNUSED(sortOrders); |
|
224 |
|
225 *error = QContactManager::NotSupportedError; |
|
226 return QList<QContactLocalId>(); |
|
227 } |
|
228 |
|
229 /*! |
|
230 Returns the list of contacts which match the given \a filter stored in the manager sorted according to the given list of \a sortOrders. |
|
231 |
|
232 Any operation error which occurs will be saved in \a error. |
|
233 |
|
234 The \a fetchHint parameter describes the optimization hints that a manager may take. |
|
235 If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences |
|
236 in the matching contacts will be returned. A client should not make changes to a contact which has |
|
237 been retrieved using a fetch hint other than the default fetch hint. Doing so will result in information |
|
238 loss when saving the contact back to the manager (as the "new" restricted contact will |
|
239 replace the previously saved contact in the backend). |
|
240 |
|
241 \sa QContactFetchHint |
|
242 */ |
|
243 QList<QContact> QContactManagerEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint, QContactManager::Error* error) const |
|
244 { |
|
245 Q_UNUSED(filter); |
|
246 Q_UNUSED(sortOrders); |
|
247 Q_UNUSED(fetchHint); |
|
248 *error = QContactManager::NotSupportedError; |
|
249 return QList<QContact>(); |
|
250 } |
|
251 |
|
252 /*! |
|
253 Returns the contact in the database identified by \a contactId. |
|
254 |
|
255 If the contact does not exist, an empty, default constructed QContact will be returned, |
|
256 and the \a error will be set to \c QContactManager::DoesNotExistError. |
|
257 |
|
258 Any operation error which occurs will be saved in \a error. |
|
259 |
|
260 The \a fetchHint parameter describes the optimization hints that a manager may take. |
|
261 If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences |
|
262 in the matching contact will be returned. A client should not make changes to a contact which has |
|
263 been retrieved using a fetch hint other than the default fetch hint. Doing so will result in information |
|
264 loss when saving the contact back to the manager (as the "new" restricted contact will |
|
265 replace the previously saved contact in the backend). |
|
266 |
|
267 \sa QContactFetchHint |
|
268 */ |
|
269 QContact QContactManagerEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const |
|
270 { |
|
271 Q_UNUSED(contactId); |
|
272 Q_UNUSED(fetchHint); |
|
273 *error = QContactManager::NotSupportedError; |
|
274 return QContact(); |
|
275 } |
|
276 |
|
277 /*! |
|
278 Sets the id of the "self" contact to the given \a contactId. |
|
279 Returns true if the "self" contact id was set successfully. |
|
280 If the given \a contactId does not identify a contact |
|
281 stored in this manager, the \a error will be set to |
|
282 \c QContactManager::DoesNotExistError and the function will |
|
283 return false; if the backend does not support the |
|
284 concept of a "self" contact, the \a error will be set to |
|
285 \c QContactManager::NotSupportedError and the function will |
|
286 return false. |
|
287 */ |
|
288 bool QContactManagerEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error* error) |
|
289 { |
|
290 Q_UNUSED(contactId); |
|
291 |
|
292 *error = QContactManager::NotSupportedError; |
|
293 return false; |
|
294 } |
|
295 |
|
296 /*! |
|
297 Returns the id of the "self" contact which has previously been set. |
|
298 If no "self" contact has been set, or if the self contact was removed |
|
299 from the manager after being set, or if the backend does not support |
|
300 the concept of a "self" contact, an invalid id will be returned |
|
301 and the \a error will be set to \c QContactManager::DoesNotExistError. |
|
302 */ |
|
303 QContactLocalId QContactManagerEngine::selfContactId(QContactManager::Error* error) const |
|
304 { |
|
305 *error = QContactManager::DoesNotExistError; |
|
306 return QContactLocalId(); |
|
307 } |
|
308 |
|
309 /*! |
|
310 Returns a list of relationships of the given \a relationshipType in which the contact identified by the given \a participantId participates in the given \a role. |
|
311 If \a participantId is the default-constructed id, \a role is ignored and all relationships of the given \a relationshipType are returned. |
|
312 If \a relationshipType is empty, relationships of any type are returned. |
|
313 If no relationships of the given \a relationshipType in which the contact identified by the given \a participantId is involved in the given \a role exists, |
|
314 \a error is set to QContactManager::DoesNotExistError. |
|
315 */ |
|
316 QList<QContactRelationship> QContactManagerEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const |
|
317 { |
|
318 Q_UNUSED(relationshipType); |
|
319 Q_UNUSED(participantId); |
|
320 Q_UNUSED(role); |
|
321 |
|
322 *error = QContactManager::NotSupportedError; |
|
323 return QList<QContactRelationship>(); |
|
324 } |
|
325 |
|
326 /*! |
|
327 Saves the given \a relationships in the database and returns true if the operation was successful. |
|
328 For any relationship which was unable to be saved, an entry into the \a errorMap will be created, |
|
329 with the key being the index into the input relationships list, and the value being the error which |
|
330 occurred for that index. |
|
331 |
|
332 The supplied \a errorMap parameter may be null, if the client does not desire detailed error information. |
|
333 If supplied, it will be empty upon entry to this function. |
|
334 |
|
335 The overall operation error will be saved in \a error. |
|
336 */ |
|
337 bool QContactManagerEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
338 { |
|
339 Q_UNUSED(relationships); |
|
340 Q_UNUSED(errorMap); |
|
341 |
|
342 *error = QContactManager::NotSupportedError; |
|
343 return false; |
|
344 } |
|
345 |
|
346 /*! |
|
347 Saves the given \a relationship in the database. If the relationship already exists in the database, this function will |
|
348 return \c false and the \a error will be set to \c QContactManager::AlreadyExistsError. |
|
349 If the relationship is saved successfully, this function will return \c true and \a error will be set |
|
350 to \c QContactManager::NoError. Note that relationships cannot be updated directly using this function; in order |
|
351 to update a relationship, you must remove the old relationship, make the required modifications, and then save it. |
|
352 |
|
353 The given relationship is invalid if it is circular (the first contact is the second contact), or |
|
354 if it references a non-existent local contact (either the first or second contact). If the given \a relationship is invalid, |
|
355 the function will return \c false and the \a error will be set to \c QContactManager::InvalidRelationshipError. |
|
356 |
|
357 The default implementation of this function converts the argument into a call to saveRelationships. |
|
358 */ |
|
359 bool QContactManagerEngine::saveRelationship(QContactRelationship *relationship, QContactManager::Error *error) |
|
360 { |
|
361 // Convert to a list op |
|
362 if (relationship) { |
|
363 QList<QContactRelationship> list; |
|
364 list.append(*relationship); |
|
365 |
|
366 QMap<int, QContactManager::Error> errors; |
|
367 bool ret = saveRelationships(&list, &errors, error); |
|
368 |
|
369 if (errors.count() > 0) |
|
370 *error = errors.begin().value(); |
|
371 |
|
372 *relationship = list.value(0); |
|
373 return ret; |
|
374 } else { |
|
375 *error = QContactManager::BadArgumentError; |
|
376 return false; |
|
377 } |
|
378 } |
|
379 |
|
380 /*! |
|
381 Removes the given \a relationship from the manager. If the relationship exists in the manager, the relationship |
|
382 will be removed, the \a error will be set to \c QContactManager::NoError and this function will return true. If no such |
|
383 relationship exists in the manager, the \a error will be set to \c QContactManager::DoesNotExistError and this function |
|
384 will return false. |
|
385 |
|
386 The default implementation of this function converts the argument into a call to removeRelationships |
|
387 */ |
|
388 bool QContactManagerEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error* error) |
|
389 { |
|
390 // Convert to a list op |
|
391 QList<QContactRelationship> list; |
|
392 list.append(relationship); |
|
393 |
|
394 QMap<int, QContactManager::Error> errors; |
|
395 bool ret = removeRelationships(list, &errors, error); |
|
396 |
|
397 if (errors.count() > 0) |
|
398 *error = errors.begin().value(); |
|
399 |
|
400 return ret; |
|
401 } |
|
402 |
|
403 |
|
404 /*! |
|
405 Removes the given \a relationships from the database and returns true if the operation was successful. |
|
406 For any relationship which was unable to be removed, an entry into the \a errorMap will be created, |
|
407 with the key being the index into the input relationships list, and the value being the error which |
|
408 occurred for that index. |
|
409 |
|
410 The supplied \a errorMap parameter may be null, if the client does not desire detailed error information. |
|
411 If supplied, it will be empty upon entry to this function. |
|
412 |
|
413 The overall operation error will be saved in \a error. |
|
414 */ |
|
415 bool QContactManagerEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
416 { |
|
417 Q_UNUSED(relationships); |
|
418 Q_UNUSED(errorMap); |
|
419 |
|
420 *error = QContactManager::NotSupportedError; |
|
421 return false; |
|
422 } |
|
423 |
|
424 /*! |
|
425 Synthesizes the display label of the given \a contact in a platform specific manner. |
|
426 Any error that occurs will be stored in \a error. |
|
427 Returns the synthesized display label. |
|
428 */ |
|
429 QString QContactManagerEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const |
|
430 { |
|
431 // synthesize the display name from the name of the contact, or, failing that, the organisation of the contact. |
|
432 *error = QContactManager::NoError; |
|
433 QList<QContactDetail> allNames = contact.details(QContactName::DefinitionName); |
|
434 |
|
435 const QLatin1String space(" "); |
|
436 |
|
437 // synthesize the display label from the name. |
|
438 for (int i=0; i < allNames.size(); i++) { |
|
439 const QContactName& name = allNames.at(i); |
|
440 |
|
441 if (!name.customLabel().isEmpty()) { |
|
442 // default behaviour is to allow the user to define a custom display label. |
|
443 return name.customLabel(); |
|
444 } |
|
445 |
|
446 QString result; |
|
447 if (!name.value(QContactName::FieldPrefix).trimmed().isEmpty()) { |
|
448 result += name.value(QContactName::FieldPrefix); |
|
449 } |
|
450 |
|
451 if (!name.value(QContactName::FieldFirstName).trimmed().isEmpty()) { |
|
452 if (!result.isEmpty()) |
|
453 result += space; |
|
454 result += name.value(QContactName::FieldFirstName); |
|
455 } |
|
456 |
|
457 if (!name.value(QContactName::FieldMiddleName).trimmed().isEmpty()) { |
|
458 if (!result.isEmpty()) |
|
459 result += space; |
|
460 result += name.value(QContactName::FieldMiddleName); |
|
461 } |
|
462 |
|
463 if (!name.value(QContactName::FieldLastName).trimmed().isEmpty()) { |
|
464 if (!result.isEmpty()) |
|
465 result += space; |
|
466 result += name.value(QContactName::FieldLastName); |
|
467 } |
|
468 |
|
469 if (!name.value(QContactName::FieldSuffix).trimmed().isEmpty()) { |
|
470 if (!result.isEmpty()) |
|
471 result += space; |
|
472 result += name.value(QContactName::FieldSuffix); |
|
473 } |
|
474 |
|
475 if (!result.isEmpty()) { |
|
476 return result; |
|
477 } |
|
478 } |
|
479 |
|
480 /* Well, we had no non empty names. if we have orgs, fall back to those */ |
|
481 QList<QContactDetail> allOrgs = contact.details(QContactOrganization::DefinitionName); |
|
482 for (int i=0; i < allOrgs.size(); i++) { |
|
483 const QContactOrganization& org = allOrgs.at(i); |
|
484 if (!org.name().isEmpty()) { |
|
485 return org.name(); |
|
486 } |
|
487 } |
|
488 |
|
489 *error = QContactManager::UnspecifiedError; |
|
490 return QString(); |
|
491 } |
|
492 |
|
493 /*! |
|
494 Sets the contact display label of \a contact to the supplied \a displayLabel. |
|
495 */ |
|
496 void QContactManagerEngine::setContactDisplayLabel(QContact* contact, const QString& displayLabel) |
|
497 { |
|
498 QContactDisplayLabel dl; |
|
499 dl.setValue(QContactDisplayLabel::FieldLabel, displayLabel); |
|
500 setDetailAccessConstraints(&dl, QContactDetail::Irremovable | QContactDetail::ReadOnly); |
|
501 contact->d->m_details.replace(0, dl); |
|
502 } |
|
503 |
|
504 /*! |
|
505 \deprecated |
|
506 |
|
507 Returns a copy of \a contact with the contact display label set to the supplied \a displayLabel. |
|
508 |
|
509 This function does not touch the database in any way, and is purely a convenience to allow engine implementations to set the display label. |
|
510 |
|
511 This function has been deprecated - use the function with the same name that accepts different parameters. |
|
512 */ |
|
513 QContact QContactManagerEngine::setContactDisplayLabel(const QString& displayLabel, const QContact& contact) |
|
514 { |
|
515 QContact newContact = contact; |
|
516 setContactDisplayLabel(&newContact, displayLabel); |
|
517 return newContact; |
|
518 } |
|
519 |
|
520 /*! |
|
521 Returns true if the given \a feature is supported by this engine for contacts of the given \a contactType |
|
522 */ |
|
523 bool QContactManagerEngine::hasFeature(QContactManager::ManagerFeature feature, const QString& contactType) const |
|
524 { |
|
525 Q_UNUSED(feature); |
|
526 Q_UNUSED(contactType); |
|
527 |
|
528 return false; |
|
529 } |
|
530 |
|
531 /*! |
|
532 Given an input \a filter, returns the canonical version of the filter. |
|
533 |
|
534 Some of the following transformations may be applied: |
|
535 \list |
|
536 \o Any QContactActionFilters are transformed into the corresponding |
|
537 QContactFilters returned by matching actions |
|
538 \o Any QContactInvalidFilters contained in a union filter will be removed |
|
539 \o Any default QContactFilters contained in an intersection filter will be removed |
|
540 \o Any QContactIntersectionFilters with a QContactInvalidFilter contained will be |
|
541 replaced with a QContactInvalidFilter |
|
542 \o Any QContactUnionFilters with a default QContactFilter contained will be replaced |
|
543 with a default QContactFilter |
|
544 \o An empty QContactIntersectionFilter will be replaced with a QContactDefaultFilter |
|
545 \o An empty QContactUnionFilter will be replaced with a QContactInvalidFilter |
|
546 \o An empty QContactLocalIdFilter will be replaced with a QContactInvalidFilter |
|
547 \o An intersection or union filter with a single entry will be replaced by that entry |
|
548 \o A QContactDetailFilter or QContactDetailRangeFilter with no definition name will be replaced with a QContactInvalidFilter |
|
549 \o A QContactDetailRangeFilter with no range specified will be converted to a QContactDetailFilter |
|
550 \endlist |
|
551 */ |
|
552 QContactFilter QContactManagerEngine::canonicalizedFilter(const QContactFilter &filter) |
|
553 { |
|
554 switch(filter.type()) { |
|
555 case QContactFilter::ActionFilter: |
|
556 { |
|
557 // Find any matching actions, and do a union filter on their filter objects |
|
558 QContactActionFilter af(filter); |
|
559 QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion()); |
|
560 |
|
561 QList<QContactFilter> filters; |
|
562 // There's a small wrinkle if there's a value specified in the action filter |
|
563 // we have to adjust any contained QContactDetailFilters to have that value |
|
564 // or test if a QContactDetailRangeFilter contains this value already |
|
565 for (int j = 0; j < descriptors.count(); j++) { |
|
566 QContactAction* action = QContactAction::action(descriptors.at(j)); |
|
567 |
|
568 // Action filters are not allowed to return action filters, at all |
|
569 // it's too annoying to check for recursion |
|
570 QContactFilter d = action->contactFilter(af.value()); |
|
571 delete action; // clean up. |
|
572 if (!validateActionFilter(d)) |
|
573 continue; |
|
574 |
|
575 filters.append(d); |
|
576 } |
|
577 |
|
578 if (filters.count() == 0) |
|
579 return QContactInvalidFilter(); |
|
580 if (filters.count() == 1) |
|
581 return filters.first(); |
|
582 |
|
583 QContactUnionFilter f; |
|
584 f.setFilters(filters); |
|
585 return canonicalizedFilter(f); |
|
586 } |
|
587 // unreachable |
|
588 |
|
589 case QContactFilter::IntersectionFilter: |
|
590 { |
|
591 QContactIntersectionFilter f(filter); |
|
592 QList<QContactFilter> filters = f.filters(); |
|
593 QList<QContactFilter>::iterator it = filters.begin(); |
|
594 |
|
595 // XXX in theory we can remove duplicates in a set filter |
|
596 while (it != filters.end()) { |
|
597 QContactFilter canon = canonicalizedFilter(*it); |
|
598 if (canon.type() == QContactFilter::DefaultFilter) { |
|
599 it = filters.erase(it); |
|
600 } else if (canon.type() == QContactFilter::InvalidFilter) { |
|
601 return QContactInvalidFilter(); |
|
602 } else { |
|
603 *it = canon; |
|
604 ++it; |
|
605 } |
|
606 } |
|
607 |
|
608 if (filters.count() == 0) |
|
609 return QContactFilter(); |
|
610 if (filters.count() == 1) |
|
611 return filters.first(); |
|
612 |
|
613 f.setFilters(filters); |
|
614 return f; |
|
615 } |
|
616 // unreachable |
|
617 |
|
618 case QContactFilter::UnionFilter: |
|
619 { |
|
620 QContactUnionFilter f(filter); |
|
621 QList<QContactFilter> filters = f.filters(); |
|
622 QList<QContactFilter>::iterator it = filters.begin(); |
|
623 |
|
624 // XXX in theory we can remove duplicates in a set filter |
|
625 while (it != filters.end()) { |
|
626 QContactFilter canon = canonicalizedFilter(*it); |
|
627 if (canon.type() == QContactFilter::InvalidFilter) { |
|
628 it = filters.erase(it); |
|
629 } else if (canon.type() == QContactFilter::DefaultFilter) { |
|
630 return QContactFilter(); |
|
631 } else { |
|
632 *it = canon; |
|
633 ++it; |
|
634 } |
|
635 } |
|
636 |
|
637 if (filters.count() == 0) |
|
638 return QContactInvalidFilter(); |
|
639 if (filters.count() == 1) |
|
640 return filters.first(); |
|
641 |
|
642 f.setFilters(filters); |
|
643 return f; |
|
644 } |
|
645 // unreachable |
|
646 |
|
647 case QContactFilter::LocalIdFilter: |
|
648 { |
|
649 QContactLocalIdFilter f(filter); |
|
650 if (f.ids().count() == 0) |
|
651 return QContactInvalidFilter(); |
|
652 } |
|
653 break; // fall through to return at end |
|
654 |
|
655 case QContactFilter::ContactDetailRangeFilter: |
|
656 { |
|
657 QContactDetailRangeFilter f(filter); |
|
658 if (f.detailDefinitionName().isEmpty()) |
|
659 return QContactInvalidFilter(); |
|
660 if (f.minValue() == f.maxValue() |
|
661 && f.rangeFlags() == (QContactDetailRangeFilter::ExcludeLower | QContactDetailRangeFilter::ExcludeUpper)) |
|
662 return QContactInvalidFilter(); |
|
663 if ((f.minValue().isNull() && f.maxValue().isNull()) || (f.minValue() == f.maxValue())) { |
|
664 QContactDetailFilter df; |
|
665 df.setDetailDefinitionName(f.detailDefinitionName(), f.detailFieldName()); |
|
666 df.setMatchFlags(f.matchFlags()); |
|
667 df.setValue(f.minValue()); |
|
668 return df; |
|
669 } |
|
670 } |
|
671 break; // fall through to return at end |
|
672 |
|
673 case QContactFilter::ContactDetailFilter: |
|
674 { |
|
675 QContactDetailFilter f(filter); |
|
676 if (f.detailDefinitionName().isEmpty()) |
|
677 return QContactInvalidFilter(); |
|
678 } |
|
679 break; // fall through to return at end |
|
680 |
|
681 default: |
|
682 break; // fall through to return at end |
|
683 } |
|
684 return filter; |
|
685 } |
|
686 |
|
687 |
|
688 /*! |
|
689 Returns a whether the supplied \a filter can be implemented |
|
690 natively by this engine. If not, the base class implementation |
|
691 will emulate the functionality. |
|
692 */ |
|
693 bool QContactManagerEngine::isFilterSupported(const QContactFilter& filter) const |
|
694 { |
|
695 Q_UNUSED(filter); |
|
696 |
|
697 return false; |
|
698 } |
|
699 |
|
700 /*! |
|
701 Returns the list of data types supported by this engine. |
|
702 */ |
|
703 QList<QVariant::Type> QContactManagerEngine::supportedDataTypes() const |
|
704 { |
|
705 return QList<QVariant::Type>(); |
|
706 } |
|
707 |
|
708 /*! |
|
709 Returns true if the manager supports the relationship type specified in \a relationshipType for |
|
710 contacts whose type is the given \a contactType. |
|
711 |
|
712 Note that some managers may support the relationship type for a contact in a limited manner |
|
713 (for example, only as the first contact in the relationship, or only as the second contact |
|
714 in the relationship). In this case, it will still return true. It will only return false |
|
715 if the relationship is entirely unsupported for the given type of contact. |
|
716 */ |
|
717 bool QContactManagerEngine::isRelationshipTypeSupported(const QString& relationshipType, const QString& contactType) const |
|
718 { |
|
719 Q_UNUSED(relationshipType); |
|
720 Q_UNUSED(contactType); |
|
721 |
|
722 return false; |
|
723 } |
|
724 |
|
725 /*! |
|
726 Returns the list of contact types which are supported by this engine. |
|
727 This is a convenience function, equivalent to retrieving the allowable values |
|
728 for the \c QContactType::FieldType field of the QContactType definition |
|
729 which is valid in this engine. |
|
730 */ |
|
731 QStringList QContactManagerEngine::supportedContactTypes() const |
|
732 { |
|
733 QContactManager::Error error; |
|
734 QList<QVariant> allowableVals = detailDefinition(QContactType::DefinitionName, QContactType::TypeContact, &error).fields().value(QContactType::FieldType).allowableValues(); |
|
735 QStringList retn; |
|
736 for (int i = 0; i < allowableVals.size(); i++) |
|
737 retn += allowableVals.at(i).toString(); |
|
738 return retn; |
|
739 } |
|
740 |
|
741 /*! |
|
742 \fn int QContactManagerEngine::managerVersion() const |
|
743 |
|
744 Returns the engine backend implementation version number |
|
745 */ |
|
746 |
|
747 /*! Returns the base schema definitions */ |
|
748 QMap<QString, QMap<QString, QContactDetailDefinition> > QContactManagerEngine::schemaDefinitions() |
|
749 { |
|
750 // This implementation provides the base schema. |
|
751 // The schema documentation (contactsschema.qdoc) |
|
752 // MUST BE KEPT UP TO DATE as definitions are added here. |
|
753 |
|
754 // the map we will eventually return |
|
755 QMap<QString, QContactDetailDefinition> retn; |
|
756 |
|
757 // local variables for reuse |
|
758 QMap<QString, QContactDetailFieldDefinition> fields; |
|
759 QContactDetailFieldDefinition f; |
|
760 QContactDetailDefinition d; |
|
761 QVariantList contexts; |
|
762 contexts << QString(QLatin1String(QContactDetail::ContextHome)) << QString(QLatin1String(QContactDetail::ContextWork)) << QString(QLatin1String(QContactDetail::ContextOther)); |
|
763 QVariantList subTypes; |
|
764 |
|
765 // sync target |
|
766 d.setName(QContactSyncTarget::DefinitionName); |
|
767 fields.clear(); |
|
768 f.setDataType(QVariant::String); |
|
769 f.setAllowableValues(QVariantList()); |
|
770 fields.insert(QContactSyncTarget::FieldSyncTarget, f); |
|
771 f.setDataType(QVariant::StringList); |
|
772 f.setAllowableValues(contexts); |
|
773 fields.insert(QContactDetail::FieldContext, f); |
|
774 d.setFields(fields); |
|
775 d.setUnique(true); |
|
776 retn.insert(d.name(), d); |
|
777 |
|
778 // timestamp |
|
779 d.setName(QContactTimestamp::DefinitionName); |
|
780 fields.clear(); |
|
781 f.setDataType(QVariant::DateTime); |
|
782 f.setAllowableValues(QVariantList()); |
|
783 fields.insert(QContactTimestamp::FieldModificationTimestamp, f); |
|
784 fields.insert(QContactTimestamp::FieldCreationTimestamp, f); |
|
785 f.setDataType(QVariant::StringList); |
|
786 f.setAllowableValues(contexts); |
|
787 fields.insert(QContactDetail::FieldContext, f); |
|
788 d.setFields(fields); |
|
789 d.setUnique(true); |
|
790 retn.insert(d.name(), d); |
|
791 |
|
792 // type |
|
793 d.setName(QContactType::DefinitionName); |
|
794 fields.clear(); |
|
795 f.setDataType(QVariant::String); |
|
796 subTypes.clear(); |
|
797 subTypes << QString(QLatin1String(QContactType::TypeContact)) << QString(QLatin1String(QContactType::TypeGroup)); |
|
798 f.setAllowableValues(subTypes); |
|
799 fields.insert(QContactType::FieldType, f); // note: NO CONTEXT!! |
|
800 d.setFields(fields); |
|
801 d.setUnique(true); |
|
802 retn.insert(d.name(), d); |
|
803 |
|
804 // guid |
|
805 d.setName(QContactGuid::DefinitionName); |
|
806 fields.clear(); |
|
807 f.setDataType(QVariant::String); |
|
808 f.setAllowableValues(QVariantList()); |
|
809 fields.insert(QContactGuid::FieldGuid, f); |
|
810 f.setDataType(QVariant::StringList); |
|
811 f.setAllowableValues(contexts); |
|
812 fields.insert(QContactDetail::FieldContext, f); |
|
813 d.setFields(fields); |
|
814 d.setUnique(false); |
|
815 retn.insert(d.name(), d); |
|
816 |
|
817 // display label |
|
818 d.setName(QContactDisplayLabel::DefinitionName); |
|
819 fields.clear(); |
|
820 f.setDataType(QVariant::String); |
|
821 f.setAllowableValues(QVariantList()); |
|
822 fields.insert(QContactDisplayLabel::FieldLabel, f); |
|
823 d.setFields(fields); |
|
824 d.setUnique(true); |
|
825 retn.insert(d.name(), d); |
|
826 |
|
827 // email address |
|
828 d.setName(QContactEmailAddress::DefinitionName); |
|
829 fields.clear(); |
|
830 f.setDataType(QVariant::String); |
|
831 f.setAllowableValues(QVariantList()); |
|
832 fields.insert(QContactEmailAddress::FieldEmailAddress, f); |
|
833 f.setDataType(QVariant::StringList); |
|
834 f.setAllowableValues(contexts); |
|
835 fields.insert(QContactDetail::FieldContext, f); |
|
836 d.setFields(fields); |
|
837 d.setUnique(false); |
|
838 retn.insert(d.name(), d); |
|
839 |
|
840 // organisation |
|
841 d.setName(QContactOrganization::DefinitionName); |
|
842 fields.clear(); |
|
843 f.setDataType(QVariant::String); |
|
844 f.setAllowableValues(QVariantList()); |
|
845 fields.insert(QContactOrganization::FieldName, f); |
|
846 fields.insert(QContactOrganization::FieldLocation, f); |
|
847 fields.insert(QContactOrganization::FieldTitle, f); |
|
848 f.setDataType(QVariant::Url); |
|
849 fields.insert(QContactOrganization::FieldLogoUrl, f); |
|
850 f.setDataType(QVariant::StringList); |
|
851 fields.insert(QContactOrganization::FieldDepartment, f); |
|
852 f.setAllowableValues(contexts); |
|
853 fields.insert(QContactDetail::FieldContext, f); |
|
854 d.setFields(fields); |
|
855 d.setUnique(false); |
|
856 retn.insert(d.name(), d); |
|
857 |
|
858 // phone number |
|
859 d.setName(QContactPhoneNumber::DefinitionName); |
|
860 fields.clear(); |
|
861 f.setDataType(QVariant::String); |
|
862 f.setAllowableValues(QVariantList()); |
|
863 fields.insert(QContactPhoneNumber::FieldNumber, f); |
|
864 f.setDataType(QVariant::StringList); // can implement multiple subtypes |
|
865 subTypes.clear(); |
|
866 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeAssistant)); |
|
867 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeBulletinBoardSystem)); |
|
868 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeCar)); |
|
869 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeDtmfMenu)); |
|
870 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeFax)); |
|
871 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeLandline)); |
|
872 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeMessagingCapable)); |
|
873 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeMobile)); |
|
874 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeModem)); |
|
875 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypePager)); |
|
876 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeVideo)); |
|
877 subTypes << QString(QLatin1String(QContactPhoneNumber::SubTypeVoice)); |
|
878 f.setAllowableValues(subTypes); |
|
879 fields.insert(QContactPhoneNumber::FieldSubTypes, f); |
|
880 f.setDataType(QVariant::StringList); |
|
881 f.setAllowableValues(contexts); |
|
882 fields.insert(QContactDetail::FieldContext, f); |
|
883 d.setFields(fields); |
|
884 d.setUnique(false); |
|
885 retn.insert(d.name(), d); |
|
886 |
|
887 // anniversary |
|
888 d.setName(QContactAnniversary::DefinitionName); |
|
889 fields.clear(); |
|
890 f.setDataType(QVariant::Date); |
|
891 f.setAllowableValues(QVariantList()); |
|
892 fields.insert(QContactAnniversary::FieldOriginalDate, f); |
|
893 f.setDataType(QVariant::String); |
|
894 f.setAllowableValues(QVariantList()); |
|
895 fields.insert(QContactAnniversary::FieldCalendarId, f); |
|
896 f.setDataType(QVariant::String); |
|
897 f.setAllowableValues(QVariantList()); |
|
898 fields.insert(QContactAnniversary::FieldEvent, f); |
|
899 f.setDataType(QVariant::String); // only allowed to be a single subtype. |
|
900 subTypes.clear(); |
|
901 subTypes << QString(QLatin1String(QContactAnniversary::SubTypeEmployment)); |
|
902 subTypes << QString(QLatin1String(QContactAnniversary::SubTypeEngagement)); |
|
903 subTypes << QString(QLatin1String(QContactAnniversary::SubTypeHouse)); |
|
904 subTypes << QString(QLatin1String(QContactAnniversary::SubTypeMemorial)); |
|
905 subTypes << QString(QLatin1String(QContactAnniversary::SubTypeWedding)); |
|
906 f.setAllowableValues(subTypes); |
|
907 fields.insert(QContactAnniversary::FieldSubType, f); |
|
908 f.setDataType(QVariant::StringList); |
|
909 f.setAllowableValues(contexts); |
|
910 fields.insert(QContactDetail::FieldContext, f); |
|
911 d.setFields(fields); |
|
912 d.setUnique(false); |
|
913 retn.insert(d.name(), d); |
|
914 |
|
915 // birthday |
|
916 d.setName(QContactBirthday::DefinitionName); |
|
917 fields.clear(); |
|
918 f.setDataType(QVariant::Date); |
|
919 f.setAllowableValues(QVariantList()); |
|
920 fields.insert(QContactBirthday::FieldBirthday, f); |
|
921 f.setDataType(QVariant::StringList); |
|
922 f.setAllowableValues(contexts); |
|
923 fields.insert(QContactDetail::FieldContext, f); |
|
924 d.setFields(fields); |
|
925 d.setUnique(true); |
|
926 retn.insert(d.name(), d); |
|
927 |
|
928 // nickname |
|
929 d.setName(QContactNickname::DefinitionName); |
|
930 fields.clear(); |
|
931 f.setDataType(QVariant::String); |
|
932 f.setAllowableValues(QVariantList()); |
|
933 fields.insert(QContactNickname::FieldNickname, f); |
|
934 f.setDataType(QVariant::StringList); |
|
935 f.setAllowableValues(contexts); |
|
936 fields.insert(QContactDetail::FieldContext, f); |
|
937 d.setFields(fields); |
|
938 d.setUnique(false); |
|
939 retn.insert(d.name(), d); |
|
940 |
|
941 // note |
|
942 fields.clear(); |
|
943 f.setDataType(QVariant::String); |
|
944 f.setAllowableValues(QVariantList()); |
|
945 d.setName(QContactNote::DefinitionName); |
|
946 fields.insert(QContactNote::FieldNote, f); |
|
947 f.setDataType(QVariant::StringList); |
|
948 f.setAllowableValues(contexts); |
|
949 fields.insert(QContactDetail::FieldContext, f); |
|
950 d.setFields(fields); |
|
951 d.setUnique(false); |
|
952 retn.insert(d.name(), d); |
|
953 |
|
954 // url |
|
955 d.setName(QContactUrl::DefinitionName); |
|
956 fields.clear(); |
|
957 f.setDataType(QVariant::String); |
|
958 f.setAllowableValues(QVariantList()); |
|
959 fields.insert(QContactUrl::FieldUrl, f); |
|
960 f.setDataType(QVariant::String); // only allowed to be a single subtype |
|
961 subTypes.clear(); |
|
962 subTypes << QString(QLatin1String(QContactUrl::SubTypeFavourite)); |
|
963 subTypes << QString(QLatin1String(QContactUrl::SubTypeHomePage)); |
|
964 f.setAllowableValues(subTypes); |
|
965 fields.insert(QContactUrl::FieldSubType, f); |
|
966 f.setDataType(QVariant::StringList); |
|
967 f.setAllowableValues(contexts); |
|
968 fields.insert(QContactDetail::FieldContext, f); |
|
969 d.setFields(fields); |
|
970 d.setUnique(false); |
|
971 retn.insert(d.name(), d); |
|
972 |
|
973 // gender |
|
974 d.setName(QContactGender::DefinitionName); |
|
975 fields.clear(); |
|
976 f.setDataType(QVariant::String); |
|
977 f.setAllowableValues(QVariantList() << QString(QLatin1String(QContactGender::GenderMale)) << QString(QLatin1String(QContactGender::GenderFemale)) << QString(QLatin1String(QContactGender::GenderUnspecified))); |
|
978 fields.insert(QContactGender::FieldGender, f); |
|
979 f.setDataType(QVariant::StringList); |
|
980 f.setAllowableValues(contexts); |
|
981 fields.insert(QContactDetail::FieldContext, f); |
|
982 d.setFields(fields); |
|
983 d.setUnique(false); |
|
984 retn.insert(d.name(), d); |
|
985 |
|
986 // online account |
|
987 d.setName(QContactOnlineAccount::DefinitionName); |
|
988 fields.clear(); |
|
989 f.setAllowableValues(QVariantList()); |
|
990 f.setDataType(QVariant::String); |
|
991 fields.insert(QContactOnlineAccount::FieldAccountUri, f); |
|
992 f.setDataType(QVariant::StringList); |
|
993 fields.insert(QContactOnlineAccount::FieldCapabilities, f); |
|
994 f.setDataType(QVariant::String); |
|
995 fields.insert(QContactOnlineAccount::FieldAccountUri, f); |
|
996 fields.insert(QContactOnlineAccount::FieldServiceProvider, f); |
|
997 f.setDataType(QVariant::StringList); |
|
998 f.setAllowableValues(contexts); |
|
999 fields.insert(QContactDetail::FieldContext, f); |
|
1000 f.setAllowableValues(QVariantList()); // allow any subtypes! |
|
1001 fields.insert(QContactOnlineAccount::FieldSubTypes, f); |
|
1002 d.setFields(fields); |
|
1003 d.setUnique(false); |
|
1004 retn.insert(d.name(), d); |
|
1005 |
|
1006 // presence |
|
1007 d.setName(QContactPresence::DefinitionName); |
|
1008 fields.clear(); |
|
1009 f.setAllowableValues(QVariantList()); |
|
1010 f.setDataType(QVariant::DateTime); |
|
1011 fields.insert(QContactPresence::FieldTimestamp, f); |
|
1012 f.setDataType(QVariant::String); |
|
1013 fields.insert(QContactPresence::FieldNickname, f); |
|
1014 fields.insert(QContactPresence::FieldCustomMessage, f); |
|
1015 fields.insert(QContactPresence::FieldPresenceStateText, f); |
|
1016 QVariantList presenceValues; |
|
1017 presenceValues << QContactPresence::PresenceAvailable; |
|
1018 presenceValues << QContactPresence::PresenceAway; |
|
1019 presenceValues << QContactPresence::PresenceBusy; |
|
1020 presenceValues << QContactPresence::PresenceExtendedAway; |
|
1021 presenceValues << QContactPresence::PresenceHidden; |
|
1022 presenceValues << QContactPresence::PresenceOffline; |
|
1023 presenceValues << QContactPresence::PresenceUnknown; |
|
1024 f.setAllowableValues(presenceValues); |
|
1025 f.setDataType(QVariant::Int); |
|
1026 fields.insert(QContactPresence::FieldPresenceState, f); |
|
1027 f.setAllowableValues(QVariantList()); |
|
1028 f.setDataType(QVariant::Url); |
|
1029 fields.insert(QContactPresence::FieldPresenceStateImageUrl, f); |
|
1030 f.setDataType(QVariant::StringList); |
|
1031 f.setAllowableValues(contexts); |
|
1032 fields.insert(QContactDetail::FieldContext, f); |
|
1033 d.setFields(fields); |
|
1034 d.setUnique(false); |
|
1035 retn.insert(d.name(), d); |
|
1036 |
|
1037 // global presence |
|
1038 d.setName(QContactGlobalPresence::DefinitionName); |
|
1039 fields.clear(); |
|
1040 f.setAllowableValues(QVariantList()); |
|
1041 f.setDataType(QVariant::DateTime); |
|
1042 fields.insert(QContactGlobalPresence::FieldTimestamp, f); |
|
1043 f.setDataType(QVariant::String); |
|
1044 fields.insert(QContactGlobalPresence::FieldNickname, f); |
|
1045 fields.insert(QContactGlobalPresence::FieldCustomMessage, f); |
|
1046 fields.insert(QContactGlobalPresence::FieldPresenceStateText, f); |
|
1047 f.setAllowableValues(presenceValues); |
|
1048 f.setDataType(QVariant::Int); |
|
1049 fields.insert(QContactGlobalPresence::FieldPresenceState, f); |
|
1050 f.setAllowableValues(QVariantList()); |
|
1051 f.setDataType(QVariant::Url); |
|
1052 fields.insert(QContactGlobalPresence::FieldPresenceStateImageUrl, f); |
|
1053 f.setDataType(QVariant::StringList); |
|
1054 f.setAllowableValues(contexts); |
|
1055 fields.insert(QContactDetail::FieldContext, f); |
|
1056 d.setFields(fields); |
|
1057 d.setUnique(true); // unique and read only! |
|
1058 retn.insert(d.name(), d); |
|
1059 |
|
1060 // avatar |
|
1061 d.setName(QContactAvatar::DefinitionName); |
|
1062 fields.clear(); |
|
1063 f.setDataType(QVariant::Url); |
|
1064 f.setAllowableValues(QVariantList()); |
|
1065 fields.insert(QContactAvatar::FieldImageUrl, f); |
|
1066 fields.insert(QContactAvatar::FieldVideoUrl, f); |
|
1067 f.setDataType(QVariant::StringList); |
|
1068 f.setAllowableValues(contexts); |
|
1069 fields.insert(QContactDetail::FieldContext, f); |
|
1070 d.setFields(fields); |
|
1071 d.setUnique(false); |
|
1072 retn.insert(d.name(), d); |
|
1073 |
|
1074 // ringtone |
|
1075 d.setName(QContactRingtone::DefinitionName); |
|
1076 fields.clear(); |
|
1077 f.setDataType(QVariant::Url); |
|
1078 f.setAllowableValues(QVariantList()); |
|
1079 fields.insert(QContactRingtone::FieldAudioRingtoneUrl, f); |
|
1080 fields.insert(QContactRingtone::FieldVideoRingtoneUrl, f); |
|
1081 fields.insert(QContactRingtone::FieldVibrationRingtoneUrl, f); |
|
1082 f.setDataType(QVariant::StringList); |
|
1083 f.setAllowableValues(contexts); |
|
1084 fields.insert(QContactDetail::FieldContext, f); |
|
1085 d.setFields(fields); |
|
1086 d.setUnique(false); |
|
1087 retn.insert(d.name(), d); |
|
1088 |
|
1089 // thumbnail |
|
1090 d.setName(QContactThumbnail::DefinitionName); |
|
1091 fields.clear(); |
|
1092 f.setDataType(QVariant::Image); |
|
1093 f.setAllowableValues(QVariantList()); |
|
1094 fields.insert(QContactThumbnail::FieldThumbnail, f); |
|
1095 d.setFields(fields); |
|
1096 d.setUnique(true); // only one thumbnail, no context. |
|
1097 retn.insert(d.name(), d); |
|
1098 |
|
1099 // GeoLocation |
|
1100 d.setName(QContactGeoLocation::DefinitionName); |
|
1101 fields.clear(); |
|
1102 f.setDataType(QVariant::String); |
|
1103 f.setAllowableValues(QVariantList()); |
|
1104 fields.insert(QContactGeoLocation::FieldLabel, f); |
|
1105 f.setDataType(QVariant::Double); |
|
1106 fields.insert(QContactGeoLocation::FieldLatitude, f); |
|
1107 fields.insert(QContactGeoLocation::FieldLongitude, f); |
|
1108 fields.insert(QContactGeoLocation::FieldAccuracy, f); |
|
1109 fields.insert(QContactGeoLocation::FieldAltitude, f); |
|
1110 fields.insert(QContactGeoLocation::FieldAltitudeAccuracy, f); |
|
1111 fields.insert(QContactGeoLocation::FieldSpeed, f); |
|
1112 fields.insert(QContactGeoLocation::FieldHeading, f); |
|
1113 f.setDataType(QVariant::DateTime); |
|
1114 fields.insert(QContactGeoLocation::FieldTimestamp, f); |
|
1115 f.setDataType(QVariant::StringList); |
|
1116 f.setAllowableValues(contexts); |
|
1117 fields.insert(QContactDetail::FieldContext, f); |
|
1118 d.setFields(fields); |
|
1119 d.setUnique(false); |
|
1120 retn.insert(d.name(), d); |
|
1121 |
|
1122 // street address |
|
1123 d.setName(QContactAddress::DefinitionName); |
|
1124 fields.clear(); |
|
1125 f.setDataType(QVariant::String); |
|
1126 f.setAllowableValues(QVariantList()); |
|
1127 fields.insert(QContactAddress::FieldPostOfficeBox, f); |
|
1128 fields.insert(QContactAddress::FieldStreet, f); |
|
1129 fields.insert(QContactAddress::FieldLocality, f); |
|
1130 fields.insert(QContactAddress::FieldRegion, f); |
|
1131 fields.insert(QContactAddress::FieldPostcode, f); |
|
1132 fields.insert(QContactAddress::FieldCountry, f); |
|
1133 f.setDataType(QVariant::StringList); // can implement multiple subtypes |
|
1134 subTypes.clear(); |
|
1135 subTypes << QString(QLatin1String(QContactAddress::SubTypeDomestic)); |
|
1136 subTypes << QString(QLatin1String(QContactAddress::SubTypeInternational)); |
|
1137 subTypes << QString(QLatin1String(QContactAddress::SubTypeParcel)); |
|
1138 subTypes << QString(QLatin1String(QContactAddress::SubTypePostal)); |
|
1139 f.setAllowableValues(subTypes); |
|
1140 fields.insert(QContactAddress::FieldSubTypes, f); |
|
1141 f.setDataType(QVariant::StringList); |
|
1142 f.setAllowableValues(contexts); |
|
1143 fields.insert(QContactDetail::FieldContext, f); |
|
1144 d.setFields(fields); |
|
1145 d.setUnique(false); |
|
1146 retn.insert(d.name(), d); |
|
1147 |
|
1148 // name |
|
1149 d.setName(QContactName::DefinitionName); |
|
1150 fields.clear(); |
|
1151 f.setDataType(QVariant::String); |
|
1152 f.setAllowableValues(QVariantList()); |
|
1153 fields.insert(QContactName::FieldPrefix, f); |
|
1154 fields.insert(QContactName::FieldFirstName, f); |
|
1155 fields.insert(QContactName::FieldMiddleName, f); |
|
1156 fields.insert(QContactName::FieldLastName, f); |
|
1157 fields.insert(QContactName::FieldSuffix, f); |
|
1158 fields.insert(QContactName::FieldCustomLabel, f); |
|
1159 f.setDataType(QVariant::StringList); |
|
1160 f.setAllowableValues(contexts); |
|
1161 fields.insert(QContactDetail::FieldContext, f); |
|
1162 d.setFields(fields); |
|
1163 d.setUnique(false); |
|
1164 retn.insert(d.name(), d); |
|
1165 |
|
1166 // tag |
|
1167 d.setName(QContactTag::DefinitionName); |
|
1168 fields.clear(); |
|
1169 f.setDataType(QVariant::String); |
|
1170 f.setAllowableValues(QVariantList()); |
|
1171 fields.insert(QContactTag::FieldTag, f); |
|
1172 f.setDataType(QVariant::StringList); |
|
1173 f.setAllowableValues(contexts); |
|
1174 fields.insert(QContactDetail::FieldContext, f); |
|
1175 d.setFields(fields); |
|
1176 d.setUnique(false); |
|
1177 retn.insert(d.name(), d); |
|
1178 |
|
1179 // in the default schema, we have two contact types: TypeContact, TypeGroup. |
|
1180 // the entire default schema is valid for both types. |
|
1181 QMap<QString, QMap<QString, QContactDetailDefinition> > retnSchema; |
|
1182 retnSchema.insert(QContactType::TypeContact, retn); |
|
1183 retnSchema.insert(QContactType::TypeGroup, retn); |
|
1184 |
|
1185 return retnSchema; |
|
1186 } |
|
1187 |
|
1188 /*! |
|
1189 Checks that the given contact \a contact does not have details which |
|
1190 don't conform to a valid definition, violate uniqueness constraints, |
|
1191 or contain values for nonexistent fields, and that the values contained are |
|
1192 of the correct type for each field, and are allowable values for that field. |
|
1193 |
|
1194 Note that this function is unable to ensure that the access constraints |
|
1195 (such as CreateOnly and ReadOnly) are observed; backend specific code |
|
1196 must be written if you wish to enforce these constraints. |
|
1197 |
|
1198 Returns true if the \a contact is valid according to the definitions for |
|
1199 its details, otherwise returns false. |
|
1200 |
|
1201 Any errors encountered during this operation should be stored to |
|
1202 \a error. |
|
1203 */ |
|
1204 bool QContactManagerEngine::validateContact(const QContact& contact, QContactManager::Error* error) const |
|
1205 { |
|
1206 QList<QString> uniqueDefinitionIds; |
|
1207 |
|
1208 // check that each detail conforms to its definition as supported by this manager. |
|
1209 foreach (const QContactDetail& detail, contact.details()) { |
|
1210 QVariantMap values = detail.variantValues(); |
|
1211 QContactDetailDefinition def = detailDefinition(detail.definitionName(), contact.type(), error); |
|
1212 // check that the definition is supported |
|
1213 if (*error != QContactManager::NoError) { |
|
1214 *error = QContactManager::InvalidDetailError; |
|
1215 return false; // this definition is not supported. |
|
1216 } |
|
1217 |
|
1218 // check uniqueness |
|
1219 if (def.isUnique()) { |
|
1220 if (uniqueDefinitionIds.contains(def.name())) { |
|
1221 *error = QContactManager::AlreadyExistsError; |
|
1222 return false; // can't have two of a unique detail. |
|
1223 } |
|
1224 uniqueDefinitionIds.append(def.name()); |
|
1225 } |
|
1226 |
|
1227 QMapIterator<QString,QVariant> fieldIt(values); |
|
1228 while (fieldIt.hasNext()) { |
|
1229 fieldIt.next(); |
|
1230 const QString& key = fieldIt.key(); |
|
1231 const QVariant& variant = fieldIt.value(); |
|
1232 // check that no values exist for nonexistent fields. |
|
1233 if (!def.fields().contains(key)) { |
|
1234 *error = QContactManager::InvalidDetailError; |
|
1235 return false; // value for nonexistent field. |
|
1236 } |
|
1237 |
|
1238 QContactDetailFieldDefinition field = def.fields().value(key); |
|
1239 // check that the type of each value corresponds to the allowable field type |
|
1240 if (static_cast<int>(field.dataType()) != variant.userType()) { |
|
1241 *error = QContactManager::InvalidDetailError; |
|
1242 return false; // type doesn't match. |
|
1243 } |
|
1244 |
|
1245 // check that the value is allowable |
|
1246 // if the allowable values is an empty list, any are allowed. |
|
1247 if (!field.allowableValues().isEmpty()) { |
|
1248 // if the field datatype is a list, check that it contains only allowable values |
|
1249 if (field.dataType() == QVariant::List || field.dataType() == QVariant::StringList) { |
|
1250 QList<QVariant> innerValues = variant.toList(); |
|
1251 QListIterator<QVariant> it(innerValues); |
|
1252 while (it.hasNext()) { |
|
1253 if (!field.allowableValues().contains(it.next())) { |
|
1254 *error = QContactManager::InvalidDetailError; |
|
1255 return false; // value not allowed. |
|
1256 } |
|
1257 } |
|
1258 } else if (!field.allowableValues().contains(variant)) { |
|
1259 // the datatype is not a list; the value wasn't allowed. |
|
1260 *error = QContactManager::InvalidDetailError; |
|
1261 return false; // value not allowed. |
|
1262 } |
|
1263 } |
|
1264 } |
|
1265 } |
|
1266 |
|
1267 return true; |
|
1268 } |
|
1269 |
|
1270 /*! |
|
1271 Checks that the given detail definition \a definition seems valid, |
|
1272 with a correct id, defined fields, and any specified value types |
|
1273 are supported by this engine. This function is called before |
|
1274 trying to save a definition. |
|
1275 |
|
1276 Returns true if the \a definition seems valid, otherwise returns |
|
1277 false. |
|
1278 |
|
1279 Any errors encountered during this operation should be stored to |
|
1280 \a error. |
|
1281 */ |
|
1282 bool QContactManagerEngine::validateDefinition(const QContactDetailDefinition& definition, QContactManager::Error* error) const |
|
1283 { |
|
1284 if (definition.name().isEmpty()) { |
|
1285 *error = QContactManager::BadArgumentError; |
|
1286 return false; |
|
1287 } |
|
1288 |
|
1289 if (definition.fields().count() == 0) { |
|
1290 *error = QContactManager::BadArgumentError; |
|
1291 return false; |
|
1292 } |
|
1293 |
|
1294 // Check each field now |
|
1295 QList<QVariant::Type> types = supportedDataTypes(); |
|
1296 QMapIterator<QString, QContactDetailFieldDefinition> it(definition.fields()); |
|
1297 while(it.hasNext()) { |
|
1298 it.next(); |
|
1299 if (it.key().isEmpty()) { |
|
1300 *error = QContactManager::BadArgumentError; |
|
1301 return false; |
|
1302 } |
|
1303 |
|
1304 if (!types.contains(it.value().dataType())) { |
|
1305 *error = QContactManager::BadArgumentError; |
|
1306 return false; |
|
1307 } |
|
1308 |
|
1309 // Check that each allowed value is the same type |
|
1310 for (int i=0; i < it.value().allowableValues().count(); i++) { |
|
1311 if (it.value().allowableValues().at(i).type() != it.value().dataType()) { |
|
1312 *error = QContactManager::BadArgumentError; |
|
1313 return false; |
|
1314 } |
|
1315 } |
|
1316 } |
|
1317 *error = QContactManager::NoError; |
|
1318 return true; |
|
1319 } |
|
1320 |
|
1321 /*! |
|
1322 Returns the registered detail definitions which are valid for contacts whose type is of the given \a contactType in this engine. |
|
1323 |
|
1324 Any errors encountered during this operation should be stored to |
|
1325 \a error. |
|
1326 */ |
|
1327 QMap<QString, QContactDetailDefinition> QContactManagerEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const |
|
1328 { |
|
1329 Q_UNUSED(contactType); |
|
1330 *error = QContactManager::NotSupportedError; |
|
1331 return QMap<QString, QContactDetailDefinition>(); |
|
1332 } |
|
1333 |
|
1334 /*! |
|
1335 Returns the definition identified by the given \a definitionName that |
|
1336 is valid for contacts whose type is of the given \a contactType in this store, or a default-constructed QContactDetailDefinition |
|
1337 if no such definition exists |
|
1338 |
|
1339 Any errors encountered during this operation should be stored to |
|
1340 \a error. |
|
1341 */ |
|
1342 QContactDetailDefinition QContactManagerEngine::detailDefinition(const QString& definitionName, const QString& contactType, QContactManager::Error* error) const |
|
1343 { |
|
1344 QMap<QString, QContactDetailDefinition> definitions = detailDefinitions(contactType, error); |
|
1345 if (definitions.contains(definitionName)) { |
|
1346 *error = QContactManager::NoError; |
|
1347 return definitions.value(definitionName); |
|
1348 } else { |
|
1349 *error = QContactManager::DoesNotExistError; |
|
1350 return QContactDetailDefinition(); |
|
1351 } |
|
1352 } |
|
1353 |
|
1354 /*! |
|
1355 Persists the given definition \a def in the database, which is valid for contacts whose type is the given \a contactType. |
|
1356 |
|
1357 Returns true if the definition was saved successfully, and otherwise returns false. |
|
1358 |
|
1359 The backend must emit the appropriate signals to inform clients of changes |
|
1360 to the database resulting from this operation. |
|
1361 |
|
1362 Any errors encountered during this operation should be stored to |
|
1363 \a error. |
|
1364 */ |
|
1365 bool QContactManagerEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error* error) |
|
1366 { |
|
1367 Q_UNUSED(def); |
|
1368 Q_UNUSED(contactType); |
|
1369 |
|
1370 *error = QContactManager::NotSupportedError; |
|
1371 return false; |
|
1372 } |
|
1373 |
|
1374 /*! |
|
1375 Removes the definition identified by the given \a definitionName from the database, where it was valid for contacts whose type was the given \a contactType. |
|
1376 |
|
1377 Returns true if the definition was removed successfully, otherwise returns false. |
|
1378 |
|
1379 The backend must emit the appropriate signals to inform clients of changes |
|
1380 to the database resulting from this operation. |
|
1381 |
|
1382 Any errors encountered during this operation should be stored to |
|
1383 \a error. |
|
1384 */ |
|
1385 bool QContactManagerEngine::removeDetailDefinition(const QString& definitionName, const QString& contactType, QContactManager::Error* error) |
|
1386 { |
|
1387 Q_UNUSED(definitionName); |
|
1388 Q_UNUSED(contactType); |
|
1389 |
|
1390 *error = QContactManager::NotSupportedError; |
|
1391 return false; |
|
1392 } |
|
1393 |
|
1394 /*! |
|
1395 Sets the access constraints of \a detail to the supplied \a constraints. |
|
1396 |
|
1397 This function is provided to allow engine implementations to report the |
|
1398 access constraints of retrieved details, without generally allowing the |
|
1399 access constraints to be modified after retrieval. |
|
1400 |
|
1401 Application code should not call this function, since validation of the |
|
1402 detail will happen in the engine in any case. |
|
1403 */ |
|
1404 void QContactManagerEngine::setDetailAccessConstraints(QContactDetail *detail, QContactDetail::AccessConstraints constraints) |
|
1405 { |
|
1406 if (detail) { |
|
1407 QContactDetailPrivate::setAccessConstraints(detail, constraints); |
|
1408 } |
|
1409 } |
|
1410 |
|
1411 |
|
1412 /*! |
|
1413 Adds the given \a contact to the database if \a contact has a |
|
1414 default-constructed id, or an id with the manager URI set to the URI of |
|
1415 this manager and a local id of zero, otherwise updates the contact in |
|
1416 the database which has the same id to be the given \a contact. |
|
1417 If the id is non-zero but does not identify any contact stored in the |
|
1418 manager, the function will return false and \a error will be set to |
|
1419 \c QContactManager::DoesNotExistError. |
|
1420 |
|
1421 Returns true if the save operation completed successfully, otherwise |
|
1422 returns false. Any error which occurs will be saved in \a error. |
|
1423 |
|
1424 The default implementation will convert this into a call to saveContacts. |
|
1425 |
|
1426 \sa managerUri() |
|
1427 */ |
|
1428 bool QContactManagerEngine::saveContact(QContact* contact, QContactManager::Error* error) |
|
1429 { |
|
1430 // Convert to a list op |
|
1431 if (contact) { |
|
1432 QList<QContact> list; |
|
1433 list.append(*contact); |
|
1434 |
|
1435 QMap<int, QContactManager::Error> errors; |
|
1436 bool ret = saveContacts(&list, &errors, error); |
|
1437 |
|
1438 if (errors.count() > 0) |
|
1439 *error = errors.begin().value(); |
|
1440 |
|
1441 *contact = list.value(0); |
|
1442 return ret; |
|
1443 } else { |
|
1444 *error = QContactManager::BadArgumentError; |
|
1445 return false; |
|
1446 } |
|
1447 } |
|
1448 |
|
1449 /*! |
|
1450 Remove the contact identified by \a contactId from the database, |
|
1451 and also removes any relationships in which the contact was involved. |
|
1452 Returns true if the contact was removed successfully, otherwise |
|
1453 returns false. |
|
1454 |
|
1455 Any error which occurs will be saved in \a error. |
|
1456 |
|
1457 The default implementation will convert this into a call to removeContacts. |
|
1458 */ |
|
1459 bool QContactManagerEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error) |
|
1460 { |
|
1461 // Convert to a list op |
|
1462 QList<QContactLocalId> list; |
|
1463 list.append(contactId); |
|
1464 |
|
1465 QMap<int, QContactManager::Error> errors; |
|
1466 bool ret = removeContacts(list, &errors, error); |
|
1467 |
|
1468 if (errors.count() > 0) |
|
1469 *error = errors.begin().value(); |
|
1470 |
|
1471 return ret; |
|
1472 } |
|
1473 |
|
1474 /*! |
|
1475 Adds the list of contacts given by \a contacts list to the database. |
|
1476 Returns true if the contacts were saved successfully, otherwise false. |
|
1477 |
|
1478 The manager might populate \a errorMap (the map of indices of the \a contacts list to |
|
1479 the error which occurred when saving the contact at that index) for |
|
1480 every index for which the contact could not be saved, if it is able. |
|
1481 |
|
1482 The supplied \a errorMap parameter may be null, if the client does not desire detailed error information. |
|
1483 If supplied, it will be empty upon entry to this function. |
|
1484 |
|
1485 The \l QContactManager::error() function will only return \c QContactManager::NoError |
|
1486 if all contacts were saved successfully. |
|
1487 |
|
1488 For each newly saved contact that was successful, the id of the contact |
|
1489 in the \a contacts list will be updated with the new value. If a failure occurs |
|
1490 when saving a new contact, the id will be cleared. |
|
1491 |
|
1492 Any errors encountered during this operation should be stored to |
|
1493 \a error. |
|
1494 |
|
1495 \sa QContactManager::saveContact() |
|
1496 */ |
|
1497 bool QContactManagerEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
1498 { |
|
1499 Q_UNUSED(contacts); |
|
1500 Q_UNUSED(errorMap); |
|
1501 *error = QContactManager::NotSupportedError; |
|
1502 return false; |
|
1503 } |
|
1504 |
|
1505 /*! |
|
1506 Remove every contact whose id is contained in the list of contacts ids |
|
1507 \a contactIds. Returns true if all contacts were removed successfully, |
|
1508 otherwise false. |
|
1509 |
|
1510 Any contact that was removed successfully will have the relationships |
|
1511 in which it was involved removed also. |
|
1512 |
|
1513 The manager might populate \a errorMap (the map of indices of the \a contactIds list to |
|
1514 the error which occurred when saving the contact at that index) for every |
|
1515 index for which the contact could not be removed, if it is able. |
|
1516 |
|
1517 The supplied \a errorMap parameter may be null, if the client does not desire detailed error information. |
|
1518 If supplied, it will be empty upon entry to this function. |
|
1519 |
|
1520 The \l QContactManager::error() function will |
|
1521 only return \c QContactManager::NoError if all contacts were removed |
|
1522 successfully. |
|
1523 |
|
1524 If the list contains ids which do not identify a valid contact in the manager, the function will |
|
1525 remove any contacts which are identified by ids in the \a contactIds list, insert |
|
1526 \c QContactManager::DoesNotExist entries into the \a errorMap for the indices of invalid ids |
|
1527 in the \a contactIds list, return false, and set the overall operation error to |
|
1528 \c QContactManager::DoesNotExistError. |
|
1529 |
|
1530 Any errors encountered during this operation should be stored to |
|
1531 \a error. |
|
1532 |
|
1533 \sa QContactManager::removeContact() |
|
1534 */ |
|
1535 bool QContactManagerEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
1536 { |
|
1537 Q_UNUSED(contactIds); |
|
1538 Q_UNUSED(errorMap); |
|
1539 *error = QContactManager::NotSupportedError; |
|
1540 return false; |
|
1541 } |
|
1542 |
|
1543 /*! |
|
1544 Returns a pruned or modified version of the \a original contact which is valid and can be saved in the manager. |
|
1545 The returned contact might have details removed or arbitrarily changed. The cache of relationships |
|
1546 in the contact are ignored entirely when considering compatibility with the backend, as they are |
|
1547 saved and validated separately. Any error which occurs will be saved to \a error. |
|
1548 */ |
|
1549 QContact QContactManagerEngine::compatibleContact(const QContact& original, QContactManager::Error* error) const |
|
1550 { |
|
1551 QContact conforming; |
|
1552 conforming.setId(original.id()); |
|
1553 QContactManager::Error tempError; |
|
1554 QList<QString> uniqueDefinitionIds; |
|
1555 foreach (QContactDetail detail, original.details()) { |
|
1556 // check that the detail conforms to the definition in this manager. |
|
1557 // if so, then add it to the conforming contact to be returned. if not, prune it. |
|
1558 |
|
1559 QVariantMap values = detail.variantValues(); |
|
1560 QContactDetailDefinition def = detailDefinition(detail.definitionName(), original.type(), &tempError); |
|
1561 // check that the definition is supported |
|
1562 if (tempError != QContactManager::NoError) { |
|
1563 continue; // this definition is not supported. |
|
1564 } |
|
1565 |
|
1566 // check uniqueness |
|
1567 if (def.isUnique()) { |
|
1568 if (uniqueDefinitionIds.contains(def.name())) { |
|
1569 continue; // can't have two of a unique detail. |
|
1570 } |
|
1571 uniqueDefinitionIds.append(def.name()); |
|
1572 } |
|
1573 |
|
1574 QMapIterator<QString,QVariant> fieldIt(values); |
|
1575 while (fieldIt.hasNext()) { |
|
1576 fieldIt.next(); |
|
1577 const QString& key = fieldIt.key(); |
|
1578 const QVariant& variant = fieldIt.value(); |
|
1579 // prune values for nonexistent fields. |
|
1580 if (!def.fields().contains(key)) { |
|
1581 detail.removeValue(key); |
|
1582 } |
|
1583 |
|
1584 QContactDetailFieldDefinition field = def.fields().value(key); |
|
1585 // prune values that do not correspond to the allowable field type |
|
1586 if (static_cast<int>(field.dataType()) != variant.userType()) { |
|
1587 detail.removeValue(key); |
|
1588 } |
|
1589 |
|
1590 // check that the value is allowable |
|
1591 // if the allowable values is an empty list, any are allowed. |
|
1592 if (!field.allowableValues().isEmpty()) { |
|
1593 // if the field datatype is a list, remove non-allowable values |
|
1594 if (field.dataType() == QVariant::List) { |
|
1595 QVariantList innerValues = variant.toList(); |
|
1596 QMutableListIterator<QVariant> it(innerValues); |
|
1597 while (it.hasNext()) { |
|
1598 if (!field.allowableValues().contains(it.next())) { |
|
1599 it.remove(); |
|
1600 } |
|
1601 } |
|
1602 if (innerValues.isEmpty()) |
|
1603 detail.removeValue(key); |
|
1604 else |
|
1605 detail.setValue(key, innerValues); |
|
1606 } |
|
1607 if (field.dataType() == QVariant::StringList) { |
|
1608 QStringList innerValues = variant.toStringList(); |
|
1609 QMutableListIterator<QString> it(innerValues); |
|
1610 while (it.hasNext()) { |
|
1611 if (!field.allowableValues().contains(it.next())) { |
|
1612 it.remove(); |
|
1613 } |
|
1614 } |
|
1615 if (innerValues.isEmpty()) |
|
1616 detail.removeValue(key); |
|
1617 else |
|
1618 detail.setValue(key, innerValues); |
|
1619 } else if (!field.allowableValues().contains(variant)) { |
|
1620 detail.removeValue(key); |
|
1621 } |
|
1622 } |
|
1623 } |
|
1624 |
|
1625 // if it hasn't been pruned away to nothing, save it in the conforming contact |
|
1626 if (!detail.isEmpty()) { |
|
1627 conforming.saveDetail(&detail); |
|
1628 } |
|
1629 } |
|
1630 |
|
1631 if (!conforming.isEmpty()) |
|
1632 *error = QContactManager::NoError; |
|
1633 else |
|
1634 *error = QContactManager::DoesNotExistError; |
|
1635 return conforming; |
|
1636 } |
|
1637 |
|
1638 |
|
1639 /* This implements the string comparison behaviour required for compareVariant, amongst others */ |
|
1640 static inline int compareStrings(const QString& left, const QString& right, Qt::CaseSensitivity sensitivity) |
|
1641 { |
|
1642 if (sensitivity == Qt::CaseSensitive) { |
|
1643 return left.localeAwareCompare(right); |
|
1644 } else { |
|
1645 return left.toCaseFolded().localeAwareCompare(right.toCaseFolded()); |
|
1646 } |
|
1647 } |
|
1648 |
|
1649 /*! |
|
1650 Compares \a first against \a second. If the types are |
|
1651 strings (QVariant::String), the \a sensitivity argument controls |
|
1652 case sensitivity when comparing. Also, when comparing strings, |
|
1653 a locale aware comparison is used, and if the sensitivity is |
|
1654 CaseSensitive, strings that are identical under a case insensitive |
|
1655 sort are then sorted case sensitively within that context. |
|
1656 |
|
1657 |
|
1658 For example: |
|
1659 |
|
1660 aaron |
|
1661 Bob |
|
1662 Aaron |
|
1663 aAron |
|
1664 Carol |
|
1665 |
|
1666 would sort as: |
|
1667 |
|
1668 aaron |
|
1669 aAron |
|
1670 Aaron |
|
1671 Bob |
|
1672 Carol |
|
1673 |
|
1674 Returns: |
|
1675 <0 if \a first is less than \a second |
|
1676 0 if \a first is equal to \a second |
|
1677 >0 if \a first is greater than \a second. |
|
1678 |
|
1679 The results are undefined if the variants are different types, or |
|
1680 cannot be compared. |
|
1681 */ |
|
1682 int QContactManagerEngine::compareVariant(const QVariant& first, const QVariant& second, Qt::CaseSensitivity sensitivity) |
|
1683 { |
|
1684 switch(first.type()) { |
|
1685 case QVariant::Int: |
|
1686 return first.toInt() - second.toInt(); |
|
1687 |
|
1688 case QVariant::LongLong: |
|
1689 return first.toLongLong() - second.toLongLong(); |
|
1690 |
|
1691 case QVariant::Bool: |
|
1692 case QVariant::Char: |
|
1693 case QVariant::UInt: |
|
1694 return first.toUInt() - second.toUInt(); |
|
1695 |
|
1696 case QVariant::ULongLong: |
|
1697 return first.toULongLong() - second.toULongLong(); |
|
1698 |
|
1699 case QVariant::String: |
|
1700 return compareStrings(first.toString(), second.toString(), sensitivity); |
|
1701 |
|
1702 case QVariant::Double: |
|
1703 { |
|
1704 const double a = first.toDouble(); |
|
1705 const double b = second.toDouble(); |
|
1706 return (a < b) ? -1 : ((a == b) ? 0 : 1); |
|
1707 } |
|
1708 |
|
1709 case QVariant::DateTime: |
|
1710 { |
|
1711 const QDateTime a = first.toDateTime(); |
|
1712 const QDateTime b = second.toDateTime(); |
|
1713 return (a < b) ? -1 : ((a == b) ? 0 : 1); |
|
1714 } |
|
1715 |
|
1716 case QVariant::Date: |
|
1717 return first.toDate().toJulianDay() - second.toDate().toJulianDay(); |
|
1718 |
|
1719 case QVariant::Time: |
|
1720 { |
|
1721 const QTime a = first.toTime(); |
|
1722 const QTime b = second.toTime(); |
|
1723 return (a < b) ? -1 : ((a == b) ? 0 : 1); |
|
1724 } |
|
1725 |
|
1726 default: |
|
1727 return 0; |
|
1728 } |
|
1729 } |
|
1730 |
|
1731 /*! |
|
1732 Returns true if the supplied contact \a contact matches the supplied filter \a filter. |
|
1733 |
|
1734 This function will test each condition in the filter, possibly recursing. |
|
1735 */ |
|
1736 bool QContactManagerEngine::testFilter(const QContactFilter &filter, const QContact &contact) |
|
1737 { |
|
1738 switch(filter.type()) { |
|
1739 case QContactFilter::InvalidFilter: |
|
1740 return false; |
|
1741 |
|
1742 case QContactFilter::DefaultFilter: |
|
1743 return true; |
|
1744 |
|
1745 case QContactFilter::LocalIdFilter: |
|
1746 { |
|
1747 const QContactLocalIdFilter idf(filter); |
|
1748 if (idf.ids().contains(contact.id().localId())) |
|
1749 return true; |
|
1750 } |
|
1751 // Fall through to end |
|
1752 break; |
|
1753 |
|
1754 case QContactFilter::ContactDetailFilter: |
|
1755 { |
|
1756 const QContactDetailFilter cdf(filter); |
|
1757 if (cdf.detailDefinitionName().isEmpty()) |
|
1758 return false; |
|
1759 |
|
1760 /* See if this contact has one of these details in it */ |
|
1761 const QList<QContactDetail>& details = contact.details(cdf.detailDefinitionName()); |
|
1762 |
|
1763 if (details.count() == 0) |
|
1764 return false; /* can't match */ |
|
1765 |
|
1766 /* See if we need to check the values */ |
|
1767 if (cdf.detailFieldName().isEmpty()) |
|
1768 return true; /* just testing for the presence of a detail of the specified definition */ |
|
1769 |
|
1770 /* Now figure out what tests we are doing */ |
|
1771 const bool valueTest = cdf.value().isValid(); |
|
1772 const bool presenceTest = !valueTest; |
|
1773 |
|
1774 /* See if we need to test any values at all */ |
|
1775 if (presenceTest) { |
|
1776 for(int j=0; j < details.count(); j++) { |
|
1777 const QContactDetail& detail = details.at(j); |
|
1778 |
|
1779 /* Check that the field is present and has a non-empty value */ |
|
1780 if (detail.variantValues().contains(cdf.detailFieldName()) && !detail.value(cdf.detailFieldName()).isEmpty()) |
|
1781 return true; |
|
1782 } |
|
1783 return false; |
|
1784 } |
|
1785 |
|
1786 /* Case sensitivity, for those parts that use it */ |
|
1787 Qt::CaseSensitivity cs = (cdf.matchFlags() & QContactFilter::MatchCaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive; |
|
1788 |
|
1789 /* See what flags are requested, since we're looking at a value */ |
|
1790 if (cdf.matchFlags() & QContactFilter::MatchPhoneNumber) { |
|
1791 /* Doing phone number filtering. We hand roll an implementation here, backends will obviously want to override this. */ |
|
1792 QString input = cdf.value().toString(); |
|
1793 |
|
1794 /* preprocess the input - ignore any non-digits (doesn't perform ITU-T collation */ |
|
1795 QString preprocessedInput; |
|
1796 for (int i = 0; i < input.size(); i++) { |
|
1797 QChar current = input.at(i).toLower(); |
|
1798 if (current.isDigit()) preprocessedInput.append(current); |
|
1799 // note: we ignore characters like '+', 'p', 'w', '*' and '#' which may be important. |
|
1800 } |
|
1801 |
|
1802 /* Look at every detail in the set of details and compare */ |
|
1803 for (int j = 0; j < details.count(); j++) { |
|
1804 const QContactDetail& detail = details.at(j); |
|
1805 const QString& valueString = detail.value(cdf.detailFieldName()); |
|
1806 QString preprocessedValueString; |
|
1807 for (int i = 0; i < valueString.size(); i++) { |
|
1808 QChar current = valueString.at(i).toLower(); |
|
1809 if (current.isDigit()) preprocessedValueString.append(current); |
|
1810 // note: we ignore characters like '+', 'p', 'w', '*' and '#' which may be important. |
|
1811 } |
|
1812 |
|
1813 // if the matchflags input don't require a particular criteria to pass, we assume that it has passed. |
|
1814 // the "default" match strategy is an "endsWith" strategy. |
|
1815 bool me = (cdf.matchFlags() & 7) == QContactFilter::MatchExactly; |
|
1816 bool mc = (cdf.matchFlags() & 7) == QContactFilter::MatchContains; |
|
1817 bool msw = (cdf.matchFlags() & 7) == QContactFilter::MatchStartsWith; |
|
1818 bool mew = (cdf.matchFlags() & 7) == QContactFilter::MatchEndsWith; |
|
1819 |
|
1820 bool mer = (me ? preprocessedValueString == preprocessedInput : true); |
|
1821 bool mcr = (mc ? preprocessedValueString.contains(preprocessedInput) : true); |
|
1822 bool mswr = (msw ? preprocessedValueString.startsWith(preprocessedInput) : true); |
|
1823 bool mewr = (mew ? preprocessedValueString.endsWith(preprocessedInput) : true); |
|
1824 if (mewr && mswr && mcr && mer) { |
|
1825 return true; // this detail meets all of the criteria which were required, and hence must match. |
|
1826 } |
|
1827 } |
|
1828 } else if (cdf.matchFlags() & QContactFilter::MatchKeypadCollation) { |
|
1829 // XXX TODO: not sure about the filtering semantics for MatchKeypadCollation. |
|
1830 QString input = cdf.value().toString(); |
|
1831 |
|
1832 /* Look at every detail in the set of details and compare */ |
|
1833 for (int j = 0; j < details.count(); j++) { |
|
1834 const QContactDetail& detail = details.at(j); |
|
1835 const QString& valueString = detail.value(cdf.detailFieldName()).toLower(); |
|
1836 |
|
1837 // preprocess the valueString |
|
1838 QString preprocessedValue; |
|
1839 for (int i = 0; i < valueString.size(); i++) { |
|
1840 // we use ITU-T keypad collation by default. |
|
1841 QChar currentValueChar = valueString.at(i); |
|
1842 if (currentValueChar == QLatin1Char('a') || currentValueChar == QLatin1Char('b') || currentValueChar == QLatin1Char('c')) |
|
1843 preprocessedValue.append(QLatin1Char('2')); |
|
1844 else if (currentValueChar == QLatin1Char('d') || currentValueChar == QLatin1Char('e') || currentValueChar == QLatin1Char('f')) |
|
1845 preprocessedValue.append(QLatin1Char('3')); |
|
1846 else if (currentValueChar == QLatin1Char('g') || currentValueChar == QLatin1Char('h') || currentValueChar == QLatin1Char('i')) |
|
1847 preprocessedValue.append(QLatin1Char('4')); |
|
1848 else if (currentValueChar == QLatin1Char('j') || currentValueChar == QLatin1Char('k') || currentValueChar == QLatin1Char('l')) |
|
1849 preprocessedValue.append(QLatin1Char('5')); |
|
1850 else if (currentValueChar == QLatin1Char('m') || currentValueChar == QLatin1Char('n') || currentValueChar == QLatin1Char('o')) |
|
1851 preprocessedValue.append(QLatin1Char('6')); |
|
1852 else if (currentValueChar == QLatin1Char('p') || currentValueChar == QLatin1Char('q') || currentValueChar == QLatin1Char('r') || currentValueChar == QLatin1Char('s')) |
|
1853 preprocessedValue.append(QLatin1Char('7')); |
|
1854 else if (currentValueChar == QLatin1Char('t') || currentValueChar == QLatin1Char('u') || currentValueChar == QLatin1Char('v')) |
|
1855 preprocessedValue.append(QLatin1Char('8')); |
|
1856 else if (currentValueChar == QLatin1Char('w') || currentValueChar == QLatin1Char('x') || currentValueChar == QLatin1Char('y') || currentValueChar == QLatin1Char('z')) |
|
1857 preprocessedValue.append(QLatin1Char('9')); |
|
1858 else |
|
1859 preprocessedValue.append(currentValueChar); |
|
1860 } |
|
1861 |
|
1862 bool me = (cdf.matchFlags() & 7) == QContactFilter::MatchExactly; |
|
1863 bool mc = (cdf.matchFlags() & 7) == QContactFilter::MatchContains; |
|
1864 bool msw = (cdf.matchFlags() & 7) == QContactFilter::MatchStartsWith; |
|
1865 bool mew = (cdf.matchFlags() & 7) == QContactFilter::MatchEndsWith; |
|
1866 |
|
1867 bool mer = (me ? preprocessedValue == input : true); |
|
1868 bool mcr = (mc ? preprocessedValue.contains(input) : true); |
|
1869 bool mswr = (msw ? preprocessedValue.startsWith(input) : true); |
|
1870 bool mewr = (mew ? preprocessedValue.endsWith(input) : true); |
|
1871 if (mewr && mswr && mcr && mer) { |
|
1872 return true; // this detail meets all of the criteria which were required, and hence must match. |
|
1873 } |
|
1874 } |
|
1875 } else if (cdf.matchFlags() & (QContactFilter::MatchEndsWith | QContactFilter::MatchStartsWith | QContactFilter::MatchContains | QContactFilter::MatchFixedString)) { |
|
1876 /* We're strictly doing string comparisons here */ |
|
1877 bool matchStarts = (cdf.matchFlags() & 7) == QContactFilter::MatchStartsWith; |
|
1878 bool matchEnds = (cdf.matchFlags() & 7) == QContactFilter::MatchEndsWith; |
|
1879 bool matchContains = (cdf.matchFlags() & 7) == QContactFilter::MatchContains; |
|
1880 |
|
1881 /* Value equality test */ |
|
1882 for(int j=0; j < details.count(); j++) { |
|
1883 const QContactDetail& detail = details.at(j); |
|
1884 const QString& var = detail.value(cdf.detailFieldName()); |
|
1885 const QString& needle = cdf.value().toString(); |
|
1886 if (matchStarts && var.startsWith(needle, cs)) |
|
1887 return true; |
|
1888 if (matchEnds && var.endsWith(needle, cs)) |
|
1889 return true; |
|
1890 if (matchContains && var.contains(needle, cs)) |
|
1891 return true; |
|
1892 if (compareStrings(var, needle, cs) == 0) |
|
1893 return true; |
|
1894 } |
|
1895 return false; |
|
1896 } else { |
|
1897 /* Nope, testing the values as a variant */ |
|
1898 /* Value equality test */ |
|
1899 for(int j = 0; j < details.count(); j++) { |
|
1900 const QContactDetail& detail = details.at(j); |
|
1901 const QVariant& var = detail.variantValue(cdf.detailFieldName()); |
|
1902 if (!var.isNull() && compareVariant(var, cdf.value(), cs) == 0) |
|
1903 return true; |
|
1904 } |
|
1905 } |
|
1906 } |
|
1907 break; |
|
1908 |
|
1909 case QContactFilter::ContactDetailRangeFilter: |
|
1910 { |
|
1911 /* The only supported flags are: MatchExactly, MatchFixedString, MatchCaseSensitive */ |
|
1912 |
|
1913 const QContactDetailRangeFilter cdf(filter); |
|
1914 if (cdf.detailDefinitionName().isEmpty()) |
|
1915 return false; /* we do not know which field to check */ |
|
1916 |
|
1917 /* See if this contact has one of these details in it */ |
|
1918 const QList<QContactDetail>& details = contact.details(cdf.detailDefinitionName()); |
|
1919 |
|
1920 if (details.count() == 0) |
|
1921 return false; /* can't match */ |
|
1922 |
|
1923 /* Check for a detail presence test */ |
|
1924 if (cdf.detailFieldName().isEmpty()) |
|
1925 return true; |
|
1926 |
|
1927 /* See if this is a field presence test */ |
|
1928 if (!cdf.minValue().isValid() && !cdf.maxValue().isValid()) { |
|
1929 for(int j=0; j < details.count(); j++) { |
|
1930 const QContactDetail& detail = details.at(j); |
|
1931 if (detail.variantValues().contains(cdf.detailFieldName())) |
|
1932 return true; |
|
1933 } |
|
1934 return false; |
|
1935 } |
|
1936 |
|
1937 /* open or closed interval testing support */ |
|
1938 const int minComp = cdf.rangeFlags() & QContactDetailRangeFilter::ExcludeLower ? 1 : 0; |
|
1939 const int maxComp = cdf.rangeFlags() & QContactDetailRangeFilter::IncludeUpper ? 1 : 0; |
|
1940 |
|
1941 /* Case sensitivity, for those parts that use it */ |
|
1942 Qt::CaseSensitivity cs = (cdf.matchFlags() & QContactFilter::MatchCaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive; |
|
1943 |
|
1944 /* See what flags are requested, since we're looking at a value */ |
|
1945 if (cdf.matchFlags() & QContactFilter::MatchFixedString) { |
|
1946 /* We're strictly doing string comparisons here */ |
|
1947 QString minVal = cdf.minValue().toString(); |
|
1948 QString maxVal = cdf.maxValue().toString(); |
|
1949 |
|
1950 const bool testMin = !minVal.isEmpty(); |
|
1951 const bool testMax = !maxVal.isEmpty(); |
|
1952 |
|
1953 for(int j=0; j < details.count(); j++) { |
|
1954 const QContactDetail& detail = details.at(j); |
|
1955 |
|
1956 // The detail has to have a field of this type in order to be compared. |
|
1957 if (!detail.variantValue(cdf.detailFieldName()).isValid()) |
|
1958 continue; |
|
1959 const QString& var = detail.value(cdf.detailFieldName()); |
|
1960 if (testMin && compareStrings(var, minVal, cs) < minComp) |
|
1961 continue; |
|
1962 if (testMax && compareStrings(var, maxVal, cs) >= maxComp) |
|
1963 continue; |
|
1964 return true; |
|
1965 } |
|
1966 // Fall through to end |
|
1967 } else { |
|
1968 const bool testMin = cdf.minValue().isValid(); |
|
1969 const bool testMax = cdf.maxValue().isValid(); |
|
1970 |
|
1971 /* Nope, testing the values as a variant */ |
|
1972 for(int j=0; j < details.count(); j++) { |
|
1973 const QContactDetail& detail = details.at(j); |
|
1974 const QVariant& var = detail.variantValue(cdf.detailFieldName()); |
|
1975 |
|
1976 // The detail has to have a field of this type in order to be compared. |
|
1977 if (!var.isValid()) |
|
1978 continue; |
|
1979 |
|
1980 if (testMin && compareVariant(var, cdf.minValue(), cs) < minComp) |
|
1981 continue; |
|
1982 if (testMax && compareVariant(var, cdf.maxValue(), cs) >= maxComp) |
|
1983 continue; |
|
1984 return true; |
|
1985 } |
|
1986 // Fall through to end |
|
1987 } |
|
1988 } |
|
1989 break; |
|
1990 |
|
1991 case QContactFilter::RelationshipFilter: |
|
1992 { |
|
1993 // matches any contact that plays the specified role in a relationship |
|
1994 // of the specified type with the specified other participant. |
|
1995 const QContactRelationshipFilter rf(filter); |
|
1996 |
|
1997 // first, retrieve contact uris |
|
1998 QContactId contactUri = contact.id(); |
|
1999 QContactId relatedContactId = rf.relatedContactId(); |
|
2000 |
|
2001 // get the relationships in which this contact is involved. |
|
2002 QList<QContactRelationship> allRelationships; |
|
2003 allRelationships = contact.relationships(); |
|
2004 |
|
2005 // simplify the comparison of two contact id's depending on their fields. |
|
2006 #define CONTACT_IDS_MATCH(specific, other) \ |
|
2007 ((specific == QContactId()) \ |
|
2008 || (specific.managerUri().isEmpty() && specific.localId() == other.localId()) \ |
|
2009 || (specific.managerUri() == other.managerUri() && specific.localId() == QContactLocalId(0)) \ |
|
2010 || (specific.managerUri() == other.managerUri() && specific.localId() == other.localId())) |
|
2011 |
|
2012 // now check to see if we have a match. |
|
2013 foreach (const QContactRelationship& rel, allRelationships) { |
|
2014 // perform the matching. |
|
2015 if (rf.relatedContactRole() == QContactRelationship::Second) { // this is the role of the related contact; ie, to match, contact.id() must be the first in the relationship. |
|
2016 if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType()) |
|
2017 && CONTACT_IDS_MATCH(rel.first(), contact.id()) && CONTACT_IDS_MATCH(relatedContactId, rel.second())) { |
|
2018 return true; |
|
2019 } |
|
2020 } else if (rf.relatedContactRole() == QContactRelationship::First) { // this is the role of the related contact; ie, to match, contact.id() must be the second in the relationship. |
|
2021 if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType()) |
|
2022 && CONTACT_IDS_MATCH(rel.second(), contact.id()) && CONTACT_IDS_MATCH(relatedContactId, rel.first())) { |
|
2023 return true; |
|
2024 } |
|
2025 } else { // QContactRelationship::Either |
|
2026 if ((rf.relationshipType().isEmpty() || rel.relationshipType() == rf.relationshipType()) |
|
2027 && ((CONTACT_IDS_MATCH(relatedContactId, rel.first()) && !CONTACT_IDS_MATCH(contactUri, relatedContactId)) || (CONTACT_IDS_MATCH(relatedContactId, rel.second()) && !CONTACT_IDS_MATCH(contactUri, relatedContactId)))) { |
|
2028 return true; |
|
2029 } |
|
2030 } |
|
2031 } |
|
2032 |
|
2033 // if not found by now, it doesn't match the filter. |
|
2034 return false; |
|
2035 } |
|
2036 //break; // unreachable. |
|
2037 |
|
2038 case QContactFilter::ChangeLogFilter: |
|
2039 { |
|
2040 QContactChangeLogFilter ccf(filter); |
|
2041 |
|
2042 // See what we can do... |
|
2043 QContactTimestamp ts = contact.detail(QContactTimestamp::DefinitionName); |
|
2044 |
|
2045 // See if timestamps are even supported |
|
2046 if (ts.isEmpty()) |
|
2047 break; |
|
2048 |
|
2049 if (ccf.eventType() == QContactChangeLogFilter::EventAdded) |
|
2050 return ccf.since() <= ts.created(); |
|
2051 if (ccf.eventType() == QContactChangeLogFilter::EventChanged) |
|
2052 return ccf.since() <= ts.lastModified(); |
|
2053 |
|
2054 // You can't emulate a removed.. |
|
2055 // Fall through to end |
|
2056 } |
|
2057 break; |
|
2058 |
|
2059 case QContactFilter::ActionFilter: |
|
2060 { |
|
2061 // Find any matching actions, and do a union filter on their filter objects |
|
2062 QContactActionFilter af(filter); |
|
2063 QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion()); |
|
2064 |
|
2065 // There's a small wrinkle if there's a value specified in the action filter |
|
2066 // we have to adjust any contained QContactDetailFilters to have that value |
|
2067 // or test if a QContactDetailRangeFilter contains this value already |
|
2068 for (int j = 0; j < descriptors.count(); j++) { |
|
2069 QContactAction* action = QContactAction::action(descriptors.at(j)); |
|
2070 |
|
2071 // Action filters are not allowed to return action filters, at all |
|
2072 // it's too annoying to check for recursion |
|
2073 QContactFilter d = action->contactFilter(af.value()); |
|
2074 delete action; // clean up. |
|
2075 if (!validateActionFilter(d)) |
|
2076 return false; |
|
2077 |
|
2078 // Check for values etc... |
|
2079 if (testFilter(d, contact)) |
|
2080 return true; |
|
2081 } |
|
2082 // Fall through to end |
|
2083 } |
|
2084 break; |
|
2085 |
|
2086 case QContactFilter::IntersectionFilter: |
|
2087 { |
|
2088 /* XXX In theory we could reorder the terms to put the native tests first */ |
|
2089 const QContactIntersectionFilter bf(filter); |
|
2090 const QList<QContactFilter>& terms = bf.filters(); |
|
2091 if (terms.count() > 0) { |
|
2092 for(int j = 0; j < terms.count(); j++) { |
|
2093 if (!testFilter(terms.at(j), contact)) { |
|
2094 return false; |
|
2095 } |
|
2096 } |
|
2097 return true; |
|
2098 } |
|
2099 // Fall through to end |
|
2100 } |
|
2101 break; |
|
2102 |
|
2103 case QContactFilter::UnionFilter: |
|
2104 { |
|
2105 /* XXX In theory we could reorder the terms to put the native tests first */ |
|
2106 const QContactUnionFilter bf(filter); |
|
2107 const QList<QContactFilter>& terms = bf.filters(); |
|
2108 if (terms.count() > 0) { |
|
2109 for(int j = 0; j < terms.count(); j++) { |
|
2110 if (testFilter(terms.at(j), contact)) { |
|
2111 return true; |
|
2112 } |
|
2113 } |
|
2114 return false; |
|
2115 } |
|
2116 // Fall through to end |
|
2117 } |
|
2118 break; |
|
2119 } |
|
2120 return false; |
|
2121 } |
|
2122 |
|
2123 /*! |
|
2124 Given a QContactFilter \a filter retrieved from a QContactAction, |
|
2125 check that it is valid and cannot cause infinite recursion. |
|
2126 |
|
2127 In particular, a filter from a QContactAction cannot contain |
|
2128 any instances of a QContactActionFilter. |
|
2129 |
|
2130 Returns true if \a filter seems ok, or false otherwise. |
|
2131 */ |
|
2132 |
|
2133 bool QContactManagerEngine::validateActionFilter(const QContactFilter& filter) |
|
2134 { |
|
2135 QList<QContactFilter> toVerify; |
|
2136 toVerify << filter; |
|
2137 |
|
2138 while(toVerify.count() > 0) { |
|
2139 QContactFilter f = toVerify.takeFirst(); |
|
2140 if (f.type() == QContactFilter::ActionFilter) |
|
2141 return false; |
|
2142 if (f.type() == QContactFilter::IntersectionFilter) |
|
2143 toVerify.append(QContactIntersectionFilter(f).filters()); |
|
2144 if (f.type() == QContactFilter::UnionFilter) |
|
2145 toVerify.append(QContactUnionFilter(f).filters()); |
|
2146 } |
|
2147 |
|
2148 return true; |
|
2149 } |
|
2150 |
|
2151 /*! |
|
2152 Sets the cached relationships in the given \a contact to \a relationships |
|
2153 */ |
|
2154 void QContactManagerEngine::setContactRelationships(QContact* contact, const QList<QContactRelationship>& relationships) |
|
2155 { |
|
2156 contact->d->m_relationshipsCache = relationships; |
|
2157 } |
|
2158 |
|
2159 |
|
2160 /*! |
|
2161 Compares two contacts (\a a and \a b) using the given list of \a sortOrders. Returns a negative number if \a a should appear |
|
2162 before \a b according to the sort order, a positive number if \a a should appear after \a b according to the sort order, |
|
2163 and zero if the two are unable to be sorted. |
|
2164 */ |
|
2165 int QContactManagerEngine::compareContact(const QContact& a, const QContact& b, const QList<QContactSortOrder>& sortOrders) |
|
2166 { |
|
2167 foreach(const QContactSortOrder& sortOrder, sortOrders) { |
|
2168 if (!sortOrder.isValid()) |
|
2169 break; |
|
2170 |
|
2171 // obtain the values which this sort order concerns |
|
2172 const QVariant& aVal = a.detail(sortOrder.detailDefinitionName()).variantValue(sortOrder.detailFieldName()); |
|
2173 const QVariant& bVal = b.detail(sortOrder.detailDefinitionName()).variantValue(sortOrder.detailFieldName()); |
|
2174 |
|
2175 bool aIsNull = false; |
|
2176 bool bIsNull = false; |
|
2177 |
|
2178 // treat empty strings as null qvariants. |
|
2179 if ((aVal.type() == QVariant::String && aVal.toString().isEmpty()) || aVal.isNull()) { |
|
2180 aIsNull = true; |
|
2181 } |
|
2182 if ((bVal.type() == QVariant::String && bVal.toString().isEmpty()) || bVal.isNull()) { |
|
2183 bIsNull = true; |
|
2184 } |
|
2185 |
|
2186 // early exit error checking |
|
2187 if (aIsNull && bIsNull) |
|
2188 continue; // use next sort criteria. |
|
2189 if (aIsNull) |
|
2190 return (sortOrder.blankPolicy() == QContactSortOrder::BlanksFirst ? -1 : 1); |
|
2191 if (bIsNull) |
|
2192 return (sortOrder.blankPolicy() == QContactSortOrder::BlanksFirst ? 1 : -1); |
|
2193 |
|
2194 // real comparison |
|
2195 int comparison = compareVariant(aVal, bVal, sortOrder.caseSensitivity()) * (sortOrder.direction() == Qt::AscendingOrder ? 1 : -1); |
|
2196 if (comparison == 0) |
|
2197 continue; |
|
2198 return comparison; |
|
2199 } |
|
2200 |
|
2201 return 0; // or according to id? return (a.id() < b.id() ? -1 : 1); |
|
2202 } |
|
2203 |
|
2204 /* A functor that returns true iff a is less than b, according to the sortOrders passed in to the |
|
2205 * ctor. The sortOrders pointer passed in must remain valid for the lifetime of the functor. */ |
|
2206 class ContactLessThan { |
|
2207 public: |
|
2208 ContactLessThan(const QList<QContactSortOrder>* sortOrders) : mSortOrders(sortOrders) {} |
|
2209 bool operator()(const QContact& a, const QContact& b) const |
|
2210 { |
|
2211 return QContactManagerEngine::compareContact(a, b, *mSortOrders) < 0; |
|
2212 } |
|
2213 private: |
|
2214 const QList<QContactSortOrder>* mSortOrders; |
|
2215 }; |
|
2216 |
|
2217 /*! |
|
2218 Performs insertion sort of the contact \a toAdd into the \a sorted list, according to the provided \a sortOrders list. |
|
2219 The first QContactSortOrder in the list has the highest priority: if the contact \a toAdd is deemed equal to another |
|
2220 in the \a sorted list according to the first QContactSortOrder, the second QContactSortOrder in the list is used (and |
|
2221 so on until either the contact is inserted or there are no more sort order objects in the list). |
|
2222 |
|
2223 If a contact is equal to another contact according to all sort orders, it is inserted after the previously-added contact. |
|
2224 */ |
|
2225 void QContactManagerEngine::addSorted(QList<QContact>* sorted, const QContact& toAdd, const QList<QContactSortOrder>& sortOrders) |
|
2226 { |
|
2227 if (sortOrders.count() > 0) { |
|
2228 ContactLessThan lessThan(&sortOrders); |
|
2229 QList<QContact>::iterator it(qUpperBound(sorted->begin(), sorted->end(), toAdd, lessThan)); |
|
2230 sorted->insert(it, toAdd); |
|
2231 } else { |
|
2232 // no sort order? just add it to the end |
|
2233 sorted->append(toAdd); |
|
2234 } |
|
2235 } |
|
2236 |
|
2237 /*! Sorts the given list of contacts \a cs according to the provided \a sortOrders */ |
|
2238 QList<QContactLocalId> QContactManagerEngine::sortContacts(const QList<QContact>& cs, const QList<QContactSortOrder>& sortOrders) |
|
2239 { |
|
2240 QList<QContactLocalId> sortedIds; |
|
2241 QList<QContact> sortedContacts = cs; |
|
2242 if (!sortOrders.isEmpty()) { |
|
2243 ContactLessThan lessThan(&sortOrders); |
|
2244 qStableSort(sortedContacts.begin(), sortedContacts.end(), lessThan); |
|
2245 } |
|
2246 |
|
2247 foreach(const QContact& c, sortedContacts) { |
|
2248 sortedIds.append(c.localId()); |
|
2249 } |
|
2250 return sortedIds; |
|
2251 } |
|
2252 |
|
2253 /*! |
|
2254 Notifies the manager engine that the given request \a req has been destroyed |
|
2255 */ |
|
2256 void QContactManagerEngine::requestDestroyed(QContactAbstractRequest* req) |
|
2257 { |
|
2258 Q_UNUSED(req); |
|
2259 } |
|
2260 |
|
2261 /*! |
|
2262 Asks the manager engine to begin the given request \a req which |
|
2263 is currently in a (re)startable state. |
|
2264 Returns true if the request was started successfully, else returns false. |
|
2265 |
|
2266 \sa QContactAbstractRequest::start() |
|
2267 */ |
|
2268 bool QContactManagerEngine::startRequest(QContactAbstractRequest* req) |
|
2269 { |
|
2270 Q_UNUSED(req); |
|
2271 return false; |
|
2272 } |
|
2273 |
|
2274 /*! |
|
2275 Asks the manager engine to cancel the given request \a req which was |
|
2276 previously started and is currently in a cancellable state. |
|
2277 Returns true if cancellation of the request was started successfully, |
|
2278 otherwise returns false. |
|
2279 |
|
2280 \sa startRequest(), QContactAbstractRequest::cancel() |
|
2281 */ |
|
2282 bool QContactManagerEngine::cancelRequest(QContactAbstractRequest* req) |
|
2283 { |
|
2284 Q_UNUSED(req); |
|
2285 return false; |
|
2286 } |
|
2287 |
|
2288 /*! |
|
2289 Blocks until the manager engine has completed the given request \a req |
|
2290 which was previously started, or until \a msecs milliseconds have passed. |
|
2291 Returns true if the request was completed, and false if the request was not in the |
|
2292 \c QContactAbstractRequest::Active state or no progress could be reported. |
|
2293 |
|
2294 \sa startRequest() |
|
2295 */ |
|
2296 bool QContactManagerEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs) |
|
2297 { |
|
2298 Q_UNUSED(req); |
|
2299 Q_UNUSED(msecs); |
|
2300 return false; |
|
2301 } |
|
2302 |
|
2303 /*! |
|
2304 Updates the given asynchronous request \a req by setting the new \a state |
|
2305 of the request. If the new state is different, the stateChanged() signal |
|
2306 will be emitted by the request. |
|
2307 */ |
|
2308 void QContactManagerEngine::updateRequestState(QContactAbstractRequest* req, QContactAbstractRequest::State state) |
|
2309 { |
|
2310 if (req) { |
|
2311 QMutexLocker ml(&req->d_ptr->m_mutex); |
|
2312 if (req->d_ptr->m_state != state) { |
|
2313 req->d_ptr->m_state = state; |
|
2314 ml.unlock(); |
|
2315 emit req->stateChanged(state); |
|
2316 } |
|
2317 } |
|
2318 } |
|
2319 |
|
2320 /*! |
|
2321 Updates the given QContactLocalIdFetchRequest \a req with the latest results \a result, and operation error \a error. |
|
2322 In addition, the state of the request will be changed to \a newState. |
|
2323 |
|
2324 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2325 |
|
2326 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2327 */ |
|
2328 void QContactManagerEngine::updateContactLocalIdFetchRequest(QContactLocalIdFetchRequest* req, const QList<QContactLocalId>& result, QContactManager::Error error, QContactAbstractRequest::State newState) |
|
2329 { |
|
2330 if (req) { |
|
2331 QWeakPointer<QContactLocalIdFetchRequest> ireq(req); // Take this in case the first emit deletes us |
|
2332 QContactLocalIdFetchRequestPrivate* rd = static_cast<QContactLocalIdFetchRequestPrivate*>(ireq.data()->d_ptr); |
|
2333 QMutexLocker ml(&rd->m_mutex); |
|
2334 bool emitState = rd->m_state != newState; |
|
2335 rd->m_ids = result; |
|
2336 rd->m_error = error; |
|
2337 rd->m_state = newState; |
|
2338 ml.unlock(); |
|
2339 emit ireq.data()->resultsAvailable(); |
|
2340 if (emitState && ireq) |
|
2341 emit ireq.data()->stateChanged(newState); |
|
2342 } |
|
2343 } |
|
2344 |
|
2345 /*! |
|
2346 Updates the given QContactFetchRequest \a req with the latest results \a result, and operation error \a error. |
|
2347 In addition, the state of the request will be changed to \a newState. |
|
2348 |
|
2349 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2350 |
|
2351 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2352 */ |
|
2353 void QContactManagerEngine::updateContactFetchRequest(QContactFetchRequest* req, const QList<QContact>& result, QContactManager::Error error, QContactAbstractRequest::State newState) |
|
2354 { |
|
2355 if (req) { |
|
2356 QWeakPointer<QContactFetchRequest> ireq(req); // Take this in case the first emit deletes us |
|
2357 QContactFetchRequestPrivate* rd = static_cast<QContactFetchRequestPrivate*>(ireq.data()->d_ptr); |
|
2358 QMutexLocker ml(&rd->m_mutex); |
|
2359 bool emitState = rd->m_state != newState; |
|
2360 rd->m_contacts = result; |
|
2361 rd->m_error = error; |
|
2362 rd->m_state = newState; |
|
2363 ml.unlock(); |
|
2364 emit ireq.data()->resultsAvailable(); |
|
2365 if (emitState && ireq) |
|
2366 emit ireq.data()->stateChanged(newState); |
|
2367 } |
|
2368 } |
|
2369 |
|
2370 /*! |
|
2371 Updates the given QContactRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap. |
|
2372 In addition, the state of the request will be changed to \a newState. |
|
2373 |
|
2374 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2375 |
|
2376 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2377 */ |
|
2378 void QContactManagerEngine::updateContactRemoveRequest(QContactRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2379 { |
|
2380 if (req) { |
|
2381 QWeakPointer<QContactRemoveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2382 QContactRemoveRequestPrivate* rd = static_cast<QContactRemoveRequestPrivate*>(ireq.data()->d_ptr); |
|
2383 QMutexLocker ml(&rd->m_mutex); |
|
2384 bool emitState = rd->m_state != newState; |
|
2385 rd->m_errors = errorMap; |
|
2386 rd->m_error = error; |
|
2387 rd->m_state = newState; |
|
2388 ml.unlock(); |
|
2389 emit ireq.data()->resultsAvailable(); |
|
2390 if (emitState && ireq) |
|
2391 emit ireq.data()->stateChanged(newState); |
|
2392 } |
|
2393 } |
|
2394 |
|
2395 /*! |
|
2396 Updates the given QContactSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap. |
|
2397 In addition, the state of the request will be changed to \a newState. |
|
2398 |
|
2399 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2400 |
|
2401 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2402 */ |
|
2403 void QContactManagerEngine::updateContactSaveRequest(QContactSaveRequest* req, const QList<QContact>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2404 { |
|
2405 if (req) { |
|
2406 QWeakPointer<QContactSaveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2407 QContactSaveRequestPrivate* rd = static_cast<QContactSaveRequestPrivate*>(ireq.data()->d_ptr); |
|
2408 QMutexLocker ml(&rd->m_mutex); |
|
2409 bool emitState = rd->m_state != newState; |
|
2410 rd->m_contacts = result; |
|
2411 rd->m_errors = errorMap; |
|
2412 rd->m_error = error; |
|
2413 rd->m_state = newState; |
|
2414 ml.unlock(); |
|
2415 emit ireq.data()->resultsAvailable(); |
|
2416 if (emitState && ireq) |
|
2417 emit ireq.data()->stateChanged(newState); |
|
2418 } |
|
2419 } |
|
2420 |
|
2421 /*! |
|
2422 Updates the given QContactDetailDefinitionSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap. |
|
2423 In addition, the state of the request will be changed to \a newState. |
|
2424 |
|
2425 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2426 |
|
2427 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2428 */ |
|
2429 void QContactManagerEngine::updateDefinitionSaveRequest(QContactDetailDefinitionSaveRequest* req, const QList<QContactDetailDefinition>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2430 { |
|
2431 if (req) { |
|
2432 QWeakPointer<QContactDetailDefinitionSaveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2433 QContactDetailDefinitionSaveRequestPrivate* rd = static_cast<QContactDetailDefinitionSaveRequestPrivate*>(req->d_ptr); |
|
2434 QMutexLocker ml(&rd->m_mutex); |
|
2435 bool emitState = rd->m_state != newState; |
|
2436 rd->m_definitions = result; |
|
2437 rd->m_errors = errorMap; |
|
2438 rd->m_error = error; |
|
2439 rd->m_state = newState; |
|
2440 ml.unlock(); |
|
2441 emit ireq.data()->resultsAvailable(); |
|
2442 if (emitState && ireq) |
|
2443 emit ireq.data()->stateChanged(newState); |
|
2444 } |
|
2445 } |
|
2446 |
|
2447 /*! |
|
2448 Updates the given QContactDetailDefinitionRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap. |
|
2449 In addition, the state of the request will be changed to \a newState. |
|
2450 |
|
2451 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2452 |
|
2453 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2454 */ |
|
2455 void QContactManagerEngine::updateDefinitionRemoveRequest(QContactDetailDefinitionRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2456 { |
|
2457 if (req) { |
|
2458 QWeakPointer<QContactDetailDefinitionRemoveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2459 QContactDetailDefinitionRemoveRequestPrivate* rd = static_cast<QContactDetailDefinitionRemoveRequestPrivate*>(req->d_ptr); |
|
2460 QMutexLocker ml(&rd->m_mutex); |
|
2461 bool emitState = rd->m_state != newState; |
|
2462 rd->m_errors = errorMap; |
|
2463 rd->m_error = error; |
|
2464 rd->m_state = newState; |
|
2465 ml.unlock(); |
|
2466 emit ireq.data()->resultsAvailable(); |
|
2467 if (emitState && ireq) |
|
2468 emit ireq.data()->stateChanged(newState); |
|
2469 } |
|
2470 } |
|
2471 |
|
2472 /*! |
|
2473 Updates the given QContactDetailDefinitionFetchRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap. |
|
2474 In addition, the state of the request will be changed to \a newState. |
|
2475 |
|
2476 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2477 |
|
2478 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2479 */ |
|
2480 void QContactManagerEngine::updateDefinitionFetchRequest(QContactDetailDefinitionFetchRequest* req, const QMap<QString, QContactDetailDefinition>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2481 { |
|
2482 if (req) { |
|
2483 QWeakPointer<QContactDetailDefinitionFetchRequest> ireq(req); // Take this in case the first emit deletes us |
|
2484 QContactDetailDefinitionFetchRequestPrivate* rd = static_cast<QContactDetailDefinitionFetchRequestPrivate*>(req->d_ptr); |
|
2485 QMutexLocker ml(&rd->m_mutex); |
|
2486 bool emitState = rd->m_state != newState; |
|
2487 rd->m_definitions = result; |
|
2488 rd->m_errors = errorMap; |
|
2489 rd->m_error = error; |
|
2490 rd->m_state = newState; |
|
2491 ml.unlock(); |
|
2492 emit ireq.data()->resultsAvailable(); |
|
2493 if (emitState && ireq) |
|
2494 emit ireq.data()->stateChanged(newState); |
|
2495 } |
|
2496 } |
|
2497 |
|
2498 /*! |
|
2499 Updates the given QContactRelationshipSaveRequest \a req with the latest results \a result, operation error \a error, and map of input index to individual error \a errorMap. |
|
2500 In addition, the state of the request will be changed to \a newState. |
|
2501 |
|
2502 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2503 |
|
2504 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2505 */ |
|
2506 void QContactManagerEngine::updateRelationshipSaveRequest(QContactRelationshipSaveRequest* req, const QList<QContactRelationship>& result, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2507 { |
|
2508 if (req) { |
|
2509 QWeakPointer<QContactRelationshipSaveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2510 QContactRelationshipSaveRequestPrivate* rd = static_cast<QContactRelationshipSaveRequestPrivate*>(req->d_ptr); |
|
2511 QMutexLocker ml(&rd->m_mutex); |
|
2512 bool emitState = rd->m_state != newState; |
|
2513 rd->m_relationships = result; |
|
2514 rd->m_errors = errorMap; |
|
2515 rd->m_error = error; |
|
2516 rd->m_state = newState; |
|
2517 ml.unlock(); |
|
2518 emit ireq.data()->resultsAvailable(); |
|
2519 if (emitState && ireq) |
|
2520 emit ireq.data()->stateChanged(newState); |
|
2521 } |
|
2522 } |
|
2523 |
|
2524 /*! |
|
2525 Updates the given QContactRelationshipRemoveRequest \a req with the operation error \a error, and map of input index to individual error \a errorMap. |
|
2526 In addition, the state of the request will be changed to \a newState. |
|
2527 |
|
2528 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2529 |
|
2530 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2531 */ |
|
2532 void QContactManagerEngine::updateRelationshipRemoveRequest(QContactRelationshipRemoveRequest* req, QContactManager::Error error, const QMap<int, QContactManager::Error>& errorMap, QContactAbstractRequest::State newState) |
|
2533 { |
|
2534 if (req) { |
|
2535 QWeakPointer<QContactRelationshipRemoveRequest> ireq(req); // Take this in case the first emit deletes us |
|
2536 QContactRelationshipRemoveRequestPrivate* rd = static_cast<QContactRelationshipRemoveRequestPrivate*>(req->d_ptr); |
|
2537 QMutexLocker ml(&rd->m_mutex); |
|
2538 bool emitState = rd->m_state != newState; |
|
2539 rd->m_errors = errorMap; |
|
2540 rd->m_error = error; |
|
2541 rd->m_state = newState; |
|
2542 ml.unlock(); |
|
2543 emit ireq.data()->resultsAvailable(); |
|
2544 if (emitState && ireq) |
|
2545 emit ireq.data()->stateChanged(newState); |
|
2546 } |
|
2547 } |
|
2548 |
|
2549 /*! |
|
2550 Updates the given QContactRelationshipFetchRequest \a req with the latest results \a result, and operation error \a error. |
|
2551 In addition, the state of the request will be changed to \a newState. |
|
2552 |
|
2553 It then causes the request to emit its resultsAvailable() signal to notify clients of the request progress. |
|
2554 |
|
2555 If the new request state is different from the previous state, the stateChanged() signal will also be emitted from the request. |
|
2556 */ |
|
2557 void QContactManagerEngine::updateRelationshipFetchRequest(QContactRelationshipFetchRequest* req, const QList<QContactRelationship>& result, QContactManager::Error error, QContactAbstractRequest::State newState) |
|
2558 { |
|
2559 if (req) { |
|
2560 QWeakPointer<QContactRelationshipFetchRequest> ireq(req); // Take this in case the first emit deletes us |
|
2561 QContactRelationshipFetchRequestPrivate* rd = static_cast<QContactRelationshipFetchRequestPrivate*>(req->d_ptr); |
|
2562 QMutexLocker ml(&rd->m_mutex); |
|
2563 bool emitState = rd->m_state != newState; |
|
2564 rd->m_relationships = result; |
|
2565 rd->m_error = error; |
|
2566 rd->m_state = newState; |
|
2567 ml.unlock(); |
|
2568 emit ireq.data()->resultsAvailable(); |
|
2569 if (emitState && ireq) |
|
2570 emit ireq.data()->stateChanged(newState); |
|
2571 } |
|
2572 } |
|
2573 |
|
2574 #include "moc_qcontactmanagerengine.cpp" |
|
2575 |
|
2576 QTM_END_NAMESPACE |