1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtContacts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34#include "qcontactmanager.h"
35
36#include <QtCore/qmetaobject.h>
37
38#include "qcontact_p.h"
39#include "qcontactfilter.h"
40#include "qcontactmanager_p.h"
41
42QT_BEGIN_NAMESPACE_CONTACTS
43/*!
44 \class QContactManager
45 \brief The QContactManager class provides an interface which allows clients with access to contact information stored in a particular backend.
46 \inmodule QtContacts
47
48 \ingroup contacts-main
49
50 This class provides an abstraction of a datastore or aggregation of datastores which contains contact information.
51 It provides methods to retrieve and manipulate contact information and contact relationship information.
52 It also provides metadata and error information reporting.
53
54 The functions provided by QContactManager are purely synchronous; to access the same functionality in an
55 asynchronous manner, clients should use the use-case-specific classes derived from QContactAbstractRequest.
56
57 Some functionality provided by QContactManager directly is not accessible using the asynchronous API. See
58 the \l{Qt Contacts Synchronous API}{synchronous} and \l{Qt Contacts Asynchronous API}{asynchronous} API
59 information in the \l{Qt Contacts C++ API} documentation.
60 */
61
62/*!
63 \fn QContactManager::dataChanged()
64 This signal is emitted by the manager if its internal state changes, and it is unable to determine the changes
65 which occurred, or if the manager considers the changes to be radical enough to require clients to reload all data.
66 If this signal is emitted, no other signals will be emitted for the associated changes.
67 */
68
69/*!
70 \fn QContactManager::contactsAdded(const QList<QContactId>& contactIds)
71 This signal is emitted at some point once the contacts identified by \a contactIds have been added to a datastore managed by this manager.
72 This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
73 */
74
75/*!
76 \fn QContactManager::contactsChanged(const QList<QContactId>& contactIds, const QList<QContactDetail::DetailType> &typesChanged)
77 This signal is emitted at some point once the contacts identified by \a contactIds have been modified in a datastore managed by this manager.
78 The set of contact detail types modified in the reported changes is a subset of those listed in \a typesChanged,
79 unless \a typesChanged is empty, in which case no limitation on the reported changes may be assumed.
80 This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
81 */
82
83/*!
84 \fn QContactManager::contactsRemoved(const QList<QContactId>& contactIds)
85 This signal is emitted at some point once the contacts identified by \a contactIds have been removed from a datastore managed by this manager.
86 This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
87 */
88
89/*!
90 \fn QContactManager::relationshipsAdded(const QList<QContactId>& affectedContactIds)
91 This signal is emitted at some point after relationships have been added to the manager which involve the contacts identified by \a affectedContactIds.
92 This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
93 */
94
95/*!
96 \fn QContactManager::relationshipsRemoved(const QList<QContactId>& affectedContactIds)
97 This signal is emitted at some point after relationships have eben removed from the manager which involve the contacts identified by \a affectedContactIds.
98 This signal must not be emitted if the dataChanged() signal was previously emitted for these changes.
99 */
100
101/*!
102 \fn QContactManager::selfContactIdChanged(const QContactId& oldId, const QContactId& newId)
103 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.
104 If the \a newId is the invalid, then the self contact was deleted or no self contact exists.
105 This signal must not be emitted if the dataChanged() signal was previously emitted for this change.
106 */
107
108
109
110#define makestr(x) (#x)
111#define makename(x) makestr(x)
112
113/*!
114 Returns a list of available manager ids that can be used when constructing
115 a QContactManager. If an empty id is specified to the constructor, the
116 first value in this list will be used instead.
117
118 The QTCONTACTS_MANAGER_OVERRIDE environment variable may be set to
119 override the default engine.
120 */
121QStringList QContactManager::availableManagers()
122{
123 QStringList ret;
124 QContactManagerData::loadFactoriesMetadata();
125 ret = QContactManagerData::m_managerNames;
126
127 // Unless overridden, the default must be 'invalid' so that malicious plugins
128 // do not become the default selection without explicit selection
129 ret.prepend(QStringLiteral("invalid"));
130
131 // bump memory to the end of the list
132 if (ret.removeAll(QStringLiteral("memory")))
133 ret.append(QStringLiteral("memory"));
134
135#if defined(Q_CONTACTS_DEFAULT_ENGINE)
136 // now swizzle the default engine to pole position
137 const QString defaultManagerName = QString::fromLatin1(makename(Q_CONTACTS_DEFAULT_ENGINE));
138 if (ret.removeAll(defaultManagerName)) {
139 ret.prepend(defaultManagerName);
140 }
141#endif
142
143 // and prefer the override engine if specified in the environment
144 const QString overrideManagerName = QString::fromLatin1(str: qgetenv(varName: "QTCONTACTS_MANAGER_OVERRIDE"));
145 if (!overrideManagerName.isEmpty() && ret.contains(str: overrideManagerName)) {
146 ret.removeAll(t: overrideManagerName);
147 ret.prepend(t: overrideManagerName);
148 }
149
150 return ret;
151}
152
153/*!
154 Splits the given \a uri into the manager name and parameters that it describes,
155 and places the information into the memory addressed by \a managerName and \a params respectively.
156 Returns true if \a uri could be split successfully, otherwise returns false.
157*/
158bool QContactManager::parseUri(const QString &uri, QString *managerName, QMap<QString, QString> *params)
159{
160 return QContactManagerData::parseUri(uriString: uri, managerName, params, strict: false);
161}
162
163/*!
164 Returns a URI that describes a manager name and parameters with which to instantiate
165 a manager object, from the given \a managerName and \a params.
166*/
167QString QContactManager::buildUri(const QString &managerName, const QMap<QString, QString> &params)
168{
169 return QContactManagerData::buildUri(managerName, params);
170}
171
172/*!
173 Returns a URI that completely describes a manager implementation, datastore, and the parameters
174 with which to instantiate the manager, from the given \a managerName, \a params and an optional
175 \a implementationVersion. This function is generally useful only if you intend to construct a
176 manager with the \l fromUri() function, or wish to construct a contact id
177 manually (for synchronization or other purposes). Most clients will not need to use this function.
178*/
179QString QContactManager::buildUri(const QString &managerName, const QMap<QString, QString> &params, int implementationVersion)
180{
181 QMap<QString, QString> params_(params);
182 if (implementationVersion != -1) {
183 params_.insert(akey: QString::fromLatin1(QTCONTACTS_IMPLEMENTATION_VERSION_NAME),
184 avalue: QString::number(implementationVersion));
185 }
186
187 return QContactManager::buildUri(managerName, params: params_);
188}
189
190/*!
191 Constructs a QContactManager whose implementation version, manager name and specific parameters
192 are specified in the given \a managerUri, and whose parent object is \a parent.
193 */
194QContactManager* QContactManager::fromUri(const QString &managerUri, QObject *parent)
195{
196 if (managerUri.isEmpty()) {
197 return new QContactManager(QString(), QMap<QString, QString>(), parent);
198 } else {
199 QString id;
200 QMap<QString, QString> parameters;
201 if (parseUri(uri: managerUri, managerName: &id, params: &parameters)) {
202 return new QContactManager(id, parameters, parent);
203 } else {
204 // invalid
205 return new QContactManager(QStringLiteral("invalid"), QMap<QString, QString>(), parent);
206 }
207 }
208}
209
210/*!
211 Constructs a QContactManager whose parent QObject is \a parent.
212 The default implementation for the platform will be created.
213 */
214QContactManager::QContactManager(QObject *parent)
215 : QObject(parent),
216 d(new QContactManagerData)
217{
218 createEngine(managerName: QString(), parameters: QMap<QString, QString>());
219}
220
221/*!
222 Constructs a QContactManager whose implementation is identified by \a managerName with the given \a parameters.
223
224 The \a parent QObject will be used as the parent of this QContactManager.
225
226 If an empty \a managerName is specified, the default implementation for the platform will
227 be used.
228 */
229QContactManager::QContactManager(const QString &managerName, const QMap<QString, QString> &parameters, QObject *parent)
230 : QObject(parent),
231 d(new QContactManagerData)
232{
233 createEngine(managerName, parameters);
234}
235
236void QContactManager::createEngine(const QString &managerName, const QMap<QString, QString> &parameters)
237{
238 d->createEngine(managerName, parameters);
239
240 QContactManagerData::m_aliveEngines.insert(value: this);
241}
242
243/*!
244 Constructs a QContactManager whose backend has the name \a managerName and version \a implementationVersion, where the manager
245 is constructed with the provided \a parameters.
246
247 The \a parent QObject will be used as the parent of this QContactManager.
248
249 If an empty \a managerName is specified, the default implementation for the platform will be instantiated.
250 If the specified implementation version is not available, the manager with the name \a managerName with the default implementation version is instantiated.
251 */
252QContactManager::QContactManager(const QString &managerName, int implementationVersion, const QMap<QString, QString> &parameters, QObject *parent)
253 : QObject(parent),
254 d(new QContactManagerData)
255{
256 QMap<QString, QString> params = parameters;
257 params[QString(QStringLiteral(QTCONTACTS_IMPLEMENTATION_VERSION_NAME))] = QString::number(implementationVersion);
258 createEngine(managerName, parameters: params);
259}
260
261/*! Frees the memory used by the QContactManager */
262QContactManager::~QContactManager()
263{
264 QContactManagerData::m_aliveEngines.remove(value: this);
265 delete d;
266}
267
268
269/*!
270 \fn QContactManager::ParameterSignalSources()
271 The string constant for the parameter key which holds the value for signal sources.
272 If a manager supports suppressing change signals depending on the value given for
273 this construction parameter, clients can request that signals be suppressed if the
274 changes which might cause a signal to be emitted do not match particular criteria.
275
276 If the parameter (or value given for the parameter) is not supported by the manager,
277 the manager may still be constructed, however the parameter will not be reported
278 to the client if the client calls managerParameters() subsequent to manager construction.
279
280 The default (assumed) value for this parameter, if this parameter is not given,
281 is that the client wants to be notified of all changes to the data, regardless of
282 the source of the change.
283 */
284
285/*!
286 \fn QContactManager::ParameterSignalDefinitions()
287 The string constant for the parameter key which holds the names of detail definitions.
288 If a manager supports suppressing change signals depending on the value given for
289 this construction parameter, clients can request that signals be suppressed if the
290 changes which might otherwise cause a signal to be emitted, involve details whose
291 definition name is not contained in the given list.
292
293 That is, if a detail in a contact is changed, but that detail's definition name is
294 not listed in the value for this parameter, the manager will not emit a change signal
295 for that change.
296
297 If this parameter is not specified at construction time, changes to any detail of a contact
298 will cause a change signal to be emitted.
299
300 The value of this parameter should be a comma (,) separated list of definition names. Any
301 commas which might be part of a definition name must be escaped with a single backslash
302 (\) character prior to concatenation. Any backslash character which might be part of a
303 definition name must also be escaped with a backslash.
304
305 If the parameter (or value given for the parameter) is not supported by the manager,
306 the manager may still be constructed, however the parameter will not be reported
307 to the client if the client calls managerParameters() subsequent to manager construction.
308 */
309
310/*!
311 \fn QContactManager::ParameterValueOnlyOtherManagers()
312 This value tells the manager to only emit signals for changes which
313 are made in other manager instances. That is, the client wishes to receive
314 change signals when another client (or background service) changes
315 the data as it is stored in the backend, but does not wish to be
316 notified of changes (or side effects) which it has caused itself.
317 */
318
319/*!
320 \fn QContactManager::ParameterValueOnlyOtherProcesses()
321 This value tells the manager to only emit signals for changes which
322 are made in other processes. That is, the client wishes to receive
323 change signals when a client (or background service) in another process changes
324 the data as it is stored in the backend, but does not wish to be
325 notified of changes (or side effects) which were caused in the current client's
326 process, even if those changes were made in a different manager instance to this
327 one.
328 */
329
330/*!
331 \enum QContactManager::Error
332
333 This enum specifies an error that occurred during the most recent operation:
334
335 \value NoError The most recent operation was successful
336 \value DoesNotExistError The most recent operation failed because the requested contact does not exist
337 \value AlreadyExistsError The most recent operation failed because the specified contact already exists
338 \value InvalidDetailError The most recent operation failed because the specified contact contains details which do not conform to their definition
339 \value InvalidRelationshipError The most recent operation failed because the specified relationship is circular or references an invalid local contact
340 \value InvalidContactTypeError The most recent operation failed because the contact type specified was not valid for the operation
341 \value LockedError The most recent operation failed because the datastore specified is currently locked
342 \value DetailAccessError The most recent operation failed because a detail was modified or removed and its access method does not allow that
343 \value PermissionsError The most recent operation failed because the caller does not have permission to perform the operation
344 \value OutOfMemoryError The most recent operation failed due to running out of memory
345 \value VersionMismatchError The most recent operation failed because the backend of the manager is not of the required version
346 \value LimitReachedError The most recent operation failed because the limit for that type of object has been reached
347 \value NotSupportedError The most recent operation failed because the requested operation is not supported in the specified store
348 \value BadArgumentError The most recent operation failed because one or more of the parameters to the operation were invalid
349 \value TimeoutError The most recent operation failed because it took longer than expected. It may be possible to try again.
350 \value UnspecifiedError The most recent operation failed for an undocumented reason
351 \value MissingPlatformRequirementsError The most recent operation failed due to all storage locations are unavailable.
352 */
353
354/*!
355 Return the error code of the most recent operation.
356 For batch operations, if the error code is not equal to
357 \c QContactManager::NoError, detailed per-input errors
358 may be retrieved by calling \l errorMap().
359 \sa errorMap()
360 */
361QContactManager::Error QContactManager::error() const
362{
363 return d->m_lastError;
364}
365
366/*!
367 Returns per-input error codes for the most recent operation.
368 This function only returns meaningful information if the most
369 recent operation was a batch operation.
370 Each key in the map is the index of the element in the input list
371 for which the error (whose error code is stored in the value for
372 that key in the map) occurred during the batch operation.
373 \sa error(), contacts(), saveContacts(), removeContacts(), saveRelationships(), removeRelationships()
374 */
375QMap<int, QContactManager::Error> QContactManager::errorMap() const
376{
377 return d->m_lastErrorMap;
378}
379
380/*!
381 Return the list of contact ids, sorted according to the given list of \a sortOrders
382 */
383QList<QContactId> QContactManager::contactIds(const QList<QContactSortOrder> &sortOrders) const
384{
385 QContactManagerSyncOpErrorHolder h(this);
386 return d->m_engine->contactIds(filter: QContactFilter(), sortOrders, error: &h.error);
387}
388
389/*!
390 Returns a list of contact ids that match the given \a filter, sorted according to the given list of \a sortOrders.
391 Depending on the backend, this filtering operation may involve retrieving all the contacts.
392 */
393QList<QContactId> QContactManager::contactIds(const QContactFilter &filter, const QList<QContactSortOrder> &sortOrders) const
394{
395 QContactManagerSyncOpErrorHolder h(this);
396 return d->m_engine->contactIds(filter, sortOrders, error: &h.error);
397}
398
399/*!
400 Returns the list of contacts stored in the manager sorted according to the given list of \a sortOrders.
401
402 The \a fetchHint parameter describes the optimization hints that a manager may take.
403 If the \a fetchHint is the default constructed hint, all existing details, relationships and
404 action preferences in the matching contact will be returned. If a client makes changes to an
405 contact which has been retrieved with a fetch hint, they should save it back using a partial save,
406 masked by the same set of detail names in order to avoid information loss.
407
408 \sa QContactFetchHint
409 */
410QList<QContact> QContactManager::contacts(const QList<QContactSortOrder> &sortOrders, const QContactFetchHint &fetchHint) const
411{
412 QContactManagerSyncOpErrorHolder h(this);
413 return d->m_engine->contacts(filter: QContactFilter(), sortOrders, fetchHint, error: &h.error);
414}
415
416/*!
417 Returns a list of contacts that match the given \a filter, sorted according to the given list of \a sortOrders.
418
419 Depending on the manager implementation, this filtering operation might be slow and involve retrieving all the
420 contacts and testing them against the supplied filter - see the \l isFilterSupported() function.
421
422 The \a fetchHint parameter describes the optimization hints that a manager may take.
423 If the \a fetchHint is the default constructed hint, all existing details, relationships and
424 action preferences in the matching contact will be returned. If a client makes changes to an
425 contact which has been retrieved with a fetch hint, they should save it back using a partial save,
426 masked by the same set of detail names in order to avoid information loss.
427
428 \sa QContactFetchHint
429 */
430QList<QContact> QContactManager::contacts(const QContactFilter &filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint &fetchHint) const
431{
432 QContactManagerSyncOpErrorHolder h(this);
433 return d->m_engine->contacts(filter, sortOrders, fetchHint, error: &h.error);
434}
435
436/*!
437 Returns the contact in the database identified by \a contactId.
438
439 If the contact does not exist, an empty, default constructed QContact will be returned,
440 and the error returned by \l error() will be \c QContactManager::DoesNotExistError.
441
442 The \a fetchHint parameter describes the optimization hints that a manager may take.
443 If the \a fetchHint is the default constructed hint, all existing details, relationships and
444 action preferences in the matching contact will be returned. If a client makes changes to an
445 contact which has been retrieved with a fetch hint, they should save it back using a partial save,
446 masked by the same set of detail names in order to avoid information loss.
447
448
449 \sa QContactFetchHint
450 */
451QContact QContactManager::contact(const QContactId &contactId, const QContactFetchHint &fetchHint) const
452{
453 QContactManagerSyncOpErrorHolder h(this);
454 return d->m_engine->contact(contactId, fetchHint, error: &h.error);
455}
456
457/*!
458 Returns a list of contacts given a list of ids (\a contactIds).
459
460 Returns the list of contacts with the ids given by \a contactIds. There is a one-to-one
461 correspondence between the returned contacts and the supplied \a contactIds.
462
463 If there is an invalid id in \a contactIds, then an empty QContact will take its place in the
464 returned list. The \a errorMap parameter can be supplied to store per-input errors in.
465 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
466
467 The \a fetchHint parameter describes the optimization hints that a manager may take.
468 If the \a fetchHint is the default constructed hint, all existing details, relationships and
469 action preferences in the matching contact will be returned. If a client makes changes to an
470 contact which has been retrieved with a fetch hint, they should save it back using a partial save,
471 masked by the same set of detail names in order to avoid information loss.
472
473 \sa QContactFetchHint
474 */
475QList<QContact> QContactManager::contacts(const QList<QContactId> &contactIds, const QContactFetchHint &fetchHint, QMap<int, QContactManager::Error> *errorMap) const
476{
477 QContactManagerSyncOpErrorHolder h(this, errorMap);
478
479 return d->m_engine->contacts(contactIds, fetchHint, errorMap: &h.errorMap, error: &h.error);
480}
481
482/*!
483 Adds the given \a contact to the database if \a contact has
484 the (default constructed) null id.
485
486 If the manager URI of the id of the \a contact is neither empty nor equal to the URI of
487 this manager, or id of the \a contact is not null but does not exist in the
488 manager, the operation will fail and calling error() will return
489 \c QContactManager::DoesNotExistError.
490
491 Alternatively, the function will update the existing contact in the database if \a contact
492 has a id which is not null and currently exists in the database.
493
494 If the \a contact contains one or more details whose types are not
495 supported by the used engine, the operation will fail and calling
496 error() will return \c QContactManager::UnsupportedError.
497
498 If the \a contact has had its relationships reordered, the manager
499 will check to make sure that every relationship that the contact is currently
500 involved in is included in the reordered list, and that no relationships which
501 either do not involve the contact, or have not been saved in the manager are
502 included in the list. If these conditions are not met, the function will
503 return \c false and calling error() will return
504 \c QContactManager::InvalidRelationshipError.
505
506 Returns false on failure, or true on
507 success. On successful save of an contact with a null id, its
508 id will be set to a new, non-null id.
509
510 The manager is not required to fetch updated details of the contact on save,
511 and as such, clients should fetch a contact if they want the most up-to-date information
512 by calling \l QContactManager::contact().
513
514 \sa managerUri()
515 */
516bool QContactManager::saveContact(QContact *contact)
517{
518 QContactManagerSyncOpErrorHolder h(this);
519
520 if (contact) {
521 return d->m_engine->saveContact(contact, error: &h.error);
522 } else {
523 h.error = QContactManager::BadArgumentError;
524 return false;
525 }
526}
527
528/*!
529 Remove the contact identified by \a contactId from the database,
530 and also removes any relationships in which the contact was involved.
531 Returns true if the contact was removed successfully, otherwise
532 returns false.
533 */
534bool QContactManager::removeContact(const QContactId &contactId)
535{
536 QContactManagerSyncOpErrorHolder h(this);
537 return d->m_engine->removeContact(contactId, error: &h.error);
538}
539
540/*!
541 Adds the list of contacts given by \a contacts list to the database.
542 Returns true if the contacts were saved successfully, otherwise false.
543
544 The \a errorMap parameter can be supplied to store per-input errors in.
545 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
546 The \l QContactManager::error() function will only return \c QContactManager::NoError
547 if all contacts were saved successfully.
548
549 For each newly saved contact that was successful, the id of the contact
550 in the \a contacts list will be updated with the new value.
551
552 \sa QContactManager::saveContact()
553 */
554bool QContactManager::saveContacts(QList<QContact> *contacts, QMap<int, QContactManager::Error> *errorMap)
555{
556 QContactManagerSyncOpErrorHolder h(this, errorMap);
557
558 if (contacts) {
559 return d->m_engine->saveContacts(contacts, errorMap: &h.errorMap, error: &h.error);
560 } else {
561 h.error = QContactManager::BadArgumentError;
562 return false;
563 }
564}
565
566/*!
567 Adds the list of contacts given by \a contacts list to the database.
568 Returns true if the contacts were saved successfully, otherwise false.
569
570 This function accepts a \a typeMask, which specifies which details of
571 the contacts should be updated. Details with types not included in
572 the typeMask will not be updated or added.
573
574 The \a errorMap parameter can be supplied to store per-input errors in.
575 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
576 The \l QContactManager::error() function will only return \c QContactManager::NoError
577 if all contacts were saved successfully.
578
579 For each newly saved contact that was successful, the id of the contact
580 in the \a contacts list will be updated with the new value.
581
582 \sa QContactManager::saveContact()
583 */
584bool QContactManager::saveContacts(QList<QContact> *contacts, const QList<QContactDetail::DetailType> &typeMask, QMap<int, QContactManager::Error> *errorMap)
585{
586 QContactManagerSyncOpErrorHolder h(this, errorMap);
587
588 if (contacts) {
589 return d->m_engine->saveContacts(contacts, typeMask, errorMap: &h.errorMap, error: &h.error);
590 } else {
591 h.error = QContactManager::BadArgumentError;
592 return false;
593 }
594}
595
596/*!
597 Remove every contact whose id is contained in the list of contacts ids
598 \a contactIds. Returns true if all contacts were removed successfully,
599 otherwise false.
600
601 Any contact that was removed successfully will have the relationships
602 in which it was involved removed also.
603
604 The \a errorMap parameter can be supplied to store per-input errors in.
605 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
606 The \l QContactManager::error() function will
607 only return \c QContactManager::NoError if all contacts were removed
608 successfully.
609
610 If the given list of contact ids \a contactIds is empty, the function will return false
611 and calling error() will return \c QContactManager::BadArgumentError. If the list is non-empty
612 and contains ids which do not identify a valid contact in the manager, the function will
613 remove any contacts which are identified by ids in the \a contactIds list, insert
614 \c QContactManager::DoesNotExist entries into the \a errorMap for the indices of invalid ids
615 in the \a contactIds list, return false, and set the overall operation error to
616 \c QContactManager::DoesNotExistError.
617
618 \sa QContactManager::removeContact()
619 */
620bool QContactManager::removeContacts(const QList<QContactId> &contactIds, QMap<int, QContactManager::Error> *errorMap)
621{
622 QContactManagerSyncOpErrorHolder h(this, errorMap);
623
624 if (!contactIds.isEmpty()) {
625 return d->m_engine->removeContacts(contactIds, errorMap: &h.errorMap, error: &h.error);
626 } else {
627 h.error = QContactManager::BadArgumentError;
628 return false;
629 }
630}
631
632/*!
633 Sets the id of the "self" contact to the given \a contactId.
634 Returns true if the "self" contact id was set successfully.
635 If the given \a contactId does not identify a contact
636 stored in this manager, the error will be set to
637 \c QContactManager::DoesNotExistError and the function will
638 return false; if the backend does not support the
639 concept of a "self" contact then the error will be set to
640 \c QContactManager::NotSupportedError and the function will
641 return false.
642 */
643bool QContactManager::setSelfContactId(const QContactId &contactId)
644{
645 QContactManagerSyncOpErrorHolder h(this);
646 return d->m_engine->setSelfContactId(contactId, error: &h.error);
647}
648
649/*!
650 Returns the id of the "self" contact which has previously been set.
651 If no "self" contact has been set, or if the self contact was removed
652 from the manager after being set, or if the backend does not support
653 the concept of a "self" contact, an invalid id will be returned
654 and the error will be set to \c QContactManager::DoesNotExistError.
655 */
656QContactId QContactManager::selfContactId() const
657{
658 QContactManagerSyncOpErrorHolder h(this);
659 return d->m_engine->selfContactId(error: &h.error);
660}
661
662/*!
663 Returns a list of relationships in which the contact identified by \a participantId participates in the given \a role.
664 If \a participantId is default-constructed, \a role is ignored and all relationships are returned.
665 */
666QList<QContactRelationship> QContactManager::relationships(const QContactId &participantId, QContactRelationship::Role role) const
667{
668 QContactManagerSyncOpErrorHolder h(this);
669 return d->m_engine->relationships(relationshipType: QString(), participantId, role, error: &h.error);
670}
671
672/*!
673 Returns a list of relationships of the given \a relationshipType in which the contact identified by \a participantId participates in the given \a role.
674 If \a participantId is default-constructed, \a role is ignored and all relationships of the given \a relationshipType are returned.
675 If \a relationshipType is empty, relationships of any type are returned.
676 */
677QList<QContactRelationship> QContactManager::relationships(const QString &relationshipType, const QContactId &participantId, QContactRelationship::Role role) const
678{
679 QContactManagerSyncOpErrorHolder h(this);
680 return d->m_engine->relationships(relationshipType, participantId, role, error: &h.error);
681}
682
683/*!
684 Saves the given \a relationship in the database. If the relationship already exists in the database, this function will
685 return \c false and the error will be set to \c QContactManager::AlreadyExistsError.
686 If the relationship is saved successfully, this function will return \c true and error will be set
687 to \c QContactManager::NoError. Note that relationships cannot be updated directly using this function; in order
688 to update a relationship, you must remove the old relationship, make the required modifications, and then save it.
689
690 The given relationship is invalid if it is circular (the first contact is the second contact), or
691 if it references a non-existent local contact (either the first or second contact). If the given \a relationship is invalid,
692 the function will return \c false and the error will be set to \c QContactManager::InvalidRelationshipError.
693 If the given \a relationship could not be saved in the database (due to backend limitations)
694 the function will return \c false and error will be set to \c QContactManager::NotSupportedError.
695 */
696bool QContactManager::saveRelationship(QContactRelationship *relationship)
697{
698 QContactManagerSyncOpErrorHolder h(this);
699 if (relationship) {
700 return d->m_engine->saveRelationship(relationship, error: &h.error);
701 } else {
702 h.error = QContactManager::BadArgumentError;
703 return false;
704 }
705}
706
707/*!
708 Saves the given \a relationships in the database and returns true if the operation was successful.
709 The \a errorMap parameter can be supplied to store per-input errors in.
710 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
711 */
712bool QContactManager::saveRelationships(QList<QContactRelationship> *relationships, QMap<int, QContactManager::Error> *errorMap)
713{
714 QContactManagerSyncOpErrorHolder h(this, errorMap);
715
716 if (relationships) {
717 return d->m_engine->saveRelationships(relationships, errorMap: &h.errorMap, error: &h.error);
718 } else {
719 h.error = QContactManager::BadArgumentError;
720 return false;
721 }
722}
723
724/*!
725 Removes the given \a relationship from the manager. If the relationship exists in the manager, the relationship
726 will be removed, the error will be set to \c QContactManager::NoError and this function will return true. If no such
727 relationship exists in the manager, the error will be set to \c QContactManager::DoesNotExistError and this function
728 will return false.
729 */
730bool QContactManager::removeRelationship(const QContactRelationship &relationship)
731{
732 QContactManagerSyncOpErrorHolder h(this);
733 return d->m_engine->removeRelationship(relationship, error: &h.error);
734}
735
736
737/*!
738 Removes the given \a relationships from the database and returns true if the operation was successful.
739 The \a errorMap parameter can be supplied to store per-input errors in.
740 In all cases, calling \l errorMap() will return the per-input errors for the latest batch function.
741 */
742bool QContactManager::removeRelationships(const QList<QContactRelationship> &relationships, QMap<int, QContactManager::Error> *errorMap)
743{
744 QContactManagerSyncOpErrorHolder h(this, errorMap);
745 return d->m_engine->removeRelationships(relationships, errorMap: &h.errorMap, error: &h.error);
746}
747
748/*!
749 Returns the list of data types supported by the manager
750 */
751QList<QVariant::Type> QContactManager::supportedDataTypes() const
752{
753 return d->m_engine->supportedDataTypes();
754}
755
756/*!
757 Returns true if the given \a filter is supported natively by the
758 manager, and false if the filter behaviour would be emulated.
759
760 Note: In some cases, the behaviour of an unsupported filter
761 cannot be emulated. For example, a filter that requests contacts
762 that have changed since a given time depends on having that information
763 available. In these cases, the filter will fail.
764 */
765bool QContactManager::isFilterSupported(const QContactFilter &filter) const
766{
767 return d->m_engine->isFilterSupported(filter);
768}
769
770/*!
771 Returns true if the manager supports the relationship type specified in \a relationshipType for
772 contacts whose type is the given \a contactType.
773
774 Note that some managers may support the relationship type for a contact in a limited manner
775 (for example, only as the first contact in the relationship, or only as the second contact
776 in the relationship). In this case, it will still return true. It will only return false
777 if the relationship is entirely unsupported for the given type of contact.
778 */
779bool QContactManager::isRelationshipTypeSupported(const QString& relationshipType, QContactType::TypeValues contactType) const
780{
781 return d->m_engine->isRelationshipTypeSupported(relationshipType, contactType);
782}
783
784/*!
785 Returns the list of contact types which are supported by this manager.
786 This is a convenience function, equivalent to retrieving the allowable values
787 for the \c QContactType::FieldType field of the QContactType detail
788 which is valid in this manager.
789 */
790QList<QContactType::TypeValues> QContactManager::supportedContactTypes() const
791{
792 return d->m_engine->supportedContactTypes();
793}
794
795/*!
796 Returns the list of contact detail types which are supported by this manager.
797 The returned list can be used by clients to identify incompatibilities between
798 contact objects to be saved and the actual subset of detail types supported by
799 this manager.
800 */
801QList<QContactDetail::DetailType> QContactManager::supportedContactDetailTypes() const
802{
803 return d->m_engine->supportedContactDetailTypes();
804}
805
806/*!
807 Returns the id of a default collection managed by this manager.
808 There is always only one default collection for each backend.
809 */
810QContactCollectionId QContactManager::defaultCollectionId() const
811{
812 return d->m_engine->defaultCollectionId();
813}
814
815/*!
816 Returns the collection identified by the given \a collectionId which is managed by this manager.
817 */
818QContactCollection QContactManager::collection(const QContactCollectionId& collectionId)
819{
820 QContactManagerSyncOpErrorHolder h(this);
821 return d->m_engine->collection(collectionId, error: &h.error);
822}
823
824/*!
825 Returns a list of all of the collections managed by this manager.
826 */
827QList<QContactCollection> QContactManager::collections()
828{
829 QContactManagerSyncOpErrorHolder h(this);
830 return d->m_engine->collections(error: &h.error);
831}
832
833/*!
834 Saves the given \a collection to the backend, and returns true on success or false otherwise.
835
836 Note that certain backends may not allow modification nor adding new collections, in such cases
837 the operation will fail and result a QContactManager::PermissionsError error.
838
839 A new collection will be created in the backend store if the collection ID of it is null.
840 Otherwise, an existing collection with the same ID will be updated. If the given collection ID
841 does not exist in the backend, it will result a QContactManager::DoesNotExistError error.
842
843 Note that upon successful saving, the backend may update the collection, e.g. collection ID for
844 newly saved collections.
845 */
846bool QContactManager::saveCollection(QContactCollection* collection)
847{
848 QContactManagerSyncOpErrorHolder h(this);
849 if (collection) {
850 return d->m_engine->saveCollection(collection, error: &h.error);
851 } else {
852 h.error = QContactManager::BadArgumentError;
853 return false;
854 }
855}
856
857/*!
858 Removes the collection identified by the given \a collectionId (and all items in the collection)
859 from the manager. Returns true on success, false on failure.
860
861 If the given \a collectionId does not exist, the operation will fail and QContactManager::DoesNotExistError
862 will be returned when calling error().
863
864 If the given \a collectionId refers to the default collection, the operation will fail and
865 QContactManager::PermissionsError will be returned when calling error().
866 */
867bool QContactManager::removeCollection(const QContactCollectionId &collectionId)
868{
869 QContactManagerSyncOpErrorHolder h(this);
870 return d->m_engine->removeCollection(collectionId, error: &h.error);
871}
872
873/*!
874 Returns the engine backend implementation version number
875 */
876int QContactManager::managerVersion() const
877{
878 return d->m_engine->managerVersion();
879}
880
881/*! Returns the manager name for this QContactManager */
882QString QContactManager::managerName() const
883{
884 return d->m_engine->managerName();
885}
886
887/*! Return the parameters relevant to the creation of this QContactManager */
888QMap<QString, QString> QContactManager::managerParameters() const
889{
890 QMap<QString, QString> params = d->m_engine->managerParameters();
891
892 params.remove(akey: QString::fromLatin1(QTCONTACTS_VERSION_NAME));
893 params.remove(akey: QString::fromLatin1(QTCONTACTS_IMPLEMENTATION_VERSION_NAME));
894 return params;
895}
896
897/*!
898 Return the uri describing this QContactManager, consisting of the manager name and any parameters.
899 */
900QString QContactManager::managerUri() const
901{
902 return d->m_engine->managerUri();
903}
904
905/*!
906 \internal
907
908 Returns the signal that corresponds to \a proxySignal in the
909 meta-object of the \a sourceObject.
910*/
911static QMetaMethod proxyToSourceSignal(const QMetaMethod &proxySignal, QObject *sourceObject)
912{
913 if (!proxySignal.isValid())
914 return proxySignal;
915 Q_ASSERT(proxySignal.methodType() == QMetaMethod::Signal);
916 Q_ASSERT(sourceObject != 0);
917 const QMetaObject *sourceMeta = sourceObject->metaObject();
918 int sourceIndex = sourceMeta->indexOfSignal(signal: proxySignal.methodSignature());
919 Q_ASSERT(sourceIndex != -1);
920 return sourceMeta->method(index: sourceIndex);
921}
922
923/*!
924 \internal
925
926 When someone connects to this manager, connect the corresponding signal from the engine, if we
927 haven't before. If we have, just increment a count.
928
929 This allows lazy evaluation on the engine side (e.g. setting up dbus watchers) and prevents
930 unnecessary work.
931*/
932void QContactManager::connectNotify(const QMetaMethod &signal)
933{
934 /* For most signals we just connect from the engine to ourselves, since we just proxy, but we should connect only once */
935 QMetaMethod sourceSignal = proxyToSourceSignal(proxySignal: signal, sourceObject: d->m_engine);
936 connect(sender: d->m_engine, signal: sourceSignal, receiver: this, method: signal, type: Qt::UniqueConnection);
937}
938
939/*!
940 \internal
941
942 When someone disconnects, disconnect from the engine too if there are no more users of that signal.
943*/
944void QContactManager::disconnectNotify(const QMetaMethod &signal)
945{
946 if (!isSignalConnected(signal)) {
947 QMetaMethod sourceSignal = proxyToSourceSignal(proxySignal: signal, sourceObject: d->m_engine);
948 disconnect(sender: d->m_engine, signal: sourceSignal, receiver: this, member: signal);
949 }
950}
951
952#include "moc_qcontactmanager.cpp"
953
954QT_END_NAMESPACE_CONTACTS
955

source code of qtpim/src/contacts/qcontactmanager.cpp