File indexing completed on 2024-06-23 05:21:18

0001 /* Copyright (C) 2017 Roland Pallai <dap78@magex.hu>
0002    Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
0003 
0004    This file is part of the Trojita Qt IMAP e-mail client,
0005    http://trojita.flaska.net/
0006 
0007    This program is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU General Public License as
0009    published by the Free Software Foundation; either version 2 of
0010    the License or (at your option) version 3 or any later version
0011    accepted by the membership of KDE e.V. (or its successor approved
0012    by the membership of KDE e.V.), which shall act as a proxy
0013    defined in Section 14 of version 3 of the license.
0014 
0015    This program is distributed in the hope that it will be useful,
0016    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018    GNU General Public License for more details.
0019 
0020    You should have received a copy of the GNU General Public License
0021    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022 */
0023 
0024 #include "AkonadiAddressbookCompletionJob.h"
0025 
0026 #include <QDebug>
0027 
0028 AkonadiAddressbookCompletionJob::AkonadiAddressbookCompletionJob(const QString &input, const QStringList &ignores, int max, AkonadiAddressbook *parent) :
0029     AddressbookCompletionJob(parent), m_input(input), m_ignores(ignores), m_max(max), m_parent(parent), m_job(nullptr)
0030 {
0031 }
0032 
0033 void AkonadiAddressbookCompletionJob::doStart()
0034 {
0035     Q_ASSERT(!m_job);
0036     m_job = new Akonadi::ContactSearchJob(this);
0037     // Contacts without email are skipped below so fetch some more
0038     if (m_max != -1)
0039         m_job->setLimit(m_max * 2);
0040     m_job->setQuery(Akonadi::ContactSearchJob::NameOrEmail, m_input, Akonadi::ContactSearchJob::StartsWithMatch);
0041     connect(m_job, &KJob::result, this, &AkonadiAddressbookCompletionJob::searchResult);
0042 }
0043 
0044 void AkonadiAddressbookCompletionJob::doStop()
0045 {
0046     Q_ASSERT(m_job);
0047     disconnect(m_job, &KJob::result, this, &AkonadiAddressbookCompletionJob::searchResult);
0048     // Kills and deletes the job immediately
0049     bool ok = m_job->kill();
0050     Q_ASSERT(ok); Q_UNUSED(ok);
0051     m_job = nullptr;
0052     emit error(AddressbookJob::Stopped);
0053     finished();
0054 }
0055 
0056 void AkonadiAddressbookCompletionJob::searchResult(KJob *job)
0057 {
0058     Akonadi::ContactSearchJob *searchJob = qobject_cast<Akonadi::ContactSearchJob*>(job);
0059     Q_ASSERT(searchJob);
0060     if (job->error()) {
0061         qWarning() << "AkonadiAddressbookCompletionJob::searchResult:" << job->errorString();
0062         emit error(AddressbookJob::UnknownError);
0063     } else {
0064         NameEmailList list;
0065         const auto contacts = searchJob->contacts();
0066 
0067         for (int i = 0; i < contacts.size() && (m_max == -1 || list.size() < m_max); ++i) {
0068             KContacts::Addressee contact = contacts[i];
0069 
0070             // put the matching ones first and then the rest
0071             QSet<QString> emailsSet(contact.emails().begin(), contact.emails().end());
0072             QStringList emails1 = contact.emails().filter(m_input, Qt::CaseInsensitive);
0073             const QSet<QString> emails1Set(emails1.begin(), emails1.end());
0074             QStringList emails2 = emailsSet.subtract(emails1Set).values();
0075 
0076             Q_FOREACH(const QString &email, emails1 + emails2) {
0077                 if (!m_ignores.contains(email)) {
0078                     list << NameEmail(contact.realName(), email);
0079                     if (m_max != -1 && list.size() >= m_max)
0080                         break;
0081                 }
0082             }
0083         }
0084         emit completionAvailable(list);
0085     }
0086 
0087     finished();
0088 }