Mailcommon

entitycollectionorderproxymodel.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2010-2023 Laurent Montel <[email protected]>
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 
18 using namespace MailCommon;
19 class Q_DECL_HIDDEN MailCommon::EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModelPrivate
20 {
21 public:
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 
70  QMap<Akonadi::Collection::Id, int> collectionRanks;
71  QStringList topLevelOrder;
72  HierarchicalFolderMatcher matcher;
73  bool manualSortingActive = false;
74 };
75 
76 EntityCollectionOrderProxyModel::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 
91 EntityCollectionOrderProxyModel::~EntityCollectionOrderProxyModel()
92 {
93  if (d->manualSortingActive) {
94  saveOrder();
95  }
96 }
97 
98 void EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged()
99 {
100  if (!d->manualSortingActive) {
101  d->collectionRanks.clear();
102  invalidate();
103  }
104 }
105 
106 void EntityCollectionOrderProxyModel::setTopLevelOrder(const QStringList &list)
107 {
108  d->topLevelOrder = list;
109  clearRanks();
110 }
111 
112 void EntityCollectionOrderProxyModel::clearRanks()
113 {
114  d->collectionRanks.clear();
115  invalidate();
116 }
117 
118 bool 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 
142 void 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 
153 bool EntityCollectionOrderProxyModel::isManualSortingActive() const
154 {
155  return d->manualSortingActive;
156 }
157 
158 void EntityCollectionOrderProxyModel::setFolderMatcher(const HierarchicalFolderMatcher &matcher)
159 {
160  d->matcher = matcher;
162 }
163 
164 bool 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"
QTextStream & right(QTextStream &stream)
CaseInsensitive
QTextStream & left(QTextStream &stream)
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool isEmpty() const const
Collection & parentCollection()
static Collection root()
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const const
QString resource() const
static SpecialMailCollections * self()
void collectionsChanged(const Akonadi::AgentInstance &instance)
The filter dialog.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:00:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.