1/* This file is part of the KDE libraries
2 Copyright (C) 2004 George Staikos <staikos@kde.org>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "kwalletwizard.h"
20#include "kwalletwizard.moc"
21
22#include "ui_kwalletwizardpageexplanation.h"
23#include "ui_kwalletwizardpageintro.h"
24#include "ui_kwalletwizardpageoptions.h"
25#include "ui_kwalletwizardpagepassword.h"
26#ifdef HAVE_QGPGME
27#include "ui_kwalletwizardpagepasswordgpg.h"
28#include "ui_kwalletwizardpagegpgkey.h"
29#endif
30
31#include <QButtonGroup>
32
33#include <klocale.h>
34
35#ifdef HAVE_QGPGME
36#include <QComboBox>
37#include <gpgme++/context.h>
38#include <gpgme++/key.h>
39#include <gpgme++/keylistresult.h>
40#include <kdebug.h>
41#include <kmessagebox.h>
42#include <gpgme.h>
43#endif
44
45class PageIntro : public QWizardPage
46{
47public:
48 PageIntro(QWidget *parent)
49 : QWizardPage(parent)
50 {
51 ui.setupUi(this);
52
53 ui.ktitlewidget->setText("<h1>" + i18n("KWallet") + "</h1>");
54
55 int iconSize = 3 * fontMetrics().height();
56 // round to multiple of 16
57 iconSize = (iconSize + 8) & ~15;
58 QPixmap pix = KIconLoader::global()->loadIcon("kwalletmanager", KIconLoader::Dialog, iconSize);
59 ui.ktitlewidget->setPixmap(pix);
60
61 bg = new QButtonGroup(this);
62 bg->setExclusive(true);
63 bg->addButton(ui._basic, 0);
64 bg->addButton(ui._advanced, 1);
65
66 // force the "basic" button to be selected
67 ui._basic->setChecked(true);
68 }
69
70 QButtonGroup *bg;
71
72private:
73 Ui::KWalletWizardPageIntro ui;
74};
75
76class PagePassword : public QWizardPage
77{
78public:
79 PagePassword(QWidget *parent)
80 : QWizardPage(parent)
81 {
82
83 ui.setupUi(this);
84
85 registerField("useWallet", ui._useWallet);
86 registerField("pass1", ui._pass1);
87 registerField("pass2", ui._pass2);
88#ifdef HAVE_QGPGME
89 registerField("useGPG", ui._radioGpg);
90 registerField("useBlowfish", ui._radioBlowfish);
91 connect(ui._radioBlowfish, SIGNAL(toggled(bool)), parent, SLOT(passwordPageUpdate()));
92#endif
93
94 connect(ui._useWallet, SIGNAL(clicked()), parent, SLOT(passwordPageUpdate()));
95 connect(ui._pass1, SIGNAL(textChanged(QString)), parent, SLOT(passwordPageUpdate()));
96 connect(ui._pass2, SIGNAL(textChanged(QString)), parent, SLOT(passwordPageUpdate()));
97 }
98
99 virtual int nextId() const
100 {
101#ifdef HAVE_QGPGME
102 int nextId = -1;
103 if (field("useWallet").toBool()) {
104 if (field("useBlowfish").toBool()) {
105 nextId = static_cast<KWalletWizard*>(wizard())->wizardType() == KWalletWizard::Basic ? -1 : KWalletWizard::PageOptionsId; // same as non QGPGME case
106 } else {
107 nextId = KWalletWizard::PageGpgKeyId;
108 }
109 }
110
111 return nextId;
112#else
113 return static_cast<KWalletWizard*>(wizard())->wizardType() == KWalletWizard::Basic ? -1 : KWalletWizard::PageOptionsId;
114#endif
115 }
116
117 void setMatchLabelText(const QString &text)
118 {
119 ui._matchLabel->setText(text);
120 }
121
122private:
123#ifdef HAVE_QGPGME
124 Ui::KWalletWizardPagePasswordGpg ui;
125#else
126 Ui::KWalletWizardPagePassword ui;
127#endif
128};
129
130#ifdef HAVE_QGPGME
131typedef std::vector< GpgME::Key > KeysVector;
132Q_DECLARE_METATYPE(GpgME::Key)
133
134struct AddKeyToCombo {
135 QComboBox *_list;
136 AddKeyToCombo(QComboBox *list) : _list(list) {}
137 void operator()( const GpgME::Key &k) {
138 QString text = QString("%1 (%2)").arg(k.shortKeyID()).arg(k.userID(0).email());
139 QVariant varKey;
140 varKey.setValue(k);
141 _list->addItem(text, varKey);
142 }
143};
144
145class PageGpgKey : public QWizardPage
146{
147public:
148 PageGpgKey(QWidget* parent)
149 : QWizardPage(parent)
150 , userHasGpgKeys(false)
151 {
152 ui.setupUi(this);
153
154 registerField("gpgKey", ui._gpgKey);
155
156 KeysVector keys;
157 GpgME::initializeLibrary();
158 GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
159 if (err){
160 kDebug() << "OpenPGP not supported on your system!";
161 KMessageBox::error(this, i18n("The QGpgME library failed to initialize for the OpenPGP protocol. Please check your system's configuration then try again."));
162 } else {
163 boost::shared_ptr< GpgME::Context > ctx( GpgME::Context::createForProtocol(GpgME::OpenPGP) );
164 if (0 == ctx) {
165 KMessageBox::error(this, i18n("The QGpgME library failed to initialize for the OpenPGP protocol. Please check your system's configuration then try again."));
166 } else {
167
168 ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
169 int row =0;
170 err = ctx->startKeyListing();
171 while (!err) {
172 GpgME::Key k = ctx->nextKey(err);
173 if (err)
174 break;
175 if (!k.isInvalid() && k.canEncrypt() && (k.ownerTrust() == GpgME::Key::Ultimate)) {
176 keys.push_back(k);
177 }
178 }
179 ctx->endKeyListing();
180 }
181 }
182 std::for_each(keys.begin(), keys.end(), AddKeyToCombo(ui._gpgKey));
183
184 userHasGpgKeys = keys.size() >0;
185 if (userHasGpgKeys) {
186 ui.stackedWidget->setCurrentWidget(ui._pageWhenHasKeys);
187 } else {
188 ui.stackedWidget->setCurrentWidget(ui._pageNoKeys);
189 setFinalPage(true);
190 }
191 emit completeChanged();
192 }
193
194 virtual int nextId() const {
195 return static_cast<KWalletWizard*>(wizard())->wizardType() == KWalletWizard::Basic ? -1 : KWalletWizard::PageOptionsId;
196 }
197
198 virtual bool isComplete() const {
199 return userHasGpgKeys;
200 }
201
202 bool hasGpgKeys() const { return userHasGpgKeys; }
203
204 GpgME::Key gpgKey() const {
205 QVariant varKey = ui._gpgKey->itemData(field("gpgKey").toInt());
206 return varKey.value< GpgME::Key >();
207 }
208private:
209 Ui::KWalletWizardPageGpgKey ui;
210 bool userHasGpgKeys;
211};
212#endif
213
214class PageOptions : public QWizardPage
215{
216public:
217 PageOptions(QWidget *parent)
218 : QWizardPage(parent)
219 {
220 ui.setupUi(this);
221
222 registerField("closeWhenIdle", ui._closeIdle);
223 registerField("networkWallet", ui._networkWallet);
224 }
225
226private:
227 Ui::KWalletWizardPageOptions ui;
228};
229
230
231class PageExplanation : public QWizardPage
232{
233public:
234 PageExplanation(QWidget *parent)
235 : QWizardPage(parent)
236 {
237 ui.setupUi(this);
238 setFinalPage(true);
239 }
240
241private:
242 Ui::KWalletWizardPageExplanation ui;
243};
244
245
246
247KWalletWizard::KWalletWizard( QWidget *parent )
248 : QWizard(parent)
249{
250 setOption(HaveFinishButtonOnEarlyPages);
251
252 m_pageIntro = new PageIntro(this);
253 setPage(PageIntroId, m_pageIntro);
254 m_pagePasswd = new PagePassword(this);
255 setPage(PagePasswordId, m_pagePasswd);
256#ifdef HAVE_QGPGME
257 m_pageGpgKey = new PageGpgKey(this);
258 setPage(PageGpgKeyId, m_pageGpgKey);
259#endif
260 setPage(PageOptionsId, new PageOptions(this));
261 setPage(PageExplanationId, new PageExplanation(this));
262
263 resize(500, 420);
264}
265
266void KWalletWizard::passwordPageUpdate()
267{
268 bool complete = true;
269 if (field("useWallet").toBool()) {
270#ifdef HAVE_QGPGME
271 if (field("useBlowfish").toBool()) {
272 m_pagePasswd->setFinalPage(wizardType() == Basic);
273 button(NextButton)->setVisible(wizardType() != Basic);
274#endif
275 if (field("pass1").toString() == field("pass2").toString()) {
276 if (field("pass1").toString().isEmpty()) {
277 m_pagePasswd->setMatchLabelText(i18n("<qt>Password is empty. <b>(WARNING: Insecure)</b></qt>"));
278 } else {
279 m_pagePasswd->setMatchLabelText(i18n("Passwords match."));
280 }
281 } else {
282 m_pagePasswd->setMatchLabelText(i18n("Passwords do not match."));
283 complete = false;
284 }
285#ifdef HAVE_QGPGME
286 } else {
287 m_pagePasswd->setFinalPage(false);
288 button(NextButton)->setEnabled(true);
289 return;
290 }
291#endif
292 } else {
293 m_pagePasswd->setMatchLabelText(QString());
294 }
295 button(wizardType() == Basic ? FinishButton : NextButton)->setEnabled(complete);
296}
297
298KWalletWizard::WizardType KWalletWizard::wizardType() const
299{
300 return (KWalletWizard::WizardType)m_pageIntro->bg->checkedId();
301}
302
303void KWalletWizard::initializePage(int id)
304{
305 switch (id) {
306 case PagePasswordId:
307 {
308 bool islast = m_pageIntro->bg->checkedId() == 0;
309 m_pagePasswd->setFinalPage(islast);
310 button(NextButton)->setVisible(!islast);
311 break;
312 }
313 }
314}
315
316#ifdef HAVE_QGPGME
317GpgME::Key KWalletWizard::gpgKey() const {
318 return m_pageGpgKey->gpgKey();
319}
320#endif
321