Warning, file /pim/mailcommon/src/folder/entitycollectionorderproxymodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 0003 SPDX-FileCopyrightText: 2010-2024 Laurent Montel <montel@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "entitycollectionorderproxymodel.h" 0009 #include "hierarchicalfoldermatcher_p.h" 0010 #include "kernel/mailkernel.h" 0011 #include "mailcommon_debug.h" 0012 #include "util/mailutil.h" 0013 #include <Akonadi/AgentManager> 0014 #include <Akonadi/Collection> 0015 #include <Akonadi/EntityTreeModel> 0016 #include <Akonadi/SpecialMailCollections> 0017 0018 using namespace MailCommon; 0019 class Q_DECL_HIDDEN MailCommon::EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModelPrivate 0020 { 0021 public: 0022 EntityCollectionOrderProxyModelPrivate() = default; 0023 0024 int collectionRank(const Akonadi::Collection &collection) 0025 { 0026 const Akonadi::Collection::Id id = collection.id(); 0027 const int cachedRank = collectionRanks.value(id, -1); 0028 if (cachedRank != -1) { 0029 return cachedRank; 0030 } 0031 0032 int rank = 100; 0033 if (Kernel::folderIsInbox(collection)) { 0034 rank = 1; 0035 } else if (Kernel::self()->folderIsDraftOrOutbox(collection)) { 0036 if (Kernel::self()->folderIsDrafts(collection)) { 0037 rank = 5; 0038 } else { 0039 rank = 2; 0040 } 0041 } else if (Kernel::self()->folderIsSentMailFolder(collection)) { 0042 rank = 3; 0043 } else if (Kernel::self()->folderIsTrash(collection)) { 0044 rank = 4; 0045 } else if (Kernel::self()->folderIsTemplates(collection)) { 0046 rank = 6; 0047 } else if (MailCommon::Util::isVirtualCollection(collection)) { 0048 rank = 200; 0049 } else if (collection.parentCollection() == Akonadi::Collection::root() && MailCommon::Util::isUnifiedMailboxesAgent(collection)) { 0050 // special treatment for Unified Mailboxes: they are *always* on top 0051 rank = 0; 0052 } else if (!topLevelOrder.isEmpty()) { 0053 if (collection.parentCollection() == Akonadi::Collection::root()) { 0054 const QString resource = collection.resource(); 0055 if (resource.isEmpty()) { 0056 qCDebug(MAILCOMMON_LOG) << " collection has not resource: " << collection; 0057 // Don't save in collectionranks because we don't have resource name => pb. 0058 return rank; 0059 } 0060 const int order = topLevelOrder.indexOf(resource); 0061 if (order != -1) { 0062 rank = order + 1; /* top-level rank "0" belongs to Unified Mailboxes */ 0063 } 0064 } 0065 } 0066 collectionRanks.insert(id, rank); 0067 return rank; 0068 } 0069 0070 QMap<Akonadi::Collection::Id, int> collectionRanks; 0071 QStringList topLevelOrder; 0072 HierarchicalFolderMatcher matcher; 0073 bool manualSortingActive = false; 0074 }; 0075 0076 EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModel(QObject *parent) 0077 : EntityOrderProxyModel(parent) 0078 , d(new EntityCollectionOrderProxyModelPrivate()) 0079 { 0080 setSortCaseSensitivity(Qt::CaseInsensitive); 0081 connect(Akonadi::SpecialMailCollections::self(), 0082 &Akonadi::SpecialMailCollections::defaultCollectionsChanged, 0083 this, 0084 &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged); 0085 connect(Akonadi::SpecialMailCollections::self(), 0086 &Akonadi::SpecialMailCollections::collectionsChanged, 0087 this, 0088 &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged); 0089 } 0090 0091 EntityCollectionOrderProxyModel::~EntityCollectionOrderProxyModel() 0092 { 0093 if (d->manualSortingActive) { 0094 saveOrder(); 0095 } 0096 } 0097 0098 void EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged() 0099 { 0100 if (!d->manualSortingActive) { 0101 d->collectionRanks.clear(); 0102 invalidate(); 0103 } 0104 } 0105 0106 void EntityCollectionOrderProxyModel::setTopLevelOrder(const QStringList &list) 0107 { 0108 d->topLevelOrder = list; 0109 clearRanks(); 0110 } 0111 0112 void EntityCollectionOrderProxyModel::clearRanks() 0113 { 0114 d->collectionRanks.clear(); 0115 invalidate(); 0116 } 0117 0118 bool EntityCollectionOrderProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const 0119 { 0120 const auto leftData = left.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0121 const auto rightData = right.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0122 if (!d->manualSortingActive) { 0123 const int rankLeft = d->collectionRank(leftData); 0124 const int rankRight = d->collectionRank(rightData); 0125 0126 if (rankLeft < rankRight) { 0127 return true; 0128 } else if (rankLeft > rankRight) { 0129 return false; 0130 } 0131 0132 return QSortFilterProxyModel::lessThan(left, right); 0133 } 0134 0135 if (MailCommon::Util::isUnifiedMailboxesAgent(leftData)) { 0136 return true; 0137 } else { 0138 return EntityOrderProxyModel::lessThan(left, right); 0139 } 0140 } 0141 0142 void EntityCollectionOrderProxyModel::setManualSortingActive(bool active) 0143 { 0144 if (d->manualSortingActive == active) { 0145 return; 0146 } 0147 0148 d->manualSortingActive = active; 0149 d->collectionRanks.clear(); 0150 invalidate(); 0151 } 0152 0153 bool EntityCollectionOrderProxyModel::isManualSortingActive() const 0154 { 0155 return d->manualSortingActive; 0156 } 0157 0158 void EntityCollectionOrderProxyModel::setFolderMatcher(const HierarchicalFolderMatcher &matcher) 0159 { 0160 d->matcher = matcher; 0161 invalidateFilter(); 0162 } 0163 0164 bool EntityCollectionOrderProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0165 { 0166 if (d->matcher.isNull()) { 0167 return EntityOrderProxyModel::filterAcceptsRow(sourceRow, sourceParent); 0168 } 0169 const QModelIndex sourceIndex = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent); 0170 return d->matcher.matches(sourceModel(), sourceIndex, filterRole()); 0171 } 0172 0173 #include "moc_entitycollectionorderproxymodel.cpp"