Akonadi Calendar

calendarbase.cpp
1 /*
2  SPDX-FileCopyrightText: 2011 Sérgio Martins <[email protected]>
3  SPDX-FileCopyrightText: 2012 Sérgio Martins <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "calendarbase.h"
9 #include "akonadicalendar_debug.h"
10 #include "calendarbase_p.h"
11 #include "incidencechanger.h"
12 #include "utils_p.h"
13 #include <Akonadi/CollectionFetchJob>
14 
15 #include <KLocalizedString>
16 #include <QTimeZone>
17 
18 using namespace Akonadi;
19 using namespace KCalendarCore;
20 
21 static QString itemToString(const Akonadi::Item &item)
22 {
23  const KCalendarCore::Incidence::Ptr &incidence = CalendarUtils::incidence(item);
24  QString str;
25  QTextStream stream(&str);
26  stream << item.id() << "; summary=" << incidence->summary() << "; uid=" << incidence->uid() << "; type=" << incidence->type()
27  << "; recurs=" << incidence->recurs() << "; recurrenceId=" << incidence->recurrenceId().toString() << "; dtStart=" << incidence->dtStart().toString()
28  << "; dtEnd=" << incidence->dateTime(Incidence::RoleEnd).toString() << "; parentCollection=" << item.storageCollectionId()
29  << item.parentCollection().displayName();
30 
31  return str;
32 }
33 
34 CalendarBasePrivate::CalendarBasePrivate(CalendarBase *qq)
35  : QObject()
36  , mIncidenceChanger(new IncidenceChanger())
37  , q(qq)
38 {
39  connect(mIncidenceChanger, &IncidenceChanger::createFinished, this, &CalendarBasePrivate::slotCreateFinished);
40 
41  connect(mIncidenceChanger, &IncidenceChanger::deleteFinished, this, &CalendarBasePrivate::slotDeleteFinished);
42 
43  connect(mIncidenceChanger, &IncidenceChanger::modifyFinished, this, &CalendarBasePrivate::slotModifyFinished);
44 
45  mIncidenceChanger->setDestinationPolicy(IncidenceChanger::DestinationPolicyAsk);
46  mIncidenceChanger->setGroupwareCommunication(false);
47  mIncidenceChanger->setHistoryEnabled(false);
48 }
49 
50 CalendarBasePrivate::~CalendarBasePrivate()
51 {
52  delete mIncidenceChanger;
53 }
54 
55 void CalendarBasePrivate::internalInsert(const Akonadi::Item &item)
56 {
57  Q_ASSERT(item.isValid());
58  Q_ASSERT(item.hasPayload<KCalendarCore::Incidence::Ptr>());
59  KCalendarCore::Incidence::Ptr incidence = CalendarUtils::incidence(item);
60 
61  if (!incidence) {
62  qCritical() << "Incidence is null. id=" << item.id() << "; hasPayload()=" << item.hasPayload()
63  << "; has incidence=" << item.hasPayload<KCalendarCore::Incidence::Ptr>() << "; mime type=" << item.mimeType();
64  Q_ASSERT(false);
65  return;
66  }
67 
68  // qCDebug(AKONADICALENDAR_LOG) << "Inserting incidence in calendar. id=" << item.id() << "uid=" << incidence->uid();
69  const QString uid = incidence->instanceIdentifier();
70 
71  if (uid.isEmpty()) {
72  // This code path should never happen
73  qCritical() << "Incidence has empty UID. id=" << item.id() << "; summary=" << incidence->summary() << "Please fix it. Ignoring this incidence.";
74  return;
75  }
76 
77  if (mItemIdByUid.contains(uid) && mItemIdByUid[uid] != item.id()) {
78  // We only allow duplicate UIDs if they have the same item id, for example
79  // when using virtual folders.
80 #if 0
81  qCWarning(AKONADICALENDAR_LOG) << "Discarding duplicate incidence with instanceIdentifier=" << uid
82  << "and summary " << incidence->summary()
83  << "; recurrenceId() =" << incidence->recurrenceId()
84  << "; new id=" << item.id()
85  << "; existing id=" << mItemIdByUid[uid];
86 #endif
87  return;
88  }
89 
90  if (incidence->type() == KCalendarCore::Incidence::TypeEvent && !incidence->dtStart().isValid()) {
91  // TODO: make the parser discard them would also be a good idea
92  qCWarning(AKONADICALENDAR_LOG) << "Discarding event with invalid DTSTART. identifier=" << incidence->instanceIdentifier()
93  << "; summary=" << incidence->summary();
94  return;
95  }
96 
97  Akonadi::Collection collection = item.parentCollection();
98  if (collection.isValid()) {
99  // Some items don't have collection set
100  if (item.storageCollectionId() != collection.id() && item.storageCollectionId() > -1) {
101  if (mCollections.contains(item.storageCollectionId())) {
102  collection = mCollections.value(item.storageCollectionId());
103  incidence->setReadOnly(!(collection.rights() & Akonadi::Collection::CanChangeItem));
104  } else if (!mCollectionJobs.key(item.storageCollectionId())) {
105  collection = Akonadi::Collection(item.storageCollectionId());
106  auto job = new Akonadi::CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base, this);
107  QObject::connect(job, &KJob::result, this, &CalendarBasePrivate::collectionFetchResult);
108  mCollectionJobs.insert(job, collection.id());
109  }
110  } else {
111  mCollections.insert(collection.id(), collection);
112  incidence->setReadOnly(!(collection.rights() & Akonadi::Collection::CanChangeItem));
113  }
114  }
115 
116  mItemById.insert(item.id(), item);
117  mItemIdByUid.insert(uid, item.id());
118  mItemsByCollection.insert(item.storageCollectionId(), item);
119 
120  if (!incidence->hasRecurrenceId()) {
121  // Insert parent relationships
122  const QString parentUid = incidence->relatedTo();
123  if (!parentUid.isEmpty()) {
124  mParentUidToChildrenUid[parentUid].append(incidence->uid());
125  mUidToParent.insert(uid, parentUid);
126  }
127  }
128 
129  incidence->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id()));
130  // Must be the last one due to re-entrancy
131  const bool result = q->MemoryCalendar::addIncidence(incidence);
132  if (!result) {
133  qCritical() << "Error adding incidence " << itemToString(item);
134  Q_ASSERT(false);
135  }
136 }
137 
138 void CalendarBasePrivate::collectionFetchResult(KJob *job)
139 {
140  Akonadi::Collection::Id colid = mCollectionJobs.take(job);
141 
142  if (job->error()) {
143  qWarning() << "Error occurred: " << job->errorString();
144  return;
145  }
146 
147  auto fetchJob = qobject_cast<Akonadi::CollectionFetchJob *>(job);
148 
149  const Akonadi::Collection collection = fetchJob->collections().at(0);
150  if (collection.id() != colid) {
151  qCritical() << "Fetched the wrong collection, should fetch: " << colid << "fetched: " << collection.id();
152  }
153 
154  bool isReadOnly = !(collection.rights() & Akonadi::Collection::CanChangeItem);
155  const auto lst = mItemsByCollection.values(collection.id());
156  for (const Akonadi::Item &item : lst) {
157  KCalendarCore::Incidence::Ptr incidence = CalendarUtils::incidence(item);
158  incidence->setReadOnly(isReadOnly);
159  }
160 
161  mCollections.insert(collection.id(), collection);
162 
163  if (mCollectionJobs.isEmpty()) {
164  Q_EMIT fetchFinished();
165  }
166 }
167 
168 void CalendarBasePrivate::internalRemove(const Akonadi::Item &item)
169 {
170  Q_ASSERT(item.isValid());
171 
172  Incidence::Ptr tmp = CalendarUtils::incidence(item);
173  if (!tmp) {
174  qCritical() << "CalendarBase::internalRemove1: incidence is null, item.id=" << item.id();
175  return;
176  }
177 
178  // We want the one stored in the calendar
179  Incidence::Ptr incidence = q->incidence(tmp->uid(), tmp->recurrenceId());
180 
181  // Null incidence means it was deleted via CalendarBase::deleteIncidence(), but then
182  // the ETMCalendar received the monitor notification and tried to delete it again.
183  if (incidence) {
184  q->Calendar::notifyIncidenceAboutToBeDeleted(incidence);
185 
186  mItemById.remove(item.id());
187  // qCDebug(AKONADICALENDAR_LOG) << "Deleting incidence from calendar .id=" << item.id() << "uid=" << incidence->uid();
188  mItemIdByUid.remove(incidence->instanceIdentifier());
189 
190  mItemsByCollection.remove(item.storageCollectionId(), item);
191 
192  if (!incidence->hasRecurrenceId()) {
193  const QString uid = incidence->uid();
194  const QString parentUid = incidence->relatedTo();
195  mParentUidToChildrenUid.remove(uid);
196  if (!parentUid.isEmpty()) {
197  mParentUidToChildrenUid[parentUid].removeAll(uid);
198  mUidToParent.remove(uid);
199  }
200  }
201 
202  q->Calendar::setObserversEnabled(false);
203  // Must be the last one due to re-entrancy
204  const bool result = q->MemoryCalendar::deleteIncidence(incidence);
205  q->Calendar::setObserversEnabled(true);
206  q->Calendar::notifyIncidenceDeleted(incidence);
207  if (!result) {
208  qCritical() << "Error removing incidence " << itemToString(item);
209  Q_ASSERT(false);
210  }
211  } else {
212  qCWarning(AKONADICALENDAR_LOG) << "CalendarBase::internalRemove2: incidence is null, item.id=" << itemToString(item);
213  }
214 }
215 
216 void CalendarBasePrivate::slotDeleteFinished(int changeId,
217  const QVector<Akonadi::Item::Id> &itemIds,
218  IncidenceChanger::ResultCode resultCode,
219  const QString &errorMessage)
220 {
221  Q_UNUSED(changeId)
222  if (resultCode == IncidenceChanger::ResultCodeSuccess) {
223  for (const Akonadi::Item::Id &id : itemIds) {
224  if (mItemById.contains(id)) {
225  internalRemove(mItemById.value(id));
226  }
227  }
228  }
229 
230  Q_EMIT q->deleteFinished(resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage);
231 }
232 
233 void CalendarBasePrivate::slotCreateFinished(int changeId, const Akonadi::Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorMessage)
234 {
235  Q_UNUSED(changeId)
236  Q_UNUSED(item)
237  if (resultCode == IncidenceChanger::ResultCodeSuccess && !mListensForNewItems) {
238  Q_ASSERT(item.isValid());
239  Q_ASSERT(item.hasPayload<KCalendarCore::Incidence::Ptr>());
240  internalInsert(item);
241  }
242 
243  mLastCreationCancelled = (resultCode == IncidenceChanger::ResultCodeUserCanceled);
244 
245  Q_EMIT q->createFinished(resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage);
246 }
247 
248 void CalendarBasePrivate::slotModifyFinished(int changeId, const Akonadi::Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorMessage)
249 {
250  Q_UNUSED(changeId)
251  Q_UNUSED(item)
252  QString message = errorMessage;
253  if (resultCode == IncidenceChanger::ResultCodeSuccess) {
254  KCalendarCore::Incidence::Ptr incidence = CalendarUtils::incidence(item);
255  Q_ASSERT(incidence);
256  KCalendarCore::Incidence::Ptr localIncidence = q->incidence(incidence->instanceIdentifier());
257 
258  if (localIncidence) {
259  // update our local one
260  *(static_cast<KCalendarCore::IncidenceBase *>(localIncidence.data())) = *(incidence.data());
261  } else {
262  // This shouldn't happen, unless the incidence gets deleted between event loops
263  qCWarning(AKONADICALENDAR_LOG) << "CalendarBasePrivate::slotModifyFinished() Incidence was deleted already probably? id=" << item.id();
264  message = i18n("Could not find incidence to update, it probably was deleted recently.");
265  resultCode = IncidenceChanger::ResultCodeAlreadyDeleted;
266  }
267  }
268  Q_EMIT q->modifyFinished(resultCode == IncidenceChanger::ResultCodeSuccess, message);
269 }
270 
271 void CalendarBasePrivate::handleUidChange(const Akonadi::Item &oldItem, const Akonadi::Item &newItem, const QString &newIdentifier)
272 {
273  Q_ASSERT(oldItem.isValid());
274  Incidence::Ptr newIncidence = CalendarUtils::incidence(newItem);
275  Q_ASSERT(newIncidence);
276  Incidence::Ptr oldIncidence = CalendarUtils::incidence(oldItem);
277  Q_ASSERT(oldIncidence);
278 
279  const QString newUid = newIncidence->uid();
280  if (mItemIdByUid.contains(newIdentifier)) {
281  Incidence::Ptr oldIncidence = CalendarUtils::incidence(oldItem);
282 #if 0
283  qCWarning(AKONADICALENDAR_LOG) << "New uid shouldn't be known: " << newIdentifier << "; id="
284  << newItem.id() << "; oldItem.id=" << mItemIdByUid[newIdentifier]
285  << "; new summary= " << newIncidence->summary()
286  << "; new recurrenceId=" << newIncidence->recurrenceId()
287  << "; oldIncidence" << oldIncidence;
288 #endif
289  if (oldIncidence) {
290 #if 0
291  qCWarning(AKONADICALENDAR_LOG) << "; oldIncidence uid=" << oldIncidence->uid()
292  << "; oldIncidence recurrenceId = " << oldIncidence->recurrenceId()
293  << "; oldIncidence summary = " << oldIncidence->summary();
294 #endif
295  }
296  Q_ASSERT(false);
297  return;
298  }
299 
300  mItemIdByUid[newIdentifier] = newItem.id();
301 
302  // Get the real pointer
303  oldIncidence = q->MemoryCalendar::incidence(oldIncidence->uid());
304 
305  if (!oldIncidence) {
306  // How can this happen ?
307  qCWarning(AKONADICALENDAR_LOG) << "Couldn't find old incidence";
308  Q_ASSERT(false);
309  return;
310  }
311 
312  if (newIncidence->instanceIdentifier() == oldIncidence->instanceIdentifier()) {
313 #if 0
314  qCWarning(AKONADICALENDAR_LOG) << "New uid=" << newIncidence->uid() << "; old uid=" << oldIncidence->uid()
315  << "; new recurrenceId="
316  << newIncidence->recurrenceId()
317  << "; old recurrenceId=" << oldIncidence->recurrenceId()
318  << "; new summary = " << newIncidence->summary()
319  << "; old summary = " << oldIncidence->summary()
320  << "; id = " << newItem.id();
321 #endif
322  Q_ASSERT(false); // The reason we're here in the first place
323  return;
324  }
325 
326  mItemIdByUid.remove(oldIncidence->instanceIdentifier());
327  const QString oldUid = oldIncidence->uid();
328 
329  if (mParentUidToChildrenUid.contains(oldUid)) {
330  Q_ASSERT(!mParentUidToChildrenUid.contains(newIdentifier));
331  QStringList children = mParentUidToChildrenUid.value(oldUid);
332  mParentUidToChildrenUid.insert(newIdentifier, children);
333  mParentUidToChildrenUid.remove(oldUid);
334  }
335 
336  // Update internal maps of the base class, MemoryCalendar
337  q->setObserversEnabled(false);
338  q->MemoryCalendar::deleteIncidence(oldIncidence);
339  q->MemoryCalendar::addIncidence(newIncidence);
340 
341  newIncidence->setUid(oldUid); // We set and unset just to notify observers of a change.
342  q->setObserversEnabled(true);
343  newIncidence->setUid(newUid);
344 }
345 
346 void CalendarBasePrivate::handleParentChanged(const KCalendarCore::Incidence::Ptr &newIncidence)
347 {
348  Q_ASSERT(newIncidence);
349 
350  if (newIncidence->hasRecurrenceId()) { // These ones don't/shouldn't have a parent
351  return;
352  }
353 
354  const QString originalParentUid = mUidToParent.value(newIncidence->uid());
355  const QString newParentUid = newIncidence->relatedTo();
356 
357  if (originalParentUid == newParentUid) {
358  return; // nothing changed
359  }
360 
361  if (!originalParentUid.isEmpty()) {
362  // Remove this child from it's old parent:
363  Q_ASSERT(mParentUidToChildrenUid.contains(originalParentUid));
364  mParentUidToChildrenUid[originalParentUid].removeAll(newIncidence->uid());
365  }
366 
367  mUidToParent.remove(newIncidence->uid());
368 
369  if (!newParentUid.isEmpty()) {
370  // Deliver this child to it's new parent:
371  Q_ASSERT(!mParentUidToChildrenUid[newParentUid].contains(newIncidence->uid()));
372  mParentUidToChildrenUid[newParentUid].append(newIncidence->uid());
373  mUidToParent.insert(newIncidence->uid(), newParentUid);
374  }
375 }
376 
378  : MemoryCalendar(QTimeZone::systemTimeZone())
379  , d_ptr(new CalendarBasePrivate(this))
380 {
381  setParent(parent);
382  setDeletionTracking(false);
383 }
384 
385 CalendarBase::CalendarBase(CalendarBasePrivate *const dd, QObject *parent)
387  , d_ptr(dd)
388 {
389  setParent(parent);
390  setDeletionTracking(false);
391 }
392 
393 CalendarBase::~CalendarBase() = default;
394 
396 {
397  Q_D(const CalendarBase);
398  Akonadi::Item i;
399  auto it = d->mItemById.constFind(id);
400  if (it != d->mItemById.cend()) {
401  i = *it;
402  } else {
403  qCDebug(AKONADICALENDAR_LOG) << "Can't find any item with id " << id;
404  }
405  return i;
406 }
407 
409 {
410  Q_D(const CalendarBase);
411  Akonadi::Item i;
412 
413  if (uid.isEmpty()) {
414  return i;
415  }
416 
417  auto it = d->mItemIdByUid.constFind(uid);
418  if (it != d->mItemIdByUid.cend()) {
419  const Akonadi::Item::Id id = *it;
420  auto it2 = d->mItemById.constFind(id);
421  if (it2 == d->mItemById.cend()) {
422  qCritical() << "Item with id " << id << "(uid=" << uid << ") not found, but in uid map";
423  Q_ASSERT_X(false, "CalendarBase::item", "not in mItemById");
424  } else {
425  i = *it2;
426  }
427  } else {
428  qCDebug(AKONADICALENDAR_LOG) << "Can't find any incidence with uid " << uid;
429  }
430  return i;
431 }
432 
433 Item CalendarBase::item(const Incidence::Ptr &incidence) const
434 {
435  return incidence ? item(incidence->instanceIdentifier()) : Item();
436 }
437 
439 {
440  Q_D(const CalendarBase);
441 
442  Akonadi::Item::List result;
443  if (id == -1) {
444  result.reserve(d->mItemsByCollection.size());
445  }
446 
447  auto it = id == -1 ? d->mItemsByCollection.cbegin() : d->mItemsByCollection.constFind(id);
448  while (it != d->mItemsByCollection.cend() && (id == -1 || it.key() == id)) {
449  result.push_back(*it);
450  ++it;
451  }
452 
453  return result;
454 }
455 
457 {
459  items.reserve(incidences.size());
460 
461  for (const KCalendarCore::Incidence::Ptr &incidence : incidences) {
462  if (incidence) {
463  items << item(incidence->instanceIdentifier());
464  } else {
465  items << Akonadi::Item();
466  }
467  }
468 
469  return items;
470 }
471 
473 {
474  Q_D(const CalendarBase);
476 
477  if (d->mItemById.contains(parentId)) {
478  const Akonadi::Item item = d->mItemById.value(parentId);
479  Q_ASSERT(item.isValid());
480  KCalendarCore::Incidence::Ptr parent = CalendarUtils::incidence(item);
481 
482  if (parent) {
483  children = childIncidences(parent->uid());
484  } else {
485  Q_ASSERT(false);
486  }
487  }
488 
489  return children;
490 }
491 
493 {
494  Q_D(const CalendarBase);
496  const QStringList uids = d->mParentUidToChildrenUid.value(parentUid);
497  for (const QString &uid : uids) {
498  Incidence::Ptr child = incidence(uid);
499  if (child) {
500  children.append(child);
501  } else {
502  qCWarning(AKONADICALENDAR_LOG) << "Invalid child with uid " << uid;
503  }
504  }
505  return children;
506 }
507 
509 {
510  Q_D(const CalendarBase);
512 
513  if (d->mItemById.contains(parentId)) {
514  const Akonadi::Item item = d->mItemById.value(parentId);
515  Q_ASSERT(item.isValid());
516  KCalendarCore::Incidence::Ptr parent = CalendarUtils::incidence(item);
517 
518  if (parent) {
519  children = childItems(parent->uid());
520  } else {
521  Q_ASSERT(false);
522  }
523  }
524 
525  return children;
526 }
527 
529 {
530  Q_D(const CalendarBase);
532  const QStringList uids = d->mParentUidToChildrenUid.value(parentUid);
533  for (const QString &uid : uids) {
534  Akonadi::Item child = item(uid);
535  if (child.isValid() && child.hasPayload<KCalendarCore::Incidence::Ptr>()) {
536  children.append(child);
537  } else {
538  qCWarning(AKONADICALENDAR_LOG) << "Invalid child with uid " << uid;
539  }
540  }
541  return children;
542 }
543 
545 {
546  return addIncidence(event);
547 }
548 
550 {
551  return deleteIncidence(event);
552 }
553 
555 {
556  return addIncidence(todo);
557 }
558 
560 {
561  return deleteIncidence(todo);
562 }
563 
565 {
566  return addIncidence(journal);
567 }
568 
570 {
571  return deleteIncidence(journal);
572 }
573 
575 {
576  // TODO: Parent for dialogs
577  Q_D(CalendarBase);
578 
579  // User canceled on the collection selection dialog
580  if (batchAdding() && d->mBatchInsertionCancelled) {
581  return false;
582  }
583 
584  d->mLastCreationCancelled = false;
585 
586  Akonadi::Collection collection;
587 
588  if (batchAdding() && d->mCollectionForBatchInsertion.isValid()) {
589  collection = d->mCollectionForBatchInsertion;
590  }
591 
592  if (incidence->hasRecurrenceId() && !collection.isValid()) {
593  // We are creating an exception, reuse the same collection that the main incidence uses
594  Item mainItem = item(incidence->uid());
595  if (mainItem.isValid()) {
596  collection = Collection(mainItem.storageCollectionId());
597  }
598  }
599 
600  const int changeId = d->mIncidenceChanger->createIncidence(incidence, collection);
601 
602  if (batchAdding()) {
603  const Akonadi::Collection lastCollection = d->mIncidenceChanger->lastCollectionUsed();
604  if (changeId != -1 && !lastCollection.isValid()) {
605  d->mBatchInsertionCancelled = true;
606  } else if (lastCollection.isValid() && !d->mCollectionForBatchInsertion.isValid()) {
607  d->mCollectionForBatchInsertion = d->mIncidenceChanger->lastCollectionUsed();
608  }
609  }
610 
611  return changeId != -1;
612 }
613 
615 {
616  Q_D(CalendarBase);
617  Q_ASSERT(incidence);
618  if (!incidence->hasRecurrenceId() && incidence->recurs()) {
619  deleteIncidenceInstances(incidence);
620  }
621  Akonadi::Item item_ = item(incidence->instanceIdentifier());
622  return -1 != d->mIncidenceChanger->deleteIncidence(item_);
623 }
624 
626 {
627  Q_D(CalendarBase);
628  Q_ASSERT(newIncidence);
629  Akonadi::Item item_ = item(newIncidence->instanceIdentifier());
630  item_.setPayload<KCalendarCore::Incidence::Ptr>(newIncidence);
631  return -1 != d->mIncidenceChanger->modifyIncidence(item_);
632 }
633 
634 IncidenceChanger *CalendarBase::incidenceChanger() const
635 {
636  Q_D(const CalendarBase);
637  return d->mIncidenceChanger;
638 }
639 
641 {
643 }
644 
646 {
647  Q_D(CalendarBase);
648  d->mCollectionForBatchInsertion = Akonadi::Collection();
649  d->mBatchInsertionCancelled = false;
651 }
652 
654 {
655  return true;
656 }
657 
658 #include "moc_calendarbase.cpp"
659 #include "moc_calendarbase_p.cpp"
KCOREADDONS_EXPORT void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
QString id() const
bool isValid() const
bool isValid() const
QString displayName() const
void append(const T &value)
Akonadi::Item::List itemList(const KCalendarCore::Incidence::List &incidenceList) const
Returns the item list that corresponds to the incidenceList.
Collection parentCollection() const
virtual QString errorString() const
virtual bool isLoaded() const
Returns if the calendar already finished loading.
const QObjectList & children() const const
Akonadi::Item item(const QString &uid) const
Returns the Item containing the incidence with uid uid or an invalid Item if the incidence isn&#39;t foun...
bool addEvent(const KCalendarCore::Event::Ptr &event) override
Adds an Event to the calendar.
Akonadi::Item::List items(Akonadi::Collection::Id=-1) const
Returns the list of items contained in this calendar that belong to the specified collection...
bool deleteTodo(const KCalendarCore::Todo::Ptr &todo) override
Deletes a Todo from the calendar.
bool deleteEvent(const KCalendarCore::Event::Ptr &event) override
Deletes an Event from the calendar.
T * data() const const
void setPayload(const T &p)
Todo::Ptr todo(const QString &uid, const QDateTime &recurrenceId={}) const override
bool addIncidence(const KCalendarCore::Incidence::Ptr &incidence) override
Adds an incidence to the calendar.
bool modifyIncidence(const KCalendarCore::Incidence::Ptr &newIncidence)
Modifies an incidence.
T value(int i) const const
Id id() const
QString number(int n, int base)
void setDeletionTracking(bool enable)
MemoryCalendar(const QTimeZone &timeZone)
bool isEmpty() const const
Journal::Ptr journal(const QString &uid, const QDateTime &recurrenceId={}) const override
QTimeZone systemTimeZone()
Event::Ptr event(const QString &uid, const QDateTime &recurrenceId={}) const override
KCalendarCore::Incidence::List childIncidences(const QString &parentUid) const
Returns the child incidences of the parent identified by parentUid.
Rights rights() const
QString mimeType() const
virtual void endBatchAdding()
void reserve(int size)
void setParent(QObject *parent)
bool addJournal(const KCalendarCore::Journal::Ptr &journal) override
Adds a Journal to the calendar.
~CalendarBase() override
Destroys the calendar.
Akonadi::Item::List childItems(const QString &parentUid) const
Returns the child items of the parent identified by parentUid.
QString i18n(const char *text, const TYPE &arg...)
virtual void startBatchAdding()
bool batchAdding() const
bool addTodo(const KCalendarCore::Todo::Ptr &todo) override
Adds a Todo to the calendar.
FreeBusyManager::Singleton.
Akonadi::IncidenceChanger * incidenceChanger() const
Returns the IncidenceChanger used by this calendar to make changes in akonadi.
Incidence::Ptr incidence(const QString &uid, const QDateTime &recurrenceId={}) const
void endBatchAdding() override
Tells the Calendar that you stopped adding a batch of incidences.
void push_back(const T &value)
void startBatchAdding() override
Call this to tell the calendar that you&#39;re adding a batch of incidences.
bool deleteJournal(const KCalendarCore::Journal::Ptr &journal) override
Deletes a Journal from the calendar.
Collection::Id storageCollectionId() const
void result(KJob *job)
The base class for all akonadi aware calendars.
Definition: calendarbase.h:37
bool deleteIncidence(const KCalendarCore::Incidence::Ptr &incidence) override
Deletes an incidence from the calendar.
CalendarBase(QObject *parent=nullptr)
Constructs a CalendarBase object.
bool hasPayload() const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
int size() const const
bool isReadOnly
virtual Incidence::List incidences() const
int error() const
bool deleteIncidenceInstances(const Incidence::Ptr &incidence) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Dec 6 2021 23:02:55 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.