• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.14
  • kdepimlibs
  • akonadi
  • calendar
etmcalendar.cpp
1 /*
2  Copyright (C) 2011-2013 Sérgio Martins <iamsergio@gmail.com>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "etmcalendar.h"
21 #include "etmcalendar_p.h"
22 #include "blockalarmsattribute.h"
23 #include "calendarmodel_p.h"
24 #include "kcolumnfilterproxymodel_p.h"
25 #include "calfilterproxymodel_p.h"
26 #include "utils_p.h"
27 
28 #include <akonadi/item.h>
29 #include <akonadi/session.h>
30 #include <akonadi/collection.h>
31 #include <akonadi/changerecorder.h>
32 #include <akonadi/itemfetchscope.h>
33 #include <akonadi/entitydisplayattribute.h>
34 #include <akonadi/entitymimetypefiltermodel.h>
35 #include <akonadi/collectionfilterproxymodel.h>
36 #include <KSelectionProxyModel>
37 #include <KDescendantsProxyModel>
38 
39 #include <QItemSelectionModel>
40 #include <QTreeView>
41 
42 using namespace Akonadi;
43 using namespace KCalCore;
44 
45 //TODO: implement batchAdding
46 
47 ETMCalendarPrivate::ETMCalendarPrivate(ETMCalendar *qq) : CalendarBasePrivate(qq)
48  , mETM(0)
49  , mFilteredETM(0)
50  , mCheckableProxyModel(0)
51  , mCollectionProxyModel(0)
52  , mCalFilterProxyModel(0)
53  , mSelectionProxy(0)
54  , mCollectionFilteringEnabled(true)
55  , q(qq)
56 {
57  mListensForNewItems = true;
58 }
59 
60 void ETMCalendarPrivate::init()
61 {
62  if (!mETM) {
63  Akonadi::Session *session = new Akonadi::Session("ETMCalendar", q);
64  Akonadi::ChangeRecorder *monitor = new Akonadi::ChangeRecorder(q);
65  connect(monitor, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)),
66  SLOT(onCollectionChanged(Akonadi::Collection,QSet<QByteArray>)));
67 
68  Akonadi::ItemFetchScope scope;
69  scope.fetchFullPayload(true);
70  scope.fetchAttribute<Akonadi::EntityDisplayAttribute>();
71 
72  monitor->setSession(session);
73  monitor->setCollectionMonitored(Akonadi::Collection::root());
74  monitor->fetchCollection(true);
75  monitor->setItemFetchScope(scope);
76 
77  QStringList allMimeTypes;
78  allMimeTypes << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType()
79  << KCalCore::Journal::journalMimeType();
80 
81  foreach(const QString &mimetype, allMimeTypes) {
82  monitor->setMimeTypeMonitored(mimetype, mMimeTypes.isEmpty() || mMimeTypes.contains(mimetype));
83  }
84 
85  mETM = CalendarModel::create(monitor);
86  mETM->setObjectName("ETM");
87  }
88 
89  setupFilteredETM();
90 
91  connect(q, SIGNAL(filterChanged()), SLOT(onFilterChanged()));
92 
93  connect(mETM.data(), SIGNAL(collectionPopulated(Akonadi::Collection::Id)),
94  SLOT(onCollectionPopulated(Akonadi::Collection::Id)));
95  connect(mETM.data(), SIGNAL(rowsInserted(QModelIndex,int,int)),
96  SLOT(onRowsInserted(QModelIndex,int,int)));
97  connect(mETM.data(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
98  SLOT(onDataChanged(QModelIndex,QModelIndex)));
99  connect(mETM.data(), SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
100  SLOT(onRowsMoved(QModelIndex,int,int,QModelIndex,int)));
101  connect(mETM.data(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
102  SLOT(onRowsRemoved(QModelIndex,int,int)));
103 
104  connect(mFilteredETM, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
105  SLOT(onDataChangedInFilteredModel(QModelIndex,QModelIndex)));
106  connect(mFilteredETM, SIGNAL(layoutChanged()),
107  SLOT(onLayoutChangedInFilteredModel()));
108  connect(mFilteredETM, SIGNAL(modelReset()),
109  SLOT(onModelResetInFilteredModel()));
110  connect(mFilteredETM, SIGNAL(rowsInserted(QModelIndex,int,int)),
111  SLOT(onRowsInsertedInFilteredModel(QModelIndex,int,int)));
112  connect(mFilteredETM, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
113  SLOT(onRowsAboutToBeRemovedInFilteredModel(QModelIndex,int,int)));
114 
115  loadFromETM();
116 }
117 
118 void ETMCalendarPrivate::onCollectionChanged(const Akonadi::Collection &collection,
119  const QSet<QByteArray> &attributeNames)
120 {
121  Q_ASSERT(collection.isValid());
122  // Is the collection changed to read-only, we update all Incidences
123  if (attributeNames.contains("AccessRights")) {
124  Akonadi::Item::List items = q->items();
125  foreach(const Akonadi::Item &item, items) {
126  if (item.storageCollectionId() == collection.id()) {
127  KCalCore::Incidence::Ptr incidence = CalendarUtils::incidence(item);
128  if (incidence)
129  incidence->setReadOnly(!(collection.rights() & Akonadi::Collection::CanChangeItem));
130  }
131  }
132  }
133 
134  emit q->collectionChanged(collection, attributeNames);
135 }
136 
137 void ETMCalendarPrivate::setupFilteredETM()
138 {
139  // We're only interested in the CollectionTitle column
140  KColumnFilterProxyModel *columnFilterProxy = new KColumnFilterProxyModel(this);
141  columnFilterProxy->setSourceModel(mETM.data());
142  columnFilterProxy->setVisibleColumn(CalendarModel::CollectionTitle);
143  columnFilterProxy->setObjectName("Remove columns");
144 
145  mCollectionProxyModel = new Akonadi::CollectionFilterProxyModel(this);
146  mCollectionProxyModel->setObjectName("Only show collections");
147  mCollectionProxyModel->setDynamicSortFilter(true);
148  mCollectionProxyModel->addMimeTypeFilter(QString::fromLatin1("text/calendar"));
149  mCollectionProxyModel->setExcludeVirtualCollections(true);
150  mCollectionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
151  mCollectionProxyModel->setSourceModel(columnFilterProxy);
152 
153  // Keep track of selected items.
154  QItemSelectionModel* selectionModel = new QItemSelectionModel(mCollectionProxyModel);
155  selectionModel->setObjectName("Calendar Selection Model");
156 
157  // Make item selection work by means of checkboxes.
158  mCheckableProxyModel = new CheckableProxyModel(this);
159  mCheckableProxyModel->setSelectionModel(selectionModel);
160  mCheckableProxyModel->setSourceModel(mCollectionProxyModel);
161  mCheckableProxyModel->setObjectName("Add checkboxes");
162 
163  mSelectionProxy = new KSelectionProxyModel(selectionModel, this);
164  mSelectionProxy->setObjectName("Only show items of selected collection");
165  mSelectionProxy->setFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection);
166  mSelectionProxy->setSourceModel(mETM.data());
167 
168  mCalFilterProxyModel = new CalFilterProxyModel(this);
169  mCalFilterProxyModel->setFilter(q->filter());
170  mCalFilterProxyModel->setSourceModel(mSelectionProxy);
171  mCalFilterProxyModel->setObjectName("KCalCore::CalFilter filtering");
172 
173  mFilteredETM = new Akonadi::EntityMimeTypeFilterModel(this);
174  mFilteredETM->setSourceModel(mCalFilterProxyModel);
175  mFilteredETM->setHeaderGroup(Akonadi::EntityTreeModel::ItemListHeaders);
176  mFilteredETM->setSortRole(CalendarModel::SortRole);
177  mFilteredETM->setObjectName("Show headers");
178 
179 #ifdef AKONADI_CALENDAR_DEBUG_MODEL
180  QTreeView *view = new QTreeView;
181  view->setModel(mFilteredETM);
182  view->show();
183 #endif
184 }
185 
186 ETMCalendarPrivate::~ETMCalendarPrivate()
187 {
188 }
189 
190 void ETMCalendarPrivate::loadFromETM()
191 {
192  itemsAdded(itemsFromModel(mFilteredETM));
193 }
194 
195 void ETMCalendarPrivate::clear()
196 {
197  mCollectionMap.clear();
198  mItemsByCollection.clear();
199 
200  itemsRemoved(mItemById.values());
201 
202  if (!mItemById.isEmpty()) {
203  // This never happens
204  kDebug() << "This shouldnt happen: !mItemById.isEmpty()";
205  foreach(Akonadi::Item::Id id, mItemById.keys()) {
206  kDebug() << "Id = " << id;
207  }
208 
209  mItemById.clear();
210  //Q_ASSERT(false); // TODO: discover why this happens
211  }
212 
213  if (!mItemIdByUid.isEmpty()) {
214  // This never happens
215  kDebug() << "This shouldnt happen: !mItemIdByUid.isEmpty()";
216  foreach(const QString &uid, mItemIdByUid.keys()) {
217  kDebug() << "uid: " << uid;
218  }
219  mItemIdByUid.clear();
220  //Q_ASSERT(false);
221  }
222  mParentUidToChildrenUid.clear();
223  //m_virtualItems.clear();
224 }
225 
226 Akonadi::Item::List ETMCalendarPrivate::itemsFromModel(const QAbstractItemModel *model,
227  const QModelIndex &parentIndex,
228  int start, int end)
229 {
230  const int endRow = end >= 0 ? end : model->rowCount(parentIndex) - 1;
231  Akonadi::Item::List items;
232  int row = start;
233  QModelIndex i = model->index(row, 0, parentIndex);
234  while (row <= endRow) {
235  const Akonadi::Item item = itemFromIndex(i);
236  if (item.hasPayload<KCalCore::Incidence::Ptr>()) {
237  items << item;
238  } else {
239  const QModelIndex childIndex = i.child(0, 0);
240  if (childIndex.isValid()) {
241  items << itemsFromModel(model, i);
242  }
243  }
244  ++row;
245  i = i.sibling(row, 0);
246  }
247  return items;
248 }
249 
250 Akonadi::Collection::List ETMCalendarPrivate::collectionsFromModel(const QAbstractItemModel *model,
251  const QModelIndex &parentIndex,
252  int start, int end)
253 {
254  const int endRow = end >= 0 ? end : model->rowCount(parentIndex) - 1;
255  Akonadi::Collection::List collections;
256  int row = start;
257  QModelIndex i = model->index(row, 0, parentIndex);
258  while (row <= endRow) {
259  const Akonadi::Collection collection = collectionFromIndex(i);
260  if (collection.isValid()) {
261  collections << collection;
262  QModelIndex childIndex = i.child(0, 0);
263  if (childIndex.isValid()) {
264  collections << collectionsFromModel(model, i);
265  }
266  }
267  ++row;
268  i = i.sibling(row, 0);
269  }
270  return collections;
271 }
272 
273 Akonadi::Item ETMCalendarPrivate::itemFromIndex(const QModelIndex &idx)
274 {
275  Akonadi::Item item = idx.data(Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
276  item.setParentCollection(
277  idx.data(Akonadi::EntityTreeModel::ParentCollectionRole).value<Akonadi::Collection>());
278  return item;
279 }
280 
281 void ETMCalendarPrivate::itemsAdded(const Akonadi::Item::List &items)
282 {
283  if (!items.isEmpty()) {
284  foreach(const Akonadi::Item &item, items) {
285  internalInsert(item);
286  }
287 
288  Akonadi::Collection::Id id = items.first().storageCollectionId();
289  if (mPopulatedCollectionIds.contains(id)) {
290  // If the collection isn't populated yet, it will be sent later
291  // Saves some cpu cycles
292  emit q->calendarChanged();
293  }
294  }
295 }
296 
297 void ETMCalendarPrivate::itemsRemoved(const Akonadi::Item::List &items)
298 {
299  foreach(const Akonadi::Item &item, items) {
300  internalRemove(item);
301  }
302  emit q->calendarChanged();
303 }
304 
305 Akonadi::Collection ETMCalendarPrivate::collectionFromIndex(const QModelIndex &index)
306 {
307  return index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
308 }
309 
310 void ETMCalendarPrivate::onRowsInserted(const QModelIndex &index,
311  int start, int end)
312 {
313  Akonadi::Collection::List collections = collectionsFromModel(mETM.data(), index,
314  start, end);
315 
316  foreach(const Akonadi::Collection &collection, collections) {
317  mCollectionMap[collection.id()] = collection;
318  }
319 
320  if (!collections.isEmpty())
321  emit q->collectionsAdded(collections);
322 }
323 
324 void ETMCalendarPrivate::onCollectionPopulated(Akonadi::Collection::Id id)
325 {
326  mPopulatedCollectionIds.insert(id);
327  emit q->calendarChanged();
328 }
329 
330 void ETMCalendarPrivate::onRowsRemoved(const QModelIndex &index, int start, int end)
331 {
332  Akonadi::Collection::List collections = collectionsFromModel(mETM.data(), index, start, end);
333  foreach(const Akonadi::Collection &collection, collections) {
334  mCollectionMap.remove(collection.id());
335  }
336 
337  if (!collections.isEmpty())
338  emit q->collectionsRemoved(collections);
339 }
340 
341 void ETMCalendarPrivate::onDataChanged(const QModelIndex &topLeft,
342  const QModelIndex &bottomRight)
343 {
344  // We only update collections, because items are handled in the filtered model
345  Q_ASSERT(topLeft.row() <= bottomRight.row());
346  const int endRow = bottomRight.row();
347  QModelIndex i(topLeft);
348  int row = i.row();
349  while (row <= endRow) {
350  const Akonadi::Collection col = collectionFromIndex(i);
351  if (col.isValid()) {
352  // Attributes might have changed, store the new collection and discard the old one
353  mCollectionMap.insert(col.id(), col);
354  }
355  ++row;
356  }
357 }
358 
359 void ETMCalendarPrivate::onRowsMoved(const QModelIndex &sourceParent,
360  int sourceStart,
361  int sourceEnd,
362  const QModelIndex &destinationParent,
363  int destinationRow)
364 {
365  //TODO
366  Q_UNUSED(sourceParent);
367  Q_UNUSED(sourceStart);
368  Q_UNUSED(sourceEnd);
369  Q_UNUSED(destinationParent);
370  Q_UNUSED(destinationRow);
371 }
372 
373 void ETMCalendarPrivate::onLayoutChangedInFilteredModel()
374 {
375  clear();
376  loadFromETM();
377 }
378 
379 void ETMCalendarPrivate::onModelResetInFilteredModel()
380 {
381  clear();
382  loadFromETM();
383 }
384 
385 void ETMCalendarPrivate::onDataChangedInFilteredModel(const QModelIndex &topLeft,
386  const QModelIndex &bottomRight)
387 {
388  Q_ASSERT(topLeft.row() <= bottomRight.row());
389  const int endRow = bottomRight.row();
390  QModelIndex i(topLeft);
391  int row = i.row();
392  while (row <= endRow) {
393  const Akonadi::Item item = itemFromIndex(i);
394  if (item.isValid() && item.hasPayload<KCalCore::Incidence::Ptr>())
395  updateItem(item);
396 
397  ++row;
398  i = i.sibling(row, topLeft.column());
399  }
400 
401  emit q->calendarChanged();
402 }
403 
404 void ETMCalendarPrivate::updateItem(const Akonadi::Item &item)
405 {
406  Incidence::Ptr newIncidence = CalendarUtils::incidence(item);
407  Q_ASSERT(newIncidence);
408  Q_ASSERT(!newIncidence->uid().isEmpty());
409  newIncidence->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id()));
410  IncidenceBase::Ptr existingIncidence = q->incidence(newIncidence->uid(), newIncidence->recurrenceId());
411 
412  if (!existingIncidence && !mItemById.contains(item.id())) {
413  // We don't know about this one because it was discarded, for example because of not having DTSTART
414  return;
415  }
416 
417  mItemsByCollection.insert(item.storageCollectionId(), item);
418  Akonadi::Item oldItem = mItemById.value(item.id());
419 
420  if (existingIncidence) {
421  // We set the payload so that the internal incidence pointer and the one in mItemById stay the same
422  Akonadi::Item updatedItem = item;
423  updatedItem.setPayload<KCalCore::Incidence::Ptr>(existingIncidence.staticCast<KCalCore::Incidence>());
424  mItemById.insert(item.id(), updatedItem); // The item needs updating too, revision changed.
425 
426  // Check if RELATED-TO changed, updating parenting information
427  handleParentChanged(newIncidence);
428  *(existingIncidence.data()) = *(newIncidence.data());
429  } else {
430  mItemById.insert(item.id(), item); // The item needs updating too, revision changed.
431  // The item changed it's UID, update our maps, the Google resource changes the UID when we create incidences.
432  handleUidChange(oldItem, item, newIncidence->instanceIdentifier());
433  }
434 }
435 
436 void ETMCalendarPrivate::onRowsInsertedInFilteredModel(const QModelIndex &index,
437  int start, int end)
438 {
439  itemsAdded(itemsFromModel(mFilteredETM, index, start, end));
440 }
441 
442 void ETMCalendarPrivate::onRowsAboutToBeRemovedInFilteredModel(const QModelIndex &index,
443  int start, int end)
444 {
445  itemsRemoved(itemsFromModel(mFilteredETM, index, start, end));
446 }
447 
448 void ETMCalendarPrivate::onFilterChanged()
449 {
450  mCalFilterProxyModel->setFilter(q->filter());
451 }
452 
453 ETMCalendar::ETMCalendar(QObject *parent) : CalendarBase(new ETMCalendarPrivate(this), parent)
454 {
455  Q_D(ETMCalendar);
456  d->init();
457 }
458 
459 ETMCalendar::ETMCalendar(const QStringList &mimeTypes, QObject *parent) : CalendarBase(new ETMCalendarPrivate(this), parent)
460 {
461  Q_D(ETMCalendar);
462  d->mMimeTypes = mimeTypes;
463  d->init();
464 }
465 
466 ETMCalendar::ETMCalendar(ETMCalendar *other, QObject *parent)
467  : CalendarBase(new ETMCalendarPrivate(this), parent)
468 {
469  Q_D(ETMCalendar);
470 
471  CalendarModel *model = qobject_cast<Akonadi::CalendarModel*>(other->entityTreeModel());
472  if (model) {
473  d->mETM = model->weakPointer().toStrongRef();
474  }
475 
476  d->init();
477 }
478 
479 ETMCalendar::~ETMCalendar()
480 {
481 }
482 
483 //TODO: move this up?
484 Akonadi::Collection ETMCalendar::collection(Akonadi::Collection::Id id) const
485 {
486  Q_D(const ETMCalendar);
487  return d->mCollectionMap.value(id);
488 }
489 
490 bool ETMCalendar::hasRight(const QString &uid, Akonadi::Collection::Right right) const
491 {
492  return hasRight(item(uid), right);
493 }
494 
495 bool ETMCalendar::hasRight(const Akonadi::Item &item, Akonadi::Collection::Right right) const
496 {
497  // if the users changes the rights, item.parentCollection()
498  // can still have the old rights, so we use call collection()
499  // which returns the updated one
500  const Akonadi::Collection col = collection(item.storageCollectionId());
501  return col.rights() & right;
502 }
503 
504 QAbstractItemModel *ETMCalendar::model() const
505 {
506  Q_D(const ETMCalendar);
507  return d->mFilteredETM;
508 }
509 
510 KCheckableProxyModel *ETMCalendar::checkableProxyModel() const
511 {
512  Q_D(const ETMCalendar);
513  return d->mCheckableProxyModel;
514 }
515 
516 KCalCore::Alarm::List ETMCalendar::alarms(const KDateTime &from,
517  const KDateTime &to,
518  bool excludeBlockedAlarms) const
519 {
520  Q_D(const ETMCalendar);
521  KCalCore::Alarm::List alarmList;
522  QHashIterator<Akonadi::Item::Id, Akonadi::Item> i(d->mItemById);
523  while (i.hasNext()) {
524  const Akonadi::Item item = i.next().value();
525 
526  BlockAlarmsAttribute *blockedAttr = 0;
527 
528  if (excludeBlockedAlarms) {
529  // take the collection from m_collectionMap, because we need the up-to-date collection attrs
530  Akonadi::Collection parentCollection = d->mCollectionMap.value(item.storageCollectionId());
531  if (parentCollection.isValid() && parentCollection.hasAttribute<BlockAlarmsAttribute>()) {
532  blockedAttr = parentCollection.attribute<BlockAlarmsAttribute>();
533  if (blockedAttr->isAlarmTypeBlocked(Alarm::Audio) && blockedAttr->isAlarmTypeBlocked(Alarm::Display)
534  && blockedAttr->isAlarmTypeBlocked(Alarm::Email) && blockedAttr->isAlarmTypeBlocked(Alarm::Procedure))
535  {
536  continue;
537  }
538  }
539  }
540 
541  KCalCore::Incidence::Ptr incidence;
542  if (item.isValid() && item.hasPayload<KCalCore::Incidence::Ptr>()) {
543  incidence = KCalCore::Incidence::Ptr(item.payload<KCalCore::Incidence::Ptr>()->clone());
544  } else {
545  continue;
546  }
547 
548  if (!incidence) {
549  continue;
550  }
551 
552  if (blockedAttr) {
553  // Remove all blocked types of alarms
554  Q_FOREACH(const KCalCore::Alarm::Ptr &alarm, incidence->alarms()) {
555  if (blockedAttr->isAlarmTypeBlocked(alarm->type())) {
556  incidence->removeAlarm(alarm);
557  }
558  }
559  }
560 
561  if (incidence->alarms().isEmpty()) {
562  continue;
563  }
564 
565  Alarm::List tmpList;
566  if (incidence->recurs()) {
567  appendRecurringAlarms(tmpList, incidence, from, to);
568  } else {
569  appendAlarms(tmpList, incidence, from, to);
570  }
571 
572  // We need to tag them with the incidence uid in case
573  // the caller will need it, because when we get out of
574  // this scope the incidence will be destroyed.
575  QVectorIterator<Alarm::Ptr> a(tmpList);
576  while (a.hasNext()) {
577  a.next()->setCustomProperty("ETMCalendar", "parentUid", incidence->uid());
578  }
579  alarmList += tmpList;
580  }
581  return alarmList;
582 }
583 
584 Akonadi::EntityTreeModel *ETMCalendar::entityTreeModel() const
585 {
586  Q_D(const ETMCalendar);
587  return d->mETM.data();
588 }
589 
590 void ETMCalendar::setCollectionFilteringEnabled(bool enable)
591 {
592  Q_D(ETMCalendar);
593  if (d->mCollectionFilteringEnabled != enable) {
594  d->mCollectionFilteringEnabled = enable;
595  if (enable) {
596  d->mSelectionProxy->setSourceModel(d->mETM.data());
597  QAbstractItemModel *oldModel = d->mCalFilterProxyModel->sourceModel();
598  d->mCalFilterProxyModel->setSourceModel(d->mSelectionProxy);
599  delete qobject_cast<KDescendantsProxyModel *>(oldModel);
600  } else {
601  KDescendantsProxyModel *flatner = new KDescendantsProxyModel(this);
602  flatner->setSourceModel(d->mETM.data());
603  d->mCalFilterProxyModel->setSourceModel(flatner);
604  }
605  }
606 }
607 
608 bool ETMCalendar::collectionFilteringEnabled() const
609 {
610  Q_D(const ETMCalendar);
611  return d->mCollectionFilteringEnabled;
612 }
613 
614 bool ETMCalendar::isLoaded() const
615 {
616  Q_D(const ETMCalendar);
617 
618  if (!entityTreeModel()->isCollectionTreeFetched())
619  return false;
620 
621  Akonadi::Collection::List collections = d->mCollectionMap.values();
622  foreach (const Akonadi::Collection &collection, collections) {
623  if (!entityTreeModel()->isCollectionPopulated(collection.id()))
624  return false;
625  }
626 
627  return true;
628 }
629 
630 #include "moc_etmcalendar.cpp"
631 #include "moc_etmcalendar_p.cpp"
QModelIndex
Akonadi::ItemFetchScope::fetchAttribute
void fetchAttribute(const QByteArray &type, bool fetch=true)
Sets whether the attribute of the given type should be fetched.
Definition: itemfetchscope.cpp:80
QAbstractItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const =0
QList::remove
iterator remove(iterator pos)
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
Akonadi::CollectionFilterProxyModel
A proxy model that filters collections by mime type.
Definition: collectionfilterproxymodel.h:54
Akonadi::Monitor::setSession
void setSession(Akonadi::Session *session)
Sets the session used by the Monitor to communicate with the Akonadi server.
Definition: monitor.cpp:348
QSortFilterProxyModel::setSourceModel
virtual void setSourceModel(QAbstractItemModel *sourceModel)
Akonadi::Monitor::setMimeTypeMonitored
void setMimeTypeMonitored(const QString &mimetype, bool monitored=true)
Sets whether items of the specified mime type shall be monitored for changes.
Definition: monitor.cpp:126
Akonadi::Monitor::setCollectionMonitored
void setCollectionMonitored(const Collection &collection, bool monitored=true)
Sets whether the specified collection shall be monitored for changes.
Definition: monitor.cpp:66
Akonadi::ETMCalendar::entityTreeModel
Akonadi::EntityTreeModel * entityTreeModel() const
Returns the underlying EntityTreeModel.
Definition: etmcalendar.cpp:584
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::KColumnFilterProxyModel
Filter model to make only certain columns of a model visible.
Definition: kcolumnfilterproxymodel_p.h:38
Akonadi::Monitor::setItemFetchScope
void setItemFetchScope(const ItemFetchScope &fetchScope)
Sets the item fetch scope.
Definition: monitor.cpp:231
Akonadi::Entity::Id
qint64 Id
Describes the unique id type.
Definition: entity.h:65
Akonadi::CalendarBase::item
Akonadi::Item item(const QString &uid) const
Returns the Item containing the incidence with uid uid or an invalid Item if the incidence isn't foun...
Definition: calendarbase.cpp:402
QVariant::value
T value() const
Akonadi::Collection::CanChangeItem
Can change items in this collection.
Definition: collection.h:88
Akonadi::EntityMimeTypeFilterModel
A proxy model that filters entities by mime type.
Definition: entitymimetypefiltermodel.h:61
Akonadi::ItemFetchScope::fetchFullPayload
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
Definition: itemfetchscope.cpp:70
QString::clear
void clear()
Akonadi::Entity::attribute
Attribute * attribute(const QByteArray &name) const
Returns the attribute of the given type name if available, 0 otherwise.
Definition: entity.cpp:167
QModelIndex::isValid
bool isValid() const
QString::number
QString number(int n, int base)
QObject
Akonadi::ETMCalendar::collectionFilteringEnabled
bool collectionFilteringEnabled() const
Returns whether collection filtering is enabled.
Definition: etmcalendar.cpp:608
Akonadi::ETMCalendar::model
QAbstractItemModel * model() const
Convenience method to access the contents of this KCalCore::Calendar through a QAIM interface...
Definition: etmcalendar.cpp:504
Akonadi::ETMCalendar::checkableProxyModel
KCheckableProxyModel * checkableProxyModel() const
Returns the KCheckableProxyModel used to select from which collections should the calendar be populat...
Definition: etmcalendar.cpp:510
QList::isEmpty
bool isEmpty() const
QObject::setObjectName
void setObjectName(const QString &name)
QHashIterator
QString::isEmpty
bool isEmpty() const
QModelIndex::row
int row() const
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::ETMCalendar::ETMCalendar
ETMCalendar(QObject *parent=0)
Constructs a new ETMCalendar.
Definition: etmcalendar.cpp:453
Akonadi::Session
A communication session with the Akonadi storage.
Definition: session.h:59
QSet< QByteArray >
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:336
QString
QList
Akonadi::EntityTreeModel::ParentCollectionRole
The parent collection of the entity.
Definition: entitytreemodel.h:341
Akonadi::Monitor::fetchCollection
void fetchCollection(bool enable)
Enables automatic fetching of changed collections from the Akonadi storage.
Definition: monitor.cpp:219
Akonadi::Entity::id
Id id() const
Returns the unique identifier of the entity.
Definition: entity.cpp:72
QStringList
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
Akonadi::ItemFetchScope
Specifies which parts of an item should be fetched from the Akonadi storage.
Definition: itemfetchscope.h:69
QSet::contains
bool contains(const T &value) const
QModelIndex::child
QModelIndex child(int row, int column) const
QVectorIterator
Akonadi::EntityTreeModel::ItemListHeaders
Header information for a list of items.
Definition: entitytreemodel.h:386
Akonadi::ETMCalendar::collection
Akonadi::Collection collection(Akonadi::Collection::Id) const
Returns the collection having id.
Definition: etmcalendar.cpp:484
Akonadi::BlockAlarmsAttribute::isAlarmTypeBlocked
bool isAlarmTypeBlocked(KCalCore::Alarm::Type type) const
Returns whether given alarm type is blocked or not.
Definition: blockalarmsattribute.cpp:77
Akonadi::Collection::Right
Right
Describes rights of a collection.
Definition: collection.h:86
QModelIndex::data
QVariant data(int role) const
Akonadi::EntityTreeModel::ItemRole
The Item.
Definition: entitytreemodel.h:332
QTreeView
QModelIndex::sibling
QModelIndex sibling(int row, int column) const
Akonadi::Entity::hasAttribute
bool hasAttribute(const QByteArray &name) const
Returns true if the entity has an attribute of the given type name, false otherwise.
Definition: entity.cpp:148
QTreeView::setModel
virtual void setModel(QAbstractItemModel *model)
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:318
QModelIndex::column
int column() const
Akonadi::ETMCalendar::isLoaded
bool isLoaded() const
Returns if the calendar already finished loading.
Definition: etmcalendar.cpp:614
QAbstractItemModel
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QWidget::show
void show()
Akonadi::ETMCalendar::~ETMCalendar
~ETMCalendar()
Destroys this ETMCalendar.
Definition: etmcalendar.cpp:479
Akonadi::CalendarBase
The base class for all akonadi aware calendars.
Definition: calendarbase.h:50
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
QItemSelectionModel
Akonadi::EntityDisplayAttribute
Attribute that stores the properties that are used to display an entity.
Definition: entitydisplayattribute.h:39
Akonadi::ETMCalendar
A KCalCore::Calendar that uses an EntityTreeModel to populate itself.
Definition: etmcalendar.h:54
Akonadi::KColumnFilterProxyModel::setVisibleColumn
void setVisibleColumn(int column)
Convenience function.
Definition: kcolumnfilterproxymodel.cpp:52
Akonadi::ETMCalendar::hasRight
bool hasRight(const Akonadi::Item &item, Akonadi::Collection::Right right) const
Returns true if the collection owning incidence has righ right.
Definition: etmcalendar.cpp:495
Akonadi::ETMCalendar::setCollectionFilteringEnabled
void setCollectionFilteringEnabled(bool enable)
Enable or disable collection filtering.
Definition: etmcalendar.cpp:590
Akonadi::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:47
Akonadi::BlockAlarmsAttribute
An Attribute that marks that alarms from a calendar collection are blocked.
Definition: blockalarmsattribute.h:41
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:38:03 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal