Akonadi

scope.cpp
1/*
2 * SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3 * SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@redhat.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#include "datastream_p_p.h"
9#include "scope_p.h"
10#include "shared/akranges.h"
11
12#include <QJsonArray>
13#include <QJsonObject>
14#include <QStringList>
15
16using namespace AkRanges;
17
18namespace Akonadi
19{
20class ScopePrivate : public QSharedData
21{
22public:
23 QList<qint64> uidSet;
24 QStringList ridSet;
25 QList<Scope::HRID> hridChain;
26 QStringList gidSet;
27 Scope::SelectionScope scope = Scope::Invalid;
28};
29
30Scope::HRID::HRID()
31 : id(-1)
32{
33}
34
35Scope::HRID::HRID(qint64 id, const QString &remoteId)
36 : id(id)
37 , remoteId(remoteId)
38{
39}
40
41bool Scope::HRID::isEmpty() const
42{
43 return id <= 0 && remoteId.isEmpty();
44}
45
46void Scope::HRID::toJson(QJsonObject &json) const
47{
48 json[QStringLiteral("ID")] = id;
49 json[QStringLiteral("RemoteID")] = remoteId;
50}
51
52Scope::Scope()
53 : d(new ScopePrivate)
54{
55}
56
57Scope::Scope(const Scope &) = default;
58Scope::Scope(Scope &&) noexcept = default;
59
60Scope::Scope(std::initializer_list<qint64> ids)
61 : d(new ScopePrivate)
62{
63 setUidSet(std::move(ids));
64}
65
66Scope::Scope(qint64 id)
67 : d(new ScopePrivate)
68{
69 setUidSet({id});
70}
71
72Scope::Scope(const QList<qint64> &uidSet)
73 : d(new ScopePrivate)
74{
75 setUidSet(uidSet);
76}
77
78Scope::Scope(SelectionScope scope, const QStringList &ids)
79 : d(new ScopePrivate)
80{
81 Q_ASSERT(scope == Rid || scope == Gid);
82 if (scope == Rid) {
83 d->scope = scope;
84 d->ridSet = ids;
85 } else if (scope == Gid) {
86 d->scope = scope;
87 d->gidSet = ids;
88 }
89}
90
91Scope::Scope(const QList<HRID> &hrid)
92 : d(new ScopePrivate)
93{
94 d->scope = HierarchicalRid;
95 d->hridChain = hrid;
96}
97
98Scope::~Scope() = default;
99
100Scope &Scope::operator=(const Scope &) = default;
101Scope &Scope::operator=(Scope &&) noexcept = default;
102
103bool Scope::operator==(const Scope &other) const
104{
105 if (d->scope != other.d->scope) {
106 return false;
107 }
108
109 switch (d->scope) {
110 case Uid:
111 return d->uidSet == other.d->uidSet;
112 case Gid:
113 return d->gidSet == other.d->gidSet;
114 case Rid:
115 return d->ridSet == other.d->ridSet;
116 case HierarchicalRid:
117 return d->hridChain == other.d->hridChain;
118 case Invalid:
119 return true;
120 }
121
122 Q_ASSERT(false);
123 return false;
124}
125
126bool Scope::operator!=(const Scope &other) const
127{
128 return !(*this == other);
129}
130
131Scope::SelectionScope Scope::scope() const
132{
133 return d->scope;
134}
135
136bool Scope::isEmpty() const
137{
138 switch (d->scope) {
139 case Invalid:
140 return true;
141 case Uid:
142 return d->uidSet.isEmpty();
143 case Rid:
144 return d->ridSet.isEmpty();
145 case HierarchicalRid:
146 return d->hridChain.isEmpty();
147 case Gid:
148 return d->gidSet.isEmpty();
149 }
150
151 Q_ASSERT(false);
152 return true;
153}
154
155void Scope::setUidSet(const QList<qint64> &uidSet)
156{
157 d->scope = Uid;
158 d->uidSet = uidSet;
159}
160
161QList<qint64> Scope::uidSet() const
162{
163 return d->uidSet;
164}
165
166void Scope::setRidSet(const QStringList &ridSet)
167{
168 d->scope = Rid;
169 d->ridSet = ridSet;
170}
171
172QStringList Scope::ridSet() const
173{
174 return d->ridSet;
175}
176
177void Scope::setHRidChain(const QList<HRID> &hridChain)
178{
179 d->scope = HierarchicalRid;
180 d->hridChain = hridChain;
181}
182
183QList<Scope::HRID> Scope::hridChain() const
184{
185 return d->hridChain;
186}
187
188void Scope::setGidSet(const QStringList &gidSet)
189{
190 d->scope = Gid;
191 d->gidSet = gidSet;
192}
193
194QStringList Scope::gidSet() const
195{
196 return d->gidSet;
197}
198
199qint64 Scope::uid() const
200{
201 if (d->uidSet.size() != 1) {
202 // TODO: Error handling!
203 Q_ASSERT(d->uidSet.size() == 1);
204 return -1;
205 }
206
207 return d->uidSet.front();
208}
209
210QString Scope::rid() const
211{
212 if (d->ridSet.size() != 1) {
213 // TODO: Error handling!
214 Q_ASSERT(d->ridSet.size() == 1);
215 return QString();
216 }
217 return d->ridSet.at(0);
218}
219
220QString Scope::gid() const
221{
222 if (d->gidSet.size() != 1) {
223 // TODO: Error handling!
224 Q_ASSERT(d->gidSet.size() == 1);
225 return QString();
226 }
227 return d->gidSet.at(0);
228}
229
230void Scope::toJson(QJsonObject &json) const
231{
232 switch (scope()) {
233 case Scope::Uid:
234 json[QStringLiteral("type")] = QStringLiteral("UID");
235 json[QStringLiteral("value")] = QJsonArray::fromVariantList(uidSet() | Views::transform([](qint64 id) {
236 return QVariant(id);
237 })
238 | Actions::toQList);
239 break;
240 case Scope::Rid:
241 json[QStringLiteral("type")] = QStringLiteral("RID");
242 json[QStringLiteral("value")] = QJsonArray::fromStringList(ridSet());
243 break;
244 case Scope::Gid:
245 json[QStringLiteral("type")] = QStringLiteral("GID");
246 json[QStringLiteral("value")] = QJsonArray::fromStringList(gidSet());
247 break;
248 case Scope::HierarchicalRid: {
249 const auto &chain = hridChain();
250 QJsonArray hridArray;
251 for (const auto &hrid : chain) {
252 QJsonObject obj;
253 hrid.toJson(obj);
254 hridArray.append(obj);
255 }
256 json[QStringLiteral("type")] = QStringLiteral("HRID");
257 json[QStringLiteral("value")] = hridArray;
258 } break;
259 default:
260 json[QStringLiteral("type")] = QStringLiteral("invalid");
261 json[QStringLiteral("value")] = QJsonValue(static_cast<int>(scope()));
262 }
263}
264
265Protocol::DataStream &operator<<(Protocol::DataStream &stream, const Akonadi::Scope &scope)
266{
267 stream << static_cast<quint8>(scope.d->scope);
268 switch (scope.d->scope) {
269 case Scope::Invalid:
270 return stream;
271 case Scope::Uid:
272 stream << scope.d->uidSet;
273 return stream;
274 case Scope::Rid:
275 stream << scope.d->ridSet;
276 return stream;
277 case Scope::HierarchicalRid:
278 stream << scope.d->hridChain;
279 return stream;
280 case Scope::Gid:
281 stream << scope.d->gidSet;
282 return stream;
283 }
284
285 return stream;
286}
287
288Protocol::DataStream &operator<<(Protocol::DataStream &stream, const Akonadi::Scope::HRID &hrid)
289{
290 return stream << hrid.id << hrid.remoteId;
291}
292
293Protocol::DataStream &operator>>(Protocol::DataStream &stream, Akonadi::Scope::HRID &hrid)
294{
295 return stream >> hrid.id >> hrid.remoteId;
296}
297
298Protocol::DataStream &operator>>(Protocol::DataStream &stream, Akonadi::Scope &scope)
299{
300 scope.d->uidSet.clear();
301 scope.d->ridSet.clear();
302 scope.d->hridChain.clear();
303 scope.d->gidSet.clear();
304
305 stream >> reinterpret_cast<quint8 &>(scope.d->scope);
306 switch (scope.d->scope) {
307 case Scope::Invalid:
308 return stream;
309 case Scope::Uid:
310 stream >> scope.d->uidSet;
311 return stream;
312 case Scope::Rid:
313 stream >> scope.d->ridSet;
314 return stream;
315 case Scope::HierarchicalRid:
316 stream >> scope.d->hridChain;
317 return stream;
318 case Scope::Gid:
319 stream >> scope.d->gidSet;
320 return stream;
321 }
322
323 return stream;
324}
325
326} // namespace Akonadi
327
328using namespace Akonadi;
329
330QDebug operator<<(QDebug dbg, const Akonadi::Scope::HRID &hrid)
331{
332 return dbg.nospace() << "(ID: " << hrid.id << ", RemoteID: " << hrid.remoteId << ")";
333}
334
335QDebug operator<<(QDebug dbg, const Akonadi::Scope &scope)
336{
337 switch (scope.scope()) {
338 case Scope::Uid:
339 return dbg.nospace() << "Scope(UID, " << scope.uidSet() << ")";
340 case Scope::Rid:
341 return dbg.nospace() << "Scope(RID, " << scope.ridSet() << ")";
342 case Scope::Gid:
343 return dbg.nospace() << "Scope(GID, " << scope.gidSet() << ")";
344 case Scope::HierarchicalRid:
345 return dbg.nospace() << "Scope(HRID, " << scope.hridChain() << ")";
346 default:
347 return dbg.nospace() << "Scope(Invalid)";
348 }
349}
Helper integration between Akonadi and Qt.
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
A glue between Qt and the standard library.
QDebug & nospace()
void append(const QJsonValue &value)
QJsonArray fromStringList(const QStringList &list)
QJsonArray fromVariantList(const QVariantList &list)
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 14 2024 11:51:45 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.