1 /*
2 This file is part of Akonadi Contact.
3
4 SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8
9 #include "contactgroupexpandjob.h"
10 #include "akonadi_contact_debug.h"
11 #include "job/contactgroupsearchjob.h"
12 #include <Akonadi/ItemFetchJob>
13 #include <Akonadi/ItemFetchScope>
14 #include <Akonadi/ItemSearchJob>
15 #include <kcontacts_version.h>
16 using namespace Akonadi;
17
18 class Akonadi::ContactGroupExpandJobPrivate
19 {
20 public:
ContactGroupExpandJobPrivate(const KContacts::ContactGroup & group,ContactGroupExpandJob * parent)21 ContactGroupExpandJobPrivate(const KContacts::ContactGroup &group, ContactGroupExpandJob *parent)
22 : mParent(parent)
23 , mGroup(group)
24 {
25 }
26
ContactGroupExpandJobPrivate(const QString & name,ContactGroupExpandJob * parent)27 ContactGroupExpandJobPrivate(const QString &name, ContactGroupExpandJob *parent)
28 : mParent(parent)
29 , mName(name)
30 {
31 }
32
resolveGroup()33 void resolveGroup()
34 {
35 for (int i = 0, total = mGroup.dataCount(); i < total; ++i) {
36 const KContacts::ContactGroup::Data data = mGroup.data(i);
37
38 KContacts::Addressee contact;
39 contact.setNameFromString(data.name());
40 #if KContacts_VERSION < QT_VERSION_CHECK(5, 88, 0)
41 contact.insertEmail(data.email(), true);
42 #else
43 KContacts::Email email(data.email());
44 email.setPreferred(true);
45 contact.addEmail(email);
46 #endif
47 mContacts.append(contact);
48 }
49
50 for (int i = 0, total = mGroup.contactReferenceCount(); i < total; ++i) {
51 const KContacts::ContactGroup::ContactReference reference = mGroup.contactReference(i);
52
53 Item item;
54 if (!reference.gid().isEmpty()) {
55 item.setGid(reference.gid());
56 } else {
57 item.setId(reference.uid().toLongLong());
58 }
59 auto job = new ItemFetchJob(item, mParent);
60 job->fetchScope().fetchFullPayload();
61 job->setProperty("preferredEmail", reference.preferredEmail());
62
63 mParent->connect(job, &ItemFetchJob::result, mParent, [this](KJob *job) {
64 fetchResult(job);
65 });
66
67 mFetchCount++;
68 }
69
70 if (mFetchCount == 0) { // nothing to fetch, so we can return immediately
71 mParent->emitResult();
72 }
73 }
74
searchResult(KJob * job)75 void searchResult(KJob *job)
76 {
77 if (job->error()) {
78 mParent->setError(job->error());
79 mParent->setErrorText(job->errorText());
80 mParent->emitResult();
81 return;
82 }
83
84 auto searchJob = qobject_cast<ContactGroupSearchJob *>(job);
85
86 if (searchJob->contactGroups().isEmpty()) {
87 mParent->emitResult();
88 return;
89 }
90
91 mGroup = searchJob->contactGroups().at(0);
92 resolveGroup();
93 }
94
fetchResult(KJob * job)95 void fetchResult(KJob *job)
96 {
97 const ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job);
98
99 const Item::List items = fetchJob->items();
100 if (!items.isEmpty()) {
101 const QString preferredEmail = fetchJob->property("preferredEmail").toString();
102
103 const Item item = items.first();
104 if (item.hasPayload<KContacts::Addressee>()) {
105 auto contact = item.payload<KContacts::Addressee>();
106 #if KContacts_VERSION < QT_VERSION_CHECK(5, 88, 0)
107 if (!preferredEmail.isEmpty()) {
108 contact.insertEmail(preferredEmail, true);
109 }
110 #else
111 if (!preferredEmail.isEmpty()) {
112 KContacts::Email email(preferredEmail);
113 email.setPreferred(true);
114 contact.addEmail(email);
115 }
116 #endif
117 mContacts.append(contact);
118 } else {
119 qCWarning(AKONADICONTACT_LOG) << "Contact for Akonadi item" << item.id() << "does not exist anymore!";
120 }
121 }
122
123 mFetchCount--;
124
125 if (mFetchCount == 0) {
126 mParent->emitResult();
127 }
128 }
129
130 ContactGroupExpandJob *const mParent;
131 KContacts::ContactGroup mGroup;
132 QString mName;
133 KContacts::Addressee::List mContacts;
134
135 int mFetchCount = 0;
136 };
137
ContactGroupExpandJob(const KContacts::ContactGroup & group,QObject * parent)138 ContactGroupExpandJob::ContactGroupExpandJob(const KContacts::ContactGroup &group, QObject *parent)
139 : KJob(parent)
140 , d(new ContactGroupExpandJobPrivate(group, this))
141 {
142 }
143
ContactGroupExpandJob(const QString & name,QObject * parent)144 ContactGroupExpandJob::ContactGroupExpandJob(const QString &name, QObject *parent)
145 : KJob(parent)
146 , d(new ContactGroupExpandJobPrivate(name, this))
147 {
148 }
149
150 ContactGroupExpandJob::~ContactGroupExpandJob() = default;
151
start()152 void ContactGroupExpandJob::start()
153 {
154 if (!d->mName.isEmpty() && !d->mName.contains(QLatin1Char('@'))) {
155 // we have to search the contact group first
156 auto searchJob = new ContactGroupSearchJob(this);
157 searchJob->setQuery(ContactGroupSearchJob::Name, d->mName);
158 searchJob->setLimit(1);
159 connect(searchJob, &ContactGroupSearchJob::result, this, [this](KJob *job) {
160 d->searchResult(job);
161 });
162 } else {
163 QMetaObject::invokeMethod(
164 this,
165 [this]() {
166 d->resolveGroup();
167 },
168 Qt::QueuedConnection);
169 }
170 }
171
contacts() const172 KContacts::Addressee::List ContactGroupExpandJob::contacts() const
173 {
174 return d->mContacts;
175 }
176
177 #include "moc_contactgroupexpandjob.cpp"
178