Mailcommon

entitycollectionorderproxymodel.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2010-2022 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 #include <QRegularExpression>
19 
20 using namespace MailCommon;
21 class Q_DECL_HIDDEN MailCommon::EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModelPrivate
22 {
23 public:
24  EntityCollectionOrderProxyModelPrivate() = default;
25 
26  int collectionRank(const Akonadi::Collection &collection)
27  {
28  const Akonadi::Collection::Id id = collection.id();
29  const int cachedRank = collectionRanks.value(id, -1);
30  if (cachedRank != -1) {
31  return cachedRank;
32  }
33 
34  int rank = 100;
35  if (Kernel::folderIsInbox(collection)) {
36  rank = 1;
37  } else if (Kernel::self()->folderIsDraftOrOutbox(collection)) {
38  if (Kernel::self()->folderIsDrafts(collection)) {
39  rank = 5;
40  } else {
41  rank = 2;
42  }
43  } else if (Kernel::self()->folderIsSentMailFolder(collection)) {
44  rank = 3;
45  } else if (Kernel::self()->folderIsTrash(collection)) {
46  rank = 4;
47  } else if (Kernel::self()->folderIsTemplates(collection)) {
48  rank = 6;
49  } else if (MailCommon::Util::isVirtualCollection(collection)) {
50  rank = 200;
51  } else if (collection.parentCollection() == Akonadi::Collection::root() && MailCommon::Util::isUnifiedMailboxesAgent(collection)) {
52  // special treatment for Unified Mailboxes: they are *always* on top
53  rank = 0;
54  } else if (!topLevelOrder.isEmpty()) {
55  if (collection.parentCollection() == Akonadi::Collection::root()) {
56  const QString resource = collection.resource();
57  if (resource.isEmpty()) {
58  qCDebug(MAILCOMMON_LOG) << " collection has not resource: " << collection;
59  // Don't save in collectionranks because we don't have resource name => pb.
60  return rank;
61  }
62  const int order = topLevelOrder.indexOf(resource);
63  if (order != -1) {
64  rank = order + 1; /* top-level rank "0" belongs to Unified Mailboxes */
65  }
66  }
67  }
68  collectionRanks.insert(id, rank);
69  return rank;
70  }
71 
72  QMap<Akonadi::Collection::Id, int> collectionRanks;
73  QStringList topLevelOrder;
74  HierarchicalFolderMatcher matcher;
75  bool manualSortingActive = false;
76 };
77 
78 EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModel(QObject *parent)
79  : EntityOrderProxyModel(parent)
80  , d(new EntityCollectionOrderProxyModelPrivate())
81 {
82  setSortCaseSensitivity(Qt::CaseInsensitive);
85  this,
86  &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged);
89  this,
90  &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged);
91 }
92 
93 EntityCollectionOrderProxyModel::~EntityCollectionOrderProxyModel()
94 {
95  if (d->manualSortingActive) {
96  saveOrder();
97  }
98 }
99 
100 void EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged()
101 {
102  if (!d->manualSortingActive) {
103  d->collectionRanks.clear();
104  invalidate();
105  }
106 }
107 
108 void EntityCollectionOrderProxyModel::setTopLevelOrder(const QStringList &list)
109 {
110  d->topLevelOrder = list;
111  clearRanks();
112 }
113 
114 void EntityCollectionOrderProxyModel::clearRanks()
115 {
116  d->collectionRanks.clear();
117  invalidate();
118 }
119 
120 bool EntityCollectionOrderProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
121 {
122  const auto leftData = left.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
123  const auto rightData = right.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
124  if (!d->manualSortingActive) {
125  const int rankLeft = d->collectionRank(leftData);
126  const int rankRight = d->collectionRank(rightData);
127 
128  if (rankLeft < rankRight) {
129  return true;
130  } else if (rankLeft > rankRight) {
131  return false;
132  }
133 
134  return QSortFilterProxyModel::lessThan(left, right);
135  }
136 
137  if (MailCommon::Util::isUnifiedMailboxesAgent(leftData)) {
138  return true;
139  } else {
140  return EntityOrderProxyModel::lessThan(left, right);
141  }
142 }
143 
144 void EntityCollectionOrderProxyModel::setManualSortingActive(bool active)
145 {
146  if (d->manualSortingActive == active) {
147  return;
148  }
149 
150  d->manualSortingActive = active;
151  d->collectionRanks.clear();
152  invalidate();
153 }
154 
155 bool EntityCollectionOrderProxyModel::isManualSortingActive() const
156 {
157  return d->manualSortingActive;
158 }
159 
160 void EntityCollectionOrderProxyModel::setFolderMatcher(const HierarchicalFolderMatcher &matcher)
161 {
162  d->matcher = matcher;
164 }
165 
166 bool EntityCollectionOrderProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
167 {
168  if (d->matcher.isNull()) {
169  return EntityOrderProxyModel::filterAcceptsRow(sourceRow, sourceParent);
170  }
171  const QModelIndex sourceIndex = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent);
172  return d->matcher.matches(sourceModel(), sourceIndex, filterRole());
173 }
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-2022 The KDE developers.
Generated on Sat Sep 24 2022 03:58:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.