File indexing completed on 2025-01-05 04:47:07

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 "collectioncombobox.h"
0010 
0011 #include "asyncselectionhandler_p.h"
0012 #include "collectiondialog.h"
0013 
0014 #include "collectionfetchscope.h"
0015 #include "collectionfilterproxymodel.h"
0016 #include "collectionutils.h"
0017 #include "entityrightsfiltermodel.h"
0018 #include "entitytreemodel.h"
0019 #include "monitor.h"
0020 #include "session.h"
0021 
0022 #include <KDescendantsProxyModel>
0023 
0024 #include <QAbstractItemModel>
0025 
0026 using namespace Akonadi;
0027 
0028 class Akonadi::CollectionComboBoxPrivate
0029 {
0030 public:
0031     CollectionComboBoxPrivate(QAbstractItemModel *customModel, CollectionComboBox *parent)
0032         : mParent(parent)
0033     {
0034         if (customModel) {
0035             mBaseModel = customModel;
0036         } else {
0037             mMonitor = new Akonadi::Monitor(mParent);
0038             mMonitor->setObjectName(QLatin1StringView("CollectionComboBoxMonitor"));
0039             mMonitor->fetchCollection(true);
0040             mMonitor->setCollectionMonitored(Akonadi::Collection::root());
0041 
0042             // This ETM will be set to only show collections with the wanted mimetype in setMimeTypeFilter
0043             mModel = new EntityTreeModel(mMonitor, mParent);
0044             mModel->setItemPopulationStrategy(EntityTreeModel::NoItemPopulation);
0045             mModel->setListFilter(CollectionFetchScope::Display);
0046 
0047             mBaseModel = mModel;
0048         }
0049 
0050         // Flatten the tree, e.g.
0051         // Kolab
0052         // Kolab / Inbox
0053         // Kolab / Inbox / Calendar
0054         auto proxyModel = new KDescendantsProxyModel(parent);
0055         proxyModel->setDisplayAncestorData(true);
0056         proxyModel->setSourceModel(mBaseModel);
0057 
0058         // Filter it by mimetype again, to only keep
0059         // Kolab / Inbox / Calendar
0060         mMimeTypeFilterModel = new CollectionFilterProxyModel(parent);
0061         mMimeTypeFilterModel->setSourceModel(proxyModel);
0062 
0063         // Filter by access rights. TODO: maybe this functionality could be provided by CollectionFilterProxyModel, to save one proxy?
0064         mRightsFilterModel = new EntityRightsFilterModel(parent);
0065         mRightsFilterModel->setSourceModel(mMimeTypeFilterModel);
0066 
0067         mParent->setModel(mRightsFilterModel);
0068         mParent->model()->sort(mParent->modelColumn());
0069 
0070         mSelectionHandler = new AsyncSelectionHandler(mRightsFilterModel, mParent);
0071         mParent->connect(mSelectionHandler, &AsyncSelectionHandler::collectionAvailable, mParent, [this](const auto &mi) {
0072             activated(mi);
0073         });
0074     }
0075 
0076     ~CollectionComboBoxPrivate() = default;
0077 
0078     void activated(int index);
0079     void activated(const QModelIndex &index);
0080 
0081     CollectionComboBox *const mParent;
0082 
0083     Monitor *mMonitor = nullptr;
0084     EntityTreeModel *mModel = nullptr;
0085     QAbstractItemModel *mBaseModel = nullptr;
0086     CollectionFilterProxyModel *mMimeTypeFilterModel = nullptr;
0087     EntityRightsFilterModel *mRightsFilterModel = nullptr;
0088     AsyncSelectionHandler *mSelectionHandler = nullptr;
0089 };
0090 
0091 void CollectionComboBoxPrivate::activated(int index)
0092 {
0093     const QModelIndex modelIndex = mParent->model()->index(index, 0);
0094     if (modelIndex.isValid()) {
0095         Q_EMIT mParent->currentChanged(modelIndex.data(EntityTreeModel::CollectionRole).value<Collection>());
0096     }
0097 }
0098 
0099 void CollectionComboBoxPrivate::activated(const QModelIndex &index)
0100 {
0101     mParent->setCurrentIndex(index.row());
0102 }
0103 
0104 CollectionComboBox::CollectionComboBox(QWidget *parent)
0105     : QComboBox(parent)
0106     , d(new CollectionComboBoxPrivate(nullptr, this))
0107 {
0108 }
0109 
0110 CollectionComboBox::CollectionComboBox(QAbstractItemModel *model, QWidget *parent)
0111     : QComboBox(parent)
0112     , d(new CollectionComboBoxPrivate(model, this))
0113 {
0114 }
0115 
0116 CollectionComboBox::~CollectionComboBox() = default;
0117 
0118 void CollectionComboBox::setMimeTypeFilter(const QStringList &contentMimeTypes)
0119 {
0120     d->mMimeTypeFilterModel->clearFilters();
0121     d->mMimeTypeFilterModel->addMimeTypeFilters(contentMimeTypes);
0122 
0123     if (d->mMonitor) {
0124         for (const QString &mimeType : contentMimeTypes) {
0125             d->mMonitor->setMimeTypeMonitored(mimeType, true);
0126         }
0127     }
0128 }
0129 
0130 QStringList CollectionComboBox::mimeTypeFilter() const
0131 {
0132     return d->mMimeTypeFilterModel->mimeTypeFilters();
0133 }
0134 
0135 void CollectionComboBox::setAccessRightsFilter(Collection::Rights rights)
0136 {
0137     d->mRightsFilterModel->setAccessRights(rights);
0138 }
0139 
0140 Akonadi::Collection::Rights CollectionComboBox::accessRightsFilter() const
0141 {
0142     return d->mRightsFilterModel->accessRights();
0143 }
0144 
0145 void CollectionComboBox::setDefaultCollection(const Collection &collection)
0146 {
0147     d->mSelectionHandler->waitForCollection(collection);
0148 }
0149 
0150 Akonadi::Collection CollectionComboBox::currentCollection() const
0151 {
0152     const QModelIndex modelIndex = model()->index(currentIndex(), 0);
0153     if (modelIndex.isValid()) {
0154         return modelIndex.data(Akonadi::EntityTreeModel::CollectionRole).value<Collection>();
0155     } else {
0156         return Akonadi::Collection();
0157     }
0158 }
0159 
0160 void CollectionComboBox::setExcludeVirtualCollections(bool b)
0161 {
0162     d->mMimeTypeFilterModel->setExcludeVirtualCollections(b);
0163 }
0164 
0165 bool CollectionComboBox::excludeVirtualCollections() const
0166 {
0167     return d->mMimeTypeFilterModel->excludeVirtualCollections();
0168 }
0169 
0170 #include "moc_collectioncombobox.cpp"