File indexing completed on 2024-11-24 04:44:17
0001 /* 0002 SPDX-FileCopyrightText: 2014 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0003 SPDX-FileContributor: Kevin Krammer <kevin.krammer@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "kolabchangeitemstagstask.h" 0009 #include "kolabresource_debug.h" 0010 0011 #include <Akonadi/ItemFetchJob> 0012 #include <Akonadi/ItemFetchScope> 0013 #include <Akonadi/TagFetchJob> 0014 #include <Akonadi/TagFetchScope> 0015 0016 KolabChangeItemsTagsTask::KolabChangeItemsTagsTask(const ResourceStateInterface::Ptr &resource, 0017 const QSharedPointer<TagConverter> &tagConverter, 0018 QObject *parent) 0019 : KolabRelationResourceTask(resource, parent) 0020 , mTagConverter(tagConverter) 0021 { 0022 } 0023 0024 void KolabChangeItemsTagsTask::startRelationTask(KIMAP::Session *session) 0025 { 0026 mSession = session; 0027 0028 // It's entirely possible that we don't have an rid yet 0029 0030 // compile a set of changed tags 0031 const auto addedTags{resourceState()->addedTags()}; 0032 for (const Akonadi::Tag &tag : addedTags) { 0033 mChangedTags.append(tag); 0034 } 0035 const auto removedTags{resourceState()->removedTags()}; 0036 for (const Akonadi::Tag &tag : removedTags) { 0037 mChangedTags.append(tag); 0038 } 0039 qCDebug(KOLABRESOURCE_LOG) << mChangedTags; 0040 0041 processNextTag(); 0042 } 0043 0044 void KolabChangeItemsTagsTask::processNextTag() 0045 { 0046 if (mChangedTags.isEmpty()) { 0047 changeProcessed(); 0048 return; 0049 } 0050 0051 // "take first" 0052 const Akonadi::Tag tag = mChangedTags.takeFirst(); 0053 0054 // We have to fetch it again in case it changed since the notification was emitted (which is likely) 0055 // Otherwise we get an empty remoteid for new tags that were immediately applied on an item 0056 auto fetch = new Akonadi::TagFetchJob(tag); 0057 fetch->fetchScope().setFetchRemoteId(true); 0058 connect(fetch, &KJob::result, this, &KolabChangeItemsTagsTask::onTagFetchDone); 0059 } 0060 0061 void KolabChangeItemsTagsTask::onTagFetchDone(KJob *job) 0062 { 0063 if (job->error()) { 0064 qCWarning(KOLABRESOURCE_LOG) << "TagFetch failed: " << job->errorString(); 0065 // TODO: we could continue for the other tags? 0066 cancelTask(job->errorString()); 0067 return; 0068 } 0069 0070 const Akonadi::Tag::List tags = static_cast<Akonadi::TagFetchJob *>(job)->tags(); 0071 if (tags.size() != 1) { 0072 qCWarning(KOLABRESOURCE_LOG) << "Invalid number of tags retrieved: " << tags.size(); 0073 // TODO: we could continue for the other tags? 0074 cancelTask(job->errorString()); 0075 return; 0076 } 0077 0078 auto fetch = new Akonadi::ItemFetchJob(tags.first()); 0079 fetch->fetchScope().setCacheOnly(true); 0080 fetch->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::All); 0081 fetch->fetchScope().setFetchGid(true); 0082 fetch->fetchScope().fetchFullPayload(true); 0083 fetch->setProperty("tag", QVariant::fromValue(tags.first())); 0084 connect(fetch, &KJob::result, this, &KolabChangeItemsTagsTask::onItemsFetchDone); 0085 } 0086 0087 void KolabChangeItemsTagsTask::onItemsFetchDone(KJob *job) 0088 { 0089 if (job->error()) { 0090 qCWarning(KOLABRESOURCE_LOG) << "ItemFetch failed: " << job->errorString(); 0091 // TODO: we could continue for the other tags? 0092 cancelTask(job->errorString()); 0093 return; 0094 } 0095 0096 auto changeHelper = new TagChangeHelper(this); 0097 0098 connect(changeHelper, &TagChangeHelper::applyCollectionChanges, this, &KolabChangeItemsTagsTask::onApplyCollectionChanged); 0099 connect(changeHelper, &TagChangeHelper::cancelTask, this, &KolabChangeItemsTagsTask::onCancelTask); 0100 connect(changeHelper, &TagChangeHelper::changeCommitted, this, &KolabChangeItemsTagsTask::onChangeCommitted); 0101 0102 const Akonadi::Item::List items = static_cast<Akonadi::ItemFetchJob *>(job)->items(); 0103 qCDebug(KOLABRESOURCE_LOG) << items.size(); 0104 const auto tag = job->property("tag").value<Akonadi::Tag>(); 0105 { 0106 qCDebug(KOLABRESOURCE_LOG) << "Writing " << tag.name() << " with " << items.size() << " members to the server: "; 0107 for (const Akonadi::Item &item : items) { 0108 qCDebug(KOLABRESOURCE_LOG) << "member(localid, remoteid): " << item.id() << item.remoteId(); 0109 } 0110 } 0111 Q_ASSERT(tag.isValid()); 0112 changeHelper->start(tag, mTagConverter->createMessage(tag, items, resourceState()->userName()), mSession); 0113 } 0114 0115 void KolabChangeItemsTagsTask::onApplyCollectionChanged(const Akonadi::Collection &collection) 0116 { 0117 mRelationCollection = collection; 0118 applyCollectionChanges(collection); 0119 } 0120 0121 void KolabChangeItemsTagsTask::onCancelTask(const QString &errorText) 0122 { 0123 // TODO: we could continue for the other tags? 0124 cancelTask(errorText); 0125 } 0126 0127 void KolabChangeItemsTagsTask::onChangeCommitted() 0128 { 0129 processNextTag(); 0130 } 0131 0132 #include "moc_kolabchangeitemstagstask.cpp"