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

akonadi

  • akonadi
entitytreemodel.cpp
1 /*
2  Copyright (c) 2008 Stephen Kelly <steveire@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 "entitytreemodel.h"
21 #include "entitytreemodel_p.h"
22 
23 #include "monitor_p.h"
24 
25 #include <QtCore/QHash>
26 #include <QtCore/QMimeData>
27 #include <QtCore/QTimer>
28 #include <QAbstractProxyModel>
29 
30 #include <KDE/KIcon>
31 #include <KDE/KLocalizedString>
32 #include <KDE/KMessageBox>
33 #include <KDE/KUrl>
34 
35 #include <akonadi/attributefactory.h>
36 #include <akonadi/changerecorder.h>
37 #include <akonadi/collectionmodifyjob.h>
38 #include <akonadi/entitydisplayattribute.h>
39 #include <akonadi/transactionsequence.h>
40 #include <akonadi/itemmodifyjob.h>
41 #include <akonadi/session.h>
42 #include "collectionfetchscope.h"
43 
44 #include "collectionutils_p.h"
45 
46 #include "kdebug.h"
47 #include "pastehelper_p.h"
48 
49 Q_DECLARE_METATYPE(QSet<QByteArray>)
50 
51 using namespace Akonadi;
52 
53 EntityTreeModel::EntityTreeModel(ChangeRecorder *monitor, QObject *parent)
54  : QAbstractItemModel(parent)
55  , d_ptr(new EntityTreeModelPrivate(this))
56 {
57  Q_D(EntityTreeModel);
58  d->init(monitor);
59 }
60 
61 EntityTreeModel::EntityTreeModel(ChangeRecorder *monitor, EntityTreeModelPrivate *d, QObject *parent)
62  : QAbstractItemModel(parent)
63  , d_ptr(d)
64 {
65  d->init(monitor);
66 }
67 
68 EntityTreeModel::~EntityTreeModel()
69 {
70  Q_D(EntityTreeModel);
71 
72  foreach (const QList<Node *> &list, d->m_childEntities) {
73  QList<Node *>::const_iterator it = list.constBegin();
74  const QList<Node *>::const_iterator end = list.constEnd();
75  for (; it != end; ++it) {
76  delete *it;
77  }
78  }
79 
80  d->m_rootNode = 0;
81 
82  delete d_ptr;
83 }
84 
85 bool EntityTreeModel::includeUnsubscribed() const
86 {
87  return (listFilter() == CollectionFetchScope::NoFilter);
88 }
89 
90 void EntityTreeModel::setIncludeUnsubscribed(bool show)
91 {
92  if (show) {
93  setListFilter(CollectionFetchScope::NoFilter);
94  } else {
95  setListFilter(CollectionFetchScope::Enabled);
96  }
97 }
98 
99 CollectionFetchScope::ListFilter EntityTreeModel::listFilter() const
100 {
101  Q_D(const EntityTreeModel);
102  return d->m_listFilter;
103 }
104 
105 void EntityTreeModel::setListFilter(CollectionFetchScope::ListFilter filter)
106 {
107  Q_D(EntityTreeModel);
108  d->beginResetModel();
109  d->m_listFilter = filter;
110  d->m_monitor->setAllMonitored(filter == CollectionFetchScope::NoFilter);
111  d->endResetModel();
112 }
113 
114 void EntityTreeModel::setCollectionsMonitored(const Collection::List &collections)
115 {
116  Q_D(EntityTreeModel);
117  d->beginResetModel();
118  foreach(const Akonadi::Collection &col, d->m_monitor->collectionsMonitored()) {
119  d->m_monitor->setCollectionMonitored(col, false);
120  }
121  foreach(const Akonadi::Collection &col, collections) {
122  d->m_monitor->setCollectionMonitored(col, true);
123  }
124  d->endResetModel();
125 }
126 
127 void EntityTreeModel::setCollectionMonitored(const Collection &col, bool monitored)
128 {
129  Q_D(EntityTreeModel);
130  d->m_monitor->setCollectionMonitored(col, monitored);
131 }
132 
133 void EntityTreeModel::setCollectionReferenced(const Akonadi::Collection &col, bool referenced)
134 {
135  Q_D(EntityTreeModel);
136  d->m_monitor->setCollectionMonitored(col, referenced);
137  Akonadi::Collection referencedCollection = col;
138  referencedCollection.setReferenced(referenced);
139  //We have to use the same session as the monitor, so the monitor can fetch the collection afterwards
140  new Akonadi::CollectionModifyJob(referencedCollection, d->m_monitor->session());
141 }
142 
143 bool EntityTreeModel::systemEntitiesShown() const
144 {
145  Q_D(const EntityTreeModel);
146  return d->m_showSystemEntities;
147 }
148 
149 void EntityTreeModel::setShowSystemEntities(bool show)
150 {
151  Q_D(EntityTreeModel);
152  d->m_showSystemEntities = show;
153 }
154 
155 void EntityTreeModel::clearAndReset()
156 {
157  Q_D(EntityTreeModel);
158  d->beginResetModel();
159  d->endResetModel();
160 }
161 
162 int EntityTreeModel::columnCount(const QModelIndex &parent) const
163 {
164 // TODO: Statistics?
165  if (parent.isValid() &&
166  parent.column() != 0) {
167  return 0;
168  }
169 
170  return qMax(entityColumnCount(CollectionTreeHeaders), entityColumnCount(ItemListHeaders));
171 }
172 
173 QVariant EntityTreeModel::entityData(const Item &item, int column, int role) const
174 {
175  if (column == 0) {
176  switch (role) {
177  case Qt::DisplayRole:
178  case Qt::EditRole:
179  if (item.hasAttribute<EntityDisplayAttribute>() &&
180  !item.attribute<EntityDisplayAttribute>()->displayName().isEmpty()) {
181  return item.attribute<EntityDisplayAttribute>()->displayName();
182  } else {
183  if (!item.remoteId().isEmpty()) {
184  return item.remoteId();
185  }
186  return QString(QLatin1String("<") + QString::number(item.id()) + QLatin1String(">"));
187  }
188  break;
189  case Qt::DecorationRole:
190  if (item.hasAttribute<EntityDisplayAttribute>() &&
191  !item.attribute<EntityDisplayAttribute>()->iconName().isEmpty()) {
192  return item.attribute<EntityDisplayAttribute>()->icon();
193  }
194  break;
195  default:
196  break;
197  }
198  }
199 
200  return QVariant();
201 }
202 
203 QVariant EntityTreeModel::entityData(const Collection &collection, int column, int role) const
204 {
205  Q_D(const EntityTreeModel);
206 
207  if (column > 0) {
208  return QString();
209  }
210 
211  if (collection == Collection::root()) {
212  // Only display the root collection. It may not be edited.
213  if (role == Qt::DisplayRole) {
214  return d->m_rootCollectionDisplayName;
215  }
216 
217  if (role == Qt::EditRole) {
218  return QVariant();
219  }
220  }
221 
222  switch (role) {
223  case Qt::DisplayRole:
224  case Qt::EditRole:
225  if (column == 0) {
226  const QString displayName = collection.displayName();
227  if (!displayName.isEmpty()) {
228  return displayName;
229  } else {
230  return i18n("Loading...");
231  }
232  }
233  break;
234  case Qt::DecorationRole:
235  if (collection.hasAttribute<EntityDisplayAttribute>() &&
236  !collection.attribute<EntityDisplayAttribute>()->iconName().isEmpty()) {
237  return collection.attribute<EntityDisplayAttribute>()->icon();
238  }
239  return KIcon(CollectionUtils::defaultIconName(collection));
240  default:
241  break;
242  }
243 
244  return QVariant();
245 }
246 
247 QVariant EntityTreeModel::data(const QModelIndex &index, int role) const
248 {
249  Q_D(const EntityTreeModel);
250  if (role == SessionRole) {
251  return QVariant::fromValue(qobject_cast<QObject *>(d->m_session));
252  }
253 
254  // Ugly, but at least the API is clean.
255  const HeaderGroup headerGroup = static_cast<HeaderGroup>((role / static_cast<int>(TerminalUserRole)));
256 
257  role %= TerminalUserRole;
258  if (!index.isValid()) {
259  if (ColumnCountRole != role) {
260  return QVariant();
261  }
262 
263  return entityColumnCount(headerGroup);
264  }
265 
266  if (ColumnCountRole == role) {
267  return entityColumnCount(headerGroup);
268  }
269 
270  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
271 
272  if (ParentCollectionRole == role &&
273  d->m_collectionFetchStrategy != FetchNoCollections) {
274  const Collection parentCollection = d->m_collections.value(node->parent);
275  Q_ASSERT(parentCollection.isValid());
276 
277  return QVariant::fromValue(parentCollection);
278  }
279 
280  if (Node::Collection == node->type) {
281 
282  const Collection collection = d->m_collections.value(node->id);
283 
284  if (!collection.isValid()) {
285  return QVariant();
286  }
287 
288  switch (role) {
289  case MimeTypeRole:
290  return collection.mimeType();
291  break;
292  case RemoteIdRole:
293  return collection.remoteId();
294  break;
295  case CollectionIdRole:
296  return collection.id();
297  break;
298  case ItemIdRole:
299  // QVariant().toInt() is 0, not -1, so we have to handle the ItemIdRole
300  // and CollectionIdRole (below) specially
301  return -1;
302  break;
303  case CollectionRole:
304  return QVariant::fromValue(collection);
305  break;
306  case EntityUrlRole:
307  return collection.url().url();
308  break;
309  case UnreadCountRole: {
310  CollectionStatistics statistics = collection.statistics();
311  return statistics.unreadCount();
312  }
313  case FetchStateRole: {
314  return d->m_pendingCollectionRetrieveJobs.contains(collection.id()) ? FetchingState : IdleState;
315  }
316  case CollectionSyncProgressRole: {
317  return QVariant(); // no longer supported
318  }
319  case IsPopulatedRole: {
320  return d->m_populatedCols.contains(collection.id());
321  }
322  case Qt::BackgroundRole: {
323  if (collection.hasAttribute<EntityDisplayAttribute>()) {
324  EntityDisplayAttribute *eda = collection.attribute<EntityDisplayAttribute>();
325  QColor color = eda->backgroundColor();
326  if (color.isValid()) {
327  return color;
328  }
329  }
330  // fall through.
331  }
332  default:
333  return entityData(collection, index.column(), role);
334  break;
335  }
336 
337  } else if (Node::Item == node->type) {
338  const Item item = d->m_items.value(node->id);
339  if (!item.isValid()) {
340  return QVariant();
341  }
342 
343  switch (role) {
344  case ParentCollectionRole:
345  return QVariant::fromValue(item.parentCollection());
346  case MimeTypeRole:
347  return item.mimeType();
348  break;
349  case RemoteIdRole:
350  return item.remoteId();
351  break;
352  case ItemRole:
353  return QVariant::fromValue(item);
354  break;
355  case ItemIdRole:
356  return item.id();
357  break;
358  case CollectionIdRole:
359  return -1;
360  break;
361  case LoadedPartsRole:
362  return QVariant::fromValue(item.loadedPayloadParts());
363  break;
364  case AvailablePartsRole:
365  return QVariant::fromValue(item.availablePayloadParts());
366  break;
367  case EntityUrlRole:
368  return item.url(Akonadi::Item::UrlWithMimeType).url();
369  break;
370  case Qt::BackgroundRole: {
371  if (item.hasAttribute<EntityDisplayAttribute>()) {
372  EntityDisplayAttribute *eda = item.attribute<EntityDisplayAttribute>();
373  const QColor color = eda->backgroundColor();
374  if (color.isValid()) {
375  return color;
376  }
377  }
378  // fall through.
379  }
380  default:
381  return entityData(item, index.column(), role);
382  break;
383  }
384  }
385 
386  return QVariant();
387 }
388 
389 Qt::ItemFlags EntityTreeModel::flags(const QModelIndex &index) const
390 {
391  Q_D(const EntityTreeModel);
392  // Pass modeltest.
393  if (!index.isValid()) {
394  return 0;
395  }
396 
397  Qt::ItemFlags flags = QAbstractItemModel::flags(index);
398 
399  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
400 
401  if (Node::Collection == node->type) {
402  // cut out entities will be shown as inactive
403  if (d->m_pendingCutCollections.contains(node->id)) {
404  return Qt::ItemIsSelectable;
405  }
406 
407  const Collection collection = d->m_collections.value(node->id);
408  if (collection.isValid()) {
409 
410  if (collection == Collection::root()) {
411  // Selectable and displayable only.
412  return flags;
413  }
414 
415  const int rights = collection.rights();
416 
417  if (rights & Collection::CanChangeCollection) {
418  if (index.column() == 0) {
419  flags |= Qt::ItemIsEditable;
420  }
421  // Changing the collection includes changing the metadata (child entityordering).
422  // Need to allow this by drag and drop.
423  flags |= Qt::ItemIsDropEnabled;
424  }
425  if (rights & (Collection::CanCreateCollection | Collection::CanCreateItem | Collection::CanLinkItem)) {
426  // Can we drop new collections and items into this collection?
427  flags |= Qt::ItemIsDropEnabled;
428  }
429 
430  // dragging is always possible, even for read-only objects, but they can only be copied, not moved.
431  flags |= Qt::ItemIsDragEnabled;
432 
433  }
434  } else if (Node::Item == node->type) {
435  if (d->m_pendingCutItems.contains(node->id)) {
436  return Qt::ItemIsSelectable;
437  }
438 
439  // Rights come from the parent collection.
440 
441  Collection parentCollection;
442  if (!index.parent().isValid()) {
443  parentCollection = d->m_rootCollection;
444  } else {
445  const Node *parentNode = reinterpret_cast<Node *>(index.parent().internalPointer());
446 
447  parentCollection = d->m_collections.value(parentNode->id);
448  }
449  if (parentCollection.isValid()) {
450  const int rights = parentCollection.rights();
451 
452  // Can't drop onto items.
453  if (rights &Collection::CanChangeItem && index.column() == 0) {
454  flags = flags | Qt::ItemIsEditable;
455  }
456  // dragging is always possible, even for read-only objects, but they can only be copied, not moved.
457  flags |= Qt::ItemIsDragEnabled;
458  }
459  }
460 
461  return flags;
462 }
463 
464 Qt::DropActions EntityTreeModel::supportedDropActions() const
465 {
466  return (Qt::CopyAction | Qt::MoveAction | Qt::LinkAction);
467 }
468 
469 QStringList EntityTreeModel::mimeTypes() const
470 {
471  // TODO: Should this return the mimetypes that the items provide? Allow dragging a contact from here for example.
472  return QStringList() << QLatin1String("text/uri-list");
473 }
474 
475 bool EntityTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
476 {
477  Q_UNUSED(row);
478  Q_UNUSED(column);
479  Q_D(EntityTreeModel);
480 
481  // Can't drop onto Collection::root.
482  if (!parent.isValid()) {
483  return false;
484  }
485 
486  // TODO Use action and collection rights and return false if necessary
487 
488  // if row and column are -1, then the drop was on parent directly.
489  // data should then be appended on the end of the items of the collections as appropriate.
490  // That will mean begin insert rows etc.
491  // Otherwise it was a sibling of the row^th item of parent.
492  // Needs to be handled when ordering is accounted for.
493 
494  // Handle dropping between items as well as on items.
495 // if ( row != -1 && column != -1 )
496 // {
497 // }
498 
499  if (action == Qt::IgnoreAction) {
500  return true;
501  }
502 
503 // Shouldn't do this. Need to be able to drop vcards for example.
504 // if ( !data->hasFormat( "text/uri-list" ) )
505 // return false;
506 
507  Node *node = reinterpret_cast<Node *>(parent.internalId());
508 
509  Q_ASSERT(node);
510 
511  if (Node::Item == node->type) {
512  if (!parent.parent().isValid()) {
513  // The drop is somehow on an item with no parent (shouldn't happen)
514  // The drop should be considered handled anyway.
515  kWarning() << "Dropped onto item with no parent collection";
516  return true;
517  }
518 
519  // A drop onto an item should be considered as a drop onto its parent collection
520  node = reinterpret_cast<Node *>(parent.parent().internalId());
521  }
522 
523  if (Node::Collection == node->type) {
524  const Collection destCollection = d->m_collections.value(node->id);
525 
526  // Applications can't create new collections in root. Only resources can.
527  if (destCollection == Collection::root()) {
528  // Accept the event so that it doesn't propagate.
529  return true;
530  }
531 
532  if (data->hasFormat(QLatin1String("text/uri-list"))) {
533 
534  MimeTypeChecker mimeChecker;
535  mimeChecker.setWantedMimeTypes(destCollection.contentMimeTypes());
536 
537  const KUrl::List urls = KUrl::List::fromMimeData(data);
538  foreach (const KUrl &url, urls) {
539  const Collection collection = d->m_collections.value(Collection::fromUrl(url).id());
540  if (collection.isValid()) {
541  if (collection.parentCollection().id() == destCollection.id() &&
542  action != Qt::CopyAction) {
543  kDebug() << "Error: source and destination of move are the same.";
544  return false;
545  }
546 
547  if (!mimeChecker.isWantedCollection(collection)) {
548  kDebug() << "unwanted collection" << mimeChecker.wantedMimeTypes() << collection.contentMimeTypes();
549  return false;
550  }
551 
552  if (url.hasQueryItem(QLatin1String("name"))) {
553  const QString collectionName = url.queryItemValue(QLatin1String("name"));
554  const QStringList collectionNames = d->childCollectionNames(destCollection);
555 
556  if (collectionNames.contains(collectionName)) {
557  KMessageBox::error(0, i18n("The target collection '%1' contains already\na collection with name '%2'.",
558  destCollection.name(), collection.name()));
559  return false;
560  }
561  }
562  } else {
563  const Item item = d->m_items.value(Item::fromUrl(url).id());
564  if (item.isValid()) {
565  if (item.parentCollection().id() == destCollection.id() && action != Qt::CopyAction) {
566  kDebug() << "Error: source and destination of move are the same.";
567  return false;
568  }
569 
570  if (!mimeChecker.isWantedItem(item)) {
571  kDebug() << "unwanted item" << mimeChecker.wantedMimeTypes() << item.mimeType();
572  return false;
573  }
574  }
575  }
576  }
577 
578  KJob *job = PasteHelper::pasteUriList(data, destCollection, action, d->m_session);
579  if (!job) {
580  return false;
581  }
582 
583  connect(job, SIGNAL(result(KJob*)), SLOT(pasteJobDone(KJob*)));
584 
585  // Accpet the event so that it doesn't propagate.
586  return true;
587  } else {
588 // not a set of uris. Maybe vcards etc. Check if the parent supports them, and maybe do
589  // fromMimeData for them. Hmm, put it in the same transaction with the above?
590  // TODO: This should be handled first, not last.
591  }
592  }
593 
594  return false;
595 }
596 
597 QModelIndex EntityTreeModel::index(int row, int column, const QModelIndex &parent) const
598 {
599 
600  Q_D(const EntityTreeModel);
601 
602  if (parent.column() > 0) {
603  return QModelIndex();
604  }
605 
606  //TODO: don't use column count here? Use some d-> func.
607  if (column >= columnCount() ||
608  column < 0) {
609  return QModelIndex();
610  }
611 
612  QList<Node *> childEntities;
613 
614  const Node *parentNode = reinterpret_cast<Node *>(parent.internalPointer());
615 
616  if (!parentNode || !parent.isValid()) {
617  if (d->m_showRootCollection) {
618  childEntities << d->m_childEntities.value(-1);
619  } else {
620  childEntities = d->m_childEntities.value(d->m_rootCollection.id());
621  }
622  } else {
623  if (parentNode->id >= 0) {
624  childEntities = d->m_childEntities.value(parentNode->id);
625  }
626  }
627 
628  const int size = childEntities.size();
629  if (row < 0 || row >= size) {
630  return QModelIndex();
631  }
632 
633  Node *node = childEntities.at(row);
634 
635  return createIndex(row, column, reinterpret_cast<void *>(node));
636 }
637 
638 QModelIndex EntityTreeModel::parent(const QModelIndex &index) const
639 {
640  Q_D(const EntityTreeModel);
641 
642  if (!index.isValid()) {
643  return QModelIndex();
644  }
645 
646  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
647  d->m_collectionFetchStrategy == FetchNoCollections) {
648  return QModelIndex();
649  }
650 
651  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
652 
653  if (!node) {
654  return QModelIndex();
655  }
656 
657  const Collection collection = d->m_collections.value(node->parent);
658 
659  if (!collection.isValid()) {
660  return QModelIndex();
661  }
662 
663  if (collection.id() == d->m_rootCollection.id()) {
664  if (!d->m_showRootCollection) {
665  return QModelIndex();
666  } else {
667  return createIndex(0, 0, reinterpret_cast<void *>(d->m_rootNode));
668  }
669  }
670 
671  Q_ASSERT(collection.parentCollection().isValid());
672  const int row = d->indexOf<Node::Collection>(d->m_childEntities.value(collection.parentCollection().id()), collection.id());
673 
674  Q_ASSERT(row >= 0);
675  Node *parentNode = d->m_childEntities.value(collection.parentCollection().id()).at(row);
676 
677  return createIndex(row, 0, reinterpret_cast<void *>(parentNode));
678 }
679 
680 int EntityTreeModel::rowCount(const QModelIndex &parent) const
681 {
682  Q_D(const EntityTreeModel);
683 
684  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
685  d->m_collectionFetchStrategy == FetchNoCollections) {
686  if (parent.isValid()) {
687  return 0;
688  } else {
689  return d->m_items.size();
690  }
691  }
692 
693  if (!parent.isValid()) {
694  // If we're showing the root collection then it will be the only child of the root.
695  if (d->m_showRootCollection) {
696  return d->m_childEntities.value(-1).size();
697  }
698  return d->m_childEntities.value(d->m_rootCollection.id()).size();
699  }
700 
701  if (parent.column() != 0) {
702  return 0;
703  }
704 
705  const Node *node = reinterpret_cast<Node *>(parent.internalPointer());
706 
707  if (!node) {
708  return 0;
709  }
710 
711  if (Node::Item == node->type) {
712  return 0;
713  }
714 
715  Q_ASSERT(parent.isValid());
716  return d->m_childEntities.value(node->id).size();
717 }
718 
719 int EntityTreeModel::entityColumnCount(HeaderGroup headerGroup) const
720 {
721  // Not needed in this model.
722  Q_UNUSED(headerGroup);
723 
724  return 1;
725 }
726 
727 QVariant EntityTreeModel::entityHeaderData(int section, Qt::Orientation orientation, int role, HeaderGroup headerGroup) const
728 {
729  Q_D(const EntityTreeModel);
730  // Not needed in this model.
731  Q_UNUSED(headerGroup);
732 
733  if (section == 0 &&
734  orientation == Qt::Horizontal &&
735  role == Qt::DisplayRole) {
736  if (d->m_rootCollection == Collection::root()) {
737  return i18nc("@title:column Name of a thing", "Name");
738  }
739  return d->m_rootCollection.name();
740  }
741 
742  return QAbstractItemModel::headerData(section, orientation, role);
743 }
744 
745 QVariant EntityTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
746 {
747  const HeaderGroup headerGroup = static_cast<HeaderGroup>((role / static_cast<int>(TerminalUserRole)));
748 
749  role %= TerminalUserRole;
750  return entityHeaderData(section, orientation, role, headerGroup);
751 }
752 
753 QMimeData *EntityTreeModel::mimeData(const QModelIndexList &indexes) const
754 {
755  Q_D(const EntityTreeModel);
756 
757  QMimeData *data = new QMimeData();
758  KUrl::List urls;
759  foreach (const QModelIndex &index, indexes) {
760  if (index.column() != 0) {
761  continue;
762  }
763 
764  if (!index.isValid()) {
765  continue;
766  }
767 
768  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
769 
770  if (Node::Collection == node->type) {
771  urls << d->m_collections.value(node->id).url(Collection::UrlWithName);
772  } else if (Node::Item == node->type) {
773  KUrl url = d->m_items.value(node->id).url(Item::Item::UrlWithMimeType);
774  // Encode the "virtual" parent
775  url.addQueryItem(QLatin1String("parent"), QString::number(node->parent));
776  urls << url;
777  } else { // if that happens something went horrible wrong
778  Q_ASSERT(false);
779  }
780  }
781 
782  urls.populateMimeData(data);
783 
784  return data;
785 }
786 
787 // Always return false for actions which take place asyncronously, eg via a Job.
788 bool EntityTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
789 {
790  Q_D(EntityTreeModel);
791 
792  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
793 
794  if (role == PendingCutRole) {
795  if (index.isValid() && value.toBool()) {
796  if (Node::Collection == node->type) {
797  d->m_pendingCutCollections.append(node->id);
798  }
799 
800  if (Node::Item == node->type) {
801  d->m_pendingCutItems.append(node->id);
802  }
803  } else {
804  d->m_pendingCutCollections.clear();
805  d->m_pendingCutItems.clear();
806  }
807  return true;
808  }
809 
810  if (index.isValid() &&
811  node->type == Node::Collection &&
812  (role == CollectionRefRole ||
813  role == CollectionDerefRole)) {
814  const Collection collection = index.data(CollectionRole).value<Collection>();
815  Q_ASSERT(collection.isValid());
816 
817  if (role == CollectionDerefRole) {
818  d->deref(collection.id());
819  } else if (role == CollectionRefRole) {
820  d->ref(collection.id());
821  }
822  return true;
823  }
824 
825  if (index.column() == 0 &&
826  (role &(Qt::EditRole | ItemRole | CollectionRole))) {
827  if (Node::Collection == node->type) {
828 
829  Collection collection = d->m_collections.value(node->id);
830 
831  if (!collection.isValid() || !value.isValid()) {
832  return false;
833  }
834 
835  if (Qt::EditRole == role) {
836  collection.setName(value.toString());
837 
838  if (collection.hasAttribute<EntityDisplayAttribute>()) {
839  EntityDisplayAttribute *displayAttribute = collection.attribute<EntityDisplayAttribute>();
840  displayAttribute->setDisplayName(value.toString());
841  }
842  }
843 
844  if (Qt::BackgroundRole == role) {
845  QColor color = value.value<QColor>();
846 
847  if (!color.isValid()) {
848  return false;
849  }
850 
851  EntityDisplayAttribute *eda = collection.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
852  eda->setBackgroundColor(color);
853  }
854 
855  if (CollectionRole == role) {
856  collection = value.value<Collection>();
857  }
858 
859  CollectionModifyJob *job = new CollectionModifyJob(collection, d->m_session);
860  connect(job, SIGNAL(result(KJob*)),
861  SLOT(updateJobDone(KJob*)));
862 
863  return false;
864  } else if (Node::Item == node->type) {
865 
866  Item item = d->m_items.value(node->id);
867 
868  if (!item.isValid() || !value.isValid()) {
869  return false;
870  }
871 
872  if (Qt::EditRole == role) {
873  if (item.hasAttribute<EntityDisplayAttribute>()) {
874  EntityDisplayAttribute *displayAttribute = item.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
875  displayAttribute->setDisplayName(value.toString());
876  }
877  }
878 
879  if (Qt::BackgroundRole == role) {
880  QColor color = value.value<QColor>();
881 
882  if (!color.isValid()) {
883  return false;
884  }
885 
886  EntityDisplayAttribute *eda = item.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
887  eda->setBackgroundColor(color);
888  }
889 
890  if (ItemRole == role) {
891  item = value.value<Item>();
892  Q_ASSERT(item.id() == node->id);
893  }
894 
895  ItemModifyJob *itemModifyJob = new ItemModifyJob(item, d->m_session);
896  connect(itemModifyJob, SIGNAL(result(KJob*)),
897  SLOT(updateJobDone(KJob*)));
898 
899  return false;
900  }
901  }
902 
903  return QAbstractItemModel::setData(index, value, role);
904 }
905 
906 bool EntityTreeModel::canFetchMore(const QModelIndex &parent) const
907 {
908  Q_UNUSED(parent)
909  return false;
910 }
911 
912 void EntityTreeModel::fetchMore(const QModelIndex &parent)
913 {
914  Q_D(EntityTreeModel);
915 
916  if (!d->canFetchMore(parent)) {
917  return;
918  }
919 
920  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch) {
921  return;
922  }
923 
924  if (d->m_itemPopulation == ImmediatePopulation) {
925  // Nothing to do. The items are already in the model.
926  return;
927  } else if (d->m_itemPopulation == LazyPopulation) {
928  const Collection collection = parent.data(CollectionRole).value<Collection>();
929 
930  if (!collection.isValid()) {
931  return;
932  }
933 
934  d->fetchItems(collection);
935  }
936 }
937 
938 bool EntityTreeModel::hasChildren(const QModelIndex &parent) const
939 {
940  Q_D(const EntityTreeModel);
941 
942  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
943  d->m_collectionFetchStrategy == FetchNoCollections) {
944  return parent.isValid() ? false : !d->m_items.isEmpty();
945  }
946 
947  // TODO: Empty collections right now will return true and get a little + to expand.
948  // There is probably no way to tell if a collection
949  // has child items in akonadi without first attempting an itemFetchJob...
950  // Figure out a way to fix this. (Statistics)
951  return ((rowCount(parent) > 0) ||
952  (canFetchMore(parent) && d->m_itemPopulation == LazyPopulation));
953 }
954 
955 bool EntityTreeModel::isCollectionTreeFetched() const
956 {
957  Q_D(const EntityTreeModel);
958 
959  return d->m_collectionTreeFetched;
960 }
961 
962 bool EntityTreeModel::isCollectionPopulated(Collection::Id id) const
963 {
964  Q_D(const EntityTreeModel);
965  return d->m_populatedCols.contains(id);
966 }
967 
968 bool EntityTreeModel::isFullyPopulated() const
969 {
970  Q_D(const EntityTreeModel);
971  return d->m_collectionTreeFetched && d->m_pendingCollectionRetrieveJobs.isEmpty();
972 }
973 
974 bool EntityTreeModel::entityMatch(const Item &item, const QVariant &value, Qt::MatchFlags flags) const
975 {
976  Q_UNUSED(item);
977  Q_UNUSED(value);
978  Q_UNUSED(flags);
979  return false;
980 }
981 
982 bool EntityTreeModel::entityMatch(const Collection &collection, const QVariant &value, Qt::MatchFlags flags) const
983 {
984  Q_UNUSED(collection);
985  Q_UNUSED(value);
986  Q_UNUSED(flags);
987  return false;
988 }
989 
990 QModelIndexList EntityTreeModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
991 {
992  Q_D(const EntityTreeModel);
993 
994  if (role == CollectionIdRole || role == CollectionRole) {
995  Collection::Id id;
996  if (role == CollectionRole) {
997  const Collection collection = value.value<Collection>();
998  id = collection.id();
999  } else {
1000  id = value.toLongLong();
1001  }
1002 
1003  QModelIndexList list;
1004 
1005  const Collection collection = d->m_collections.value(id);
1006 
1007  if (!collection.isValid()) {
1008  return list;
1009  }
1010 
1011  const QModelIndex collectionIndex = d->indexForCollection(collection);
1012  Q_ASSERT(collectionIndex.isValid());
1013  list << collectionIndex;
1014 
1015  return list;
1016  }
1017 
1018  if (role == ItemIdRole || role == ItemRole) {
1019  Item::Id id;
1020  if (role == ItemRole) {
1021  const Item item = value.value<Item>();
1022  id = item.id();
1023  } else {
1024  id = value.toLongLong();
1025  }
1026  QModelIndexList list;
1027 
1028  const Item item = d->m_items.value(id);
1029  if (!item.isValid()) {
1030  return list;
1031  }
1032 
1033  return d->indexesForItem(item);
1034  }
1035 
1036  if (role == EntityUrlRole) {
1037  const KUrl url(value.toString());
1038  const Item item = Item::fromUrl(url);
1039 
1040  if (item.isValid()) {
1041  return d->indexesForItem(d->m_items.value(item.id()));
1042  }
1043 
1044  const Collection collection = Collection::fromUrl(url);
1045  QModelIndexList list;
1046  if (collection.isValid()) {
1047  list << d->indexForCollection(collection);
1048  }
1049 
1050  return list;
1051  }
1052 
1053  if (role != AmazingCompletionRole) {
1054  return QAbstractItemModel::match(start, role, value, hits, flags);
1055  }
1056 
1057  // Try to match names, and email addresses.
1058  QModelIndexList list;
1059 
1060  if (role < 0 ||
1061  !start.isValid() ||
1062  !value.isValid()) {
1063  return list;
1064  }
1065 
1066  const int column = 0;
1067  int row = start.row();
1068  const QModelIndex parentIndex = start.parent();
1069  const int parentRowCount = rowCount(parentIndex);
1070 
1071  while (row < parentRowCount &&
1072  (hits == -1 || list.size() < hits)) {
1073  const QModelIndex idx = index(row, column, parentIndex);
1074  const Item item = idx.data(ItemRole).value<Item>();
1075 
1076  if (!item.isValid()) {
1077  const Collection collection = idx.data(CollectionRole).value<Collection>();
1078  if (!collection.isValid()) {
1079  continue;
1080  }
1081 
1082  if (entityMatch(collection, value, flags)) {
1083  list << idx;
1084  }
1085 
1086  } else {
1087  if (entityMatch(item, value, flags)) {
1088  list << idx;
1089  }
1090  }
1091 
1092  ++row;
1093  }
1094 
1095  return list;
1096 }
1097 
1098 bool EntityTreeModel::insertRows(int, int, const QModelIndex &)
1099 {
1100  return false;
1101 }
1102 
1103 bool EntityTreeModel::insertColumns(int, int, const QModelIndex &)
1104 {
1105  return false;
1106 }
1107 
1108 bool EntityTreeModel::removeRows(int, int, const QModelIndex &)
1109 {
1110  return false;
1111 }
1112 
1113 bool EntityTreeModel::removeColumns(int, int, const QModelIndex &)
1114 {
1115  return false;
1116 }
1117 
1118 void EntityTreeModel::setItemPopulationStrategy(ItemPopulationStrategy strategy)
1119 {
1120  Q_D(EntityTreeModel);
1121  d->beginResetModel();
1122  d->m_itemPopulation = strategy;
1123 
1124  if (strategy == NoItemPopulation) {
1125  disconnect(d->m_monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)),
1126  this, SLOT(monitoredItemAdded(Akonadi::Item,Akonadi::Collection)));
1127  disconnect(d->m_monitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
1128  this, SLOT(monitoredItemChanged(Akonadi::Item,QSet<QByteArray>)));
1129  disconnect(d->m_monitor, SIGNAL(itemRemoved(Akonadi::Item)),
1130  this, SLOT(monitoredItemRemoved(Akonadi::Item)));
1131  disconnect(d->m_monitor, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)),
1132  this, SLOT(monitoredItemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)));
1133 
1134  disconnect(d->m_monitor, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
1135  this, SLOT(monitoredItemLinked(Akonadi::Item,Akonadi::Collection)));
1136  disconnect(d->m_monitor, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
1137  this, SLOT(monitoredItemUnlinked(Akonadi::Item,Akonadi::Collection)));
1138  }
1139 
1140  d->m_monitor->d_ptr->useRefCounting = (strategy == LazyPopulation);
1141 
1142  d->endResetModel();
1143 }
1144 
1145 EntityTreeModel::ItemPopulationStrategy EntityTreeModel::itemPopulationStrategy() const
1146 {
1147  Q_D(const EntityTreeModel);
1148  return d->m_itemPopulation;
1149 }
1150 
1151 void EntityTreeModel::setIncludeRootCollection(bool include)
1152 {
1153  Q_D(EntityTreeModel);
1154  d->beginResetModel();
1155  d->m_showRootCollection = include;
1156  d->endResetModel();
1157 }
1158 
1159 bool EntityTreeModel::includeRootCollection() const
1160 {
1161  Q_D(const EntityTreeModel);
1162  return d->m_showRootCollection;
1163 }
1164 
1165 void EntityTreeModel::setRootCollectionDisplayName(const QString &displayName)
1166 {
1167  Q_D(EntityTreeModel);
1168  d->m_rootCollectionDisplayName = displayName;
1169 
1170  // TODO: Emit datachanged if it is being shown.
1171 }
1172 
1173 QString EntityTreeModel::rootCollectionDisplayName() const
1174 {
1175  Q_D(const EntityTreeModel);
1176  return d->m_rootCollectionDisplayName;
1177 }
1178 
1179 void EntityTreeModel::setCollectionFetchStrategy(CollectionFetchStrategy strategy)
1180 {
1181  Q_D(EntityTreeModel);
1182  d->beginResetModel();
1183  d->m_collectionFetchStrategy = strategy;
1184 
1185  if (strategy == FetchNoCollections ||
1186  strategy == InvisibleCollectionFetch) {
1187  disconnect(d->m_monitor, SIGNAL(collectionChanged(Akonadi::Collection)),
1188  this, SLOT(monitoredCollectionChanged(Akonadi::Collection)));
1189  disconnect(d->m_monitor, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
1190  this, SLOT(monitoredCollectionAdded(Akonadi::Collection,Akonadi::Collection)));
1191  disconnect(d->m_monitor, SIGNAL(collectionRemoved(Akonadi::Collection)),
1192  this, SLOT(monitoredCollectionRemoved(Akonadi::Collection)));
1193  disconnect(d->m_monitor,
1194  SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)),
1195  this, SLOT(monitoredCollectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)));
1196  d->m_monitor->fetchCollection(false);
1197  } else {
1198  d->m_monitor->fetchCollection(true);
1199  }
1200 
1201  d->endResetModel();
1202 }
1203 
1204 EntityTreeModel::CollectionFetchStrategy EntityTreeModel::collectionFetchStrategy() const
1205 {
1206  Q_D(const EntityTreeModel);
1207  return d->m_collectionFetchStrategy;
1208 }
1209 
1210 static QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> proxiesAndModel(const QAbstractItemModel *model)
1211 {
1212  QList<const QAbstractProxyModel *> proxyChain;
1213  const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model);
1214  const QAbstractItemModel *_model = model;
1215  while (proxy) {
1216  proxyChain.prepend(proxy);
1217  _model = proxy->sourceModel();
1218  proxy = qobject_cast<const QAbstractProxyModel *>(_model);
1219  }
1220 
1221  const EntityTreeModel *etm = qobject_cast<const EntityTreeModel *>(_model);
1222  return qMakePair(proxyChain, etm);
1223 }
1224 
1225 static QModelIndex proxiedIndex(const QModelIndex &idx, QList<const QAbstractProxyModel *> proxyChain)
1226 {
1227  QListIterator<const QAbstractProxyModel *> it(proxyChain);
1228  QModelIndex _idx = idx;
1229  while (it.hasNext()) {
1230  _idx = it.next()->mapFromSource(_idx);
1231  }
1232  return _idx;
1233 }
1234 
1235 QModelIndex EntityTreeModel::modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection)
1236 {
1237  QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> pair = proxiesAndModel(model);
1238 
1239  Q_ASSERT(pair.second);
1240  QModelIndex idx = pair.second->d_ptr->indexForCollection(collection);
1241  return proxiedIndex(idx, pair.first);
1242 }
1243 
1244 QModelIndexList EntityTreeModel::modelIndexesForItem(const QAbstractItemModel *model, const Item &item)
1245 {
1246  QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> pair = proxiesAndModel(model);
1247 
1248  if (!pair.second) {
1249  kWarning() << "Couldn't find an EntityTreeModel";
1250  return QModelIndexList();
1251  }
1252 
1253  QModelIndexList list = pair.second->d_ptr->indexesForItem(item);
1254  QModelIndexList proxyList;
1255  foreach (const QModelIndex &idx, list) {
1256  const QModelIndex pIdx = proxiedIndex(idx, pair.first);
1257  if (pIdx.isValid()) {
1258  proxyList << pIdx;
1259  }
1260  }
1261  return proxyList;
1262 }
1263 
1264 #include "moc_entitytreemodel.cpp"
Akonadi::Monitor::setAllMonitored
void setAllMonitored(bool monitored=true)
Sets whether all items shall be monitored.
Definition: monitor.cpp:186
Akonadi::EntityTreeModel::entityMatch
virtual bool entityMatch(const Item &item, const QVariant &value, Qt::MatchFlags flags) const
Reimplement this in a subclass to return true if item matches value with flags in the AmazingCompleti...
Definition: entitytreemodel.cpp:974
Akonadi::CollectionModifyJob
Job that modifies a collection in the Akonadi storage.
Definition: collectionmodifyjob.h:82
Akonadi::EntityTreeModel::setIncludeRootCollection
void setIncludeRootCollection(bool include)
Sets whether the root collection shall be provided by the model.
Definition: entitytreemodel.cpp:1151
Akonadi::EntityTreeModel::LoadedPartsRole
Parts available in the model for the item.
Definition: entitytreemodel.h:343
Akonadi::EntityTreeModel::systemEntitiesShown
bool systemEntitiesShown() const
Returns true if internal system entities are shown, and false otherwise.
Definition: entitytreemodel.cpp:143
Akonadi::Monitor::session
Session * session() const
Returns the Session used by the monitor to communicate with Akonadi.
Definition: monitor.cpp:365
Akonadi::Collection::name
QString name() const
Returns the i18n'ed name of the collection.
Definition: collection.cpp:81
Akonadi::EntityDisplayAttribute::iconName
QString iconName() const
Returns the icon name of the icon returned by icon().
Definition: entitydisplayattribute.cpp:67
Akonadi::EntityTreeModel::CollectionIdRole
The collection id.
Definition: entitytreemodel.h:335
Akonadi::EntityTreeModel::UnreadCountRole
Returns the number of unread items in a collection.
Definition: entitytreemodel.h:350
Akonadi::Collection::displayName
QString displayName() const
Returns the display name (EntityDisplayAttribute::displayName()) if set, and Collection::name() other...
Definition: collection.cpp:86
Akonadi::EntityTreeModel::entityData
virtual QVariant entityData(const Item &item, int column, int role=Qt::DisplayRole) const
Provided for convenience of subclasses.
Definition: entitytreemodel.cpp:173
Akonadi::EntityTreeModel::TerminalUserRole
Last role for user extensions. Don't use a role beyond this or headerData will break.
Definition: entitytreemodel.h:355
Akonadi::EntityTreeModel::CollectionRefRole
Definition: entitytreemodel.h:346
Akonadi::CollectionStatistics
Provides statistics information of a Collection.
Definition: collectionstatistics.h:69
Akonadi::EntityTreeModel::FetchStateRole
Returns the FetchState of a particular item.
Definition: entitytreemodel.h:351
Akonadi::EntityTreeModelPrivate::indexForCollection
QModelIndex indexForCollection(const Collection &collection) const
Returns the model index for the given collection.
Akonadi::EntityTreeModel::InvisibleCollectionFetch
Fetches collections, but does not put them in the model. This can be used to create a list of items i...
Definition: entitytreemodel.h:530
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::Collection::url
KUrl url() const
Returns the url of the collection.
Definition: collection.cpp:154
Akonadi::EntityTreeModel::ItemPopulationStrategy
ItemPopulationStrategy
Describes how the model should populated its items.
Definition: entitytreemodel.h:407
Akonadi::EntityTreeModelPrivate::indexOf
int indexOf(const QList< Node * > &nodes, Entity::Id id) const
Returns the index of the node in list with the id id.
Definition: entitytreemodel_p.h:178
Akonadi::EntityDisplayAttribute::displayName
QString displayName() const
Returns the name that should be used for display.
Definition: entitydisplayattribute.cpp:52
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::EntityTreeModel::NoItemPopulation
Do not include items in the model.
Definition: entitytreemodel.h:408
Akonadi::Entity::Id
qint64 Id
Describes the unique id type.
Definition: entity.h:65
Akonadi::Collection::mimeType
static QString mimeType()
Returns the mimetype used for collections.
Definition: collection.cpp:197
Akonadi::Collection::CanCreateCollection
Can create new subcollections in this collection.
Definition: collection.h:92
Akonadi::PasteHelper::pasteUriList
KJob * pasteUriList(const QMimeData *mimeData, const Collection &collection, Qt::DropAction action, Session *session=0)
URI list paste/drop.
Definition: pastehelper.cpp:307
Akonadi::Collection::CanChangeItem
Can change items in this collection.
Definition: collection.h:88
Akonadi::MimeTypeChecker
Helper for checking MIME types of Collections and Items.
Definition: mimetypechecker.h:109
Akonadi::EntityTreeModel::setCollectionsMonitored
void setCollectionsMonitored(const Akonadi::Collection::List &collections)
Monitors the specified collections and resets the model.
Definition: entitytreemodel.cpp:114
Akonadi::EntityTreeModel::setCollectionMonitored
void setCollectionMonitored(const Akonadi::Collection &col, bool monitored=true)
Adds or removes a specific collection from the monitored set without resetting the model...
Definition: entitytreemodel.cpp:127
Akonadi::EntityTreeModel::entityHeaderData
virtual QVariant entityHeaderData(int section, Qt::Orientation orientation, int role, HeaderGroup headerGroup) const
Reimplement this to provide different header data.
Definition: entitytreemodel.cpp:727
Akonadi::EntityTreeModel::IdleState
There is no fetch of items in this collection in progress.
Definition: entitytreemodel.h:374
Akonadi::EntityTreeModel::isCollectionPopulated
bool isCollectionPopulated(Akonadi::Collection::Id) const
Returns whether the collection has been populated.
Definition: entitytreemodel.cpp:962
Akonadi::Collection::setName
void setName(const QString &name)
Sets the i18n'ed name of the collection.
Definition: collection.cpp:93
Akonadi::EntityTreeModel::CollectionSyncProgressRole
Returns the progress of synchronization in percent for a particular collection.
Definition: entitytreemodel.h:352
Akonadi::EntityTreeModel::CollectionTreeHeaders
Header information for a collection-only tree.
Definition: entitytreemodel.h:384
Akonadi::CollectionFetchScope::ListFilter
ListFilter
Describes the list filter.
Definition: collectionfetchscope.h:132
Akonadi::EntityTreeModel::HeaderGroup
HeaderGroup
Describes what header information the model shall return.
Definition: entitytreemodel.h:382
Akonadi::EntityTreeModel::LazyPopulation
Fetch items only when requested (using canFetchMore/fetchMore)
Definition: entitytreemodel.h:410
Akonadi::EntityTreeModel::IsPopulatedRole
Returns whether a Collection has been populated, i.e. whether its items have been fetched...
Definition: entitytreemodel.h:353
Akonadi::Entity::attribute
Attribute * attribute(const QByteArray &name) const
Returns the attribute of the given type name if available, 0 otherwise.
Definition: entity.cpp:166
Akonadi::Monitor::collectionsMonitored
Collection::List collectionsMonitored() const
Returns the list of collections being monitored.
Definition: monitor.cpp:273
Akonadi::EntityTreeModel::setCollectionFetchStrategy
void setCollectionFetchStrategy(CollectionFetchStrategy strategy)
Sets the collection fetch strategy of the model.
Definition: entitytreemodel.cpp:1179
Akonadi::Collection::CanLinkItem
Can create links to existing items in this virtual collection.
Definition: collection.h:94
Akonadi::Entity::parentCollection
Collection parentCollection() const
Returns the parent collection of this object.
Definition: entity.cpp:187
Akonadi::EntityTreeModel::itemPopulationStrategy
ItemPopulationStrategy itemPopulationStrategy() const
Returns the item population strategy of the model.
Definition: entitytreemodel.cpp:1145
Akonadi::Collection::UrlWithName
A url with identifier and name.
Definition: collection.h:266
Akonadi::EntityTreeModel::AmazingCompletionRole
Role used to implement amazing completion.
Definition: entitytreemodel.h:340
Akonadi::EntityTreeModelPrivate::indexesForItem
QModelIndexList indexesForItem(const Item &item) const
Returns the model indexes for the given item.
Akonadi::Entity::remoteId
QString remoteId() const
Returns the remote id of the entity.
Definition: entity.cpp:82
Akonadi::MimeTypeChecker::wantedMimeTypes
QStringList wantedMimeTypes() const
Returns the list of wanted MIME types this instance checks against.
Definition: mimetypechecker.cpp:52
Akonadi::EntityDisplayAttribute::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the backgroundColor to color.
Definition: entitydisplayattribute.cpp:162
Akonadi::EntityTreeModel::listFilter
Akonadi::CollectionFetchScope::ListFilter listFilter() const
Returns the currently used listfilter.
Definition: entitytreemodel.cpp:99
Akonadi::Collection::CanCreateItem
Can create new items in this collection.
Definition: collection.h:89
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:336
Akonadi::EntityTreeModel::ParentCollectionRole
The parent collection of the entity.
Definition: entitytreemodel.h:341
Akonadi::EntityTreeModel::RemoteIdRole
The remoteId of the entity.
Definition: entitytreemodel.h:338
Akonadi::EntityTreeModel::rootCollectionDisplayName
QString rootCollectionDisplayName() const
Returns the display name of the root collection.
Definition: entitytreemodel.cpp:1173
Akonadi::EntityDisplayAttribute::setDisplayName
void setDisplayName(const QString &name)
Sets the name that should be used for display.
Definition: entitydisplayattribute.cpp:57
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
Akonadi::EntityTreeModel::isFullyPopulated
bool isFullyPopulated() const
Returns whether the model is fully populated.
Definition: entitytreemodel.cpp:968
Akonadi::EntityTreeModel::setListFilter
void setListFilter(Akonadi::CollectionFetchScope::ListFilter filter)
Sets the currently used listfilter.
Definition: entitytreemodel.cpp:105
Akonadi::EntityTreeModel::ImmediatePopulation
Retrieve items immediately when their parent is in the model. This is the default.
Definition: entitytreemodel.h:409
Akonadi::MimeTypeChecker::isWantedCollection
bool isWantedCollection(const Collection &collection) const
Checks whether a given collection has one of the wanted MIME types.
Definition: mimetypechecker.cpp:86
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
Akonadi::EntityTreeModel::modelIndexForCollection
static QModelIndex modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection)
Returns a QModelIndex in model which points to collection.
Definition: entitytreemodel.cpp:1235
Akonadi::EntityTreeModel::setRootCollectionDisplayName
void setRootCollectionDisplayName(const QString &name)
Sets the display name of the root collection of the model.
Definition: entitytreemodel.cpp:1165
Akonadi::CollectionFetchScope::NoFilter
No filtering, retrieve all collections.
Definition: collectionfetchscope.h:133
Akonadi::EntityTreeModel::setItemPopulationStrategy
void setItemPopulationStrategy(ItemPopulationStrategy strategy)
Sets the item population strategy of the model.
Definition: entitytreemodel.cpp:1118
Akonadi::EntityTreeModel::FetchNoCollections
Fetches nothing. This creates an empty model.
Definition: entitytreemodel.h:527
Akonadi::EntityTreeModel::clearAndReset
void clearAndReset()
Clears and resets the model.
Definition: entitytreemodel.cpp:155
Akonadi::EntityTreeModel::ItemListHeaders
Header information for a list of items.
Definition: entitytreemodel.h:385
Akonadi::EntityDisplayAttribute::backgroundColor
QColor backgroundColor() const
Returns the backgroundColor or an invalid color if none is set.
Definition: entitydisplayattribute.cpp:157
Akonadi::EntityTreeModel::AvailablePartsRole
Parts available in the Akonadi server for the item.
Definition: entitytreemodel.h:344
Akonadi::MimeTypeChecker::setWantedMimeTypes
void setWantedMimeTypes(const QStringList &mimeTypes)
Sets the list of wanted MIME types this instance checks against.
Definition: mimetypechecker.cpp:57
Akonadi::EntityTreeModelPrivate::childCollectionNames
QStringList childCollectionNames(const Collection &collection) const
Returns the list of names of the child collections of collection.
Akonadi::EntityTreeModel::collectionFetchStrategy
CollectionFetchStrategy collectionFetchStrategy() const
Returns the collection fetch strategy of the model.
Definition: entitytreemodel.cpp:1204
Akonadi::EntityTreeModel::MimeTypeRole
The mimetype of the entity.
Definition: entitytreemodel.h:333
Akonadi::EntityTreeModel::setShowSystemEntities
void setShowSystemEntities(bool show)
Some Entities are hidden in the model, but exist for internal purposes, for example, custom object directories in groupware resources.
Definition: entitytreemodel.cpp:149
Akonadi::EntityTreeModel::ItemRole
The Item.
Definition: entitytreemodel.h:332
Akonadi::MimeTypeChecker::isWantedItem
bool isWantedItem(const Item &item) const
Checks whether a given item has one of the wanted MIME types.
Definition: mimetypechecker.cpp:72
Akonadi
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
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:147
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:318
Akonadi::ItemModifyJob
Job that modifies an existing item in the Akonadi storage.
Definition: itemmodifyjob.h:97
Akonadi::EntityTreeModel::PendingCutRole
Definition: entitytreemodel.h:348
Akonadi::EntityTreeModel::ColumnCountRole
Definition: entitytreemodel.h:342
Akonadi::EntityTreeModel::FetchingState
There is a fetch of items in this collection in progress.
Definition: entitytreemodel.h:375
Akonadi::CollectionStatistics::unreadCount
qint64 unreadCount() const
Returns the number of unread items in this collection or -1 if this information is not available...
Definition: collectionstatistics.cpp:77
Akonadi::Collection::contentMimeTypes
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:115
Akonadi::Entity::AddIfMissing
Creates the attribute if it is missing.
Definition: entity.h:205
Akonadi::EntityTreeModel::isCollectionTreeFetched
bool isCollectionTreeFetched() const
Returns whether the collection tree has been fetched at initialisation.
Definition: entitytreemodel.cpp:955
Akonadi::EntityTreeModel::~EntityTreeModel
virtual ~EntityTreeModel()
Destroys the entity tree model.
Definition: entitytreemodel.cpp:68
Akonadi::EntityTreeModelPrivate
Definition: entitytreemodel_p.h:59
Akonadi::CollectionFetchScope::Enabled
Only retrieve enabled collections, ignoring the local preference. This is the same as setIncludeUnsub...
Definition: collectionfetchscope.h:137
Akonadi::EntityTreeModel::modelIndexesForItem
static QModelIndexList modelIndexesForItem(const QAbstractItemModel *model, const Item &item)
Returns a QModelIndex in model which points to item.
Definition: entitytreemodel.cpp:1244
Akonadi::EntityTreeModel::match
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits=1, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const
Reimplemented to handle the AmazingCompletionRole.
Definition: entitytreemodel.cpp:990
Akonadi::EntityTreeModel::EntityUrlRole
The akonadi:/ Url of the entity as a string. Item urls will contain the mimetype. ...
Definition: entitytreemodel.h:349
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::EntityTreeModel::CollectionFetchStrategy
CollectionFetchStrategy
Describes what collections shall be fetched by and represent in the model.
Definition: entitytreemodel.h:526
Akonadi::EntityTreeModel::SessionRole
Definition: entitytreemodel.h:345
Akonadi::EntityTreeModel::includeUnsubscribed
AKONADI_DEPRECATED bool includeUnsubscribed() const
Returns whether unsubscribed entities will be included in the listing.
Definition: entitytreemodel.cpp:85
Akonadi::Collection::fromUrl
static Collection fromUrl(const KUrl &url)
Creates a collection from the given url.
Definition: collection.cpp:172
Akonadi::Collection::setReferenced
void setReferenced(bool referenced)
Sets a collection to be referenced.
Definition: collection.cpp:338
Akonadi::Collection::statistics
CollectionStatistics statistics() const
Returns the collection statistics of the collection.
Definition: collection.cpp:238
Akonadi::EntityTreeModel::includeRootCollection
bool includeRootCollection() const
Returns whether the root collection is provided by the model.
Definition: entitytreemodel.cpp:1159
Akonadi::Collection::List
QList< Collection > List
Describes a list of collections.
Definition: collection.h:81
Akonadi::EntityDisplayAttribute
Attribute that stores the properties that are used to display an entity.
Definition: entitydisplayattribute.h:39
Akonadi::Collection::CanChangeCollection
Can change this collection.
Definition: collection.h:91
Akonadi::EntityTreeModel::setIncludeUnsubscribed
AKONADI_DEPRECATED void setIncludeUnsubscribed(bool show)
Sets whether unsubscribed entities will be included in the listing.
Definition: entitytreemodel.cpp:90
Akonadi::EntityTreeModel::CollectionDerefRole
Definition: entitytreemodel.h:347
Akonadi::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:47
Akonadi::EntityTreeModel::setCollectionReferenced
void setCollectionReferenced(const Akonadi::Collection &col, bool referenced=true)
References a collection and starts to monitor it.
Definition: entitytreemodel.cpp:133
Akonadi::EntityTreeModel::ItemIdRole
The item id.
Definition: entitytreemodel.h:331
This file is part of the KDE documentation.
Documentation copyright © 1996-2015 The KDE developers.
Generated on Sun Apr 26 2015 01:25:52 by doxygen 1.8.9.1 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-4.14.7 API Reference

Skip menu "kdepimlibs-4.14.7 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
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