• 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
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 OriginalCollectionNameRole: {
323  return entityData(collection, index.column(), Qt::DisplayRole);
324  }
325  case Qt::BackgroundRole: {
326  if (collection.hasAttribute<EntityDisplayAttribute>()) {
327  EntityDisplayAttribute *eda = collection.attribute<EntityDisplayAttribute>();
328  QColor color = eda->backgroundColor();
329  if (color.isValid()) {
330  return color;
331  }
332  }
333  // fall through.
334  }
335  default:
336  return entityData(collection, index.column(), role);
337  break;
338  }
339 
340  } else if (Node::Item == node->type) {
341  const Item item = d->m_items.value(node->id);
342  if (!item.isValid()) {
343  return QVariant();
344  }
345 
346  switch (role) {
347  case ParentCollectionRole:
348  return QVariant::fromValue(item.parentCollection());
349  case MimeTypeRole:
350  return item.mimeType();
351  break;
352  case RemoteIdRole:
353  return item.remoteId();
354  break;
355  case ItemRole:
356  return QVariant::fromValue(item);
357  break;
358  case ItemIdRole:
359  return item.id();
360  break;
361  case CollectionIdRole:
362  return -1;
363  break;
364  case LoadedPartsRole:
365  return QVariant::fromValue(item.loadedPayloadParts());
366  break;
367  case AvailablePartsRole:
368  return QVariant::fromValue(item.availablePayloadParts());
369  break;
370  case EntityUrlRole:
371  return item.url(Akonadi::Item::UrlWithMimeType).url();
372  break;
373  case Qt::BackgroundRole: {
374  if (item.hasAttribute<EntityDisplayAttribute>()) {
375  EntityDisplayAttribute *eda = item.attribute<EntityDisplayAttribute>();
376  const QColor color = eda->backgroundColor();
377  if (color.isValid()) {
378  return color;
379  }
380  }
381  // fall through.
382  }
383  default:
384  return entityData(item, index.column(), role);
385  break;
386  }
387  }
388 
389  return QVariant();
390 }
391 
392 Qt::ItemFlags EntityTreeModel::flags(const QModelIndex &index) const
393 {
394  Q_D(const EntityTreeModel);
395  // Pass modeltest.
396  if (!index.isValid()) {
397  return 0;
398  }
399 
400  Qt::ItemFlags flags = QAbstractItemModel::flags(index);
401 
402  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
403 
404  if (Node::Collection == node->type) {
405  // cut out entities will be shown as inactive
406  if (d->m_pendingCutCollections.contains(node->id)) {
407  return Qt::ItemIsSelectable;
408  }
409 
410  const Collection collection = d->m_collections.value(node->id);
411  if (collection.isValid()) {
412 
413  if (collection == Collection::root()) {
414  // Selectable and displayable only.
415  return flags;
416  }
417 
418  const int rights = collection.rights();
419 
420  if (rights & Collection::CanChangeCollection) {
421  if (index.column() == 0) {
422  flags |= Qt::ItemIsEditable;
423  }
424  // Changing the collection includes changing the metadata (child entityordering).
425  // Need to allow this by drag and drop.
426  flags |= Qt::ItemIsDropEnabled;
427  }
428  if (rights & (Collection::CanCreateCollection | Collection::CanCreateItem | Collection::CanLinkItem)) {
429  // Can we drop new collections and items into this collection?
430  flags |= Qt::ItemIsDropEnabled;
431  }
432 
433  // dragging is always possible, even for read-only objects, but they can only be copied, not moved.
434  flags |= Qt::ItemIsDragEnabled;
435 
436  }
437  } else if (Node::Item == node->type) {
438  if (d->m_pendingCutItems.contains(node->id)) {
439  return Qt::ItemIsSelectable;
440  }
441 
442  // Rights come from the parent collection.
443 
444  Collection parentCollection;
445  if (!index.parent().isValid()) {
446  parentCollection = d->m_rootCollection;
447  } else {
448  const Node *parentNode = reinterpret_cast<Node *>(index.parent().internalPointer());
449 
450  parentCollection = d->m_collections.value(parentNode->id);
451  }
452  if (parentCollection.isValid()) {
453  const int rights = parentCollection.rights();
454 
455  // Can't drop onto items.
456  if (rights &Collection::CanChangeItem && index.column() == 0) {
457  flags = flags | Qt::ItemIsEditable;
458  }
459  // dragging is always possible, even for read-only objects, but they can only be copied, not moved.
460  flags |= Qt::ItemIsDragEnabled;
461  }
462  }
463 
464  return flags;
465 }
466 
467 Qt::DropActions EntityTreeModel::supportedDropActions() const
468 {
469  return (Qt::CopyAction | Qt::MoveAction | Qt::LinkAction);
470 }
471 
472 QStringList EntityTreeModel::mimeTypes() const
473 {
474  // TODO: Should this return the mimetypes that the items provide? Allow dragging a contact from here for example.
475  return QStringList() << QLatin1String("text/uri-list");
476 }
477 
478 bool EntityTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
479 {
480  Q_UNUSED(row);
481  Q_UNUSED(column);
482  Q_D(EntityTreeModel);
483 
484  // Can't drop onto Collection::root.
485  if (!parent.isValid()) {
486  return false;
487  }
488 
489  // TODO Use action and collection rights and return false if necessary
490 
491  // if row and column are -1, then the drop was on parent directly.
492  // data should then be appended on the end of the items of the collections as appropriate.
493  // That will mean begin insert rows etc.
494  // Otherwise it was a sibling of the row^th item of parent.
495  // Needs to be handled when ordering is accounted for.
496 
497  // Handle dropping between items as well as on items.
498 // if ( row != -1 && column != -1 )
499 // {
500 // }
501 
502  if (action == Qt::IgnoreAction) {
503  return true;
504  }
505 
506 // Shouldn't do this. Need to be able to drop vcards for example.
507 // if ( !data->hasFormat( "text/uri-list" ) )
508 // return false;
509 
510  Node *node = reinterpret_cast<Node *>(parent.internalId());
511 
512  Q_ASSERT(node);
513 
514  if (Node::Item == node->type) {
515  if (!parent.parent().isValid()) {
516  // The drop is somehow on an item with no parent (shouldn't happen)
517  // The drop should be considered handled anyway.
518  kWarning() << "Dropped onto item with no parent collection";
519  return true;
520  }
521 
522  // A drop onto an item should be considered as a drop onto its parent collection
523  node = reinterpret_cast<Node *>(parent.parent().internalId());
524  }
525 
526  if (Node::Collection == node->type) {
527  const Collection destCollection = d->m_collections.value(node->id);
528 
529  // Applications can't create new collections in root. Only resources can.
530  if (destCollection == Collection::root()) {
531  // Accept the event so that it doesn't propagate.
532  return true;
533  }
534 
535  if (data->hasFormat(QLatin1String("text/uri-list"))) {
536 
537  MimeTypeChecker mimeChecker;
538  mimeChecker.setWantedMimeTypes(destCollection.contentMimeTypes());
539 
540  const KUrl::List urls = KUrl::List::fromMimeData(data);
541  foreach (const KUrl &url, urls) {
542  const Collection collection = d->m_collections.value(Collection::fromUrl(url).id());
543  if (collection.isValid()) {
544  if (collection.parentCollection().id() == destCollection.id() &&
545  action != Qt::CopyAction) {
546  kDebug() << "Error: source and destination of move are the same.";
547  return false;
548  }
549 
550  if (!mimeChecker.isWantedCollection(collection)) {
551  kDebug() << "unwanted collection" << mimeChecker.wantedMimeTypes() << collection.contentMimeTypes();
552  return false;
553  }
554 
555  if (url.hasQueryItem(QLatin1String("name"))) {
556  const QString collectionName = url.queryItemValue(QLatin1String("name"));
557  const QStringList collectionNames = d->childCollectionNames(destCollection);
558 
559  if (collectionNames.contains(collectionName)) {
560  KMessageBox::error(0, i18n("The target collection '%1' contains already\na collection with name '%2'.",
561  destCollection.name(), collection.name()));
562  return false;
563  }
564  }
565  } else {
566  const Item item = d->m_items.value(Item::fromUrl(url).id());
567  if (item.isValid()) {
568  if (item.parentCollection().id() == destCollection.id() && action != Qt::CopyAction) {
569  kDebug() << "Error: source and destination of move are the same.";
570  return false;
571  }
572 
573  if (!mimeChecker.isWantedItem(item)) {
574  kDebug() << "unwanted item" << mimeChecker.wantedMimeTypes() << item.mimeType();
575  return false;
576  }
577  }
578  }
579  }
580 
581  KJob *job = PasteHelper::pasteUriList(data, destCollection, action, d->m_session);
582  if (!job) {
583  return false;
584  }
585 
586  connect(job, SIGNAL(result(KJob*)), SLOT(pasteJobDone(KJob*)));
587 
588  // Accpet the event so that it doesn't propagate.
589  return true;
590  } else {
591 // not a set of uris. Maybe vcards etc. Check if the parent supports them, and maybe do
592  // fromMimeData for them. Hmm, put it in the same transaction with the above?
593  // TODO: This should be handled first, not last.
594  }
595  }
596 
597  return false;
598 }
599 
600 QModelIndex EntityTreeModel::index(int row, int column, const QModelIndex &parent) const
601 {
602 
603  Q_D(const EntityTreeModel);
604 
605  if (parent.column() > 0) {
606  return QModelIndex();
607  }
608 
609  //TODO: don't use column count here? Use some d-> func.
610  if (column >= columnCount() ||
611  column < 0) {
612  return QModelIndex();
613  }
614 
615  QList<Node *> childEntities;
616 
617  const Node *parentNode = reinterpret_cast<Node *>(parent.internalPointer());
618 
619  if (!parentNode || !parent.isValid()) {
620  if (d->m_showRootCollection) {
621  childEntities << d->m_childEntities.value(-1);
622  } else {
623  childEntities = d->m_childEntities.value(d->m_rootCollection.id());
624  }
625  } else {
626  if (parentNode->id >= 0) {
627  childEntities = d->m_childEntities.value(parentNode->id);
628  }
629  }
630 
631  const int size = childEntities.size();
632  if (row < 0 || row >= size) {
633  return QModelIndex();
634  }
635 
636  Node *node = childEntities.at(row);
637 
638  return createIndex(row, column, reinterpret_cast<void *>(node));
639 }
640 
641 QModelIndex EntityTreeModel::parent(const QModelIndex &index) const
642 {
643  Q_D(const EntityTreeModel);
644 
645  if (!index.isValid()) {
646  return QModelIndex();
647  }
648 
649  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
650  d->m_collectionFetchStrategy == FetchNoCollections) {
651  return QModelIndex();
652  }
653 
654  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
655 
656  if (!node) {
657  return QModelIndex();
658  }
659 
660  const Collection collection = d->m_collections.value(node->parent);
661 
662  if (!collection.isValid()) {
663  return QModelIndex();
664  }
665 
666  if (collection.id() == d->m_rootCollection.id()) {
667  if (!d->m_showRootCollection) {
668  return QModelIndex();
669  } else {
670  return createIndex(0, 0, reinterpret_cast<void *>(d->m_rootNode));
671  }
672  }
673 
674  Q_ASSERT(collection.parentCollection().isValid());
675  const int row = d->indexOf<Node::Collection>(d->m_childEntities.value(collection.parentCollection().id()), collection.id());
676 
677  Q_ASSERT(row >= 0);
678  Node *parentNode = d->m_childEntities.value(collection.parentCollection().id()).at(row);
679 
680  return createIndex(row, 0, reinterpret_cast<void *>(parentNode));
681 }
682 
683 int EntityTreeModel::rowCount(const QModelIndex &parent) const
684 {
685  Q_D(const EntityTreeModel);
686 
687  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
688  d->m_collectionFetchStrategy == FetchNoCollections) {
689  if (parent.isValid()) {
690  return 0;
691  } else {
692  return d->m_items.size();
693  }
694  }
695 
696  if (!parent.isValid()) {
697  // If we're showing the root collection then it will be the only child of the root.
698  if (d->m_showRootCollection) {
699  return d->m_childEntities.value(-1).size();
700  }
701  return d->m_childEntities.value(d->m_rootCollection.id()).size();
702  }
703 
704  if (parent.column() != 0) {
705  return 0;
706  }
707 
708  const Node *node = reinterpret_cast<Node *>(parent.internalPointer());
709 
710  if (!node) {
711  return 0;
712  }
713 
714  if (Node::Item == node->type) {
715  return 0;
716  }
717 
718  Q_ASSERT(parent.isValid());
719  return d->m_childEntities.value(node->id).size();
720 }
721 
722 int EntityTreeModel::entityColumnCount(HeaderGroup headerGroup) const
723 {
724  // Not needed in this model.
725  Q_UNUSED(headerGroup);
726 
727  return 1;
728 }
729 
730 QVariant EntityTreeModel::entityHeaderData(int section, Qt::Orientation orientation, int role, HeaderGroup headerGroup) const
731 {
732  Q_D(const EntityTreeModel);
733  // Not needed in this model.
734  Q_UNUSED(headerGroup);
735 
736  if (section == 0 &&
737  orientation == Qt::Horizontal &&
738  role == Qt::DisplayRole) {
739  if (d->m_rootCollection == Collection::root()) {
740  return i18nc("@title:column Name of a thing", "Name");
741  }
742  return d->m_rootCollection.name();
743  }
744 
745  return QAbstractItemModel::headerData(section, orientation, role);
746 }
747 
748 QVariant EntityTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
749 {
750  const HeaderGroup headerGroup = static_cast<HeaderGroup>((role / static_cast<int>(TerminalUserRole)));
751 
752  role %= TerminalUserRole;
753  return entityHeaderData(section, orientation, role, headerGroup);
754 }
755 
756 QMimeData *EntityTreeModel::mimeData(const QModelIndexList &indexes) const
757 {
758  Q_D(const EntityTreeModel);
759 
760  QMimeData *data = new QMimeData();
761  KUrl::List urls;
762  foreach (const QModelIndex &index, indexes) {
763  if (index.column() != 0) {
764  continue;
765  }
766 
767  if (!index.isValid()) {
768  continue;
769  }
770 
771  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
772 
773  if (Node::Collection == node->type) {
774  urls << d->m_collections.value(node->id).url(Collection::UrlWithName);
775  } else if (Node::Item == node->type) {
776  KUrl url = d->m_items.value(node->id).url(Item::UrlWithMimeType);
777  // Encode the "virtual" parent
778  url.addQueryItem(QLatin1String("parent"), QString::number(node->parent));
779  urls << url;
780  } else { // if that happens something went horrible wrong
781  Q_ASSERT(false);
782  }
783  }
784 
785  urls.populateMimeData(data);
786 
787  return data;
788 }
789 
790 // Always return false for actions which take place asyncronously, eg via a Job.
791 bool EntityTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
792 {
793  Q_D(EntityTreeModel);
794 
795  const Node *node = reinterpret_cast<Node *>(index.internalPointer());
796 
797  if (role == PendingCutRole) {
798  if (index.isValid() && value.toBool()) {
799  if (Node::Collection == node->type) {
800  d->m_pendingCutCollections.append(node->id);
801  }
802 
803  if (Node::Item == node->type) {
804  d->m_pendingCutItems.append(node->id);
805  }
806  } else {
807  d->m_pendingCutCollections.clear();
808  d->m_pendingCutItems.clear();
809  }
810  return true;
811  }
812 
813  if (index.isValid() &&
814  node->type == Node::Collection &&
815  (role == CollectionRefRole ||
816  role == CollectionDerefRole)) {
817  const Collection collection = index.data(CollectionRole).value<Collection>();
818  Q_ASSERT(collection.isValid());
819 
820  if (role == CollectionDerefRole) {
821  d->deref(collection.id());
822  } else if (role == CollectionRefRole) {
823  d->ref(collection.id());
824  }
825  return true;
826  }
827 
828  if (index.column() == 0 &&
829  (role &(Qt::EditRole | ItemRole | CollectionRole))) {
830  if (Node::Collection == node->type) {
831 
832  Collection collection = d->m_collections.value(node->id);
833 
834  if (!collection.isValid() || !value.isValid()) {
835  return false;
836  }
837 
838  if (Qt::EditRole == role) {
839  collection.setName(value.toString());
840 
841  if (collection.hasAttribute<EntityDisplayAttribute>()) {
842  EntityDisplayAttribute *displayAttribute = collection.attribute<EntityDisplayAttribute>();
843  displayAttribute->setDisplayName(value.toString());
844  }
845  }
846 
847  if (Qt::BackgroundRole == role) {
848  QColor color = value.value<QColor>();
849 
850  if (!color.isValid()) {
851  return false;
852  }
853 
854  EntityDisplayAttribute *eda = collection.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
855  eda->setBackgroundColor(color);
856  }
857 
858  if (CollectionRole == role) {
859  collection = value.value<Collection>();
860  }
861 
862  CollectionModifyJob *job = new CollectionModifyJob(collection, d->m_session);
863  connect(job, SIGNAL(result(KJob*)),
864  SLOT(updateJobDone(KJob*)));
865 
866  return false;
867  } else if (Node::Item == node->type) {
868 
869  Item item = d->m_items.value(node->id);
870 
871  if (!item.isValid() || !value.isValid()) {
872  return false;
873  }
874 
875  if (Qt::EditRole == role) {
876  if (item.hasAttribute<EntityDisplayAttribute>()) {
877  EntityDisplayAttribute *displayAttribute = item.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
878  displayAttribute->setDisplayName(value.toString());
879  }
880  }
881 
882  if (Qt::BackgroundRole == role) {
883  QColor color = value.value<QColor>();
884 
885  if (!color.isValid()) {
886  return false;
887  }
888 
889  EntityDisplayAttribute *eda = item.attribute<EntityDisplayAttribute>(Entity::AddIfMissing);
890  eda->setBackgroundColor(color);
891  }
892 
893  if (ItemRole == role) {
894  item = value.value<Item>();
895  Q_ASSERT(item.id() == node->id);
896  }
897 
898  ItemModifyJob *itemModifyJob = new ItemModifyJob(item, d->m_session);
899  connect(itemModifyJob, SIGNAL(result(KJob*)),
900  SLOT(updateJobDone(KJob*)));
901 
902  return false;
903  }
904  }
905 
906  return QAbstractItemModel::setData(index, value, role);
907 }
908 
909 bool EntityTreeModel::canFetchMore(const QModelIndex &parent) const
910 {
911  Q_UNUSED(parent)
912  return false;
913 }
914 
915 void EntityTreeModel::fetchMore(const QModelIndex &parent)
916 {
917  Q_D(EntityTreeModel);
918 
919  if (!d->canFetchMore(parent)) {
920  return;
921  }
922 
923  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch) {
924  return;
925  }
926 
927  if (d->m_itemPopulation == ImmediatePopulation) {
928  // Nothing to do. The items are already in the model.
929  return;
930  } else if (d->m_itemPopulation == LazyPopulation) {
931  const Collection collection = parent.data(CollectionRole).value<Collection>();
932 
933  if (!collection.isValid()) {
934  return;
935  }
936 
937  d->fetchItems(collection);
938  }
939 }
940 
941 bool EntityTreeModel::hasChildren(const QModelIndex &parent) const
942 {
943  Q_D(const EntityTreeModel);
944 
945  if (d->m_collectionFetchStrategy == InvisibleCollectionFetch ||
946  d->m_collectionFetchStrategy == FetchNoCollections) {
947  return parent.isValid() ? false : !d->m_items.isEmpty();
948  }
949 
950  // TODO: Empty collections right now will return true and get a little + to expand.
951  // There is probably no way to tell if a collection
952  // has child items in akonadi without first attempting an itemFetchJob...
953  // Figure out a way to fix this. (Statistics)
954  return ((rowCount(parent) > 0) ||
955  (canFetchMore(parent) && d->m_itemPopulation == LazyPopulation));
956 }
957 
958 bool EntityTreeModel::isCollectionTreeFetched() const
959 {
960  Q_D(const EntityTreeModel);
961 
962  return d->m_collectionTreeFetched;
963 }
964 
965 bool EntityTreeModel::isCollectionPopulated(Collection::Id id) const
966 {
967  Q_D(const EntityTreeModel);
968  return d->m_populatedCols.contains(id);
969 }
970 
971 bool EntityTreeModel::isFullyPopulated() const
972 {
973  Q_D(const EntityTreeModel);
974  return d->m_collectionTreeFetched && d->m_pendingCollectionRetrieveJobs.isEmpty();
975 }
976 
977 bool EntityTreeModel::entityMatch(const Item &item, const QVariant &value, Qt::MatchFlags flags) const
978 {
979  Q_UNUSED(item);
980  Q_UNUSED(value);
981  Q_UNUSED(flags);
982  return false;
983 }
984 
985 bool EntityTreeModel::entityMatch(const Collection &collection, const QVariant &value, Qt::MatchFlags flags) const
986 {
987  Q_UNUSED(collection);
988  Q_UNUSED(value);
989  Q_UNUSED(flags);
990  return false;
991 }
992 
993 QModelIndexList EntityTreeModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
994 {
995  Q_D(const EntityTreeModel);
996 
997  if (role == CollectionIdRole || role == CollectionRole) {
998  Collection::Id id;
999  if (role == CollectionRole) {
1000  const Collection collection = value.value<Collection>();
1001  id = collection.id();
1002  } else {
1003  id = value.toLongLong();
1004  }
1005 
1006  QModelIndexList list;
1007 
1008  const Collection collection = d->m_collections.value(id);
1009 
1010  if (!collection.isValid()) {
1011  return list;
1012  }
1013 
1014  const QModelIndex collectionIndex = d->indexForCollection(collection);
1015  Q_ASSERT(collectionIndex.isValid());
1016  list << collectionIndex;
1017 
1018  return list;
1019  }
1020 
1021  if (role == ItemIdRole || role == ItemRole) {
1022  Item::Id id;
1023  if (role == ItemRole) {
1024  const Item item = value.value<Item>();
1025  id = item.id();
1026  } else {
1027  id = value.toLongLong();
1028  }
1029  QModelIndexList list;
1030 
1031  const Item item = d->m_items.value(id);
1032  if (!item.isValid()) {
1033  return list;
1034  }
1035 
1036  return d->indexesForItem(item);
1037  }
1038 
1039  if (role == EntityUrlRole) {
1040  const KUrl url(value.toString());
1041  const Item item = Item::fromUrl(url);
1042 
1043  if (item.isValid()) {
1044  return d->indexesForItem(d->m_items.value(item.id()));
1045  }
1046 
1047  const Collection collection = Collection::fromUrl(url);
1048  QModelIndexList list;
1049  if (collection.isValid()) {
1050  list << d->indexForCollection(collection);
1051  }
1052 
1053  return list;
1054  }
1055 
1056  if (role != AmazingCompletionRole) {
1057  return QAbstractItemModel::match(start, role, value, hits, flags);
1058  }
1059 
1060  // Try to match names, and email addresses.
1061  QModelIndexList list;
1062 
1063  if (role < 0 ||
1064  !start.isValid() ||
1065  !value.isValid()) {
1066  return list;
1067  }
1068 
1069  const int column = 0;
1070  int row = start.row();
1071  const QModelIndex parentIndex = start.parent();
1072  const int parentRowCount = rowCount(parentIndex);
1073 
1074  while (row < parentRowCount &&
1075  (hits == -1 || list.size() < hits)) {
1076  const QModelIndex idx = index(row, column, parentIndex);
1077  const Item item = idx.data(ItemRole).value<Item>();
1078 
1079  if (!item.isValid()) {
1080  const Collection collection = idx.data(CollectionRole).value<Collection>();
1081  if (!collection.isValid()) {
1082  continue;
1083  }
1084 
1085  if (entityMatch(collection, value, flags)) {
1086  list << idx;
1087  }
1088 
1089  } else {
1090  if (entityMatch(item, value, flags)) {
1091  list << idx;
1092  }
1093  }
1094 
1095  ++row;
1096  }
1097 
1098  return list;
1099 }
1100 
1101 bool EntityTreeModel::insertRows(int, int, const QModelIndex &)
1102 {
1103  return false;
1104 }
1105 
1106 bool EntityTreeModel::insertColumns(int, int, const QModelIndex &)
1107 {
1108  return false;
1109 }
1110 
1111 bool EntityTreeModel::removeRows(int, int, const QModelIndex &)
1112 {
1113  return false;
1114 }
1115 
1116 bool EntityTreeModel::removeColumns(int, int, const QModelIndex &)
1117 {
1118  return false;
1119 }
1120 
1121 void EntityTreeModel::setItemPopulationStrategy(ItemPopulationStrategy strategy)
1122 {
1123  Q_D(EntityTreeModel);
1124  d->beginResetModel();
1125  d->m_itemPopulation = strategy;
1126 
1127  if (strategy == NoItemPopulation) {
1128  disconnect(d->m_monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)),
1129  this, SLOT(monitoredItemAdded(Akonadi::Item,Akonadi::Collection)));
1130  disconnect(d->m_monitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
1131  this, SLOT(monitoredItemChanged(Akonadi::Item,QSet<QByteArray>)));
1132  disconnect(d->m_monitor, SIGNAL(itemRemoved(Akonadi::Item)),
1133  this, SLOT(monitoredItemRemoved(Akonadi::Item)));
1134  disconnect(d->m_monitor, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)),
1135  this, SLOT(monitoredItemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)));
1136 
1137  disconnect(d->m_monitor, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
1138  this, SLOT(monitoredItemLinked(Akonadi::Item,Akonadi::Collection)));
1139  disconnect(d->m_monitor, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
1140  this, SLOT(monitoredItemUnlinked(Akonadi::Item,Akonadi::Collection)));
1141  }
1142 
1143  d->m_monitor->d_ptr->useRefCounting = (strategy == LazyPopulation);
1144 
1145  d->endResetModel();
1146 }
1147 
1148 EntityTreeModel::ItemPopulationStrategy EntityTreeModel::itemPopulationStrategy() const
1149 {
1150  Q_D(const EntityTreeModel);
1151  return d->m_itemPopulation;
1152 }
1153 
1154 void EntityTreeModel::setIncludeRootCollection(bool include)
1155 {
1156  Q_D(EntityTreeModel);
1157  d->beginResetModel();
1158  d->m_showRootCollection = include;
1159  d->endResetModel();
1160 }
1161 
1162 bool EntityTreeModel::includeRootCollection() const
1163 {
1164  Q_D(const EntityTreeModel);
1165  return d->m_showRootCollection;
1166 }
1167 
1168 void EntityTreeModel::setRootCollectionDisplayName(const QString &displayName)
1169 {
1170  Q_D(EntityTreeModel);
1171  d->m_rootCollectionDisplayName = displayName;
1172 
1173  // TODO: Emit datachanged if it is being shown.
1174 }
1175 
1176 QString EntityTreeModel::rootCollectionDisplayName() const
1177 {
1178  Q_D(const EntityTreeModel);
1179  return d->m_rootCollectionDisplayName;
1180 }
1181 
1182 void EntityTreeModel::setCollectionFetchStrategy(CollectionFetchStrategy strategy)
1183 {
1184  Q_D(EntityTreeModel);
1185  d->beginResetModel();
1186  d->m_collectionFetchStrategy = strategy;
1187 
1188  if (strategy == FetchNoCollections ||
1189  strategy == InvisibleCollectionFetch) {
1190  disconnect(d->m_monitor, SIGNAL(collectionChanged(Akonadi::Collection)),
1191  this, SLOT(monitoredCollectionChanged(Akonadi::Collection)));
1192  disconnect(d->m_monitor, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
1193  this, SLOT(monitoredCollectionAdded(Akonadi::Collection,Akonadi::Collection)));
1194  disconnect(d->m_monitor, SIGNAL(collectionRemoved(Akonadi::Collection)),
1195  this, SLOT(monitoredCollectionRemoved(Akonadi::Collection)));
1196  disconnect(d->m_monitor,
1197  SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)),
1198  this, SLOT(monitoredCollectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)));
1199  d->m_monitor->fetchCollection(false);
1200  } else {
1201  d->m_monitor->fetchCollection(true);
1202  }
1203 
1204  d->endResetModel();
1205 }
1206 
1207 EntityTreeModel::CollectionFetchStrategy EntityTreeModel::collectionFetchStrategy() const
1208 {
1209  Q_D(const EntityTreeModel);
1210  return d->m_collectionFetchStrategy;
1211 }
1212 
1213 static QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> proxiesAndModel(const QAbstractItemModel *model)
1214 {
1215  QList<const QAbstractProxyModel *> proxyChain;
1216  const QAbstractProxyModel *proxy = qobject_cast<const QAbstractProxyModel *>(model);
1217  const QAbstractItemModel *_model = model;
1218  while (proxy) {
1219  proxyChain.prepend(proxy);
1220  _model = proxy->sourceModel();
1221  proxy = qobject_cast<const QAbstractProxyModel *>(_model);
1222  }
1223 
1224  const EntityTreeModel *etm = qobject_cast<const EntityTreeModel *>(_model);
1225  return qMakePair(proxyChain, etm);
1226 }
1227 
1228 static QModelIndex proxiedIndex(const QModelIndex &idx, QList<const QAbstractProxyModel *> proxyChain)
1229 {
1230  QListIterator<const QAbstractProxyModel *> it(proxyChain);
1231  QModelIndex _idx = idx;
1232  while (it.hasNext()) {
1233  _idx = it.next()->mapFromSource(_idx);
1234  }
1235  return _idx;
1236 }
1237 
1238 QModelIndex EntityTreeModel::modelIndexForCollection(const QAbstractItemModel *model, const Collection &collection)
1239 {
1240  QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> pair = proxiesAndModel(model);
1241 
1242  Q_ASSERT(pair.second);
1243  QModelIndex idx = pair.second->d_ptr->indexForCollection(collection);
1244  return proxiedIndex(idx, pair.first);
1245 }
1246 
1247 QModelIndexList EntityTreeModel::modelIndexesForItem(const QAbstractItemModel *model, const Item &item)
1248 {
1249  QPair<QList<const QAbstractProxyModel *>, const EntityTreeModel *> pair = proxiesAndModel(model);
1250 
1251  if (!pair.second) {
1252  kWarning() << "Couldn't find an EntityTreeModel";
1253  return QModelIndexList();
1254  }
1255 
1256  QModelIndexList list = pair.second->d_ptr->indexesForItem(item);
1257  QModelIndexList proxyList;
1258  foreach (const QModelIndex &idx, list) {
1259  const QModelIndex pIdx = proxiedIndex(idx, pair.first);
1260  if (pIdx.isValid()) {
1261  proxyList << pIdx;
1262  }
1263  }
1264  return proxyList;
1265 }
1266 
1267 #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:977
Akonadi::CollectionModifyJob
Job that modifies a collection in the Akonadi storage.
Definition: collectionmodifyjob.h:82
QVariant::toLongLong
qlonglong toLongLong(bool *ok) const
QModelIndex
Akonadi::EntityTreeModel::setIncludeRootCollection
void setIncludeRootCollection(bool include)
Sets whether the root collection shall be provided by the model.
Definition: entitytreemodel.cpp:1154
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:356
Akonadi::EntityTreeModel::CollectionRefRole
Definition: entitytreemodel.h:346
Akonadi::CollectionStatistics
Provides statistics information of a Collection.
Definition: collectionstatistics.h:69
QAbstractProxyModel
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:531
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
QMimeData::hasFormat
virtual bool hasFormat(const QString &mimeType) const
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:408
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:409
QList::at
const T & at(int i) const
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
Akonadi::Entity::Id
qint64 Id
Describes the unique id type.
Definition: entity.h:65
Qt::MatchFlags
typedef MatchFlags
QVariant::value
T value() const
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
QAbstractItemModel::insertRows
virtual bool insertRows(int row, int count, const QModelIndex &parent)
QModelIndex::internalId
qint64 internalId() const
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:730
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QList::const_iterator
Akonadi::EntityTreeModel::IdleState
There is no fetch of items in this collection in progress.
Definition: entitytreemodel.h:375
QMimeData
Akonadi::EntityTreeModel::isCollectionPopulated
bool isCollectionPopulated(Akonadi::Collection::Id) const
Returns whether the collection has been populated.
Definition: entitytreemodel.cpp:965
Akonadi::Collection::setName
void setName(const QString &name)
Sets the i18n'ed name of the collection.
Definition: collection.cpp:93
QList::size
int size() const
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:385
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:383
Akonadi::EntityTreeModel::LazyPopulation
Fetch items only when requested (using canFetchMore/fetchMore)
Definition: entitytreemodel.h:411
QAbstractItemModel::match
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, QFlags< Qt::MatchFlag > flags) const
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:167
QModelIndex::isValid
bool isValid() const
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:1182
QString::number
QString number(int n, int base)
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:185
Akonadi::EntityTreeModel::itemPopulationStrategy
ItemPopulationStrategy itemPopulationStrategy() const
Returns the item population strategy of the model.
Definition: entitytreemodel.cpp:1148
Akonadi::Collection::UrlWithName
A url with identifier and name.
Definition: collection.h:266
QObject
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
QString::isEmpty
bool isEmpty() const
Akonadi::MimeTypeChecker::wantedMimeTypes
QStringList wantedMimeTypes() const
Returns the list of wanted MIME types this instance checks against.
Definition: mimetypechecker.cpp:52
QModelIndex::row
int row() const
Akonadi::EntityDisplayAttribute::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the backgroundColor to color.
Definition: entitydisplayattribute.cpp:162
QAbstractItemModel::removeColumns
virtual bool removeColumns(int column, int count, const QModelIndex &parent)
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
QModelIndex::internalPointer
void * internalPointer() const
QSet< QByteArray >
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:336
QString
QList
QColor
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:1176
Akonadi::EntityDisplayAttribute::setDisplayName
void setDisplayName(const QString &name)
Sets the name that should be used for display.
Definition: entitydisplayattribute.cpp:57
QModelIndex::parent
QModelIndex parent() const
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:971
QStringList
QAbstractItemModel::headerData
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const
Akonadi::EntityTreeModel::setListFilter
void setListFilter(Akonadi::CollectionFetchScope::ListFilter filter)
Sets the currently used listfilter.
Definition: entitytreemodel.cpp:105
QPair
Akonadi::EntityTreeModel::ImmediatePopulation
Retrieve items immediately when their parent is in the model. This is the default.
Definition: entitytreemodel.h:410
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:1238
Akonadi::EntityTreeModel::setRootCollectionDisplayName
void setRootCollectionDisplayName(const QString &name)
Sets the display name of the root collection of the model.
Definition: entitytreemodel.cpp:1168
QAbstractItemModel::createIndex
QModelIndex createIndex(int row, int column, void *ptr) const
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:1121
QAbstractItemModel::insertColumns
virtual bool insertColumns(int column, int count, const QModelIndex &parent)
Akonadi::EntityTreeModel::OriginalCollectionNameRole
Returns original name for collection.
Definition: entitytreemodel.h:354
QVariant::fromValue
QVariant fromValue(const T &value)
QAbstractItemModel::removeRows
virtual bool removeRows(int row, int count, const QModelIndex &parent)
Akonadi::EntityTreeModel::FetchNoCollections
Fetches nothing. This creates an empty model.
Definition: entitytreemodel.h:528
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:386
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
QAbstractProxyModel::sourceModel
QAbstractItemModel * sourceModel() const
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:1207
QModelIndex::data
QVariant data(int role) const
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
QLatin1String
Qt::DropActions
typedef DropActions
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::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
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:376
QModelIndex::column
int column() const
QVariant::toBool
bool toBool() const
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
QAbstractItemModel
QAbstractItemModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
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:958
QVariant::isValid
bool isValid() const
QAbstractItemModel::flags
virtual Qt::ItemFlags flags(const QModelIndex &index) const
Akonadi::EntityTreeModel::~EntityTreeModel
virtual ~EntityTreeModel()
Destroys the entity tree model.
Definition: entitytreemodel.cpp:68
QList::prepend
void prepend(const T &value)
QListIterator
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:1247
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:993
QList::constEnd
const_iterator constEnd() const
Akonadi::EntityTreeModel::EntityUrlRole
The akonadi:/ Url of the entity as a string. Item urls will contain the mimetype. ...
Definition: entitytreemodel.h:349
QList::constBegin
const_iterator constBegin() const
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:527
Akonadi::EntityTreeModel::SessionRole
Definition: entitytreemodel.h:345
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
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
QVariant::toString
QString toString() const
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:1162
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
QColor::isValid
bool isValid() const
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
QVariant
Qt::ItemFlags
typedef ItemFlags
Akonadi::EntityTreeModel::ItemIdRole
The item id.
Definition: entitytreemodel.h:331
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