Mailcommon

foldertreewidgetproxymodel.cpp
1/*
2 SPDX-FileCopyrightText: 2009-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "foldertreewidgetproxymodel.h"
8#include "foldersettings.h"
9#include "kernel/mailkernel.h"
10#include "util/mailutil.h"
11
12#include <MessageCore/MessageCoreSettings>
13
14#include <Akonadi/AgentInstance>
15#include <Akonadi/AgentManager>
16#include <Akonadi/EntityTreeModel>
17#include <Akonadi/MimeTypeChecker>
18
19#include <Akonadi/CollectionQuotaAttribute>
20#include <KColorScheme>
21#include <KLocalizedString>
22
23#include <QIcon>
24#include <QPalette>
25
26using namespace MailCommon;
27class FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelPrivate
28{
29public:
30 FolderTreeWidgetProxyModelPrivate(FolderTreeWidgetProxyModel *qq)
31 : q(qq)
32 {
33 }
34
35 bool checkQuotaExcedded(const QModelIndex &index, qreal &percentage)
36 {
37 if (threshold >= 0.0) {
38 if (index.model()->hasChildren(index)) {
39 const int rowCount = index.model()->rowCount(index);
40 for (int row = 0; row < rowCount; row++) {
41 const QModelIndex firstIndex = q->mapToSource(index.model()->index(row, 0, index));
42
43 const auto collectionFirst = q->sourceModel()->data(firstIndex, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
44 if (collectionFirst.isValid() && collectionFirst.hasAttribute<Akonadi::CollectionQuotaAttribute>()) {
45 const auto quota = collectionFirst.attribute<Akonadi::CollectionQuotaAttribute>();
46
47 if (quota->currentValue() > -1 && quota->maximumValue() > 0) {
48 percentage = (100.0 * quota->currentValue()) / quota->maximumValue();
49 if (percentage >= threshold) {
50 return true;
51 }
52 }
53 }
54 }
55 }
56 }
57 return false;
58 }
59
60 QSet<QString> includedMimeTypes;
62
63 QColor brokenAccountColor;
64 qreal threshold = -1.0;
66 bool enableCheck = false;
67 bool hideVirtualFolder = false;
68 bool hideSpecificFolder = false;
69 bool hideOutboxFolder = false;
70};
71
72FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModel(QObject *parent, FolderTreeWidgetProxyModelOptions option)
73 : Akonadi::EntityRightsFilterModel(parent)
74 , d(new FolderTreeWidgetProxyModelPrivate(this))
75{
76 setDynamicSortFilter(true);
77 setFilterCaseSensitivity(Qt::CaseInsensitive);
78
79 if (option & HideVirtualFolder) {
80 d->hideVirtualFolder = true;
81 }
82 if (option & HideSpecificFolder) {
83 d->hideSpecificFolder = true;
84 }
85 if (option & HideOutboxFolder) {
86 d->hideOutboxFolder = true;
87 }
88 readConfig();
89}
90
91FolderTreeWidgetProxyModel::~FolderTreeWidgetProxyModel() = default;
92
93void FolderTreeWidgetProxyModel::setWarningThreshold(qreal threshold)
94{
95 d->threshold = threshold;
96}
97
98void FolderTreeWidgetProxyModel::readConfig()
99{
100 invalidate();
101}
102
103Qt::ItemFlags FolderTreeWidgetProxyModel::flags(const QModelIndex &index) const
104{
105 if (d->enableCheck) {
106 const QModelIndex sourceIndex = mapToSource(index);
107 const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0);
109 if (!MailCommon::Util::isVirtualCollection(collection)) {
110 const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource());
111 if (instance.status() == Akonadi::AgentInstance::Broken) {
113 }
114 }
116 }
118}
119
120void FolderTreeWidgetProxyModel::setEnabledCheck(bool enable)
121{
122 if (d->enableCheck == enable) {
123 return;
124 }
125
126 d->enableCheck = enable;
127 if (enable) {
129 }
130}
131
132bool FolderTreeWidgetProxyModel::enabledCheck() const
133{
134 return d->enableCheck;
135}
136
137void FolderTreeWidgetProxyModel::setHideVirtualFolder(bool exclude)
138{
139 if (d->hideVirtualFolder != exclude) {
140 d->hideVirtualFolder = exclude;
141 invalidate();
142 }
143}
144
145bool FolderTreeWidgetProxyModel::hideVirtualFolder() const
146{
147 return d->hideVirtualFolder;
148}
149
150void FolderTreeWidgetProxyModel::setHideSpecificFolder(bool hide)
151{
152 if (d->hideSpecificFolder != hide) {
153 d->hideSpecificFolder = hide;
154 invalidate();
155 }
156}
157
158bool FolderTreeWidgetProxyModel::hideSpecificFolder() const
159{
160 return d->hideSpecificFolder;
161}
162
163void FolderTreeWidgetProxyModel::setHideOutboxFolder(bool hide)
164{
165 if (d->hideOutboxFolder != hide) {
166 d->hideOutboxFolder = hide;
167 invalidate();
168 }
169}
170
171bool FolderTreeWidgetProxyModel::hideOutboxFolder() const
172{
173 return d->hideOutboxFolder;
174}
175
176bool FolderTreeWidgetProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
177{
178 const QModelIndex modelIndex = sourceModel()->index(sourceRow, 0, sourceParent);
179
180 const auto collection = sourceModel()->data(modelIndex, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
181 if (!d->checker.isWantedCollection(collection)) {
182 return false;
183 }
184
185 if (d->hideVirtualFolder) {
186 if (Util::isVirtualCollection(collection)) {
187 return false;
188 }
189 }
190
191 if (d->hideSpecificFolder) {
192 const QSharedPointer<FolderSettings> col = FolderSettings::forCollection(collection, false);
193 if (!col.isNull() && col->hideInSelectionDialog()) {
194 return false;
195 }
196 }
197
198 if (d->hideOutboxFolder) {
199 if (collection == Kernel::self()->outboxCollectionFolder()) {
200 return false;
201 }
202 }
203
204 return EntityRightsFilterModel::filterAcceptsRow(sourceRow, sourceParent);
205}
206
207QVariant FolderTreeWidgetProxyModel::data(const QModelIndex &index, int role) const
208{
209 if (role == Qt::ForegroundRole) {
210 const QModelIndex sourceIndex = mapToSource(index);
211 const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0);
213
214 if (!MailCommon::Util::isVirtualCollection(collection)) {
215 const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource());
216
217 if (instance.status() == Akonadi::AgentInstance::Broken) {
218 if (!d->brokenAccountColor.isValid()) {
220 d->brokenAccountColor = scheme.foreground(KColorScheme::NegativeText).color();
221 }
222 return d->brokenAccountColor;
223 }
224 }
225 } else if (role == Qt::DisplayRole) {
226 const QModelIndex sourceIndex = mapToSource(index);
227 const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0);
229 if (!MailCommon::Util::isVirtualCollection(collection)) {
230 const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource());
231 if (collection.parentCollection() == Akonadi::Collection::root()) {
232 if (!instance.isOnline()) {
233 return i18n("%1 (Offline)", Akonadi::EntityRightsFilterModel::data(index, role).toString());
234 }
235 qreal percentage = 0.0;
236 if (d->checkQuotaExcedded(index, percentage)) {
237 return i18n("%1 (Reached %2% quota)", Akonadi::EntityRightsFilterModel::data(index, role).toString(), static_cast<int>(percentage));
238 }
239 }
240 }
241 } else if (role == Qt::DecorationRole) {
242 const QModelIndex sourceIndex = mapToSource(index);
243 const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0);
245 if (!MailCommon::Util::isVirtualCollection(collection)) {
246 if (collection.parentCollection() == Akonadi::Collection::root()) {
247 qreal percentage = 0.0;
248 if (d->checkQuotaExcedded(index, percentage)) {
249 return QIcon::fromTheme(QStringLiteral("emblem-warning"));
250 }
251 }
252 }
253 }
255}
256
257void FolderTreeWidgetProxyModel::updatePalette()
258{
259 if (d->brokenAccountColor.isValid()) {
261 d->brokenAccountColor = scheme.foreground(KColorScheme::NegativeText).color();
262 invalidate();
263 }
264}
265
266void FolderTreeWidgetProxyModel::addContentMimeTypeInclusionFilter(const QString &mimeType)
267{
268 d->includedMimeTypes << mimeType;
269 d->checker.setWantedMimeTypes(d->includedMimeTypes.values());
271}
272
273#include "moc_foldertreewidgetproxymodel.cpp"
Status status() const
static AgentManager * self()
AgentInstance instance(const QString &identifier) const
static Collection root()
const T * attribute() const
void setAccessRights(Collection::Rights rights)
Qt::ItemFlags flags(const QModelIndex &index) const override
The FolderTreeWidgetProxyModel class.
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
KCALUTILS_EXPORT QString mimeType()
The filter dialog.
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual bool hasChildren(const QModelIndex &parent) const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual int rowCount(const QModelIndex &parent) const const=0
QIcon fromTheme(const QString &name)
QVariant data(int role) const const
const QAbstractItemModel * model() const const
int row() const const
QModelIndex sibling(int row, int column) const const
bool isNull() const const
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
virtual int rowCount(const QModelIndex &parent) const const override
CaseInsensitive
ForegroundRole
typedef ItemFlags
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:01 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.