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 QtOrganizer 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 "qorganizermanager.h"
35#include "qorganizermanager_p.h"
36
37QT_BEGIN_NAMESPACE_ORGANIZER
38
39/*!
40 \class QOrganizerManager
41 \brief The QOrganizerManager class provides an interface which allows clients with access to
42 organizer item and collection information stored in a particular backend.
43 \inmodule QtOrganizer
44 \ingroup organizer-main
45
46 This class provides synchronous methods to retrieve and manipulate organizer item information,
47 collection information, as well as functionality reporting and error information reporting.
48
49 Clients can also use the use-case-specific classes derived from QOrganizerAbstractRequest to
50 retrieve and manipulate organizer items and collections in an asynchronous manner. However,
51 certain functionality (e.g. backend functionality reporting) can not be accessed using the
52 asynchronous APIs.
53
54 See the \l{Qt Organizer Synchronous API}{synchronous} and \l{Qt Organizer Asynchronous API}{asynchronous}
55 API information from the \l{Qt Organizer Overview}{organizer module} API documentation for more details.
56
57 When constructing a QOrganizerManager instance, certain parameters can be given to provide more
58 control, e.g. to specify the version of the backend it wants to construct. Note that the parameters
59 returned when calling managerParameters() are not necessarily the same as the ones passed in,
60 since certain parameters might be discarded or added by the backend.
61 */
62
63/*!
64 \enum QOrganizerManager::Operation
65
66 This enumeration describes the operation that has been done to the item or collection modified.
67 \value Add The item / collection has been added.
68 \value Change The item / collection has been changed.
69 \value Remove The item / collection has been removed.
70 */
71
72/*!
73 \fn QOrganizerManager::itemsModified(const QList<QPair<QOrganizerItemId, QOrganizerManager::Operation> > &itemIds);
74
75 This signal is emitted at some point once the items have been modified in a datastore managed by
76 this manager. In the \a itemIds list, the item ID tells which item has been modified with the
77 corresponding operation.
78
79 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
80
81 \sa dataChanged()
82 */
83
84/*!
85 \fn QOrganizerManager::collectionsModified(const QList<QPair<QOrganizerCollectionId, QOrganizerManager::Operation> > &collectionIds);
86
87 This signal is emitted at some point once the collections have been modified in a datastore managed
88 by this manager. In the \a collectionIds list, the collection ID tells which item has been modified
89 with the corresponding operation.
90
91 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
92
93 \sa dataChanged()
94 */
95
96/*!
97 \macro QTORGANIZER_BACKEND_VERSION
98 \relates QOrganizerManager
99
100 This macro tells the parameter is to specify the version the backend that the customer wants to
101 create.
102
103 If the specified version is not available, a backend with the given name and a default version
104 will be created for this manager.
105 */
106
107/*!
108 \fn QOrganizerManager::dataChanged()
109
110 This signal is emitted by the manager if its internal state changes, and it is unable to determine
111 the changes which occurred, or if the manager considers the changes to be radical enough to require
112 clients to reload all data.
113
114 If this signal is emitted, no other signals will be emitted for the associated changes.
115
116 \sa itemsAdded(), itemsChanged(), itemsRemoved()
117 */
118
119/*!
120 \fn QOrganizerManager::itemsAdded(const QList<QOrganizerItemId> &itemIds)
121
122 This signal is emitted at some point once the items identified by \a itemIds have been added to
123 a datastore managed by this manager.
124
125 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
126
127 \sa dataChanged()
128 */
129
130/*!
131 \fn QOrganizerManager::itemsChanged(const QList<QOrganizerItemId> &itemIds)
132
133 This signal is emitted at some point once the items identified by \a itemIds have been modified
134 in a datastore managed by this manager.
135
136 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
137
138 \sa dataChanged()
139 */
140
141/*!
142 \fn QOrganizerManager::itemsRemoved(const QList<QOrganizerItemId> &itemIds)
143
144 This signal is emitted at some point once the items identified by \a itemIds have been removed
145 from a datastore managed by this manager.
146
147 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
148
149 \sa dataChanged()
150 */
151
152/*!
153 \fn QOrganizerManager::collectionsAdded(const QList<QOrganizerCollectionId> &collectionIds)
154
155 This signal is emitted at some point once the collections identified by \a collectionIds have
156 been added to a datastore managed by this manager.
157
158 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
159
160 \sa dataChanged()
161 */
162
163/*!
164 \fn QOrganizerManager::collectionsChanged(const QList<QOrganizerCollectionId> &collectionIds)
165
166 This signal is emitted at some point once the metadata for the collections identified by \a collectionIds
167 have been modified in a datastore managed by this manager.
168
169 This signal will not be emitted if items in the collections have been added, modified, or removed.
170
171 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
172
173 \sa dataChanged()
174 */
175
176/*!
177 \fn QOrganizerManager::collectionsRemoved(const QList<QOrganizerCollectionId> &collectionIds)
178
179 This signal is emitted at some point once the collections identified by \a collectionIds have
180 been removed from a datastore managed by this manager.
181
182 This signal will not be emitted if the dataChanged() signal was previously emitted for these changes.
183
184 \sa dataChanged()
185 */
186
187#define makestr(x) (#x)
188#define makename(x) makestr(x)
189
190/*!
191 Returns a list of available manager names that can be used to construct a QOrganizerManager.
192 */
193QStringList QOrganizerManager::availableManagers()
194{
195 QStringList ret;
196 ret << QStringLiteral("invalid");
197 QOrganizerManagerData::loadFactories();
198 ret.append(t: QOrganizerManagerData::m_engines.keys());
199
200 // now swizzle the default engine to pole position
201#if defined(Q_ORGANIZER_DEFAULT_ENGINE)
202 if (ret.removeAll(QLatin1String(makename(Q_ORGANIZER_DEFAULT_ENGINE))))
203 ret.prepend(QLatin1String(makename(Q_ORGANIZER_DEFAULT_ENGINE)));
204#endif
205
206 return ret;
207}
208
209/*!
210 Splits the given \a uri into the manager name and parameters that it describes,
211 and places the information into the memory addressed by \a managerName and \a params respectively.
212 Returns true if \a uri could be split successfully, otherwise returns false.
213 */
214bool QOrganizerManager::parseUri(const QString &uri, QString *managerName, QMap<QString, QString> *params)
215{
216 return QOrganizerManagerData::parseUri(uriString: uri, managerName, params, strict: false);
217}
218
219/*!
220 Returns a URI that describes a manager name, parameters, and version with which to instantiate
221 a manager object, from the given \a managerName and \a params.
222 */
223QString QOrganizerManager::buildUri(const QString &managerName, const QMap<QString, QString> &params)
224{
225 return QOrganizerManagerData::buildUri(managerName, params);
226}
227
228/*!
229 Constructs a QOrganizerManager whose name, parameters, and version are specified in the given
230 \a uri, and whose parent object is \a parent.
231 */
232QOrganizerManager *QOrganizerManager::fromUri(const QString &uri, QObject *parent)
233{
234 if (uri.isEmpty()) {
235 return new QOrganizerManager(QString(), QMap<QString, QString>(), parent);
236 } else {
237 QString id;
238 QMap<QString, QString> parameters;
239 if (parseUri(uri, managerName: &id, params: &parameters))
240 return new QOrganizerManager(id, parameters, parent);
241 else
242 return new QOrganizerManager(QStringLiteral("invalid"), QMap<QString, QString>(), parent);
243 }
244}
245
246/*!
247 Constructs a QOrganizerManager whose parent object is \a parent.
248
249 The default backend, i.e. the first one returned by the availableManagers() function, for the
250 platform will be created.
251 */
252QOrganizerManager::QOrganizerManager(QObject *parent)
253 : QObject(parent), d(new QOrganizerManagerData)
254{
255 createEngine(managerName: QString(), parameters: QMap<QString, QString>());
256}
257
258/*!
259 Constructs a QOrganizerManager whose backend is identified by \a managerName with the given
260 \a parameters, and the parent object is \a parent.
261
262 The default backend, i.e. the first one returned by the availableManagers() function, for the
263 platform will be created, if the \a managerName is empty. If the backend identified by \a managerName
264 does not exist, an invalid backend is created.
265 */
266QOrganizerManager::QOrganizerManager(const QString &managerName, const QMap<QString, QString> &parameters, QObject *parent)
267 : QObject(parent), d(new QOrganizerManagerData)
268{
269 createEngine(managerName, parameters);
270}
271
272void QOrganizerManager::createEngine(const QString &managerName, const QMap<QString, QString> &parameters)
273{
274 d->createEngine(managerName, parameters);
275
276 connect(sender: d->m_engine, SIGNAL(dataChanged()), receiver: this, SIGNAL(dataChanged()));
277 connect(sender: d->m_engine, SIGNAL(itemsAdded(QList<QOrganizerItemId>)), receiver: this, SIGNAL(itemsAdded(QList<QOrganizerItemId>)));
278 connect(sender: d->m_engine, SIGNAL(itemsChanged(QList<QOrganizerItemId>, QList<QOrganizerItemDetail::DetailType>)), receiver: this, SIGNAL(itemsChanged(QList<QOrganizerItemId>, QList<QOrganizerItemDetail::DetailType>)));
279 connect(sender: d->m_engine, SIGNAL(itemsRemoved(QList<QOrganizerItemId>)), receiver: this, SIGNAL(itemsRemoved(QList<QOrganizerItemId>)));
280 connect(sender: d->m_engine, SIGNAL(itemsModified(QList<QPair<QOrganizerItemId,QOrganizerManager::Operation> >)), receiver: this, SIGNAL(itemsModified(QList<QPair<QOrganizerItemId,QOrganizerManager::Operation> >)));
281 connect(sender: d->m_engine, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>)), receiver: this, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>)));
282 connect(sender: d->m_engine, SIGNAL(collectionsChanged(QList<QOrganizerCollectionId>)), receiver: this, SIGNAL(collectionsChanged(QList<QOrganizerCollectionId>)));
283 connect(sender: d->m_engine, SIGNAL(collectionsRemoved(QList<QOrganizerCollectionId>)), receiver: this, SIGNAL(collectionsRemoved(QList<QOrganizerCollectionId>)));
284 connect(sender: d->m_engine, SIGNAL(collectionsModified(QList<QPair<QOrganizerCollectionId,QOrganizerManager::Operation> >)), receiver: this, SIGNAL(collectionsModified(QList<QPair<QOrganizerCollectionId,QOrganizerManager::Operation> >)));
285 connect(sender: d->m_engine, SIGNAL(itemsChanged(QList<QOrganizerItemId>, QList<QOrganizerItemDetail::DetailType>)), receiver: this, SLOT(_q_itemsUpdated(QList<QOrganizerItemId>, QList<QOrganizerItemDetail::DetailType>)));
286 connect(sender: d->m_engine, SIGNAL(itemsRemoved(QList<QOrganizerItemId>)), receiver: this, SLOT(_q_itemsDeleted(QList<QOrganizerItemId>)));
287}
288
289/*!
290 Frees the memory used by the QOrganizerManager.
291 */
292QOrganizerManager::~QOrganizerManager()
293{
294 delete d;
295}
296
297/*!
298 \enum QOrganizerManager::Error
299
300 This enum specifies an error that occurred during the most recent operation:
301
302 \value NoError The most recent operation was successful
303 \value DoesNotExistError The most recent operation failed because the requested organizer item or detail definition does not exist
304 \value AlreadyExistsError The most recent operation failed because the specified organizer item or detail definition already exists
305 \value InvalidDetailError The most recent operation failed because the specified organizer detail definition already exists
306 \value LockedError The most recent operation failed because the datastore specified is currently locked
307 \value DetailAccessError The most recent operation failed because a detail was modified or removed and its access method does not allow that
308 \value PermissionsError The most recent operation failed because the caller does not have permission to perform the operation
309 \value OutOfMemoryError The most recent operation failed due to running out of memory
310 \value NotSupportedError The most recent operation failed because the requested operation is not supported in the specified store
311 \value BadArgumentError The most recent operation failed because one or more of the parameters to the operation were invalid
312 \value UnspecifiedError The most recent operation failed for an undocumented reason
313 \value LimitReachedError The most recent operation failed because the limit for that type of object has been reached
314 \value InvalidItemTypeError The most recent operation failed because the item given was of an invalid type for the operation
315 \value InvalidCollectionError The most recent operation failed because the collection is invalid
316 \value InvalidOccurrenceError The most recent operation failed because it was an attempt to save an occurrence without a correct InstanceOrigin detail
317 \value TimeoutError The most recent operation failed because it took longer than expected. It may be possible to try again.
318
319 Backend specific documentation might have more details on exact error cases.
320 */
321
322/*!
323 Return the error code of the most recent operation.
324
325 \sa errorMap()
326 */
327QOrganizerManager::Error QOrganizerManager::error() const
328{
329 return d->m_lastError;
330}
331
332/*!
333 Returns per-input error codes for the most recent operation.
334
335 This function only returns meaningful information if the most recent operation was a batch
336 operation.
337
338 Each key in the map is the index of the element in the input list for which the error (whose
339 error code is stored in the value for that key in the map) occurred during the batch operation.
340
341 \sa error(), saveItems(), removeItems()
342 */
343QMap<int, QOrganizerManager::Error> QOrganizerManager::errorMap() const
344{
345 return d->m_lastErrorMap;
346}
347
348/*!
349 Returns a list of a maximum of \a maxCount organizer item instances which are occurrences of
350 the given \a parentItem recurring item, which occur between the given \a startDateTime and the
351 given \a endDateTime date, inclusive.
352
353 A default-constructed (invalid) \a startDateTime specifies an open start date time (matches anything
354 which occurs up until the \a endDateTime), and a default-constructed (invalid) \a endDateTime
355 specifies an open end date time (matches anything which occurs after the \a startDateTime). If
356 both the \a startDateTime and \a endDateTime are invalid, this function will return the IDs of
357 all items.
358
359 Note that backends will decide how many occurrences are returned if \a maxCount is negative.
360
361 The \a fetchHint allows clients to specify which pieces of information they are interested or
362 not interested in, to allow backends to optimise data retrieval if possible. Note that it is
363 simply a hint; backends can ignore the \a fetchHint and return the full item. If a client makes
364 changes to an organizer item which has been retrieved with a fetch hint, they should save it
365 back using a partial save, masked by the same set of detail types in order to avoid information
366 loss.
367 */
368QList<QOrganizerItem> QOrganizerManager::itemOccurrences(const QOrganizerItem &parentItem,const QDateTime &startDateTime,
369 const QDateTime &endDateTime, int maxCount,
370 const QOrganizerItemFetchHint &fetchHint)
371{
372 QOrganizerManagerSyncOpErrorHolder h(this);
373 return d->m_engine->itemOccurrences(parentItem, startDateTime, endDateTime, maxCount, fetchHint, error: &h.error);
374}
375
376/*!
377 Returns a list of item IDs of persisted organizer items that match the given \a filter, sorted
378 according to the given list of \a sortOrders, for any item which occurs (or has an occurrence
379 which occurs) in the range specified by the given \a startDateTime and \a endDateTime, inclusive.
380
381 A default-constructed (invalid) \a startDateTime specifies an open start date time (matches anything
382 which occurs up until the \a endDateTime), and a default-constructed (invalid) \a endDateTime
383 specifies an open end date time (matches anything which occurs after the \a startDateTime). If
384 both the \a startDateTime and \a endDateTime are invalid, this function will return the IDs of
385 all items which match the \a filter criteria.
386
387 Note that certain backends may ignore the given \a filter.
388 */
389QList<QOrganizerItemId> QOrganizerManager::itemIds(const QDateTime &startDateTime, const QDateTime &endDateTime,
390 const QOrganizerItemFilter &filter, const QList<QOrganizerItemSortOrder> &sortOrders)
391{
392 QOrganizerManagerSyncOpErrorHolder h(this);
393 return d->m_engine->itemIds(filter, startDateTime, endDateTime, sortOrders, error: &h.error);
394}
395
396/*!
397 Returns a list of a maximum of \a maxCount organizer items and occurrences that match the given
398 \a filter, which occur in the range specified by the given \a startDateTime and \a endDateTime,
399 inclusive, and sorted according to the given list of \a sortOrders.
400
401 A default-constructed (invalid) \a startDateTime specifies an open start date time (matches anything
402 which occurs up until the \a endDateTime), and a default-constructed (invalid) \a endDateTime
403 specifies an open end date time (matches anything which occurs after the \a startDateTime). If
404 both the \a startDateTime and \a endDateTime are invalid, this function will return the IDs of
405 all items which match the \a filter criteria.
406
407 If no sort order is provided, the list is returned sorted by date.
408
409 Note that certain backends may ignore the given \a filter.
410
411 Note that backends will decide how many items are returned if \a maxCount is negative.
412
413 The \a fetchHint allows clients to specify which pieces of information they are interested or
414 not interested in, to allow backends to optimise data retrieval if possible. Note that it is
415 simply a hint; backends can ignore the \a fetchHint and return the full item. If a client makes
416 changes to an organizer item which has been retrieved with a fetch hint, they should save it
417 back using a partial save, masked by the same set of detail types in order to avoid information
418 loss.
419 */
420QList<QOrganizerItem> QOrganizerManager::items(const QDateTime &startDateTime, const QDateTime &endDateTime,
421 const QOrganizerItemFilter &filter, int maxCount,
422 const QList<QOrganizerItemSortOrder> &sortOrders,
423 const QOrganizerItemFetchHint &fetchHint)
424{
425 QOrganizerManagerSyncOpErrorHolder h(this);
426 return d->m_engine->items(filter, startDateTime, endDateTime, maxCount, sortOrders, fetchHint, error: &h.error);
427}
428
429/*!
430 Returns a list of organizer items that match the given \a filter, sorted according to the given
431 list of \a sortOrders, for any item which occurs (or has an occurrence which occurs) in the range
432 specified by the given \a startDateTime and \a endDateTime, inclusive.
433
434 A default-constructed (invalid) \a startDateTime specifies an open start date time (matches anything
435 which occurs up until the \a endDateTime), and a default-constructed (invalid) \a endDateTime
436 specifies an open end date time (matches anything which occurs after the \a startDateTime). If
437 both the \a startDateTime and \a endDateTime are invalid, this function will return the IDs of
438 all items which match the \a filter criteria.
439
440 This function will only return parent items and persisted exceptions which match the specified
441 criteria; not generated occurrences.
442
443 Note that certain backends may ignore the given \a filter.
444
445 The \a fetchHint allows clients to specify which pieces of information they are interested or
446 not interested in, to allow backends to optimise data retrieval if possible. Note that it is
447 simply a hint; backends can ignore the \a fetchHint and return the full item. If a client makes
448 changes to an organizer item which has been retrieved with a fetch hint, they should save it
449 back using a partial save, masked by the same set of detail types in order to avoid information
450 loss.
451 */
452QList<QOrganizerItem> QOrganizerManager::itemsForExport(const QDateTime &startDateTime, const QDateTime &endDateTime,
453 const QOrganizerItemFilter &filter,
454 const QList<QOrganizerItemSortOrder> &sortOrders,
455 const QOrganizerItemFetchHint &fetchHint)
456{
457 QOrganizerManagerSyncOpErrorHolder h(this);
458 return d->m_engine->itemsForExport(startDateTime, endDateTime, filter, sortOrders, fetchHint, error: &h.error);
459}
460
461/*!
462 Returns the organizer items in the database identified by \a itemIds.
463
464 The items fetched by the backend should have a one-to-one correspondence to the IDs passed into
465 this class. That is, the nth item in the returned list should have an ID which is equal to the
466 nth ID in the list of IDs. Any invalid ID should correspond to an empty QOrganizerItem.
467
468 The \a fetchHint allows clients to specify which pieces of information they are interested or
469 not interested in, to allow backends to optimise data retrieval if possible. Note that it is
470 simply a hint; backends can ignore the \a fetchHint and return the full item. If a client makes
471 changes to an organizer item which has been retrieved with a fetch hint, they should save it
472 back using a partial save, masked by the same set of detail types in order to avoid information
473 loss.
474
475 Calling \l errorMap() will return the per-input errors for the fetch. The \l QOrganizerManager::error()
476 function will only return \c QOrganizerManager::NoError if all organizer items are fetched
477 successfully.
478 */
479QList<QOrganizerItem> QOrganizerManager::items(const QList<QOrganizerItemId> &itemIds, const QOrganizerItemFetchHint &fetchHint)
480{
481 QOrganizerManagerSyncOpErrorHolder h(this);
482 return d->m_engine->items(itemIds, fetchHint, errorMap: &h.errorMap, error: &h.error);
483}
484
485/*!
486 Returns the organizer item in the database identified by \a itemId, or an empty item if the
487 specified item does not exist.
488
489 The \a fetchHint allows clients to specify which pieces of information they are interested or
490 not interested in, to allow backends to optimise data retrieval if possible. Note that it is
491 simply a hint; backends can ignore the \a fetchHint and return the full item. If a client makes
492 changes to an organizer item which has been retrieved with a fetch hint, they should save it
493 back using a partial save, masked by the same set of detail types in order to avoid information
494 loss.
495 */
496QOrganizerItem QOrganizerManager::item(const QOrganizerItemId& itemId, const QOrganizerItemFetchHint& fetchHint)
497{
498 QList<QOrganizerItem> tmp = items(itemIds: QList<QOrganizerItemId>() << itemId, fetchHint);
499 if (tmp.size() > 0)
500 return tmp.at(i: 0);
501 return QOrganizerItem();
502}
503
504/*!
505 Saves the given \a item to the backend, and returns true on success or false otherwise.
506
507 A new organizer item will be created in the backend store if the item ID of it is null. Otherwise,
508 an existing item with the same ID will be updated. If the given item ID does not exist in the
509 backend, it will result a QOrganizerManager::DoesNotExistError error.
510
511 If the collection ID of the item is null, it will be saved to the default collection. If the given
512 collection ID doesn't exist, the saving will fail.
513
514 If the \a detailMask is empty, only the details currently existing in the item will be saved.
515 Otherwise, only details masked by the \a detailMask will be saved or updated, others are kept
516 untouched. It's useful to avoid information loss if the items are retrieved with a fetch hint.
517
518 Note that upon successful saving, the backend may update the item, e.g. item ID for newly saved
519 items, GUID, timestamp, version, etc.
520
521 \sa saveItems()
522 */
523bool QOrganizerManager::saveItem(QOrganizerItem *item, const QList<QOrganizerItemDetail::DetailType> &detailMask)
524{
525 QList<QOrganizerItem> items;
526 items.append(t: *item);
527 bool rtn = saveItems(items: &items, detailMask);
528 *item = items.at(i: 0);
529 return rtn;
530}
531
532/*!
533 Removes all the item whose ID is \a itemId, and all its occurrences. Returns true if the item
534 and occurrences are successfully removed, or false otherwise.
535
536 \sa removeItems()
537 */
538bool QOrganizerManager::removeItem(const QOrganizerItemId& itemId)
539{
540 return removeItems(itemIds: QList<QOrganizerItemId>() << itemId);
541}
542
543/*!
544 Remove the organizer \a item from the database. If \a item is a generated occurrence,
545 the start date of the occurrence is added to its parent item's exception date list.
546 Returns true if the organizer item was removed successfully, otherwise returns false.
547
548 \sa removeItems()
549 */
550bool QOrganizerManager::removeItem(const QOrganizerItem *item)
551{
552 QList<QOrganizerItem> list;
553 list.append(t: *item);
554 return removeItems(items: &list);
555}
556
557/*!
558 Saves the given list of \a items to the backend, and returns true on success or false otherwise.
559
560 A new organizer item will be created in the backend store if the item ID of it is null. Otherwise,
561 an existing item with the same ID will be updated. If the given item ID does not exist in the
562 backend, it will result a QOrganizerManager::DoesNotExistError error.
563
564 If the collection ID of the item is null, it will be saved to the default collection. If the given
565 collection ID doesn't exist, the saving will fail.
566
567 If the \a detailMask is empty, only the details currently existing in the item will be saved.
568 Otherwise, only details masked by the \a detailMask will be saved or updated, others are kept
569 untouched. It's useful to avoid information loss if the items are retrieved with a fetch hint.
570
571 Note that upon successful saving, the backend may update the item, e.g. item ID for newly saved
572 items, GUID, timestamp, version, etc.
573
574 Calling errorMap() will return the per-input errors for the operation. The error() function will
575 only return QOrganizerManager::NoError if all organizer items were saved successfully.
576
577 \sa saveItem()
578 */
579bool QOrganizerManager::saveItems(QList<QOrganizerItem>* items, const QList<QOrganizerItemDetail::DetailType> &detailMask)
580{
581 QOrganizerManagerSyncOpErrorHolder h(this);
582 if (!items) {
583 h.error = QOrganizerManager::BadArgumentError;
584 return false;
585 }
586 return d->m_engine->saveItems(items, detailMask, errorMap: &h.errorMap, error: &h.error);
587}
588
589/*!
590 Removes all the items whose ID is contained in the given list of \a itemIds, and all the occurrences
591 whose parent ID is containd in the \a itemIds. Returns true if all the items and occurrences
592 are successfully removed, or false otherwise.
593
594 Calling errorMap() will return the per-input errors for the operation. The error() function will
595 only return QOrganizerManager::NoError if all organizer items were saved successfully.
596
597 \sa removeItem()
598 */
599bool QOrganizerManager::removeItems(const QList<QOrganizerItemId> &itemIds)
600{
601 QOrganizerManagerSyncOpErrorHolder h(this);
602 if (itemIds.isEmpty()) {
603 h.error = QOrganizerManager::BadArgumentError;
604 return false;
605 }
606 return d->m_engine->removeItems(itemIds, errorMap: &h.errorMap, error: &h.error);
607}
608
609/*!
610 Removes every organizer item which is contained in the list of organizer items
611 \a items. If the list contains generated occurrences the start date of the occurrence
612 is added to its parent item's exception date list. Returns true if all organizer items
613 were removed successfully, otherwise false.
614
615 Calling \l errorMap() will return the per-input errors for the latest batch function.
616 The \l QOrganizerManager::error() function will only return \c QOrganizerManager::NoError
617 if all organizer items were removed successfully.
618
619 If the given list of organizer \a items is empty, the function will return false
620 and calling error() will return \c QOrganizerManager::BadArgumentError. If the list is non-empty
621 and contains items which are not a valid organizer item in the manager, the function will
622 remove any valid organizer items in the \a items list, insert \c QOrganizerManager::DoesNotExist
623 entries into the error map for the indices of invalid id in the \a items list, return false,
624 and set the overall operation error to \c QOrganizerManager::DoesNotExistError.
625
626 \sa QOrganizerManager::removeItem()
627 */
628
629bool QOrganizerManager::removeItems(const QList<QOrganizerItem> *items)
630{
631 QOrganizerManagerSyncOpErrorHolder h(this);
632 if (items->isEmpty()) {
633 h.error = QOrganizerManager::BadArgumentError;
634 return false;
635 }
636
637 return d->m_engine->removeItems(items, errorMap: &h.errorMap, error: &h.error);
638}
639
640/*!
641 Returns the id of a default collection managed by this manager.
642 There is always only one default collection for each backend.
643 */
644QOrganizerCollectionId QOrganizerManager::defaultCollectionId() const
645{
646 return d->m_engine->defaultCollectionId();
647}
648
649/*!
650 Returns the collection identified by the given \a collectionId which is managed by this manager.
651 */
652QOrganizerCollection QOrganizerManager::collection(const QOrganizerCollectionId& collectionId)
653{
654 QOrganizerManagerSyncOpErrorHolder h(this);
655 return d->m_engine->collection(collectionId, error: &h.error);
656}
657
658/*!
659 Returns a list of all of the collections managed by this manager.
660 */
661QList<QOrganizerCollection> QOrganizerManager::collections()
662{
663 QOrganizerManagerSyncOpErrorHolder h(this);
664 return d->m_engine->collections(error: &h.error);
665}
666
667/*!
668 Saves the given \a collection to the backend, and returns true on success or false otherwise.
669
670 Note that certain backends may not allow modification nor adding new collections, in such cases
671 the operation will fail and result a QOrganizerManager::PermissionsError error.
672
673 A new collection will be created in the backend store if the collection ID of it is null.
674 Otherwise, an existing collection with the same ID will be updated. If the given collection ID
675 does not exist in the backend, it will result a QOrganizerManager::DoesNotExistError error.
676
677 Note that upon successful saving, the backend may update the collection, e.g. collection ID for
678 newly saved collections.
679 */
680bool QOrganizerManager::saveCollection(QOrganizerCollection* collection)
681{
682 QOrganizerManagerSyncOpErrorHolder h(this);
683 if (collection) {
684 return d->m_engine->saveCollection(collection, error: &h.error);
685 } else {
686 h.error = QOrganizerManager::BadArgumentError;
687 return false;
688 }
689}
690
691/*!
692 Removes the collection identified by the given \a collectionId (and all items in the collection)
693 from the manager. Returns true on success, false on failure.
694
695 If the given \a collectionId does not exist, the operation will fail and QOrganizerManager::DoesNotExistError
696 will be returned when calling error().
697
698 If the given \a collectionId refers to the default collection, the operation will fail and
699 QOrganizerManager::PermissionsError will be returned when calling error().
700 */
701bool QOrganizerManager::removeCollection(const QOrganizerCollectionId &collectionId)
702{
703 QOrganizerManagerSyncOpErrorHolder h(this);
704 return d->m_engine->removeCollection(collectionId, error: &h.error);
705}
706
707/*!
708 Returns the list of supported filters by this manager.
709 */
710QList<QOrganizerItemFilter::FilterType> QOrganizerManager::supportedFilters() const
711{
712 return d->m_engine->supportedFilters();
713}
714
715/*!
716 Returns the list of details that are supported by this manager for the given \a itemType.
717 */
718QList<QOrganizerItemDetail::DetailType> QOrganizerManager::supportedItemDetails(QOrganizerItemType::ItemType itemType) const
719{
720 return d->m_engine->supportedItemDetails(itemType);
721}
722
723/*!
724 Returns the list of organizer item types supported by this manager.
725 */
726QList<QOrganizerItemType::ItemType> QOrganizerManager::supportedItemTypes() const
727{
728 return d->m_engine->supportedItemTypes();
729}
730
731/*!
732 Returns the manager name for the backend.
733*/
734QString QOrganizerManager::managerName() const
735{
736 return d->m_engine->managerName();
737}
738
739/*!
740 Return the parameters used by the backend.
741
742 Note that if certain paramters are invalid, or discarded by the backend, they will not be returned.
743 Also, the backend might add certain parameters when being constructed.
744*/
745QMap<QString, QString> QOrganizerManager::managerParameters() const
746{
747 return d->m_engine->managerParameters();
748}
749
750/*!
751 Returns the version of the backend.
752
753 The version is stored as part of the parameters, with the key QTORGANIZER_BACKEND_VERSION.
754 */
755int QOrganizerManager::managerVersion() const
756{
757 return managerParameters().value(QTORGANIZER_BACKEND_VERSION).toInt();
758}
759
760/*!
761 Return the URI describing the backend.
762 */
763QString QOrganizerManager::managerUri() const
764{
765 return d->m_engine->managerUri();
766}
767
768/*!
769 Return a list of QOrganizerItemId extracted from the \a items.
770*/
771QList<QOrganizerItemId> QOrganizerManager::extractIds(const QList<QOrganizerItem> &items)
772{
773 QList<QOrganizerItemId> ids;
774 ids.reserve(alloc: items.count());
775 foreach (const QOrganizerItem &item, items)
776 ids.append(t: item.id());
777 return ids;
778}
779
780#include "moc_qorganizermanager.cpp"
781
782QT_END_NAMESPACE_ORGANIZER
783

source code of qtpim/src/organizer/qorganizermanager.cpp