File indexing completed on 2024-11-24 04:50:45

0001 /*
0002      This file is part of Akonadi Contact.
0003 
0004      SPDX-FileCopyrightText: 2007-2009 Tobias Koenig <tokoe@kde.org>
0005 
0006      SPDX-License-Identifier: LGPL-2.0-or-later
0007  */
0008 
0009 #include "collectioncomboboxmodel.h"
0010 
0011 #include <Akonadi/CollectionFetchScope>
0012 #include <Akonadi/CollectionFilterProxyModel>
0013 #include <Akonadi/CollectionUtils>
0014 #include <Akonadi/EntityRightsFilterModel>
0015 #include <Akonadi/EntityTreeModel>
0016 #include <Akonadi/Monitor>
0017 #include <Akonadi/Session>
0018 
0019 #include <KDescendantsProxyModel>
0020 
0021 #include "colorproxymodel.h"
0022 #include <QAbstractItemModel>
0023 
0024 using namespace Akonadi::Quick;
0025 
0026 class Akonadi::Quick::CollectionComboBoxModelPrivate
0027 {
0028 public:
0029     CollectionComboBoxModelPrivate(CollectionComboBoxModel *parent)
0030         : mParent(parent)
0031     {
0032         mMonitor = new Akonadi::Monitor(mParent);
0033         mMonitor->setObjectName(QLatin1StringView("CollectionComboBoxMonitor"));
0034         mMonitor->fetchCollection(true);
0035         mMonitor->setCollectionMonitored(Akonadi::Collection::root());
0036 
0037         // This ETM will be set to only show collections with the wanted mimetype in setMimeTypeFilter
0038         auto entityModel = new Akonadi::EntityTreeModel(mMonitor, mParent);
0039         entityModel->setItemPopulationStrategy(Akonadi::EntityTreeModel::NoItemPopulation);
0040         entityModel->setListFilter(Akonadi::CollectionFetchScope::Display);
0041 
0042         // Display color
0043         auto colorProxy = new ColorProxyModel(mParent);
0044         colorProxy->setObjectName(QLatin1StringView("Show collection colors"));
0045         colorProxy->setDynamicSortFilter(true);
0046         colorProxy->setSourceModel(entityModel);
0047 
0048         // Flatten the tree, e.g.
0049         // Kolab
0050         // Kolab / Inbox
0051         // Kolab / Inbox / Calendar
0052         auto proxyModel = new KDescendantsProxyModel(parent);
0053         proxyModel->setDisplayAncestorData(true);
0054         proxyModel->setSourceModel(colorProxy);
0055 
0056         // Filter it by mimetype again, to only keep
0057         // Kolab / Inbox / Calendar
0058         mMimeTypeFilterModel = new Akonadi::CollectionFilterProxyModel(parent);
0059         mMimeTypeFilterModel->setSourceModel(proxyModel);
0060 
0061         // Filter by access rights. TODO: maybe this functionality could be provided by CollectionFilterProxyModel, to save one proxy?
0062         mRightsFilterModel = new Akonadi::EntityRightsFilterModel(parent);
0063         mRightsFilterModel->setSourceModel(mMimeTypeFilterModel);
0064 
0065         mParent->setSourceModel(mRightsFilterModel);
0066         // mRightsFilterModel->sort(mParent->modelColumn());
0067 
0068         mParent->connect(mRightsFilterModel, &QAbstractItemModel::rowsInserted, mParent, [this](const QModelIndex &parent, int start, int end) {
0069             Q_UNUSED(parent)
0070             Q_UNUSED(start)
0071             Q_UNUSED(end)
0072             scanSubTree();
0073         });
0074     }
0075 
0076     ~CollectionComboBoxModelPrivate() = default;
0077 
0078     bool scanSubTree();
0079 
0080     CollectionComboBoxModel *const mParent;
0081 
0082     Akonadi::Monitor *mMonitor = nullptr;
0083     Akonadi::CollectionFilterProxyModel *mMimeTypeFilterModel = nullptr;
0084     Akonadi::EntityRightsFilterModel *mRightsFilterModel = nullptr;
0085     qint64 mDefaultCollectionId = -1;
0086     int mCurrentIndex = -1;
0087 };
0088 
0089 bool CollectionComboBoxModelPrivate::scanSubTree()
0090 {
0091     for (int row = 0; row < mRightsFilterModel->rowCount(); ++row) {
0092         const Akonadi::Collection::Id id = mRightsFilterModel->data(mRightsFilterModel->index(row, 0), EntityTreeModel::CollectionIdRole).toLongLong();
0093 
0094         if (mDefaultCollectionId == id && id > 0) {
0095             mParent->setCurrentIndex(row);
0096             return true;
0097         }
0098     }
0099 
0100     return false;
0101 }
0102 
0103 CollectionComboBoxModel::CollectionComboBoxModel(QObject *parent)
0104     : QSortFilterProxyModel(parent)
0105     , d(new CollectionComboBoxModelPrivate(this))
0106 {
0107 }
0108 
0109 CollectionComboBoxModel::~CollectionComboBoxModel() = default;
0110 
0111 void CollectionComboBoxModel::setMimeTypeFilter(const QStringList &contentMimeTypes)
0112 {
0113     d->mMimeTypeFilterModel->clearFilters();
0114     d->mMimeTypeFilterModel->addMimeTypeFilters(contentMimeTypes);
0115 
0116     if (d->mMonitor) {
0117         for (const QString &mimeType : contentMimeTypes) {
0118             d->mMonitor->setMimeTypeMonitored(mimeType, true);
0119         }
0120     }
0121 }
0122 
0123 QStringList CollectionComboBoxModel::mimeTypeFilter() const
0124 {
0125     return d->mMimeTypeFilterModel->mimeTypeFilters();
0126 }
0127 
0128 void CollectionComboBoxModel::setAccessRightsFilter(int rights)
0129 {
0130     d->mRightsFilterModel->setAccessRights((Collection::Right)rights);
0131     Q_EMIT accessRightsFilterChanged();
0132 }
0133 
0134 int CollectionComboBoxModel::accessRightsFilter() const
0135 {
0136     return (int)d->mRightsFilterModel->accessRights();
0137 }
0138 
0139 qint64 CollectionComboBoxModel::defaultCollectionId() const
0140 {
0141     return d->mDefaultCollectionId;
0142 }
0143 
0144 void CollectionComboBoxModel::setDefaultCollectionId(qint64 collectionId)
0145 {
0146     if (d->mDefaultCollectionId == collectionId) {
0147         return;
0148     }
0149     d->mDefaultCollectionId = collectionId;
0150     d->scanSubTree();
0151     Q_EMIT defaultCollectionIdChanged();
0152 }
0153 
0154 void CollectionComboBoxModel::setExcludeVirtualCollections(bool b)
0155 {
0156     d->mMimeTypeFilterModel->setExcludeVirtualCollections(b);
0157 }
0158 
0159 bool CollectionComboBoxModel::excludeVirtualCollections() const
0160 {
0161     return d->mMimeTypeFilterModel->excludeVirtualCollections();
0162 }
0163 
0164 int CollectionComboBoxModel::currentIndex() const
0165 {
0166     return d->mCurrentIndex;
0167 }
0168 
0169 void CollectionComboBoxModel::setCurrentIndex(int currentIndex)
0170 {
0171     if (d->mCurrentIndex == currentIndex) {
0172         return;
0173     }
0174     d->mCurrentIndex = currentIndex;
0175     Q_EMIT currentIndexChanged();
0176 }
0177 
0178 #include "moc_collectioncomboboxmodel.cpp"