1 /*
2    SPDX-FileCopyrightText: 2014-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "savecontactpreferencejob.h"
8 
9 #include <KJob>
10 #include <KLocalizedString>
11 
12 #include <QInputDialog>
13 
14 #include <Akonadi/CollectionDialog>
15 #include <Akonadi/Contact/ContactSearchJob>
16 #include <Akonadi/ItemCreateJob>
17 #include <Akonadi/ItemModifyJob>
18 
19 #include "messagecomposer_debug.h"
20 #include <QPointer>
21 #include <kcontacts_version.h>
22 
23 using namespace MessageComposer;
24 
SaveContactPreferenceJob(const QString & email,const Kleo::KeyResolver::ContactPreferences & pref,QObject * parent)25 SaveContactPreferenceJob::SaveContactPreferenceJob(const QString &email, const Kleo::KeyResolver::ContactPreferences &pref, QObject *parent)
26     : QObject(parent)
27     , mEmail(email)
28     , mPref(pref)
29 {
30 }
31 
~SaveContactPreferenceJob()32 SaveContactPreferenceJob::~SaveContactPreferenceJob()
33 {
34 }
35 
start()36 void SaveContactPreferenceJob::start()
37 {
38     auto job = new Akonadi::ContactSearchJob(this);
39     connect(job, &Akonadi::ContactSearchJob::result, this, &SaveContactPreferenceJob::slotSearchContact);
40     job->setLimit(1);
41     job->setQuery(Akonadi::ContactSearchJob::Email, mEmail);
42     job->start();
43 }
44 
slotSearchContact(KJob * job)45 void SaveContactPreferenceJob::slotSearchContact(KJob *job)
46 {
47     auto contactSearchJob = qobject_cast<Akonadi::ContactSearchJob *>(job);
48 
49     const Akonadi::Item::List items = contactSearchJob->items();
50 
51     if (items.isEmpty()) {
52         bool ok = true;
53         const QString fullName = QInputDialog::getText(nullptr,
54                                                        i18n("Name Selection"),
55                                                        i18n("Which name shall the contact '%1' have in your address book?", mEmail),
56                                                        QLineEdit::Normal,
57                                                        QString(),
58                                                        &ok);
59         if (!ok) {
60             deleteLater();
61             return;
62         }
63 
64         QPointer<Akonadi::CollectionDialog> dlg = new Akonadi::CollectionDialog(Akonadi::CollectionDialog::KeepTreeExpanded);
65         dlg->setMimeTypeFilter(QStringList() << KContacts::Addressee::mimeType());
66         dlg->setAccessRightsFilter(Akonadi::Collection::CanCreateItem);
67         dlg->setDescription(i18n("Select the address book folder to store the new contact in:"));
68         if (!dlg->exec()) {
69             delete dlg;
70             deleteLater();
71             return;
72         }
73 
74         const Akonadi::Collection targetCollection = dlg->selectedCollection();
75         delete dlg;
76 
77         KContacts::Addressee contact;
78         contact.setNameFromString(fullName);
79 #if KContacts_VERSION < QT_VERSION_CHECK(5, 88, 0)
80         contact.insertEmail(mEmail, true);
81 #else
82         KContacts::Email email(mEmail);
83         email.setPreferred(true);
84         contact.addEmail(email);
85 #endif
86         writeCustomContactProperties(contact, mPref);
87 
88         Akonadi::Item item(KContacts::Addressee::mimeType());
89         item.setPayload<KContacts::Addressee>(contact);
90 
91         auto createJob = new Akonadi::ItemCreateJob(item, targetCollection);
92         connect(createJob, &Akonadi::ContactSearchJob::result, this, &SaveContactPreferenceJob::slotModifyCreateItem);
93     } else {
94         Akonadi::Item item = items.first();
95 
96         auto contact = item.payload<KContacts::Addressee>();
97         writeCustomContactProperties(contact, mPref);
98 
99         item.setPayload<KContacts::Addressee>(contact);
100 
101         auto itemModifyJob = new Akonadi::ItemModifyJob(item);
102         connect(itemModifyJob, &Akonadi::ContactSearchJob::result, this, &SaveContactPreferenceJob::slotModifyCreateItem);
103     }
104 }
105 
writeCustomContactProperties(KContacts::Addressee & contact,const Kleo::KeyResolver::ContactPreferences & pref) const106 void SaveContactPreferenceJob::writeCustomContactProperties(KContacts::Addressee &contact, const Kleo::KeyResolver::ContactPreferences &pref) const
107 {
108     contact.insertCustom(QStringLiteral("KADDRESSBOOK"),
109                          QStringLiteral("CRYPTOENCRYPTPREF"),
110                          QLatin1String(Kleo::encryptionPreferenceToString(pref.encryptionPreference)));
111     contact.insertCustom(QStringLiteral("KADDRESSBOOK"),
112                          QStringLiteral("CRYPTOSIGNPREF"),
113                          QLatin1String(Kleo::signingPreferenceToString(pref.signingPreference)));
114     contact.insertCustom(QStringLiteral("KADDRESSBOOK"),
115                          QStringLiteral("CRYPTOPROTOPREF"),
116                          QLatin1String(cryptoMessageFormatToString(pref.cryptoMessageFormat)));
117     contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("OPENPGPFP"), pref.pgpKeyFingerprints.join(QLatin1Char(',')));
118     contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("SMIMEFP"), pref.smimeCertFingerprints.join(QLatin1Char(',')));
119 }
120 
slotModifyCreateItem(KJob * job)121 void SaveContactPreferenceJob::slotModifyCreateItem(KJob *job)
122 {
123     if (job->error()) {
124         qCDebug(MESSAGECOMPOSER_LOG) << "modify item failed " << job->errorString();
125     }
126     deleteLater();
127 }
128