• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 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
49Q_DECLARE_METATYPE(QSet<QByteArray>)
50
51using namespace Akonadi;
52
53EntityTreeModel::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
61EntityTreeModel::EntityTreeModel(ChangeRecorder *monitor, EntityTreeModelPrivate *d, QObject *parent)
62 : QAbstractItemModel(parent)
63 , d_ptr(d)
64{
65 d->init(monitor);
66}
67
68EntityTreeModel::~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
85bool EntityTreeModel::includeUnsubscribed() const
86{
87 return (listFilter() == CollectionFetchScope::NoFilter);
88}
89
90void EntityTreeModel::setIncludeUnsubscribed(bool show)
91{
92 if (show) {
93 setListFilter(CollectionFetchScope::NoFilter);
94 } else {
95 setListFilter(CollectionFetchScope::Enabled);
96 }
97}
98
99CollectionFetchScope::ListFilter EntityTreeModel::listFilter() const
100{
101 Q_D(const EntityTreeModel);
102 return d->m_listFilter;
103}
104
105void 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
114void 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
127void EntityTreeModel::setCollectionMonitored(const Collection &col, bool monitored)
128{
129 Q_D(EntityTreeModel);
130 d->m_monitor->setCollectionMonitored(col, monitored);
131}
132
133void 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
143bool EntityTreeModel::systemEntitiesShown() const
144{
145 Q_D(const EntityTreeModel);
146 return d->m_showSystemEntities;
147}
148
149void EntityTreeModel::setShowSystemEntities(bool show)
150{
151 Q_D(EntityTreeModel);
152 d->m_showSystemEntities = show;
153}
154
155void EntityTreeModel::clearAndReset()
156{
157 Q_D(EntityTreeModel);
158 d->beginResetModel();
159 d->endResetModel();
160}
161
162int 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
173QVariant 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
203QVariant 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
247QVariant 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
392Qt::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
467Qt::DropActions EntityTreeModel::supportedDropActions() const
468{
469 return (Qt::CopyAction | Qt::MoveAction | Qt::LinkAction);
470}
471
472QStringList 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
478bool 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
600QModelIndex 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
641QModelIndex 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
683int 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
722int EntityTreeModel::entityColumnCount(HeaderGroup headerGroup) const
723{
724 // Not needed in this model.
725 Q_UNUSED(headerGroup);
726
727 return 1;
728}
729
730QVariant 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
748QVariant 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
756QMimeData *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.
791bool 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
909bool EntityTreeModel::canFetchMore(const QModelIndex &parent) const
910{
911 Q_UNUSED(parent)
912 return false;
913}
914
915void 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
941bool 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
958bool EntityTreeModel::isCollectionTreeFetched() const
959{
960 Q_D(const EntityTreeModel);
961
962 return d->m_collectionTreeFetched;
963}
964
965bool EntityTreeModel::isCollectionPopulated(Collection::Id id) const
966{
967 Q_D(const EntityTreeModel);
968 return d->m_populatedCols.contains(id);
969}
970
971bool EntityTreeModel::isFullyPopulated() const
972{
973 Q_D(const EntityTreeModel);
974 return d->m_collectionTreeFetched && d->m_pendingCollectionRetrieveJobs.isEmpty();
975}
976
977bool 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
985bool 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
993QModelIndexList 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
1101bool EntityTreeModel::insertRows(int, int, const QModelIndex &)
1102{
1103 return false;
1104}
1105
1106bool EntityTreeModel::insertColumns(int, int, const QModelIndex &)
1107{
1108 return false;
1109}
1110
1111bool EntityTreeModel::removeRows(int, int, const QModelIndex &)
1112{
1113 return false;
1114}
1115
1116bool EntityTreeModel::removeColumns(int, int, const QModelIndex &)
1117{
1118 return false;
1119}
1120
1121void 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
1148EntityTreeModel::ItemPopulationStrategy EntityTreeModel::itemPopulationStrategy() const
1149{
1150 Q_D(const EntityTreeModel);
1151 return d->m_itemPopulation;
1152}
1153
1154void EntityTreeModel::setIncludeRootCollection(bool include)
1155{
1156 Q_D(EntityTreeModel);
1157 d->beginResetModel();
1158 d->m_showRootCollection = include;
1159 d->endResetModel();
1160}
1161
1162bool EntityTreeModel::includeRootCollection() const
1163{
1164 Q_D(const EntityTreeModel);
1165 return d->m_showRootCollection;
1166}
1167
1168void 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
1176QString EntityTreeModel::rootCollectionDisplayName() const
1177{
1178 Q_D(const EntityTreeModel);
1179 return d->m_rootCollectionDisplayName;
1180}
1181
1182void 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
1207EntityTreeModel::CollectionFetchStrategy EntityTreeModel::collectionFetchStrategy() const
1208{
1209 Q_D(const EntityTreeModel);
1210 return d->m_collectionFetchStrategy;
1211}
1212
1213static 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
1228static 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
1238QModelIndex 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
1247QModelIndexList 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::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:48
Akonadi::CollectionFetchScope::ListFilter
ListFilter
Describes the list filter.
Definition: collectionfetchscope.h:132
Akonadi::CollectionFetchScope::NoFilter
@ NoFilter
No filtering, retrieve all collections.
Definition: collectionfetchscope.h:133
Akonadi::CollectionFetchScope::Enabled
@ Enabled
Only retrieve enabled collections, ignoring the local preference. This is the same as setIncludeUnsub...
Definition: collectionfetchscope.h:137
Akonadi::CollectionModifyJob
Job that modifies a collection in the Akonadi storage.
Definition: collectionmodifyjob.h:83
Akonadi::CollectionStatistics
Provides statistics information of a Collection.
Definition: collectionstatistics.h:70
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
Represents a collection of PIM items.
Definition: collection.h:76
Akonadi::Collection::UrlWithName
@ UrlWithName
A url with identifier and name.
Definition: collection.h:266
Akonadi::Collection::contentMimeTypes
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:115
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
Akonadi::Collection::List
QList< Collection > List
Describes a list of collections.
Definition: collection.h:81
Akonadi::Collection::name
QString name() const
Returns the i18n'ed name of the collection.
Definition: collection.cpp:81
Akonadi::Collection::setReferenced
void setReferenced(bool referenced)
Sets a collection to be referenced.
Definition: collection.cpp:338
Akonadi::Collection::fromUrl
static Collection fromUrl(const KUrl &url)
Creates a collection from the given url.
Definition: collection.cpp:172
Akonadi::Collection::CanChangeCollection
@ CanChangeCollection
Can change this collection.
Definition: collection.h:91
Akonadi::Collection::CanCreateItem
@ CanCreateItem
Can create new items in this collection.
Definition: collection.h:89
Akonadi::Collection::CanLinkItem
@ CanLinkItem
Can create links to existing items in this virtual collection.
Definition: collection.h:94
Akonadi::Collection::CanCreateCollection
@ CanCreateCollection
Can create new subcollections in this collection.
Definition: collection.h:92
Akonadi::Collection::CanChangeItem
@ CanChangeItem
Can change items in this collection.
Definition: collection.h:88
Akonadi::EntityDisplayAttribute
Attribute that stores the properties that are used to display an entity.
Definition: entitydisplayattribute.h:40
Akonadi::EntityDisplayAttribute::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the backgroundColor to color.
Definition: entitydisplayattribute.cpp:162
Akonadi::EntityDisplayAttribute::backgroundColor
QColor backgroundColor() const
Returns the backgroundColor or an invalid color if none is set.
Definition: entitydisplayattribute.cpp:157
Akonadi::EntityDisplayAttribute::displayName
QString displayName() const
Returns the name that should be used for display.
Definition: entitydisplayattribute.cpp:52
Akonadi::EntityDisplayAttribute::setDisplayName
void setDisplayName(const QString &name)
Sets the name that should be used for display.
Definition: entitydisplayattribute.cpp:57
Akonadi::EntityDisplayAttribute::iconName
QString iconName() const
Returns the icon name of the icon returned by icon().
Definition: entitydisplayattribute.cpp:67
Akonadi::EntityTreeModelPrivate
Definition: entitytreemodel_p.h:60
Akonadi::EntityTreeModelPrivate::childCollectionNames
QStringList childCollectionNames(const Collection &collection) const
Returns the list of names of the child collections of collection.
Akonadi::EntityTreeModelPrivate::indexesForItem
QModelIndexList indexesForItem(const Item &item) const
Returns the model indexes for the given item.
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::EntityTreeModelPrivate::indexForCollection
QModelIndex indexForCollection(const Collection &collection) const
Returns the model index for the given collection.
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:319
Akonadi::EntityTreeModel::listFilter
Akonadi::CollectionFetchScope::ListFilter listFilter() const
Returns the currently used listfilter.
Definition: entitytreemodel.cpp:99
Akonadi::EntityTreeModel::systemEntitiesShown
bool systemEntitiesShown() const
Returns true if internal system entities are shown, and false otherwise.
Definition: entitytreemodel.cpp:143
Akonadi::EntityTreeModel::setShowSystemEntities
void setShowSystemEntities(bool show)
Some Entities are hidden in the model, but exist for internal purposes, for example,...
Definition: entitytreemodel.cpp:149
Akonadi::EntityTreeModel::setRootCollectionDisplayName
void setRootCollectionDisplayName(const QString &name)
Sets the display name of the root collection of the model.
Definition: entitytreemodel.cpp:1168
Akonadi::EntityTreeModel::ItemPopulationStrategy
ItemPopulationStrategy
Describes how the model should populated its items.
Definition: entitytreemodel.h:408
Akonadi::EntityTreeModel::ImmediatePopulation
@ ImmediatePopulation
Retrieve items immediately when their parent is in the model. This is the default.
Definition: entitytreemodel.h:410
Akonadi::EntityTreeModel::NoItemPopulation
@ NoItemPopulation
Do not include items in the model.
Definition: entitytreemodel.h:409
Akonadi::EntityTreeModel::LazyPopulation
@ LazyPopulation
Fetch items only when requested (using canFetchMore/fetchMore)
Definition: entitytreemodel.h:411
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::includeRootCollection
bool includeRootCollection() const
Returns whether the root collection is provided by the model.
Definition: entitytreemodel.cpp:1162
Akonadi::EntityTreeModel::clearAndReset
void clearAndReset()
Clears and resets the model.
Definition: entitytreemodel.cpp:155
Akonadi::EntityTreeModel::isCollectionPopulated
bool isCollectionPopulated(Akonadi::Collection::Id) const
Returns whether the collection has been populated.
Definition: entitytreemodel.cpp:965
Akonadi::EntityTreeModel::includeUnsubscribed
AKONADI_DEPRECATED bool includeUnsubscribed() const
Returns whether unsubscribed entities will be included in the listing.
Definition: entitytreemodel.cpp:85
Akonadi::EntityTreeModel::FetchingState
@ FetchingState
There is a fetch of items in this collection in progress.
Definition: entitytreemodel.h:376
Akonadi::EntityTreeModel::IdleState
@ IdleState
There is no fetch of items in this collection in progress.
Definition: entitytreemodel.h:375
Akonadi::EntityTreeModel::rootCollectionDisplayName
QString rootCollectionDisplayName() const
Returns the display name of the root collection.
Definition: entitytreemodel.cpp:1176
Akonadi::EntityTreeModel::setCollectionFetchStrategy
void setCollectionFetchStrategy(CollectionFetchStrategy strategy)
Sets the collection fetch strategy of the model.
Definition: entitytreemodel.cpp:1182
Akonadi::EntityTreeModel::~EntityTreeModel
virtual ~EntityTreeModel()
Destroys the entity tree model.
Definition: entitytreemodel.cpp:68
Akonadi::EntityTreeModel::HeaderGroup
HeaderGroup
Describes what header information the model shall return.
Definition: entitytreemodel.h:383
Akonadi::EntityTreeModel::CollectionTreeHeaders
@ CollectionTreeHeaders
Header information for a collection-only tree.
Definition: entitytreemodel.h:385
Akonadi::EntityTreeModel::ItemListHeaders
@ ItemListHeaders
Header information for a list of items.
Definition: entitytreemodel.h:386
Akonadi::EntityTreeModel::setCollectionsMonitored
void setCollectionsMonitored(const Akonadi::Collection::List &collections)
Monitors the specified collections and resets the model.
Definition: entitytreemodel.cpp:114
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::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::EntityTreeModel::itemPopulationStrategy
ItemPopulationStrategy itemPopulationStrategy() const
Returns the item population strategy of the model.
Definition: entitytreemodel.cpp:1148
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::CollectionFetchStrategy
CollectionFetchStrategy
Describes what collections shall be fetched by and represent in the model.
Definition: entitytreemodel.h:527
Akonadi::EntityTreeModel::FetchNoCollections
@ FetchNoCollections
Fetches nothing. This creates an empty model.
Definition: entitytreemodel.h:528
Akonadi::EntityTreeModel::InvisibleCollectionFetch
@ 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::EntityTreeModel::EntityTreeModel
EntityTreeModel(ChangeRecorder *monitor, QObject *parent=0)
Creates a new entity tree model.
Definition: entitytreemodel.cpp:53
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
Akonadi::EntityTreeModel::setListFilter
void setListFilter(Akonadi::CollectionFetchScope::ListFilter filter)
Sets the currently used listfilter.
Definition: entitytreemodel.cpp:105
Akonadi::EntityTreeModel::collectionFetchStrategy
CollectionFetchStrategy collectionFetchStrategy() const
Returns the collection fetch strategy of the model.
Definition: entitytreemodel.cpp:1207
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::setItemPopulationStrategy
void setItemPopulationStrategy(ItemPopulationStrategy strategy)
Sets the item population strategy of the model.
Definition: entitytreemodel.cpp:1121
Akonadi::EntityTreeModel::setIncludeRootCollection
void setIncludeRootCollection(bool include)
Sets whether the root collection shall be provided by the model.
Definition: entitytreemodel.cpp:1154
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::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::isFullyPopulated
bool isFullyPopulated() const
Returns whether the model is fully populated.
Definition: entitytreemodel.cpp:971
Akonadi::EntityTreeModel::isCollectionTreeFetched
bool isCollectionTreeFetched() const
Returns whether the collection tree has been fetched at initialisation.
Definition: entitytreemodel.cpp:958
Akonadi::EntityTreeModel::ItemIdRole
@ ItemIdRole
The item id.
Definition: entitytreemodel.h:331
Akonadi::EntityTreeModel::AvailablePartsRole
@ AvailablePartsRole
Parts available in the Akonadi server for the item.
Definition: entitytreemodel.h:344
Akonadi::EntityTreeModel::ParentCollectionRole
@ ParentCollectionRole
The parent collection of the entity.
Definition: entitytreemodel.h:341
Akonadi::EntityTreeModel::ItemRole
@ ItemRole
The Item.
Definition: entitytreemodel.h:332
Akonadi::EntityTreeModel::TerminalUserRole
@ TerminalUserRole
Last role for user extensions. Don't use a role beyond this or headerData will break.
Definition: entitytreemodel.h:356
Akonadi::EntityTreeModel::LoadedPartsRole
@ LoadedPartsRole
Parts available in the model for the item.
Definition: entitytreemodel.h:343
Akonadi::EntityTreeModel::CollectionDerefRole
@ CollectionDerefRole
Definition: entitytreemodel.h:347
Akonadi::EntityTreeModel::RemoteIdRole
@ RemoteIdRole
The remoteId of the entity.
Definition: entitytreemodel.h:338
Akonadi::EntityTreeModel::SessionRole
@ SessionRole
Definition: entitytreemodel.h:345
Akonadi::EntityTreeModel::OriginalCollectionNameRole
@ OriginalCollectionNameRole
Returns original name for collection.
Definition: entitytreemodel.h:354
Akonadi::EntityTreeModel::AmazingCompletionRole
@ AmazingCompletionRole
Role used to implement amazing completion.
Definition: entitytreemodel.h:340
Akonadi::EntityTreeModel::CollectionSyncProgressRole
@ CollectionSyncProgressRole
Returns the progress of synchronization in percent for a particular collection.
Definition: entitytreemodel.h:352
Akonadi::EntityTreeModel::CollectionRole
@ CollectionRole
The collection.
Definition: entitytreemodel.h:336
Akonadi::EntityTreeModel::EntityUrlRole
@ EntityUrlRole
The akonadi:/ Url of the entity as a string. Item urls will contain the mimetype.
Definition: entitytreemodel.h:349
Akonadi::EntityTreeModel::CollectionIdRole
@ CollectionIdRole
The collection id.
Definition: entitytreemodel.h:335
Akonadi::EntityTreeModel::PendingCutRole
@ PendingCutRole
Definition: entitytreemodel.h:348
Akonadi::EntityTreeModel::UnreadCountRole
@ UnreadCountRole
Returns the number of unread items in a collection.
Definition: entitytreemodel.h:350
Akonadi::EntityTreeModel::CollectionRefRole
@ CollectionRefRole
Definition: entitytreemodel.h:346
Akonadi::EntityTreeModel::IsPopulatedRole
@ IsPopulatedRole
Returns whether a Collection has been populated, i.e. whether its items have been fetched.
Definition: entitytreemodel.h:353
Akonadi::EntityTreeModel::MimeTypeRole
@ MimeTypeRole
The mimetype of the entity.
Definition: entitytreemodel.h:333
Akonadi::EntityTreeModel::FetchStateRole
@ FetchStateRole
Returns the FetchState of a particular item.
Definition: entitytreemodel.h:351
Akonadi::EntityTreeModel::ColumnCountRole
@ ColumnCountRole
Definition: entitytreemodel.h:342
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
Akonadi::Entity::AddIfMissing
@ AddIfMissing
Creates the attribute if it is missing.
Definition: entity.h:205
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::Entity::id
Id id() const
Returns the unique identifier of the entity.
Definition: entity.cpp:72
Akonadi::Entity::Id
qint64 Id
Describes the unique id type.
Definition: entity.h:65
Akonadi::ItemModifyJob
Job that modifies an existing item in the Akonadi storage.
Definition: itemmodifyjob.h:98
Akonadi::MimeTypeChecker
Helper for checking MIME types of Collections and Items.
Definition: mimetypechecker.h:110
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::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::MimeTypeChecker::wantedMimeTypes
QStringList wantedMimeTypes() const
Returns the list of wanted MIME types this instance checks against.
Definition: mimetypechecker.cpp:52
Akonadi::MimeTypeChecker::setWantedMimeTypes
void setWantedMimeTypes(const QStringList &mimeTypes)
Sets the list of wanted MIME types this instance checks against.
Definition: mimetypechecker.cpp:57
Akonadi::Monitor::session
Session * session() const
Returns the Session used by the monitor to communicate with Akonadi.
Definition: monitor.cpp:365
Akonadi::Monitor::collectionsMonitored
Collection::List collectionsMonitored() const
Returns the list of collections being monitored.
Definition: monitor.cpp:273
Akonadi::Monitor::setAllMonitored
void setAllMonitored(bool monitored=true)
Sets whether all items shall be monitored.
Definition: monitor.cpp:186
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::Monitor::fetchCollection
void fetchCollection(bool enable)
Enables automatic fetching of changed collections from the Akonadi storage.
Definition: monitor.cpp:219
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
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 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.10 API Reference

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