1 /* -*- mode: c++; c-basic-offset:4 -*-
2     commands/adduseridcommand.cpp
3 
4     This file is part of Kleopatra, the KDE keymanager
5     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #include <config-kleopatra.h>
11 
12 #include "adduseridcommand.h"
13 
14 #include "command_p.h"
15 
16 #include "dialogs/adduseriddialog.h"
17 #include "dialogs/addemaildialog.h"
18 
19 #include <Libkleo/Formatting>
20 #include <QGpgME/Protocol>
21 #include <QGpgME/AddUserIDJob>
22 
23 #include <gpgme++/key.h>
24 
25 #include <KLocalizedString>
26 #include "kleopatra_debug.h"
27 
28 
29 using namespace Kleo;
30 using namespace Kleo::Commands;
31 using namespace Kleo::Dialogs;
32 using namespace GpgME;
33 
34 class AddUserIDCommand::Private : public Command::Private
35 {
36     friend class ::Kleo::Commands::AddUserIDCommand;
q_func() const37     AddUserIDCommand *q_func() const
38     {
39         return static_cast<AddUserIDCommand *>(q);
40     }
41 public:
42     explicit Private(AddUserIDCommand *qq, KeyListController *c);
43     ~Private() override;
44 
45     void init();
46 
47 private:
48     void slotDialogAccepted();
49     void slotSimpleDialogAccepted();
50     void slotDialogRejected();
51     void slotResult(const Error &err);
52 
53 private:
54     void ensureDialogCreated();
55     void createJob();
56     void showErrorDialog(const Error &error);
57     void showSuccessDialog();
58 
59 private:
60     GpgME::Key key;
61     QPointer<AddUserIDDialog> dialog;
62     QPointer<AddEmailDialog> simpleDialog;
63     QPointer<QGpgME::AddUserIDJob> job;
64 };
65 
d_func()66 AddUserIDCommand::Private *AddUserIDCommand::d_func()
67 {
68     return static_cast<Private *>(d.get());
69 }
d_func() const70 const AddUserIDCommand::Private *AddUserIDCommand::d_func() const
71 {
72     return static_cast<const Private *>(d.get());
73 }
74 
75 #define d d_func()
76 #define q q_func()
77 
Private(AddUserIDCommand * qq,KeyListController * c)78 AddUserIDCommand::Private::Private(AddUserIDCommand *qq, KeyListController *c)
79     : Command::Private(qq, c),
80       key(),
81       dialog(),
82       job()
83 {
84 
85 }
86 
~Private()87 AddUserIDCommand::Private::~Private()
88 {
89     qCDebug(KLEOPATRA_LOG);
90     if (dialog) {
91         delete dialog;
92     }
93     if (simpleDialog) {
94         delete simpleDialog;
95     }
96 }
97 
AddUserIDCommand(KeyListController * c)98 AddUserIDCommand::AddUserIDCommand(KeyListController *c)
99     : Command(new Private(this, c))
100 {
101     d->init();
102 }
103 
AddUserIDCommand(QAbstractItemView * v,KeyListController * c)104 AddUserIDCommand::AddUserIDCommand(QAbstractItemView *v, KeyListController *c)
105     : Command(v, new Private(this, c))
106 {
107     d->init();
108 }
109 
AddUserIDCommand(const GpgME::Key & key)110 AddUserIDCommand::AddUserIDCommand(const GpgME::Key &key)
111     : Command(key, new Private(this, nullptr))
112 {
113     d->init();
114 }
115 
init()116 void AddUserIDCommand::Private::init()
117 {
118 
119 }
120 
~AddUserIDCommand()121 AddUserIDCommand::~AddUserIDCommand()
122 {
123     qCDebug(KLEOPATRA_LOG);
124 }
125 
doStart()126 void AddUserIDCommand::doStart()
127 {
128 
129     const std::vector<Key> keys = d->keys();
130     if (keys.size() != 1 ||
131             keys.front().protocol() != GpgME::OpenPGP ||
132             !keys.front().hasSecret()) {
133         d->finished();
134         return;
135     }
136 
137     d->key = keys.front();
138 
139     d->ensureDialogCreated();
140     Q_ASSERT(d->dialog);
141 
142     const UserID uid = d->key.userID(0);
143 
144     // d->simpleDialog->setEmail(Formatting::prettyEMail(uid.email(), uid.id()));
145 
146     d->dialog->setName(QString::fromUtf8(uid.name()));
147     d->dialog->setEmail(Formatting::prettyEMail(uid.email(), uid.id()));
148     d->dialog->setComment(QString::fromUtf8(uid.comment()));
149 
150     d->simpleDialog->show();
151 }
152 
slotSimpleDialogAccepted()153 void AddUserIDCommand::Private::slotSimpleDialogAccepted()
154 {
155     if (simpleDialog->advancedSelected()) {
156         qDebug() << "thinking advanced selected";
157         dialog->show();
158         return;
159     }
160 
161     createJob();
162     if (!job) {
163         finished();
164         return;
165     }
166     if (const Error err = job->start(key, QString(), simpleDialog->email(), QString())) {
167         showErrorDialog(err);
168         finished();
169     }
170 }
171 
slotDialogAccepted()172 void AddUserIDCommand::Private::slotDialogAccepted()
173 {
174     Q_ASSERT(dialog);
175 
176     createJob();
177     if (!job) {
178         finished();
179     }
180 
181     else if (const Error err = job->start(key, dialog->name(), dialog->email(), dialog->comment())) {
182         showErrorDialog(err);
183         finished();
184     }
185 }
186 
slotDialogRejected()187 void AddUserIDCommand::Private::slotDialogRejected()
188 {
189     Q_EMIT q->canceled();
190     finished();
191 }
192 
slotResult(const Error & err)193 void AddUserIDCommand::Private::slotResult(const Error &err)
194 {
195     if (err.isCanceled())
196         ;
197     else if (err) {
198         showErrorDialog(err);
199     } else {
200         showSuccessDialog();
201     }
202     finished();
203 }
204 
doCancel()205 void AddUserIDCommand::doCancel()
206 {
207     qCDebug(KLEOPATRA_LOG);
208     if (d->job) {
209         d->job->slotCancel();
210     }
211 }
212 
ensureDialogCreated()213 void AddUserIDCommand::Private::ensureDialogCreated()
214 {
215     if (dialog) {
216         return;
217     }
218 
219     dialog = new AddUserIDDialog;
220     applyWindowID(dialog);
221 
222     connect(dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted()));
223     connect(dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()));
224 
225     simpleDialog = new AddEmailDialog;
226     applyWindowID(simpleDialog);
227 
228     connect(simpleDialog, SIGNAL(accepted()), q, SLOT(slotSimpleDialogAccepted()));
229     connect(simpleDialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()));
230 }
231 
createJob()232 void AddUserIDCommand::Private::createJob()
233 {
234     Q_ASSERT(!job);
235 
236     const auto backend = (key.protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
237     if (!backend) {
238         return;
239     }
240 
241     QGpgME::AddUserIDJob *const j = backend->addUserIDJob();
242     if (!j) {
243         return;
244     }
245 
246     connect(j, &QGpgME::Job::progress,
247             q, &Command::progress);
248     connect(j, SIGNAL(result(GpgME::Error)),
249             q, SLOT(slotResult(GpgME::Error)));
250 
251     job = j;
252 }
253 
showErrorDialog(const Error & err)254 void AddUserIDCommand::Private::showErrorDialog(const Error &err)
255 {
256     error(xi18nc("@info",
257                  "<para>An error occurred while trying to add the user-id: "
258                  "<message>%1</message></para>",
259                  QString::fromLocal8Bit(err.asString())),
260           i18nc("@title:window", "Add User-ID Error"));
261 }
262 
showSuccessDialog()263 void AddUserIDCommand::Private::showSuccessDialog()
264 {
265     information(i18nc("@info", "User-ID successfully added."),
266                 i18nc("@title:window", "Add User-ID Succeeded"));
267 }
268 
269 #undef d
270 #undef q
271 
272 #include "moc_adduseridcommand.cpp"
273