8#include "akonadicore_debug.h"
10#include "itemserializer_p.h"
11#include "private/protocol_p.h"
16#include <QReadWriteLock>
17#include <QScopedValueRollback>
28size_t Akonadi::qHash(
const Akonadi::Item &item,
size_t seed)
noexcept
30 return ::qHash(item.id(), seed);
34const char Item::FullPayload[] =
"RFC822";
37 : d_ptr(new ItemPrivate)
42 : d_ptr(new ItemPrivate(id))
47 : d_ptr(new ItemPrivate)
60 d_ptr->mId = identifier;
70 d_ptr->mRemoteId =
id;
75 return d_ptr->mRemoteId;
85 return d_ptr->mRemoteRevision;
90 return (d_ptr->mId >= 0);
96 return (!
isValid() && !other.
isValid()) || (d_ptr->mId == other.d_ptr->mId);
101 return (isValid() || other.
isValid()) && (d_ptr->mId != other.d_ptr->mId);
106 if (
this != &other) {
115 return d_ptr->mId < other.d_ptr->mId;
120 ItemChangeLog::instance()->attributeStorage(d_ptr).
addAttribute(attr);
125 ItemChangeLog::instance()->attributeStorage(d_ptr).removeAttribute(type);
130 return ItemChangeLog::instance()->attributeStorage(d_ptr).hasAttribute(type);
135 return ItemChangeLog::instance()->attributeStorage(d_ptr).attributes();
140 ItemChangeLog::instance()->attributeStorage(d_ptr).clearAttributes();
145 return ItemChangeLog::instance()->attributeStorage(d_ptr).attribute(type);
150 return ItemChangeLog::instance()->attributeStorage(d_ptr).attribute(type);
155 if (!d_ptr->mParent) {
158 return *(d_ptr->mParent);
163 if (!d_ptr->mParent) {
164 return *(s_defaultParentCollection);
166 return *(d_ptr->mParent);
177 return d_ptr->mFlags;
182 d_ptr->mFlags.
insert(name);
183 if (!d_ptr->mFlagsOverwritten) {
184 Item::Flags &deletedFlags = ItemChangeLog::instance()->deletedFlags(d_ptr);
185 auto iter = deletedFlags.
find(name);
186 if (iter != deletedFlags.
end()) {
187 deletedFlags.
erase(iter);
189 ItemChangeLog::instance()->addedFlags(d_ptr).insert(name);
196 d_ptr->mFlags.remove(name);
197 if (!d_ptr->mFlagsOverwritten) {
198 Item::Flags &addedFlags = ItemChangeLog::instance()->addedFlags(d_ptr);
199 auto iter = addedFlags.
find(name);
200 if (iter != addedFlags.
end()) {
201 addedFlags.
erase(iter);
203 ItemChangeLog::instance()->deletedFlags(d_ptr).insert(name);
210 d_ptr->mFlags =
flags;
211 d_ptr->mFlagsOverwritten =
true;
216 d_ptr->mFlags.
clear();
217 d_ptr->mFlagsOverwritten =
true;
222 return d_ptr->mModificationTime;
227 d_ptr->mModificationTime = datetime;
232 return d_ptr->mFlags.contains(name);
238 d_ptr->mTagsOverwritten =
true;
241void Item::setTag(
const Tag &tag)
244 if (!d_ptr->mTagsOverwritten) {
245 Tag::List &deletedTags = ItemChangeLog::instance()->deletedTags(d_ptr);
249 ItemChangeLog::instance()->addedTags(d_ptr).push_back(tag);
254void Item::clearTags()
256 d_ptr->mTags.clear();
257 d_ptr->mTagsOverwritten =
true;
260void Item::clearTag(
const Tag &tag)
262 d_ptr->mTags.removeOne(tag);
263 if (!d_ptr->mTagsOverwritten) {
264 Tag::List &addedTags = ItemChangeLog::instance()->addedTags(d_ptr);
268 ItemChangeLog::instance()->deletedTags(d_ptr).push_back(tag);
273bool Item::hasTag(
const Tag &tag)
const
275 return d_ptr->mTags.contains(tag);
285 return ItemSerializer::parts(*
this);
292 ItemSerializer::serialize(*
this,
FullPayload, data, version);
298 ItemSerializer::deserialize(*
this,
FullPayload, data, 0, ItemSerializer::Internal);
303 d_ptr->mClearPayload =
true;
308 return d_ptr->mRevision;
313 d_ptr->mRevision = rev;
318 return d_ptr->mCollectionId;
323 d_ptr->mCollectionId = collectionId;
328 return d_ptr->mMimeType;
334 d_ptr->mSizeChanged =
true;
359 d_ptr->mVirtualReferences = collections;
364 return d_ptr->mVirtualReferences;
369 return d_ptr->hasMetaTypeId(-1);
377 query.addQueryItem(QStringLiteral(
"type"),
mimeType());
402Internal::PayloadBase *Item::payloadBaseV2(
int spid,
int mtid)
const
404 return d_ptr->payloadBaseImpl(spid, mtid);
407bool Item::ensureMetaTypeId(
int mtid)
const
410 if (d_ptr->mPayloads.empty()) {
415 if (d_ptr->hasMetaTypeId(mtid)) {
421 if (d_ptr->mConversionInProgress) {
428 Item converted = ItemSerializer::convert(*
this, mtid);
429 return d_ptr->movePayloadFrom(converted.d_ptr, mtid);
430 }
catch (
const std::exception &e) {
431 qCWarning(AKONADICORE_LOG) <<
"Item payload conversion threw:" << e.what();
434 qCCritical(AKONADICORE_LOG,
"conversion threw something not derived from std::exception: fix the program!");
439static QString format_type(
int spid,
int mtid)
444static QString format_types(
const PayloadContainer &container)
447 result.
reserve(container.size());
448 for (
auto it = container.begin(), end = container.end(); it != end; ++it) {
449 result.
push_back(format_type(it->sharedPointerId, it->metaTypeId));
457 return QStringLiteral(
"itemId: %1").arg(
id);
459 return QStringLiteral(
"Item is not valid");
463void Item::throwPayloadException(
int spid,
int mtid)
const
465 const auto reason = format_reason(
isValid(),
id());
467 if (d_ptr->mPayloads.empty()) {
468 qCDebug(AKONADICORE_LOG) <<
"Throwing PayloadException for Item" <<
id() <<
": No payload set";
469 throw PayloadException(QStringLiteral(
"No Item payload set (%1)").arg(reason));
471 const auto requestedType = format_type(spid, mtid);
472 const auto presentType = format_types(d_ptr->mPayloads);
473 qCDebug(AKONADICORE_LOG) <<
"Throwing PayloadException for Item" <<
id() <<
": Wrong payload type (requested:" << requestedType
474 <<
"; present: " << presentType <<
"), item mime type is" <<
mimeType();
475 throw PayloadException(QStringLiteral(
"Wrong Item payload type (requested: %1; present: %2, %3)").arg(requestedType, presentType, reason));
479void Item::setPayloadBaseV2(
int spid,
int mtid, std::unique_ptr<Internal::PayloadBase> &p)
481 d_ptr->setPayloadBaseImpl(spid, mtid, p,
false);
484void Item::addPayloadBaseVariant(
int spid,
int mtid, std::unique_ptr<Internal::PayloadBase> &p)
const
486 d_ptr->setPayloadBaseImpl(spid, mtid, p,
true);
491 return d_ptr->mCachedPayloadParts;
496 d_ptr->mCachedPayloadParts = cachedParts;
501 return ItemSerializer::availableParts(*
this);
507 result.
reserve(d_ptr->mPayloads.size());
509 for (
auto it = d_ptr->mPayloads.begin(), end = d_ptr->mPayloads.end(); it != end; ++it) {
510 result.
insert(std::upper_bound(result.
begin(), result.
end(), it->metaTypeId), it->metaTypeId);
520 ItemSerializer::deserialize(*
this,
"RFC822", filePath.
toUtf8(), 0, ItemSerializer::Foreign);
521 d_ptr->mPayloadPath = filePath;
526 return d_ptr->mPayloadPath;
532 qCDebug(AKONADICORE_LOG) <<
"mimeType() = " <<
mimeType() <<
"; other.mimeType() = " << other.
mimeType();
533 qCDebug(AKONADICORE_LOG) <<
"id() = " <<
id() <<
"; other.id() = " << other.
id();
534 Q_ASSERT_X(
false,
"Item::apply",
"mimetype or id mismatch");
541 setTags(other.tags());
547 ItemChangeLog *changelog = ItemChangeLog::instance();
548 changelog->attributeStorage(d_ptr) = changelog->attributeStorage(other.d_ptr);
550 ItemSerializer::apply(*
this, other);
551 d_ptr->resetChangeLog();
Provides interface for custom attributes for Entity.
Represents a collection of PIM items.
qint64 Id
Describes the unique id type.
Represents a PIM item stored in Akonadi storage.
void setParentCollection(const Collection &parent)
Set the parent collection of this object.
Collection::List virtualReferences() const
Lists virtual collections that this item is linked to.
bool operator<(const Item &other) const
bool hasFlag(const QByteArray &name) const
Returns whether the flag with the given name is set in the item.
~Item()
Destroys the item.
void setPayloadFromData(const QByteArray &data)
Sets the payload based on the canonical representation normally used for data of this mime type.
QString payloadPath() const
Returns path to the payload file set by setPayloadPath()
void setId(Id identifier)
Sets the unique identifier of the item.
void setVirtualReferences(const Collection::List &collections)
Sets the virtual collections that this item is linked into.
void clearFlag(const QByteArray &name)
Removes the flag with the given name from the item.
QString remoteRevision() const
Returns the remote revision of the item.
qint64 Id
Describes the unique id type.
QString gid() const
Returns the gid of the entity.
Item()
Creates a new item.
qint64 size() const
Returns the size of the items in bytes.
QString mimeType() const
Returns the mime type of the item.
void setSize(qint64 size)
Set the size of the item in bytes.
void clearFlags()
Removes all flags from the item.
void setMimeType(const QString &mimeType)
Sets the mime type of the item to mimeType.
QUrl url(UrlType type=UrlShort) const
Returns the url of the item.
Flags flags() const
Returns all flags of this item.
void setRevision(int revision)
Sets the revision number of the item.
QList< int > availablePayloadMetaTypeIds() const
Returns a list of metatype-ids, describing the different variants of payload that are currently conta...
bool operator!=(const Item &other) const
Returns whether the item's id does not equal the id of the other item.
void setModificationTime(const QDateTime &datetime)
Sets the timestamp of the last modification of this item.
bool hasPayload() const
Returns whether the item has a payload object.
Id id() const
Returns the unique identifier of the item.
bool operator==(const Item &other) const
Returns whether this item's id equals the id of the other item.
void clearAttributes()
Removes and deletes all attributes of the item.
int revision() const
Returns the revision number of the item.
Attribute::List attributes() const
Returns a list of all attributes of the item.
void setPayloadPath(const QString &filePath)
Sets a path to a file with full payload.
bool hasAttribute() const
Returns whether the item has an attribute of the requested type.
Collection::Id storageCollectionId() const
Returns the unique identifier of the collection this item is stored in.
void setRemoteId(const QString &id)
Sets the remote id of the item.
QString remoteId() const
Returns the remote id of the item.
QByteArray payloadData() const
Returns the full payload in its canonical representation, e.g.
static const char FullPayload[]
Describes the part name that is used to fetch the full payload of an item.
bool isValid() const
Returns whether the item is valid.
QSet< QByteArray > availablePayloadParts() const
Returns the parts available for this item.
Collection parentCollection() const
Returns the parent collection of this object.
void setFlag(const QByteArray &name)
Sets the flag with the given name in the item.
const T * attribute() const
Returns the attribute of the requested type or 0 if it is not available.
void setFlags(const Flags &flags)
Overwrites all flags of the item by the given flags.
void addAttribute(Attribute *attribute)
Adds an attribute to the item.
QSet< QByteArray > cachedPayloadParts() const
Returns the parts available for this item in the cache.
QDateTime modificationTime() const
Returns the timestamp of the last modification of this item.
void clearPayload()
Marks that the payload shall be cleared from the cache when this item is passed to an ItemModifyJob t...
void apply(const Item &other)
Applies the parts of Item other to this item.
void setRemoteRevision(const QString &revision)
Sets the remote revision of the item.
void setGid(const QString &gid)
Sets the gid of the entity.
QSet< QByteArray > loadedPayloadParts() const
Returns the list of loaded payload parts.
void removeAttribute()
Removes and deletes the attribute of the requested type.
UrlType
Describes the type of url which is returned in url().
@ UrlWithMimeType
A url with identifier and mimetype.
static Item fromUrl(const QUrl &url)
Creates an item from the given url.
Helper integration between Akonadi and Qt.
QString name(StandardAction id)
bool contains(const AT &value) const const
iterator insert(const_iterator before, parameter_type value)
void push_back(parameter_type value)
bool removeOne(const AT &t)
void reserve(qsizetype size)
iterator erase(const_iterator pos)
iterator find(const T &value)
iterator insert(const T &value)
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
qlonglong toLongLong(bool *ok, int base) const const
QByteArray toUtf8() const const
QString join(QChar separator) 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