9#include "itemcreatejob.h" 
   11#include "collection.h" 
   12#include "gidextractor_p.h" 
   15#include "itemserializer_p.h" 
   17#include "private/protocol_p.h" 
   18#include "protocolhelper_p.h" 
   22#include <KLocalizedString> 
   26class Akonadi::ItemCreateJobPrivate : 
public JobPrivate
 
   29    explicit ItemCreateJobPrivate(ItemCreateJob *parent)
 
   34    Protocol::PartMetaData preparePart(
const QByteArray &part);
 
   36    QString jobDebuggingString() 
const override;
 
   37    Collection mCollection;
 
   39    QSet<QByteArray> mParts;
 
   40    QSet<QByteArray> mForeignParts;
 
   52    bool mItemReceived = 
false;
 
   55QString Akonadi::ItemCreateJobPrivate::jobDebuggingString()
 const 
   57    const QString collectionName = mCollection.name();
 
   58    QString str = QStringLiteral(
"%1 Item %2 from col %3")
 
   61                      .
arg(mCollection.id());
 
   62    if (!collectionName.
isEmpty()) {
 
   63        str += QStringLiteral(
" (%1)").
arg(collectionName);
 
   68Protocol::PartMetaData ItemCreateJobPrivate::preparePart(
const QByteArray &partName)
 
   70    ProtocolHelper::PartNamespace ns; 
 
   71    const QByteArray partLabel = ProtocolHelper::decodePartIdentifier(partName, ns);
 
   72    if (!mParts.remove(partLabel)) {
 
   74        return Protocol::PartMetaData();
 
   78    if (mForeignParts.contains(partLabel)) {
 
   79        mPendingPart = PendingPart{.name = partName, .
data = mItem.d_ptr->mPayloadPath.toUtf8()};
 
   80        const auto size = QFile(mItem.d_ptr->mPayloadPath).size();
 
   81        return Protocol::PartMetaData(partName, size, version, Protocol::PartMetaData::Foreign);
 
   84        mPendingPart.name = partName;
 
   85        ItemSerializer::serialize(mItem, partLabel, mPendingPart.data, version);
 
   86        return Protocol::PartMetaData(partName, mPendingPart.data.size(), version);
 
   91    : 
Job(new ItemCreateJobPrivate(this), 
parent)
 
   95    Q_ASSERT(!
item.mimeType().isEmpty());
 
   97    d->mParts = d->mItem.loadedPayloadParts();
 
   98    d->mCollection = collection;
 
  100    if (!d->mItem.payloadPath().isEmpty()) {
 
  101        d->mForeignParts = ItemSerializer::allowedForeignParts(d->mItem);
 
 
  113    if (!d->mCollection.isValid()) {
 
  120    auto cmd = Protocol::CreateItemCommandPtr::create();
 
  121    cmd->setMimeType(d->mItem.mimeType());
 
  122    cmd->setGid(d->mItem.gid());
 
  123    cmd->setRemoteId(d->mItem.remoteId());
 
  124    cmd->setRemoteRevision(d->mItem.remoteRevision());
 
  125    cmd->setModificationTime(d->mItem.modificationTime());
 
  127    Protocol::CreateItemCommand::MergeModes mergeModes = Protocol::CreateItemCommand::None;
 
  128    if ((d->mMergeOptions & 
GID) && !d->mItem.gid().isEmpty()) {
 
  129        mergeModes |= Protocol::CreateItemCommand::GID;
 
  131    if ((d->mMergeOptions & 
RID) && !d->mItem.remoteId().isEmpty()) {
 
  132        mergeModes |= Protocol::CreateItemCommand::RemoteID;
 
  134    if ((d->mMergeOptions & 
Silent)) {
 
  135        mergeModes |= Protocol::CreateItemCommand::Silent;
 
  137    const bool merge = (mergeModes & Protocol::CreateItemCommand::GID) || (mergeModes & Protocol::CreateItemCommand::RemoteID);
 
  138    cmd->setMergeModes(mergeModes);
 
  140    if (d->mItem.d_ptr->mFlagsOverwritten || !merge) {
 
  141        cmd->setFlags(d->mItem.flags());
 
  142        cmd->setFlagsOverwritten(d->mItem.d_ptr->mFlagsOverwritten);
 
  144        const auto addedFlags = ItemChangeLog::instance()->addedFlags(d->mItem.d_ptr);
 
  145        const auto deletedFlags = ItemChangeLog::instance()->deletedFlags(d->mItem.d_ptr);
 
  146        cmd->setAddedFlags(addedFlags);
 
  147        cmd->setRemovedFlags(deletedFlags);
 
  150    if (d->mItem.d_ptr->mTagsOverwritten || !merge) {
 
  151        const auto tags = d->mItem.tags();
 
  152        if (!tags.isEmpty()) {
 
  153            cmd->setTags(ProtocolHelper::entitySetToScope(tags));
 
  156        const auto addedTags = ItemChangeLog::instance()->addedTags(d->mItem.d_ptr);
 
  157        if (!addedTags.isEmpty()) {
 
  158            cmd->setAddedTags(ProtocolHelper::entitySetToScope(addedTags));
 
  160        const auto deletedTags = ItemChangeLog::instance()->deletedTags(d->mItem.d_ptr);
 
  161        if (!deletedTags.isEmpty()) {
 
  162            cmd->setRemovedTags(ProtocolHelper::entitySetToScope(deletedTags));
 
  166    cmd->setCollection(ProtocolHelper::entityToScope(d->mCollection));
 
  167    cmd->setItemSize(d->mItem.size());
 
  169    cmd->setAttributes(ProtocolHelper::attributesToProtocol(d->mItem));
 
  171    parts.
reserve(d->mParts.size());
 
  172    for (
const QByteArray &part : std::as_const(d->mParts)) {
 
  173        parts.
insert(ProtocolHelper::encodePartIdentifier(ProtocolHelper::PartPayload, part));
 
  175    cmd->setParts(parts);
 
 
  184    if (!response->isResponse() && response->type() == Protocol::Command::StreamPayload) {
 
  185        const auto &streamCmd = Protocol::cmdCast<Protocol::StreamPayloadCommand>(response);
 
  186        auto streamResp = Protocol::StreamPayloadResponsePtr::create();
 
  187        streamResp->setPayloadName(streamCmd.payloadName());
 
  188        if (streamCmd.request() == Protocol::StreamPayloadCommand::MetaData) {
 
  189            streamResp->setMetaData(d->preparePart(streamCmd.payloadName()));
 
  190        } 
else if (streamCmd.request() == Protocol::StreamPayloadCommand::Data) {
 
  191            if (streamCmd.payloadName() != d->mPendingPart.name) {
 
  192                streamResp->setError(1, QStringLiteral(
"Unexpected payload name"));
 
  193            } 
else if (streamCmd.destination().isEmpty()) {
 
  194                streamResp->setData(d->mPendingPart.data);
 
  197                if (!ProtocolHelper::streamPayloadToFile(streamCmd.destination(), d->mPendingPart.data, 
error)) {
 
  198                    streamResp->setError(1, QStringLiteral(
"Failed to stream payload to file: %1").arg(
QString::fromUtf8(
error)));
 
  202            streamResp->setError(1, QStringLiteral(
"Unknown stream payload request"));
 
  204        d->sendCommand(tag, streamResp);
 
  208    if (response->isResponse() && response->type() == Protocol::Command::FetchItems) {
 
  209        const auto &fetchResp = Protocol::cmdCast<Protocol::FetchItemsResponse>(response);
 
  210        Item item = ProtocolHelper::parseItemFetchResult(fetchResp);
 
  211        if (!
item.isValid()) {
 
  219    if (response->isResponse() && response->type() == Protocol::Command::CreateItem) {
 
 
  230    d->mMergeOptions = options;
 
 
  238    if (d->mItem.parentCollection().isValid()) {
 
  244    item.setParentCollection(d->mCollection);
 
  245    item.setStorageCollectionId(d->mCollection.id());
 
 
  250#include "moc_itemcreatejob.cpp" 
Represents a collection of PIM items.
 
bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response) override
This method should be reimplemented in the concrete jobs in case you want to handle incoming data.
 
ItemCreateJob(const Item &item, const Collection &collection, QObject *parent=nullptr)
Creates a new item create job.
 
void doStart() override
This method must be reimplemented in the concrete jobs.
 
Item item() const
Returns the created item with the new unique id, or an invalid item if the job failed.
 
@ Silent
Only return the id of the merged/created item.
 
void setMerge(MergeOptions options)
Merge this item into an existing one if available.
 
~ItemCreateJob() override
Destroys the item create job.
 
Represents a PIM item stored in Akonadi storage.
 
virtual bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response)
This method should be reimplemented in the concrete jobs in case you want to handle incoming data.
 
Job(QObject *parent=nullptr)
Creates a new job.
 
void setErrorText(const QString &errorText)
 
void setError(int errorCode)
 
QString i18n(const char *text, const TYPE &arg...)
 
Helper integration between Akonadi and Qt.
 
KDB_EXPORT KDbVersionInfo version()
 
QObject * parent() const const
 
iterator insert(const T &value)
 
void reserve(qsizetype size)
 
QString arg(Args &&... args) const const
 
QString fromUtf8(QByteArrayView str)
 
bool isEmpty() const const