Commit f33abf5b authored by Volker Krause's avatar Volker Krause
Browse files

Move CalendarSupport::TagCache and tag color convenience methods here

This is in no way calendaring related, and not having it that high up in
the dependency chain will enable moving other things further down, which
should help with reducing widget-heavy dependencies on Kalendar for
example.

The code is substantially altered from CalendarSupport, combining TagCache
with (most of) the tag color API and the singleton behavior of KCalPrefs,
but functionality-wise it's still basically the same.
parent 1f2234ec
Pipeline #199430 passed with stage
in 13 minutes and 14 seconds
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
set(PIM_VERSION "5.20.42")
set(PIM_VERSION "5.20.43")
project(Akonadi VERSION ${PIM_VERSION})
......
......@@ -69,6 +69,7 @@ set(akonadicore_base_SRCS
sessionthread.cpp
specialcollections.cpp
tag.cpp
tagcache.cpp
tagfetchscope.cpp
tagsync.cpp
trashsettings.cpp
......@@ -132,6 +133,7 @@ set(akonadicore_base_SRCS
specialcollections.h
specialcollections_p.h
tag.h
tagcache.h
tagfetchscope.h
tagsync.h
trashsettings.h
......@@ -176,6 +178,7 @@ ecm_generate_headers(AkonadiCore_base_CC_HEADERS
SpecialCollections
Supertrait
Tag
TagCache
TagFetchScope
TrashSettings
CollectionPathResolver
......
/*
SPDX-FileCopyrightText: 2015 Sandro Knauß <knauss@kolabsys.com>
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "tagcache.h"
#include "akonadicore_debug.h"
#include <Akonadi/Monitor>
#include <Akonadi/TagAttribute>
#include <Akonadi/TagFetchJob>
#include <Akonadi/TagFetchScope>
#include <Akonadi/TagModifyJob>
namespace Akonadi
{
class TagCachePrivate
{
public:
void addTag(const Akonadi::Tag &tag);
void removeTag(const Akonadi::Tag &tag);
QHash<Akonadi::Tag::Id, Akonadi::Tag> mCache;
QHash<QByteArray, Akonadi::Tag::Id> mGidCache;
QHash<QString, Akonadi::Tag::Id> mNameCache;
Akonadi::Monitor mMonitor;
};
}
using namespace Akonadi;
TagCache::TagCache(QObject *parent)
: QObject(parent)
, d(new TagCachePrivate)
{
d->mMonitor.setObjectName(QStringLiteral("TagCacheMonitor"));
d->mMonitor.setTypeMonitored(Akonadi::Monitor::Tags);
d->mMonitor.tagFetchScope().fetchAttribute<Akonadi::TagAttribute>();
connect(&d->mMonitor, &Akonadi::Monitor::tagAdded, this, [this](const Akonadi::Tag &tag) {
d->addTag(tag);
});
connect(&d->mMonitor, &Akonadi::Monitor::tagChanged, this, [this](const Akonadi::Tag &tag) {
d->addTag(tag);
});
connect(&d->mMonitor, &Akonadi::Monitor::tagRemoved, this, [this](const Akonadi::Tag &tag) {
d->removeTag(tag);
});
auto tagFetchJob = new Akonadi::TagFetchJob(this);
tagFetchJob->fetchScope().fetchAttribute<Akonadi::TagAttribute>();
connect(tagFetchJob, &Akonadi::TagFetchJob::result, this, [tagFetchJob, this]() {
if (tagFetchJob->error()) {
qCWarning(AKONADICORE_LOG) << "Failed to fetch tags: " << tagFetchJob->errorString();
return;
}
const Akonadi::Tag::List lst = tagFetchJob->tags();
for (const Akonadi::Tag &tag : lst) {
d->addTag(tag);
}
});
}
TagCache::~TagCache() = default;
Akonadi::Tag TagCache::tagByGid(const QByteArray &gid) const
{
return d->mCache.value(d->mGidCache.value(gid));
}
Akonadi::Tag TagCache::tagByName(const QString &name) const
{
return d->mCache.value(d->mNameCache.value(name));
}
void TagCachePrivate::addTag(const Akonadi::Tag &tag)
{
mCache.insert(tag.id(), tag);
mGidCache.insert(tag.gid(), tag.id());
mNameCache.insert(tag.name(), tag.id());
}
void TagCachePrivate::removeTag(const Akonadi::Tag &tag)
{
mCache.remove(tag.id());
mGidCache.remove(tag.gid());
mNameCache.remove(tag.name());
}
QColor TagCache::tagColor(const QString &tagName) const
{
if (tagName.isEmpty()) {
return {};
}
const auto tag = tagByName(tagName);
if (const auto attr = tag.attribute<Akonadi::TagAttribute>()) {
return attr->backgroundColor();
}
return {};
}
void TagCache::setTagColor(const QString &tagName, const QColor &color)
{
Akonadi::Tag tag = tagByName(tagName);
if (!tag.isValid()) {
return;
}
auto attr = tag.attribute<Akonadi::TagAttribute>(Akonadi::Tag::AddIfMissing);
attr->setBackgroundColor(color);
new Akonadi::TagModifyJob(tag);
}
TagCache *TagCache::instance()
{
static TagCache s_instance;
return &s_instance;
}
/*
SPDX-FileCopyrightText: 2015 Sandro Knauß <knauss@kolabsys.com>
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
#include "akonadicore_export.h"
#include <Akonadi/Tag>
#include <memory>
class QColor;
namespace Akonadi
{
class TagCachePrivate;
/**
* Client-side cache of all exist tags.
*
* This can be instantiated explicitly or used as a singleton for
* process-wide sharing.
*
* @since 5.20.43
*/
class AKONADICORE_EXPORT TagCache : public QObject
{
Q_OBJECT
public:
explicit TagCache(QObject *parent = nullptr);
~TagCache();
/** Returns the tag with the GID @p gid, if available. */
Q_REQUIRED_RESULT Akonadi::Tag tagByGid(const QByteArray &gid) const;
/** Returns the tag with the name @p name, if available. */
Q_REQUIRED_RESULT Akonadi::Tag tagByName(const QString &name) const;
/** Returns the (background) color of the tag named @p tagName.
* If there is no such tag, or the tag has no color associated,
* an invalid QColor value is returned.
*/
Q_REQUIRED_RESULT QColor tagColor(const QString &tagName) const;
/** Sets the (background) color of the tag named @p tagName to @p color. */
void setTagColor(const QString &tagName, const QColor &color);
/** Returns the singleton instance. */
static TagCache *instance();
private:
std::unique_ptr<TagCachePrivate> d;
};
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment