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 | |
42 | QT_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 | */ |
121 | QStringList 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 | */ |
158 | bool 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 | */ |
167 | QString QContactManager::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms) |
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 | */ |
179 | QString QContactManager::buildUri(const QString &managerName, const QMap<QString, QString> ¶ms, 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 | */ |
194 | QContactManager* 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: ¶meters)) { |
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 | */ |
214 | QContactManager::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 | */ |
229 | QContactManager::QContactManager(const QString &managerName, const QMap<QString, QString> ¶meters, QObject *parent) |
230 | : QObject(parent), |
231 | d(new QContactManagerData) |
232 | { |
233 | createEngine(managerName, parameters); |
234 | } |
235 | |
236 | void QContactManager::createEngine(const QString &managerName, const QMap<QString, QString> ¶meters) |
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 | */ |
252 | QContactManager::QContactManager(const QString &managerName, int implementationVersion, const QMap<QString, QString> ¶meters, 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 */ |
262 | QContactManager::~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 | */ |
361 | QContactManager::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 | */ |
375 | QMap<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 | */ |
383 | QList<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 | */ |
393 | QList<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 | */ |
410 | QList<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 | */ |
430 | QList<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 | */ |
451 | QContact 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 | */ |
475 | QList<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 | */ |
516 | bool 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 | */ |
534 | bool 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 | */ |
554 | bool 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 | */ |
584 | bool 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 | */ |
620 | bool 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 | */ |
643 | bool 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 | */ |
656 | QContactId 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 | */ |
666 | QList<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 | */ |
677 | QList<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 | */ |
696 | bool 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 | */ |
712 | bool 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 | */ |
730 | bool 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 | */ |
742 | bool 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 | */ |
751 | QList<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 | */ |
765 | bool 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 | */ |
779 | bool 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 | */ |
790 | QList<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 | */ |
801 | QList<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 | */ |
810 | QContactCollectionId 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 | */ |
818 | QContactCollection 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 | */ |
827 | QList<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 | */ |
846 | bool 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 | */ |
867 | bool 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 | */ |
876 | int QContactManager::managerVersion() const |
877 | { |
878 | return d->m_engine->managerVersion(); |
879 | } |
880 | |
881 | /*! Returns the manager name for this QContactManager */ |
882 | QString QContactManager::managerName() const |
883 | { |
884 | return d->m_engine->managerName(); |
885 | } |
886 | |
887 | /*! Return the parameters relevant to the creation of this QContactManager */ |
888 | QMap<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 | */ |
900 | QString 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 | */ |
911 | static 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 | */ |
932 | void 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 | */ |
944 | void 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 | |
954 | QT_END_NAMESPACE_CONTACTS |
955 | |