Mailcommon

entitycollectionorderproxymodel.cpp
1/*
2
3 SPDX-FileCopyrightText: 2010-2024 Laurent Montel <montel@kde.org>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "entitycollectionorderproxymodel.h"
9#include "hierarchicalfoldermatcher_p.h"
10#include "kernel/mailkernel.h"
11#include "mailcommon_debug.h"
12#include "util/mailutil.h"
13#include <Akonadi/AgentManager>
14#include <Akonadi/Collection>
15#include <Akonadi/EntityTreeModel>
16#include <Akonadi/SpecialMailCollections>
17
18using namespace MailCommon;
19class Q_DECL_HIDDEN MailCommon::EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModelPrivate
20{
21public:
22 EntityCollectionOrderProxyModelPrivate() = default;
23
24 int collectionRank(const Akonadi::Collection &collection)
25 {
26 const Akonadi::Collection::Id id = collection.id();
27 const int cachedRank = collectionRanks.value(id, -1);
28 if (cachedRank != -1) {
29 return cachedRank;
30 }
31
32 int rank = 100;
33 if (Kernel::folderIsInbox(collection)) {
34 rank = 1;
35 } else if (Kernel::self()->folderIsDraftOrOutbox(collection)) {
36 if (Kernel::self()->folderIsDrafts(collection)) {
37 rank = 5;
38 } else {
39 rank = 2;
40 }
41 } else if (Kernel::self()->folderIsSentMailFolder(collection)) {
42 rank = 3;
43 } else if (Kernel::self()->folderIsTrash(collection)) {
44 rank = 4;
45 } else if (Kernel::self()->folderIsTemplates(collection)) {
46 rank = 6;
47 } else if (MailCommon::Util::isVirtualCollection(collection)) {
48 rank = 200;
49 } else if (collection.parentCollection() == Akonadi::Collection::root() && MailCommon::Util::isUnifiedMailboxesAgent(collection)) {
50 // special treatment for Unified Mailboxes: they are *always* on top
51 rank = 0;
52 } else if (!topLevelOrder.isEmpty()) {
53 if (collection.parentCollection() == Akonadi::Collection::root()) {
54 const QString resource = collection.resource();
55 if (resource.isEmpty()) {
56 qCDebug(MAILCOMMON_LOG) << " collection has not resource: " << collection;
57 // Don't save in collectionranks because we don't have resource name => pb.
58 return rank;
59 }
60 const int order = topLevelOrder.indexOf(resource);
61 if (order != -1) {
62 rank = order + 1; /* top-level rank "0" belongs to Unified Mailboxes */
63 }
64 }
65 }
66 collectionRanks.insert(id, rank);
67 return rank;
68 }
69
71 QStringList topLevelOrder;
72 HierarchicalFolderMatcher matcher;
73 bool manualSortingActive = false;
74};
75
76EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModel(QObject *parent)
77 : EntityOrderProxyModel(parent)
78 , d(new EntityCollectionOrderProxyModelPrivate())
79{
80 setSortCaseSensitivity(Qt::CaseInsensitive);
83 this,
84 &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged);
87 this,
88 &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged);
89}
90
91EntityCollectionOrderProxyModel::~EntityCollectionOrderProxyModel()
92{
93 if (d->manualSortingActive) {
94 saveOrder();
95 }
96}
97
98void EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged()
99{
100 if (!d->manualSortingActive) {
101 d->collectionRanks.clear();
102 invalidate();
103 }
104}
105
106void EntityCollectionOrderProxyModel::setTopLevelOrder(const QStringList &list)
107{
108 d->topLevelOrder = list;
109 clearRanks();
110}
111
112void EntityCollectionOrderProxyModel::clearRanks()
113{
114 d->collectionRanks.clear();
115 invalidate();
116}
117
118bool EntityCollectionOrderProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
119{
120 const auto leftData = left.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
121 const auto rightData = right.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
122 if (!d->manualSortingActive) {
123 const int rankLeft = d->collectionRank(leftData);
124 const int rankRight = d->collectionRank(rightData);
125
126 if (rankLeft < rankRight) {
127 return true;
128 } else if (rankLeft > rankRight) {
129 return false;
130 }
131
132 return QSortFilterProxyModel::lessThan(left, right);
133 }
134
135 if (MailCommon::Util::isUnifiedMailboxesAgent(leftData)) {
136 return true;
137 } else {
138 return EntityOrderProxyModel::lessThan(left, right);
139 }
140}
141
142void EntityCollectionOrderProxyModel::setManualSortingActive(bool active)
143{
144 if (d->manualSortingActive == active) {
145 return;
146 }
147
148 d->manualSortingActive = active;
149 d->collectionRanks.clear();
150 invalidate();
151}
152
153bool EntityCollectionOrderProxyModel::isManualSortingActive() const
154{
155 return d->manualSortingActive;
156}
157
158void EntityCollectionOrderProxyModel::setFolderMatcher(const HierarchicalFolderMatcher &matcher)
159{
160 d->matcher = matcher;
162}
163
164bool EntityCollectionOrderProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
165{
166 if (d->matcher.isNull()) {
167 return EntityOrderProxyModel::filterAcceptsRow(sourceRow, sourceParent);
168 }
169 const QModelIndex sourceIndex = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent);
170 return d->matcher.matches(sourceModel(), sourceIndex, filterRole());
171}
172
173#include "moc_entitycollectionorderproxymodel.cpp"
QString resource() const
static Collection root()
Collection & parentCollection()
void collectionsChanged(const Akonadi::AgentInstance &instance)
static SpecialMailCollections * self()
KIOCORE_EXPORT QStringList list(const QString &fileClass)
The filter dialog.
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
CaseInsensitive
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:00:25 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.