MauiKit Calendar

colorproxymodel.cpp
1// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
2// SPDX-FileCopyrightText: 2022 Claudio Cambra <claudio.cambra@gmail.com>
3// SPDX-License-Identifier: GPL-2.0-or-later
4
5#include "colorproxymodel.h"
6
7#include <Akonadi/AgentInstance>
8#include <Akonadi/AgentManager>
9#include <Akonadi/AttributeFactory>
10#include <Akonadi/CollectionColorAttribute>
11#include <Akonadi/CollectionModifyJob>
12#include <Akonadi/CollectionUtils>
13#include <Akonadi/EntityDisplayAttribute>
14#include <KCalendarCore/Event>
15#include <KCalendarCore/Journal>
16#include <KCalendarCore/Todo>
17#include <KConfigGroup>
18#include <KContacts/Addressee>
19#include <KContacts/ContactGroup>
20#include <KLocalizedString>
21#include <KSharedConfig>
22#include <QColor>
23#include <QFont>
24#include <QRandomGenerator>
25
26namespace
27{
28 static bool hasCompatibleMimeTypes(const Akonadi::Collection &collection)
29 {
30 static QStringList goodMimeTypes;
31
32 if (goodMimeTypes.isEmpty()) {
33 goodMimeTypes << QStringLiteral("text/calendar") << KCalendarCore::Event::eventMimeType() << KCalendarCore::Todo::todoMimeType()
35 }
36
37 for (int i = 0; i < goodMimeTypes.count(); ++i) {
38 if (collection.contentMimeTypes().contains(goodMimeTypes.at(i))) {
39 return true;
40 }
41 }
42
43 return false;
44 }
45}
46
47ColorProxyModel::ColorProxyModel(QObject *parent)
49, mInitDefaultCalendar(false)
50{
51 // Needed to read colorattribute of collections for incidence colors
52 Akonadi::AttributeFactory::registerAttribute<Akonadi::CollectionColorAttribute>();
53}
54
55QVariant ColorProxyModel::data(const QModelIndex &index, int role) const
56{
57 if (!index.isValid()) {
58 return {};
59 }
60
61 if (role == Qt::DecorationRole) {
63
64 if (hasCompatibleMimeTypes(collection)) {
66 return collection.attribute<Akonadi::EntityDisplayAttribute>()->iconName();
67 }
68 }
69 } else if (role == Qt::FontRole) {
71 if (!collection.contentMimeTypes().isEmpty() && collection.id() == m_standardCollectionId && collection.rights() & Akonadi::Collection::CanCreateItem) {
73 font.setBold(true);
74 return font;
75 }
76 } else if (role == Qt::DisplayRole) {
78 const Akonadi::Collection::Id colId = collection.id();
80
81 if (!instance.isOnline() && !collection.isVirtual()) {
82 return i18nc("@item this is the default calendar", "%1 (Offline)", collection.displayName());
83 }
84 if (colId == m_standardCollectionId) {
85 return i18nc("@item this is the default calendar", "%1 (Default)", collection.displayName());
86 }
87 } else if (role == Qt::BackgroundRole) {
88 auto color = getCollectionColor(Akonadi::CollectionUtils::fromIndex(index));
89 // Otherwise QML will get black
90 if (color.isValid()) {
91 return color;
92 } else {
93 return {};
94 }
95 } else if (role == isResource) {
96 return Akonadi::CollectionUtils::isResource(Akonadi::CollectionUtils::fromIndex(index));
97 }
98
100}
101
102Qt::ItemFlags ColorProxyModel::flags(const QModelIndex &index) const
103{
105}
106
107QHash<int, QByteArray> ColorProxyModel::roleNames() const
108{
110 roleNames[Qt::CheckStateRole] = "checkState";
111 roleNames[Qt::BackgroundRole] = "collectionColor";
112 roleNames[isResource] = "isResource";
113 return roleNames;
114}
115
116QColor ColorProxyModel::getCollectionColor(Akonadi::Collection collection) const
117{
118 const auto id = collection.id();
119 auto supportsMimeType = collection.contentMimeTypes().contains(QLatin1String("application/x-vnd.akonadi.calendar.event"))
120 || collection.contentMimeTypes().contains(QLatin1String("application/x-vnd.akonadi.calendar.todo"))
121 || collection.contentMimeTypes().contains(QLatin1String("application/x-vnd.akonadi.calendar.journal"))
124
125 if (!supportsMimeType) {
126 return {};
127 }
128
129 if (colorCache.contains(id)) {
130 return colorCache[id];
131 }
132
134 const auto colorAttr = collection.attribute<Akonadi::CollectionColorAttribute>();
135 if (colorAttr && colorAttr->color().isValid()) {
136 colorCache[id] = colorAttr->color();
137 return colorAttr->color();
138 }
139 }
140
141 KSharedConfig::Ptr config = KSharedConfig::openConfig();
142 KConfigGroup resourcesColorsConfig(config, QStringLiteral("Resources Colors"));
144
145 QColor color;
146 for (const QString &key : colorKeyList) {
147 if (key.toLongLong() == id) {
148 color = resourcesColorsConfig.readEntry(key, QColor("blue"));
149 }
150 }
151
152 if (!color.isValid()) {
153 QColor color;
154 color.setRgb(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256));
155 colorCache[id] = color;
156 }
157
159 colorAttr->setColor(color);
160
161 auto modifyJob = new Akonadi::CollectionModifyJob(collection);
163 if (job->error()) {
164 qWarning() << "Error occurred modifying collection color: " << job->errorString();
165 }
166 });
167
168 return color;
169}
170
171QColor ColorProxyModel::color(Akonadi::Collection::Id collectionId) const
172{
173 return colorCache[collectionId];
174}
175
176void ColorProxyModel::setColor(Akonadi::Collection::Id collectionId, const QColor &color)
177{
178 colorCache[collectionId] = color;
179}
180
181void ColorProxyModel::setStandardCollectionId(Akonadi::Collection::Id standardCollectionId)
182{
183 m_standardCollectionId = standardCollectionId;
184}
static AgentManager * self()
AgentInstance instance(const QString &identifier) const
QString resource() const
QStringList contentMimeTypes() const
QString displayName() const
const T * attribute() const
Rights rights() const
bool hasAttribute() const
bool isVirtual() const
static QLatin1String eventMimeType()
static QLatin1String journalMimeType()
static QLatin1String todoMimeType()
static QString mimeType()
static QString mimeType()
int error() const
void result(KJob *job)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
AKONADICORE_EXPORT Collection fromIndex(const QModelIndex &index)
virtual QHash< int, QByteArray > roleNames() const const
bool isValid() const const
void setRgb(QRgb rgb)
bool contains(const Key &key) const const
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
bool isValid() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QRandomGenerator * global()
virtual QVariant data(const QModelIndex &index, int role) const const override
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
DecorationRole
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:50:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.