12#include "akonadicore_debug.h"
13#include "itemfetchscope.h"
14#include "jobs/itemfetchjob.h"
15#include "jobs/itemmodifyjob.h"
16#include "jobs/tagcreatejob.h"
17#include "jobs/tagfetchjob.h"
18#include "jobs/tagmodifyjob.h"
19#include "tagfetchscope.h"
23bool operator==(
const Item &left,
const Item &right)
28 if (!
left.remoteId().isEmpty() && !
right.remoteId().isEmpty() && (
left.remoteId() ==
right.remoteId())) {
46void TagSync::setFullTagList(
const Akonadi::Tag::List &tags)
53void TagSync::setTagMembers(
const QHash<QString, Akonadi::Item::List> &ridMemberMap)
55 mRidMemberMap = ridMemberMap;
56 mTagMembersDeliveryDone =
true;
60void TagSync::doStart()
64 auto fetch =
new Akonadi::TagFetchJob(
this);
65 fetch->fetchScope().setFetchRemoteId(
true);
69void TagSync::onLocalTagFetchDone(KJob *job)
72 auto fetch =
static_cast<TagFetchJob *
>(job);
73 mLocalTags = fetch->tags();
74 mLocalTagsFetched =
true;
78void TagSync::diffTags()
80 if (!mDeliveryDone || !mTagMembersDeliveryDone || !mLocalTagsFetched) {
81 qCDebug(AKONADICORE_LOG) <<
"waiting for delivery: " << mDeliveryDone << mLocalTagsFetched;
85 QHash<QByteArray, Akonadi::Tag> tagByGid;
86 QHash<QByteArray, Akonadi::Tag> tagByRid;
87 QHash<Akonadi::Tag::Id, Akonadi::Tag> tagById;
88 for (
const Akonadi::Tag &localTag : std::as_const(mLocalTags)) {
89 tagByRid.
insert(localTag.remoteId(), localTag);
90 tagByGid.
insert(localTag.gid(), localTag);
91 if (!localTag.remoteId().isEmpty()) {
92 tagById.
insert(localTag.id(), localTag);
95 for (
const Akonadi::Tag &remoteTag : std::as_const(mRemoteTags)) {
96 if (tagByRid.
contains(remoteTag.remoteId())) {
98 Tag tag = tagByRid.
value(remoteTag.remoteId());
99 auto itemFetch =
new ItemFetchJob(tag,
this);
101 itemFetch->setProperty(
"merge",
false);
102 itemFetch->fetchScope().setFetchGid(
true);
105 tagById.
remove(tagByRid.
value(remoteTag.remoteId()).id());
106 }
else if (tagByGid.
contains(remoteTag.gid())) {
109 Tag tag = tagByGid.
value(remoteTag.gid());
110 tag.setRemoteId(remoteTag.remoteId());
111 auto itemFetch =
new ItemFetchJob(tag,
this);
113 itemFetch->setProperty(
"merge",
true);
114 itemFetch->fetchScope().setFetchGid(
true);
117 tagById.
remove(tagByGid.
value(remoteTag.gid()).id());
120 auto createJob =
new TagCreateJob(remoteTag,
this);
121 createJob->setMergeIfExisting(
true);
126 for (
const Tag &tag : std::as_const(tagById)) {
129 copy.setRemoteId(QByteArray(
""));
130 auto modJob =
new TagModifyJob(copy,
this);
136void TagSync::onCreateTagDone(KJob *job)
139 qCWarning(AKONADICORE_LOG) <<
"ItemFetch failed: " << job->
errorString();
143 Akonadi::Tag tag =
static_cast<Akonadi::TagCreateJob *
>(job)->tag();
145 for (Item item : remoteMembers) {
147 auto modJob =
new ItemModifyJob(item,
this);
149 qCDebug(AKONADICORE_LOG) <<
"setting tag " << item.remoteId();
153static bool containsByGidOrRid(
const Item::List &items,
const Item &key)
155 return std::any_of(items.
cbegin(), items.
cend(), [&key](
const Item &item) {
156 return ((!item.gid().isEmpty() && !key.gid().isEmpty()) && (item.gid() == key.gid())) || (item.remoteId() == key.remoteId());
160void TagSync::onTagItemsFetchDone(KJob *job)
163 qCWarning(AKONADICORE_LOG) <<
"ItemFetch failed: " << job->
errorString();
174 for (
const Item &remote : remoteMembers) {
175 if (!containsByGidOrRid(items, remote)) {
182 for (
const Item &local : items) {
185 if (local.remoteId().isEmpty()) {
188 if (!containsByGidOrRid(remoteMembers, local)) {
194 for (Item item : std::as_const(toRemove)) {
196 auto modJob =
new ItemModifyJob(item,
this);
198 qCDebug(AKONADICORE_LOG) <<
"removing tag " << item.remoteId();
201 for (Item item : std::as_const(toAdd)) {
203 auto modJob =
new ItemModifyJob(item,
this);
205 qCDebug(AKONADICORE_LOG) <<
"setting tag " << item.remoteId();
209void TagSync::onJobDone(KJob * )
214void TagSync::slotResult(KJob *job)
221 Akonadi::Job::slotResult(job);
225void TagSync::checkDone()
230 qCDebug(AKONADICORE_LOG) <<
"done";
234#include "moc_tagsync.cpp"
Represents a PIM item stored in Akonadi storage.
QList< Item > List
Describes a list of items.
Base class for all actions in the Akonadi storage.
bool removeSubjob(KJob *job) override
Removes the given subjob of this job.
virtual QString errorString() const
Helper integration between Akonadi and Qt.
QStringView merge(QStringView lhs, QStringView rhs)
QAction * copy(const QObject *recvr, const char *slot, QObject *parent)
bool contains(const Key &key) const const
iterator insert(const Key &key, const T &value)
bool remove(const Key &key)
T value(const Key &key) const const
const_iterator cbegin() const const
const_iterator cend() const const
T value(qsizetype i) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QVariant property(const char *name) const const
QString fromLatin1(QByteArrayView str)
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
QVariant fromValue(T &&value)
bool toBool() const const