Akonadi

collection.cpp
1/*
2 SPDX-FileCopyrightText: 2006-2007 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "collection.h"
8#include "collection_p.h"
9
10#include "attributefactory.h"
11#include "cachepolicy.h"
12#include "collectionrightsattribute_p.h"
13#include "collectionstatistics.h"
14#include "entitydisplayattribute.h"
15
16#include <QHash>
17#include <QString>
18#include <QStringList>
19
20#include <QUrl>
21#include <QUrlQuery>
22
23using namespace Akonadi;
24
25Q_GLOBAL_STATIC(Akonadi::Collection, s_defaultParentCollection) // NOLINT(readability-redundant-member-init)
26
27size_t Akonadi::qHash(const Akonadi::Collection &collection, size_t seed) noexcept
28{
29 return ::qHash(collection.id(), seed);
30}
31
32/**
33 * Helper method for assignment operator and copy constructor.
34 */
35static void assignCollectionPrivate(QSharedDataPointer<CollectionPrivate> &one, const QSharedDataPointer<CollectionPrivate> &other)
36{
37 // We can't simply do one = other here, we have to use a temp.
38 // Otherwise ProtocolHelperTest::testParentCollectionAfterCollectionParsing()
39 // will break.
40 //
41 // The reason are assignments like
42 // col = col.parentCollection()
43 //
44 // Here, parentCollection() actually returns a reference to a pointer owned
45 // by col. So when col (or rather, it's private class) is deleted, the pointer
46 // to the parent collection and therefore the reference becomes invalid.
47 //
48 // With a single-line assignment here, the parent collection would be deleted
49 // before it is assigned, and therefore the resulting object would point to
50 // uninitialized memory.
51 const QSharedDataPointer<CollectionPrivate> temp = other; // NOLINT(performance-unnecessary-copy-initialization): see above
52 one = temp;
53}
54
55class CollectionRoot : public Collection
56{
57public:
58 CollectionRoot()
59 : Collection(0)
60 {
62
63 // The root collection is read-only for the users
65 }
66};
67
68Q_GLOBAL_STATIC(CollectionRoot, s_root) // NOLINT(readability-redundant-member-init)
69
71 : d_ptr(new CollectionPrivate)
72{
73 static int lastId = -1;
74 d_ptr->mId = lastId--;
75}
76
78 : d_ptr(new CollectionPrivate(id))
79{
80}
81
83{
84 assignCollectionPrivate(d_ptr, other.d_ptr);
85}
86
87Collection::Collection(Collection &&) noexcept = default;
88
89Collection::~Collection() = default;
90
91void Collection::setId(Collection::Id identifier)
92{
93 d_ptr->mId = identifier;
94}
95
96Collection::Id Collection::id() const
97{
98 return d_ptr->mId;
99}
100
102{
103 d_ptr->mRemoteId = id;
104}
105
107{
108 return d_ptr->mRemoteId;
109}
110
112{
113 d_ptr->mRemoteRevision = revision;
114}
115
116QString Collection::remoteRevision() const
117{
118 return d_ptr->mRemoteRevision;
119}
120
121bool Collection::isValid() const
122{
123 return (d_ptr->mId >= 0);
124}
125
126bool Collection::operator==(const Collection &other) const
127{
128 // Invalid collections are the same, no matter what their internal ID is
129 return (!isValid() && !other.isValid()) || (d_ptr->mId == other.d_ptr->mId);
130}
131
133{
134 return (isValid() || other.isValid()) && (d_ptr->mId != other.d_ptr->mId);
135}
136
137Collection &Collection ::operator=(const Collection &other)
138{
139 if (this != &other) {
140 assignCollectionPrivate(d_ptr, other.d_ptr);
141 }
142
143 return *this;
144}
145
147{
148 return d_ptr->mId < other.d_ptr->mId;
149}
150
152{
153 d_ptr->mAttributeStorage.addAttribute(attr);
154}
155
157{
158 d_ptr->mAttributeStorage.removeAttribute(type);
159}
160
162{
163 return d_ptr->mAttributeStorage.hasAttribute(type);
164}
165
167{
168 return d_ptr->mAttributeStorage.attributes();
169}
170
172{
173 d_ptr->mAttributeStorage.clearAttributes();
174}
175
177{
178 markAttributeModified(type);
179 return d_ptr->mAttributeStorage.attribute(type);
180}
181
182const Attribute *Collection::attribute(const QByteArray &type) const
183{
184 return d_ptr->mAttributeStorage.attribute(type);
185}
186
188{
189 if (!d_ptr->mParent) {
190 d_ptr->mParent.reset(new Collection());
191 }
192 return *d_ptr->mParent;
193}
194
196{
197 if (!d_ptr->mParent) {
198 return *(s_defaultParentCollection);
199 } else {
200 return *d_ptr->mParent;
201 }
202}
203
205{
206 d_ptr->mParent.reset(new Collection(parent));
207}
208
209QString Collection::name() const
210{
211 return d_ptr->name;
212}
213
214QString Collection::displayName() const
215{
216 const auto *const attr = attribute<EntityDisplayAttribute>();
217 const QString displayName = attr ? attr->displayName() : QString();
218 return !displayName.isEmpty() ? displayName : d_ptr->name;
219}
220
222{
223 d_ptr->name = name;
224}
225
226Collection::Rights Collection::rights() const
227{
228 if (const auto *const attr = attribute<CollectionRightsAttribute>()) {
229 return attr->rights();
230 } else {
231 return AllRights;
232 }
233}
234
236{
237 attribute<CollectionRightsAttribute>(AddIfMissing)->setRights(rights);
238}
239
240QStringList Collection::contentMimeTypes() const
241{
242 return d_ptr->contentTypes;
243}
244
246{
247 if (d_ptr->contentTypes != types) {
248 d_ptr->contentTypes = types;
249 d_ptr->contentTypesChanged = true;
250 }
251}
252
254{
255 QUrlQuery query;
256 query.addQueryItem(QStringLiteral("collection"), QString::number(id()));
257 if (type == UrlWithName) {
258 query.addQueryItem(QStringLiteral("name"), name());
259 }
260
261 QUrl url;
262 url.setScheme(QStringLiteral("akonadi"));
263 url.setQuery(query);
264 return url;
265}
266
268{
269 if (url.scheme() != QLatin1StringView("akonadi")) {
270 return Collection();
271 }
272
273 const QString colStr = QUrlQuery(url).queryItemValue(QStringLiteral("collection"));
274 bool ok = false;
275 Collection::Id colId = colStr.toLongLong(&ok);
276 if (!ok) {
277 return Collection();
278 }
279
280 if (colId == 0) {
281 return Collection::root();
282 }
283
284 return Collection(colId);
285}
286
288{
289 return *s_root;
290}
291
293{
294 return QStringLiteral("inode/directory");
295}
296
298{
299 return QStringLiteral("application/x-vnd.akonadi.collection.virtual");
300}
301
302QString Collection::resource() const
303{
304 return d_ptr->resource;
305}
306
307void Collection::setResource(const QString &resource)
308{
309 d_ptr->resource = resource;
310}
311
312QDebug operator<<(QDebug d, const Akonadi::Collection &collection)
313{
314 return d << "Collection ID:" << collection.id() << " remote ID:" << collection.remoteId() << '\n'
315 << " name:" << collection.name() << '\n'
316 << " url:" << collection.url() << '\n'
317 << " parent:" << collection.parentCollection().id() << collection.parentCollection().remoteId() << '\n'
318 << " resource:" << collection.resource() << '\n'
319 << " rights:" << collection.rights() << '\n'
320 << " contents mime type:" << collection.contentMimeTypes() << '\n'
321 << " isVirtual:" << collection.isVirtual() << '\n'
322 << " " << collection.cachePolicy() << '\n'
323 << " " << collection.statistics();
324}
325
327{
328 return d_ptr->statistics;
329}
330
332{
333 d_ptr->statistics = statistics;
334}
335
337{
338 return d_ptr->cachePolicy;
339}
340
342{
343 d_ptr->cachePolicy = cachePolicy;
344 d_ptr->cachePolicyChanged = true;
345}
346
347bool Collection::isVirtual() const
348{
349 return d_ptr->isVirtual;
350}
351
353{
354 d_ptr->isVirtual = isVirtual;
355}
356
357void Collection::setEnabled(bool enabled)
358{
359 d_ptr->enabledChanged = true;
360 d_ptr->enabled = enabled;
361}
362
363bool Collection::enabled() const
364{
365 return d_ptr->enabled;
366}
367
369{
370 switch (purpose) {
371 case ListDisplay:
372 d_ptr->displayPreference = preference;
373 break;
374 case ListSync:
375 d_ptr->syncPreference = preference;
376 break;
377 case ListIndex:
378 d_ptr->indexPreference = preference;
379 break;
380 }
381 d_ptr->listPreferenceChanged = true;
382}
383
385{
386 switch (purpose) {
387 case ListDisplay:
388 return d_ptr->displayPreference;
389 case ListSync:
390 return d_ptr->syncPreference;
391 case ListIndex:
392 return d_ptr->indexPreference;
393 }
394 return ListDefault;
395}
396
398{
399 if (localListPreference(purpose) == ListDefault) {
400 return enabled();
401 }
402 return (localListPreference(purpose) == ListEnabled);
403}
404
406{
407 if (localListPreference(purpose) == ListDefault) {
408 setEnabled(list);
409 } else {
411 }
412}
413
415{
416 d_ptr->keepLocalChanges = parts;
417}
418
420{
421 return d_ptr->keepLocalChanges;
422}
423
424void Collection::markAttributeModified(const QByteArray &type)
425{
426 d_ptr->mAttributeStorage.markAttributeModified(type);
427}
428
429#include "moc_collection.cpp"
Provides interface for custom attributes for Entity.
Definition attribute.h:132
Represents the caching policy for a collection.
Definition cachepolicy.h:60
Provides statistics information of a Collection.
Represents a collection of PIM items.
Definition collection.h:62
void setVirtual(bool isVirtual)
Sets whether the collection is virtual or not.
qint64 Id
Describes the unique id type.
Definition collection.h:79
UrlType
Describes the type of url which is returned in url().
Definition collection.h:408
@ UrlWithName
A url with identifier and name.
Definition collection.h:410
void setParentCollection(const Collection &parent)
Set the parent collection of this object.
void addAttribute(Attribute *attribute)
Adds an attribute to the collection.
static QString mimeType()
Returns the mimetype used for collections.
void setLocalListPreference(ListPurpose purpose, ListPreference preference)
Sets the local list preference for the specified purpose.
CollectionStatistics statistics() const
Returns the collection statistics of the collection.
Collection()
Creates an invalid collection.
ListPurpose
Describes the purpose of the listing.
Definition collection.h:479
@ ListSync
Listing for synchronization.
Definition collection.h:480
@ ListIndex
Listing for indexing the content.
Definition collection.h:482
@ ListDisplay
Listing for display to the user.
Definition collection.h:481
bool operator<(const Collection &other) const
static Collection root()
Returns the root collection.
void setKeepLocalChanges(const QSet< QByteArray > &parts)
Set during sync to indicate that the provided parts are only default values;.
static QString virtualMimeType()
Returns the mimetype used for virtual collections.
Attribute::List attributes() const
Returns a list of all attributes of the collection.
void setName(const QString &name)
Sets the i18n'ed name of the collection.
CachePolicy cachePolicy() const
Returns the cache policy of the collection.
const T * attribute() const
Returns the attribute of the requested type or 0 if it is not available.
Definition collection.h:573
@ AddIfMissing
Creates the attribute if it is missing.
Definition collection.h:281
bool operator!=(const Collection &other) const
Returns whether the collection's id does not equal the id of the other collection.
void clearAttributes()
Removes and deletes all attributes of the collection.
void setRemoteId(const QString &id)
Sets the remote id of the collection.
ListPreference localListPreference(ListPurpose purpose) const
Returns the local list preference for the specified purpose.
void setResource(const QString &identifier)
Sets the identifier of the resource owning the collection.
static Collection fromUrl(const QUrl &url)
Creates a collection from the given url.
void setEnabled(bool enabled)
Sets the collection's enabled state.
@ ReadOnly
Can only read items or subcollection of this collection.
Definition collection.h:90
@ AllRights
Has all rights on this storage collection.
Definition collection.h:99
void setCachePolicy(const CachePolicy &policy)
Sets the cache policy of the collection.
Collection parentCollection() const
Returns the parent collection of this object.
void setContentMimeTypes(const QStringList &types)
Sets the list of possible content mime types.
QSet< QByteArray > keepLocalChanges() const
Returns what parts are only default values.
bool shouldList(ListPurpose purpose) const
Returns whether the collection should be listed or not for the specified purpose Takes enabled state ...
bool operator==(const Collection &other) const
Returns whether this collections's id equals the id of the other collection.
void setRights(Rights rights)
Sets the rights the user has on the collection.
void setStatistics(const CollectionStatistics &statistics)
Sets the collection statistics for the collection.
bool hasAttribute() const
Returns whether the collection has an attribute of the requested type.
Definition collection.h:593
void setShouldList(ListPurpose purpose, bool shouldList)
Sets whether the collection should be listed or not for the specified purpose.
QUrl url(UrlType type=UrlShort) const
Returns the url of the collection.
void setRemoteRevision(const QString &revision)
Sets the remote revision of the collection.
QString remoteId() const
Returns the remote id of the collection.
void removeAttribute()
Removes and deletes the attribute of the requested type.
Definition collection.h:587
ListPreference
Describes the list preference value.
Definition collection.h:468
@ ListDefault
Fallback to enabled state.
Definition collection.h:471
@ ListDisabled
Disable collection for specified purpose.
Definition collection.h:470
@ ListEnabled
Enable collection for specified purpose.
Definition collection.h:469
Helper integration between Akonadi and Qt.
bool isEmpty() const const
QString number(double n, char format, int precision)
qlonglong toLongLong(bool *ok, int base) const const
QString scheme() const const
void setQuery(const QString &query, ParsingMode mode)
void setScheme(const QString &scheme)
QString queryItemValue(const QString &key, QUrl::ComponentFormattingOptions encoding) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.