File indexing completed on 2024-11-24 04:39:26

0001 /*
0002     This file is part of Akonadi Contact.
0003 
0004     SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "contactgroupexpandjob.h"
0010 #include "akonadi_contact_debug.h"
0011 #include "job/contactgroupsearchjob.h"
0012 #include <Akonadi/ItemFetchJob>
0013 #include <Akonadi/ItemFetchScope>
0014 #include <Akonadi/ItemSearchJob>
0015 using namespace Akonadi;
0016 
0017 class Akonadi::ContactGroupExpandJobPrivate
0018 {
0019 public:
0020     ContactGroupExpandJobPrivate(const KContacts::ContactGroup &group, ContactGroupExpandJob *parent)
0021         : mParent(parent)
0022         , mGroup(group)
0023     {
0024     }
0025 
0026     ContactGroupExpandJobPrivate(const QString &name, ContactGroupExpandJob *parent)
0027         : mParent(parent)
0028         , mName(name)
0029     {
0030     }
0031 
0032     void resolveGroup()
0033     {
0034         for (int i = 0, total = mGroup.dataCount(); i < total; ++i) {
0035             const KContacts::ContactGroup::Data data = mGroup.data(i);
0036 
0037             KContacts::Addressee contact;
0038             contact.setNameFromString(data.name());
0039             KContacts::Email email(data.email());
0040             email.setPreferred(true);
0041             contact.addEmail(email);
0042             mContacts.append(contact);
0043         }
0044 
0045         for (int i = 0, total = mGroup.contactReferenceCount(); i < total; ++i) {
0046             const KContacts::ContactGroup::ContactReference reference = mGroup.contactReference(i);
0047 
0048             Item item;
0049             if (!reference.gid().isEmpty()) {
0050                 item.setGid(reference.gid());
0051             } else {
0052                 item.setId(reference.uid().toLongLong());
0053             }
0054             auto job = new ItemFetchJob(item, mParent);
0055             job->fetchScope().fetchFullPayload();
0056             job->setProperty("preferredEmail", reference.preferredEmail());
0057 
0058             mParent->connect(job, &ItemFetchJob::result, mParent, [this](KJob *job) {
0059                 fetchResult(job);
0060             });
0061 
0062             mFetchCount++;
0063         }
0064 
0065         if (mFetchCount == 0) { // nothing to fetch, so we can return immediately
0066             mParent->emitResult();
0067         }
0068     }
0069 
0070     void searchResult(KJob *job)
0071     {
0072         if (job->error()) {
0073             mParent->setError(job->error());
0074             mParent->setErrorText(job->errorText());
0075             mParent->emitResult();
0076             return;
0077         }
0078 
0079         auto searchJob = qobject_cast<ContactGroupSearchJob *>(job);
0080 
0081         if (searchJob->contactGroups().isEmpty()) {
0082             mParent->emitResult();
0083             return;
0084         }
0085 
0086         mGroup = searchJob->contactGroups().at(0);
0087         resolveGroup();
0088     }
0089 
0090     void fetchResult(KJob *job)
0091     {
0092         const ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job);
0093 
0094         const Item::List items = fetchJob->items();
0095         if (!items.isEmpty()) {
0096             const QString preferredEmail = fetchJob->property("preferredEmail").toString();
0097 
0098             const Item item = items.first();
0099             if (item.hasPayload<KContacts::Addressee>()) {
0100                 auto contact = item.payload<KContacts::Addressee>();
0101                 if (!preferredEmail.isEmpty()) {
0102                     KContacts::Email email(preferredEmail);
0103                     email.setPreferred(true);
0104                     contact.addEmail(email);
0105                 }
0106                 mContacts.append(contact);
0107             } else {
0108                 qCWarning(AKONADICONTACT_LOG) << "Contact for Akonadi item" << item.id() << "does not exist anymore!";
0109             }
0110         }
0111 
0112         mFetchCount--;
0113 
0114         if (mFetchCount == 0) {
0115             mParent->emitResult();
0116         }
0117     }
0118 
0119     ContactGroupExpandJob *const mParent;
0120     KContacts::ContactGroup mGroup;
0121     QString mName;
0122     KContacts::Addressee::List mContacts;
0123 
0124     int mFetchCount = 0;
0125 };
0126 
0127 ContactGroupExpandJob::ContactGroupExpandJob(const KContacts::ContactGroup &group, QObject *parent)
0128     : KJob(parent)
0129     , d(new ContactGroupExpandJobPrivate(group, this))
0130 {
0131 }
0132 
0133 ContactGroupExpandJob::ContactGroupExpandJob(const QString &name, QObject *parent)
0134     : KJob(parent)
0135     , d(new ContactGroupExpandJobPrivate(name, this))
0136 {
0137 }
0138 
0139 ContactGroupExpandJob::~ContactGroupExpandJob() = default;
0140 
0141 void ContactGroupExpandJob::start()
0142 {
0143     if (!d->mName.isEmpty() && !d->mName.contains(QLatin1Char('@'))) {
0144         // we have to search the contact group first
0145         auto searchJob = new ContactGroupSearchJob(this);
0146         searchJob->setQuery(ContactGroupSearchJob::Name, d->mName);
0147         searchJob->setLimit(1);
0148         connect(searchJob, &ContactGroupSearchJob::result, this, [this](KJob *job) {
0149             d->searchResult(job);
0150         });
0151     } else {
0152         QMetaObject::invokeMethod(
0153             this,
0154             [this]() {
0155                 d->resolveGroup();
0156             },
0157             Qt::QueuedConnection);
0158     }
0159 }
0160 
0161 KContacts::Addressee::List ContactGroupExpandJob::contacts() const
0162 {
0163     return d->mContacts;
0164 }
0165 
0166 #include "moc_contactgroupexpandjob.cpp"