2
* Copyright (C) 2002 Jean-Baptiste Mardelle <bj@altern.org>
3
* Copyright (C) 2007,2008,2009,2010,2011 Rolf Eike Beer <kde@opensource.sf-tec.de>
4
* Copyright (C) 2011 Luis Ćngel FernĆ”ndez FernĆ”ndez <laffdez@gmail.com>
7
/***************************************************************************
9
* This program is free software; you can redistribute it and/or modify *
10
* it under the terms of the GNU General Public License as published by *
11
* the Free Software Foundation; either version 2 of the License, or *
12
* (at your option) any later version. *
14
***************************************************************************/
16
#include "keysmanager.h"
18
#include <QApplication>
19
#include <QDesktopWidget>
20
#include <QKeySequence>
21
#include <QTextStream>
25
#include <QPrintDialog>
32
#include <QtDBus/QtDBus>
35
#include <kabc/addresseedialog.h>
36
#include <kabc/stdaddressbook.h>
37
#include <solid/networking.h>
38
#include <KToolInvocation>
39
#include <KStandardDirs>
40
#include <KInputDialog>
41
#include <KFileDialog>
42
#include <KMessageBox>
43
#include <KFindDialog>
45
#include <KMimeTypeTrader>
48
#include <KRecentFilesAction>
50
#include <KStandardShortcut>
57
#include <KUniqueApplication>
60
#include <KActionCollection>
61
#include <KStandardAction>
62
#include <KSelectAction>
65
#include <KToggleAction>
68
#include <kio/global.h>
69
#include <kjobtrackerinterface.h>
73
#include "selectsecretkey.h"
76
#include "kgpgeditor.h"
77
#include "keyexport.h"
78
#include "kgpgrevokewidget.h"
79
#include "keyservers.h"
80
#include "kgpginterface.h"
81
#include "kgpgsettings.h"
82
#include "kgpgkeygenerate.h"
83
#include "kgpgoptions.h"
84
#include "keyinfodialog.h"
85
#include "kgpglibrary.h"
86
#include "keyadaptor.h"
88
#include "sourceselect.h"
89
#include "keylistproxymodel.h"
90
#include "keytreeview.h"
91
#include "groupedit.h"
92
#include "kgpgchangekey.h"
93
#include "kgpgdeluid.h"
94
#include "kgpgaddphoto.h"
95
#include "kgpgadduid.h"
96
#include "kgpgexport.h"
97
#include "kgpggeneratekey.h"
98
#include "kgpggeneraterevoke.h"
99
#include "kgpgdelkey.h"
100
#include "kgpgimport.h"
101
#include "kgpgprimaryuid.h"
102
#include "detailedconsole.h"
103
#include "kstatusnotifieritem.h"
104
#include "selectpublickeydialog.h"
105
#include "kgpgtextinterface.h"
106
#include "kgpgtextedit.h"
107
#include "kgpgkeyservergettransaction.h"
108
#include "kgpgtransactionjob.h"
109
#include "kgpgsignkey.h"
110
#include "kgpgsignuid.h"
111
#include "kgpgdelsign.h"
112
#include "kgpgdecrypt.h"
114
using namespace KgpgCore;
116
KeysManager::KeysManager(QWidget *parent)
117
: KXmlGuiWindow(parent),
118
imodel(new KGpgItemModel(this)),
126
new KeyAdaptor(this);
127
QDBusConnection::sessionBus().registerObject(QLatin1String( "/KeyInterface" ), this);
129
setAttribute(Qt::WA_DeleteOnClose, false);
130
setWindowTitle(i18n("Key Management"));
132
KStandardAction::quit(this, SLOT(quitApp()), actionCollection());
133
actionCollection()->addAction(KStandardAction::Preferences, QLatin1String( "options_configure" ), this, SLOT(showOptions()));
135
openEditor = actionCollection()->addAction(QLatin1String("kgpg_editor"), this, SLOT(slotOpenEditor()));
136
openEditor->setIcon(KIcon( QLatin1String( "accessories-text-editor" )));
137
openEditor->setText(i18n("&Open Editor"));
139
kserver = actionCollection()->addAction( QLatin1String("key_server"), this, SLOT(showKeyServer()));
140
kserver->setText( i18n("&Key Server Dialog") );
141
kserver->setIcon( KIcon( QLatin1String( "network-server" )) );
143
goToDefaultKey = actionCollection()->addAction(QLatin1String("go_default_key"), this, SLOT(slotGotoDefaultKey()));
144
goToDefaultKey->setIcon(KIcon( QLatin1String( "go-home" )));
145
goToDefaultKey->setText(i18n("&Go to Default Key"));
146
goToDefaultKey->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Home));
148
s_kgpgEditor = new KgpgEditor(this, imodel, Qt::Dialog);
149
s_kgpgEditor->setAttribute(Qt::WA_DeleteOnClose, false);
151
// this must come after kserver, preferences, and openEditor are created
152
// because they are used to set up the tray icon context menu
156
installEventFilter(this);
160
action = actionCollection()->addAction(QLatin1String("help_tipofday"), this, SLOT(slotTip()));
161
action->setIcon( KIcon( QLatin1String( "help-hint" )) );
162
action->setText( i18n("Tip of the &Day") );
164
action = actionCollection()->addAction(QLatin1String("gpg_man"), this, SLOT(slotManpage()));
165
action->setText( i18n("View GnuPG Manual") );
166
action->setIcon( KIcon( QLatin1String( "help-contents" )) );
168
action = actionCollection()->addAction(QLatin1String("key_refresh"), this, SLOT(refreshkey()));
169
action->setIcon(KIcon( QLatin1String( "view-refresh" )));
170
action->setText(i18n("&Refresh List"));
171
action->setShortcuts(KStandardShortcut::reload());
173
hPublic = actionCollection()->add<KToggleAction>(QLatin1String("show_secret"), this, SLOT(slotToggleSecret(bool)));
174
hPublic->setIcon(KIcon( QLatin1String( "view-key-secret" )));
175
hPublic->setText(i18n("&Show Only Secret Keys"));
176
hPublic->setChecked(KGpgSettings::showSecret());
178
longId = actionCollection()->add<KToggleAction>(QLatin1String("show_long_keyid"), this, SLOT(slotShowLongId(bool)));
179
longId->setText(i18n("Show &Long Key Id"));
180
longId->setChecked(KGpgSettings::showLongKeyId());
182
QAction *infoKey = actionCollection()->addAction(QLatin1String("key_info"), this, SLOT(keyproperties()));
183
infoKey->setIcon(KIcon( QLatin1String( "document-properties-key" )));
184
infoKey->setText(i18n("K&ey Properties"));
186
editKey = actionCollection()->addAction(QLatin1String("key_edit"), this, SLOT(slotedit()));
187
editKey->setIcon(KIcon( QLatin1String( "utilities-terminal" )));
188
editKey->setText(i18n("Edit Key in &Terminal"));
189
editKey->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
191
KAction *generateKey = actionCollection()->addAction(QLatin1String("key_gener"), this, SLOT(slotGenerateKey()));
192
generateKey->setIcon(KIcon( QLatin1String( "key-generate-pair" )));
193
generateKey->setText(i18n("&Generate Key Pair..."));
194
generateKey->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::New));
196
exportPublicKey = actionCollection()->addAction(QLatin1String("key_export"), this, SLOT(slotexport()));
197
exportPublicKey->setIcon(KIcon( QLatin1String( "document-export-key" )));
198
exportPublicKey->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Copy));
200
KAction *importKey = actionCollection()->addAction(QLatin1String("key_import"), this, SLOT(slotPreImportKey()));
201
importKey->setIcon(KIcon( QLatin1String( "document-import-key" )));
202
importKey->setText(i18n("&Import Key..."));
203
importKey->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Paste));
205
QAction *newContact = actionCollection()->addAction(QLatin1String("add_kab"), this, SLOT(addToKAB()));
206
newContact->setIcon(KIcon( QLatin1String( "contact-new" )));
207
newContact->setText(i18n("&Create New Contact in Address Book"));
209
createGroup = actionCollection()->addAction(QLatin1String("create_group"), this, SLOT(createNewGroup()));
210
createGroup->setIcon(Images::group());
212
editCurrentGroup = actionCollection()->addAction(QLatin1String("edit_group"), this, SLOT(editGroup()));
213
editCurrentGroup->setText(i18n("&Edit Group..."));
215
delGroup = actionCollection()->addAction(QLatin1String("delete_group"), this, SLOT(deleteGroup()));
216
delGroup->setText(i18n("&Delete Group"));
217
delGroup->setIcon(KIcon( QLatin1String( "edit-delete" )));
219
m_groupRename = actionCollection()->addAction(QLatin1String("rename_group"), this, SLOT(renameGroup()));
220
m_groupRename->setText(i18n("&Rename Group"));
221
m_groupRename->setIcon(KIcon( QLatin1String( "edit-rename" )));
222
m_groupRename->setShortcut(QKeySequence(Qt::Key_F2));
224
deleteKey = actionCollection()->addAction(QLatin1String("key_delete"), this, SLOT(confirmdeletekey()));
225
deleteKey->setIcon(KIcon( QLatin1String( "edit-delete" )));
226
deleteKey->setShortcut(QKeySequence(Qt::Key_Delete));
228
setDefaultKey = actionCollection()->addAction(QLatin1String("key_default"), this, SLOT(slotSetDefKey()));
229
setDefaultKey->setText(i18n("Set as De&fault Key"));
231
QAction *addPhoto = actionCollection()->addAction(QLatin1String("add_photo"), this, SLOT(slotAddPhoto()));
232
addPhoto->setText(i18n("&Add Photo..."));
234
QAction *addUid = actionCollection()->addAction(QLatin1String("add_uid"), this, SLOT(slotAddUid()));
235
addUid->setText(i18n("&Add User Id..."));
237
QAction *exportSecretKey = actionCollection()->addAction(QLatin1String("key_sexport"), this, SLOT(slotexportsec()));
238
exportSecretKey->setText(i18n("Export Secret Key..."));
240
QAction *deleteKeyPair = actionCollection()->addAction(QLatin1String("key_pdelete"), this, SLOT(deleteseckey()));
241
deleteKeyPair->setText(i18n("Delete Key Pair"));
242
deleteKeyPair->setIcon(KIcon( QLatin1String( "edit-delete" )));
244
m_revokeKey = actionCollection()->addAction(QLatin1String("key_revoke"), this, SLOT(revokeWidget()));
245
m_revokeKey->setText(i18n("Revoke Key..."));
247
QAction *regeneratePublic = actionCollection()->addAction(QLatin1String("key_regener"), this, SLOT(slotregenerate()));
248
regeneratePublic->setText(i18n("&Regenerate Public Key"));
250
delUid = actionCollection()->addAction(QLatin1String("del_uid"), this, SLOT(slotDelUid()));
251
delUid->setIcon(KIcon( QLatin1String( "edit-delete" )));
253
setPrimUid = actionCollection()->addAction(QLatin1String("prim_uid"), this, SLOT(slotPrimUid()));
254
setPrimUid->setText(i18n("Set User Id as &Primary"));
256
QAction *openPhoto = actionCollection()->addAction(QLatin1String("key_photo"), this, SLOT(slotShowPhoto()));
257
openPhoto->setIcon(KIcon( QLatin1String( "image-x-generic" )));
258
openPhoto->setText(i18n("&Open Photo"));
260
QAction *deletePhoto = actionCollection()->addAction(QLatin1String("delete_photo"), this, SLOT(slotDeletePhoto()));
261
deletePhoto->setIcon(KIcon( QLatin1String( "edit-delete" )));
262
deletePhoto->setText(i18n("&Delete Photo"));
264
delSignKey = actionCollection()->addAction(QLatin1String("key_delsign"), this, SLOT(delsignkey()));
265
delSignKey->setIcon(KIcon( QLatin1String( "edit-delete" )));
266
delSignKey->setEnabled(false);
268
importAllSignKeys = actionCollection()->addAction(QLatin1String("key_importallsign"), this, SLOT(importallsignkey()));
269
importAllSignKeys->setIcon(KIcon( QLatin1String( "document-import" )));
270
importAllSignKeys->setText(i18n("Import &Missing Signatures From Keyserver"));
272
refreshKey = actionCollection()->addAction(QLatin1String("key_server_refresh"), this, SLOT(refreshKeyFromServer()));
273
refreshKey->setIcon(KIcon( QLatin1String( "view-refresh" )));
275
signKey = actionCollection()->addAction(QLatin1String("key_sign"), this, SLOT(signkey()));
276
signKey->setIcon(KIcon( QLatin1String( "document-sign-key" )));
278
signUid = actionCollection()->addAction(QLatin1String("key_sign_uid"), this, SLOT(signuid()));
279
signUid->setIcon(KIcon( QLatin1String( "document-sign-key" )));
281
signMailUid = actionCollection()->addAction(QLatin1String("key_sign_mail_uid"), this, SLOT(caff()));
282
signMailUid->setIcon(KIcon( QLatin1String( "document-sign-key" )));
284
importSignatureKey = actionCollection()->addAction(QLatin1String("key_importsign"), this, SLOT(preimportsignkey()));
285
importSignatureKey->setIcon(KIcon( QLatin1String( "document-import-key" )));
287
sTrust = actionCollection()->add<KToggleAction>(QLatin1String("show_trust"), this, SLOT(slotShowTrust()));
288
sTrust->setText(i18n("Trust"));
290
sSize = actionCollection()->add<KToggleAction>(QLatin1String("show_size"), this, SLOT(slotShowSize()));
291
sSize->setText(i18n("Size"));
293
sCreat = actionCollection()->add<KToggleAction>(QLatin1String("show_creat"), this, SLOT(slotShowCreation()));
294
sCreat->setText(i18n("Creation"));
296
sExpi = actionCollection()->add<KToggleAction>(QLatin1String("show_expi"), this, SLOT(slotShowExpiration()));
297
sExpi->setText(i18n("Expiration"));
299
photoProps = actionCollection()->add<KSelectAction>(QLatin1String( "photo_settings" ));
300
photoProps->setIcon(KIcon( QLatin1String( "image-x-generic" )));
301
photoProps->setText(i18n("&Photo ID's"));
303
// Keep the list in kgpg.kcfg in sync with this one!
305
list.append(i18n("Disable"));
306
list.append(i18nc("small picture", "Small"));
307
list.append(i18nc("medium picture", "Medium"));
308
list.append(i18nc("large picture", "Large"));
309
photoProps->setItems(list);
311
trustProps = actionCollection()->add<KSelectAction>(QLatin1String( "trust_filter_settings" ));
312
trustProps->setText(i18n("Minimum &Trust"));
315
tlist.append(i18nc("no filter: show all keys", "&None"));
316
tlist.append(i18nc("show only active keys", "&Active"));
317
tlist.append(i18nc("show only keys with at least marginal trust", "&Marginal"));
318
tlist.append(i18nc("show only keys with at least full trust", "&Full"));
319
tlist.append(i18nc("show only ultimately trusted keys", "&Ultimate"));
321
trustProps->setItems(tlist);
323
iproxy = new KeyListProxyModel(this);
324
iproxy->setKeyModel(imodel);
326
iview = new KeyTreeView(this, iproxy);
327
connect(iview, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(defaultAction(QModelIndex)));
328
connect(iview, SIGNAL(importDrop(KUrl::List)), SLOT(slotImport(KUrl::List)));
329
iview->setSelectionMode(QAbstractItemView::ExtendedSelection);
330
setCentralWidget(iview);
331
iview->resizeColumnsToContents();
332
iview->setAlternatingRowColors(true);
333
iview->setSortingEnabled(true);
334
connect(iview, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotMenu(QPoint)));
335
iview->setContextMenuPolicy(Qt::CustomContextMenu);
336
connect(iview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(checkList()));
338
connect (iview, SIGNAL(returnPressed()), SLOT(slotDefaultAction()));
340
int psize = KGpgSettings::photoProperties();
341
photoProps->setCurrentItem(psize);
342
slotSetPhotoSize(psize);
343
psize = KGpgSettings::trustLevel();
344
trustProps->setCurrentItem(psize);
345
slotSetTrustFilter(psize);
346
slotShowLongId(KGpgSettings::showLongKeyId());
348
m_popuppub = new KMenu(this);
349
m_popuppub->addAction(exportPublicKey);
350
m_popuppub->addAction(deleteKey);
351
m_popuppub->addAction(signKey);
352
m_popuppub->addAction(signUid);
353
m_popuppub->addAction(signMailUid);
354
m_popuppub->addAction(infoKey);
355
m_popuppub->addAction(editKey);
356
m_popuppub->addAction(refreshKey);
357
m_popuppub->addAction(createGroup);
358
m_popuppub->addAction(setDefaultKey);
359
m_popuppub->addSeparator();
360
m_popuppub->addAction(importAllSignKeys);
362
m_popupsec = new KMenu(this);
363
m_popupsec->addAction(exportPublicKey);
364
m_popupsec->addAction(signKey);
365
m_popupsec->addAction(signUid);
366
m_popupsec->addAction(signMailUid);
367
m_popupsec->addAction(infoKey);
368
m_popupsec->addAction(editKey);
369
m_popupsec->addAction(refreshKey);
370
m_popupsec->addAction(setDefaultKey);
371
m_popupsec->addSeparator();
372
m_popupsec->addAction(importAllSignKeys);
373
m_popupsec->addSeparator();
374
m_popupsec->addAction(addPhoto);
375
m_popupsec->addAction(addUid);
376
m_popupsec->addAction(exportSecretKey);
377
m_popupsec->addAction(deleteKeyPair);
379
m_popupgroup = new KMenu(this);
380
m_popupgroup->addAction(editCurrentGroup);
381
m_popupgroup->addAction(m_groupRename);
382
m_popupgroup->addAction(delGroup);
383
m_popupgroup->addAction(refreshKey);
385
m_popupout = new KMenu(this);
386
m_popupout->addAction(importKey);
388
m_popupsig = new KMenu();
389
m_popupsig->addAction(importSignatureKey);
390
m_popupsig->addAction(delSignKey);
392
m_popupphoto = new KMenu(this);
393
m_popupphoto->addAction(openPhoto);
394
m_popupphoto->addAction(signUid);
395
m_popupphoto->addAction(signMailUid);
396
m_popupphoto->addAction(deletePhoto);
398
m_popupuid = new KMenu(this);
399
m_popupuid->addAction(signUid);
400
m_popupuid->addAction(signMailUid);
401
m_popupuid->addAction(delUid);
402
m_popupuid->addAction(setPrimUid);
404
m_popuporphan = new KMenu(this);
405
m_popuporphan->addAction(regeneratePublic);
406
m_popuporphan->addAction(deleteKeyPair);
408
exportPublicKey->setEnabled(false);
410
KConfigGroup cg = KConfigGroup(KGlobal::config().data(), "KeyView");
411
iview->restoreLayout(cg);
413
connect(photoProps, SIGNAL(triggered(int)), this, SLOT(slotSetPhotoSize(int)));
414
connect(trustProps, SIGNAL(triggered(int)), this, SLOT(slotSetTrustFilter(int)));
416
QLabel *searchLabel = new QLabel(i18n("Search:"), this);
417
m_listviewsearch = new KLineEdit(this);
418
m_listviewsearch->setClearButtonShown(true);
420
QWidget *searchWidget = new QWidget(this);
421
QHBoxLayout *searchLayout = new QHBoxLayout(searchWidget);
422
searchLayout->setMargin(0);
423
searchLayout->addWidget(searchLabel);
424
searchLayout->addWidget(m_listviewsearch);
425
searchLayout->addStretch();
427
KAction *searchLineAction = new KAction(i18nc("Name of the action that is a search line, shown for example in the toolbar configuration dialog", "Search Line"), this);
428
actionCollection()->addAction(QLatin1String( "search_line" ), searchLineAction);
429
searchLineAction->setDefaultWidget(searchWidget);
431
action = actionCollection()->addAction(QLatin1String("search_focus"), m_listviewsearch, SLOT(setFocus()));
432
action->setText(i18nc("Name of the action that gives the focus to the search line", "Focus Search Line"));
433
action->setShortcut(QKeySequence(Qt::Key_F6));
434
connect(m_listviewsearch, SIGNAL(textChanged(QString)), iproxy, SLOT(setFilterFixedString(QString)));
436
setActionDescriptions(1);
439
setupGUI(KXmlGuiWindow::Create | Save | ToolBar | StatusBar | Keys, QLatin1String( "keysmanager.rc" ));
441
sTrust->setChecked(KGpgSettings::showTrust());
442
iview->setColumnHidden(2, !KGpgSettings::showTrust());
443
sSize->setChecked(KGpgSettings::showSize());
444
iview->setColumnHidden(3, !KGpgSettings::showSize());
445
sCreat->setChecked(KGpgSettings::showCreat());
446
iview->setColumnHidden(4, !KGpgSettings::showCreat());
447
sExpi->setChecked(KGpgSettings::showExpi());
448
iview->setColumnHidden(5, !KGpgSettings::showExpi());
449
iproxy->setOnlySecret(KGpgSettings::showSecret());
451
KStatusBar *statusbar = statusBar();
452
statusbar->insertPermanentFixedItem(KGpgItemModel::statusCountMessageString(9999, 999), 0);
453
statusbar->changeItem(QString(), 0);
455
cg = KConfigGroup(KGlobal::config().data(), "MainWindow");
456
setAutoSaveSettings(cg, true);
457
applyMainWindowSettings(cg);
459
connect(s_kgpgEditor, SIGNAL(refreshImported(QStringList)), imodel, SLOT(refreshKeys(QStringList)));
460
connect(this, SIGNAL(fontChanged(QFont)), s_kgpgEditor, SLOT(slotSetFont(QFont)));
462
m_netnote = Solid::Networking::notifier();
463
connect(m_netnote, SIGNAL(shouldConnect()), SLOT(slotNetworkUp()));
464
connect(m_netnote, SIGNAL(shouldDisconnect()), SLOT(slotNetworkDown()));
466
toggleNetworkActions(Solid::Networking::status() == Solid::Networking::Unknown || Solid::Networking::status() == Solid::Networking::Connected);
467
importSignatureKey->setEnabled(false);
469
stateChanged("empty_list");
471
QTimer::singleShot(0, this, SLOT(refreshkey()));
474
KeysManager::~KeysManager()
478
void KeysManager::slotGenerateKey()
481
KMessageBox::error(this,
482
i18n("Another key generation operation is still in progress.\nPlease wait a moment until this operation is complete."),
483
i18n("Generating new key pair"));
487
QPointer<KgpgKeyGenerate> kg = new KgpgKeyGenerate(this);
488
if (kg->exec() == QDialog::Accepted) {
489
if (!kg->isExpertMode()) {
490
KGpgGenerateKey *genkey = new KGpgGenerateKey(this, kg->name(), kg->email(),
491
kg->comment(), kg->algo(), kg->size(), kg->days(), kg->expiration());
493
m_genkey = new KGpgTransactionJob(genkey);
494
connect(m_genkey, SIGNAL(result(KJob*)), SLOT(slotGenerateKeyDone(KJob*)));
496
KIO::getJobTracker()->registerJob(m_genkey);
498
QApplication::setOverrideCursor(Qt::BusyCursor);
500
KConfigGroup config(KGlobal::config(), "General");
502
QString terminalApp(config.readPathEntry("TerminalApplication", QLatin1String( "konsole" )));
504
args << QLatin1String( "-e" ) << KGpgSettings::gpgBinaryPath() << QLatin1String( "--gen-key" ) << QLatin1String( "--expert" );
506
QProcess *genKeyProc = new QProcess(this);
507
genKeyProc->start(terminalApp, args);
508
if (!genKeyProc->waitForStarted(-1)) {
509
KMessageBox::error(this, i18n("Generating new key pair"),
510
i18n("Can not start \"konsole\" application for expert mode."));
512
genKeyProc->waitForFinished(-1);
521
void KeysManager::showKeyManager()
526
void KeysManager::slotOpenEditor()
528
KgpgEditor *kgpgtxtedit = new KgpgEditor(this, imodel, Qt::Window);
530
connect(kgpgtxtedit, SIGNAL(refreshImported(QStringList)), imodel, SLOT(refreshKeys(QStringList)));
531
connect(kgpgtxtedit, SIGNAL(encryptFiles(KUrl::List)), this, SIGNAL(encryptFiles(KUrl::List)));
532
connect(this, SIGNAL(fontChanged(QFont)), kgpgtxtedit, SLOT(slotSetFont(QFont)));
537
void KeysManager::changeMessage(const QString &msg, const bool keep)
539
int timeout = keep ? 0 : 10000;
541
statusBar()->showMessage(msg, timeout);
544
void KeysManager::updateStatusCounter()
546
statusBar()->changeItem(imodel->statusCountMessage(), 0);
549
void KeysManager::slotGenerateKeyDone(KJob *job)
551
changeMessage(i18nc("Application ready for user input", "Ready"));
552
QApplication::restoreOverrideCursor();
554
KGpgTransactionJob *tjob = qobject_cast<KGpgTransactionJob *>(job);
556
const KGpgGenerateKey * const genkey = qobject_cast<const KGpgGenerateKey *>(tjob->getTransaction());
557
int res = tjob->getResultCode();
559
const QString infomessage(i18n("Generating new key pair"));
562
case KGpgTransaction::TS_BAD_PASSPHRASE:
563
KMessageBox::error(this, i18n("Bad passphrase. Cannot generate a new key pair."), infomessage);
565
case KGpgTransaction::TS_USER_ABORTED:
566
KMessageBox::error(this, i18n("Aborted by the user. Cannot generate a new key pair."), infomessage);
568
case KGpgTransaction::TS_INVALID_EMAIL:
569
KMessageBox::error(this, i18n("The email address is not valid. Cannot generate a new key pair."), infomessage);
571
case KGpgGenerateKey::TS_INVALID_NAME:
572
KMessageBox::error(this, i18n("The name is not accepted by gpg. Cannot generate a new key pair."), infomessage);
574
case KGpgTransaction::TS_OK: {
575
updateStatusCounter();
577
KDialog *keyCreated = new KDialog(this);
578
keyCreated->setCaption(i18n("New Key Pair Created"));
579
keyCreated->setButtons(KDialog::Ok);
580
keyCreated->setDefaultButton(KDialog::Ok);
581
keyCreated->setModal(true);
583
newKey *page = new newKey(keyCreated);
584
page->TLname->setText(QLatin1String( "<b>" ) + genkey->getName() + QLatin1String( "</b>" ));
586
const QString email(genkey->getEmail());
587
page->TLemail->setText(QLatin1String( "<b>" ) + email + QLatin1String( "</b>" ));
590
const QString gpgPath(KGpgSettings::gpgConfigPath());
591
if (!gpgPath.isEmpty())
592
revurl = KUrl::fromPath(gpgPath).directory(KUrl::AppendTrailingSlash);
594
revurl = QDir::homePath() + QLatin1Char( '/' );
596
if (!email.isEmpty())
597
page->kURLRequester1->setUrl(QString(revurl + email.section(QLatin1Char( '@' ), 0, 0) + QLatin1String( ".revoke" )));
599
page->kURLRequester1->setUrl(QString(revurl + email.section(QLatin1Char( ' ' ), 0, 0) + QLatin1String( ".revoke" )));
601
const QString fingerprint(genkey->getFingerprint());
602
page->TLid->setText(QLatin1String( "<b>" ) + fingerprint.right(8) + QLatin1String( "</b>" ));
603
page->LEfinger->setText(fingerprint);
604
page->CBdefault->setChecked(true);
606
keyCreated->setMainWidget(page);
610
imodel->refreshKey(fingerprint);
611
KGpgKeyNode *knode = imodel->getRootNode()->findKey(fingerprint);
612
if (page->CBdefault->isChecked())
613
imodel->setDefaultKey(knode);
615
iview->selectNode(knode);
617
if (page->CBsave->isChecked() || page->CBprint->isChecked()) {
619
if (page->CBsave->isChecked())
620
revurl = page->kURLRequester1->url();
622
KGpgGenerateRevoke *genRev = new KGpgGenerateRevoke(this, fingerprint, revurl,
623
0, i18n("backup copy"));
625
connect(genRev, SIGNAL(done(int)), SLOT(slotRevokeGenerated(int)));
627
if (page->CBprint->isChecked())
628
connect(genRev, SIGNAL(revokeCertificate(QString)), SLOT(doPrint(QString)));
635
KMessageBox::detailedError(this, i18n("gpg process did not finish. Cannot generate a new key pair."), genkey->gpgErrorMessage(), infomessage);
641
void KeysManager::slotShowTrust()
643
bool b = !sTrust->isChecked();
644
iview->setColumnHidden(KEYCOLUMN_TRUST, b);
645
if (!b && (iview->columnWidth(KEYCOLUMN_TRUST) == 0))
646
iview->resizeColumnToContents(KEYCOLUMN_TRUST);
649
void KeysManager::slotShowExpiration()
651
bool b = !sExpi->isChecked();
652
iview->setColumnHidden(KEYCOLUMN_EXPIR, b);
653
if (!b && (iview->columnWidth(KEYCOLUMN_EXPIR) == 0))
654
iview->resizeColumnToContents(KEYCOLUMN_EXPIR);
657
void KeysManager::slotShowSize()
659
bool b = !sSize->isChecked();
660
iview->setColumnHidden(KEYCOLUMN_SIZE, b);
661
if (!b && (iview->columnWidth(KEYCOLUMN_SIZE) == 0))
662
iview->resizeColumnToContents(KEYCOLUMN_SIZE);
665
void KeysManager::slotShowCreation()
667
bool b = !sCreat->isChecked();
668
iview->setColumnHidden(KEYCOLUMN_CREAT, b);
669
if (!b && (iview->columnWidth(KEYCOLUMN_CREAT) == 0))
670
iview->resizeColumnToContents(KEYCOLUMN_CREAT);
673
void KeysManager::slotToggleSecret(bool b)
675
iproxy->setOnlySecret(b);
678
void KeysManager::slotShowLongId(bool b)
680
iproxy->setIdLength(b ? 16 : 8);
683
void KeysManager::slotSetTrustFilter(int i)
685
KgpgCore::KgpgKeyTrustFlag t;
687
Q_ASSERT((i >= 0) && (i < 5));
705
iproxy->setTrustFilter(t);
708
bool KeysManager::eventFilter(QObject *, QEvent *e)
710
if ((e->type() == QEvent::Show) && (showTipOfDay)) {
711
KTipDialog::showTip(this, QLatin1String("kgpg/tips"), false);
712
showTipOfDay = false;
718
void KeysManager::slotGotoDefaultKey()
720
iview->selectNode(imodel->getRootNode()->findKey(KGpgSettings::defaultKey()));
723
void KeysManager::refreshKeyFromServer()
725
QList<KGpgNode *> keysList(iview->selectedNodes());
726
if (keysList.isEmpty())
731
foreach (KGpgNode *item, keysList) {
732
if (item->getType() == ITYPE_GROUP)
734
for (int j = 0; j < item->getChildCount(); j++)
735
keyIDS << item->getChild(j)->getId();
740
if (item->getType() & ITYPE_PAIR) {
741
keyIDS << item->getId();
743
KMessageBox::sorry(this, i18n("You can only refresh primary keys. Please check your selection."));
749
if (KGpgSettings::useProxy())
750
proxy = QLatin1String( qgetenv("http_proxy") );
752
KGpgRefreshKeys *t = new KGpgRefreshKeys(this, KGpgSettings::keyServers().first(), keyIDS, true, proxy);
753
connect(t, SIGNAL(done(int)), SLOT(slotKeyRefreshDone(int)));
754
QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
758
void KeysManager::slotKeyRefreshDone(int result)
760
KGpgRefreshKeys *t = qobject_cast<KGpgRefreshKeys *>(sender());
763
if (result == KGpgTransaction::TS_USER_ABORTED) {
765
QApplication::restoreOverrideCursor();
769
const QStringList log(t->getLog());
770
const QStringList keys(KGpgImport::getImportedIds(log));
771
const QStringList message(KGpgImport::getImportMessage(log));
776
imodel->refreshKeys(keys);
778
QApplication::restoreOverrideCursor();
779
(void) new KgpgDetailedInfo(this, message.join(QLatin1String("\n")), log.join(QLatin1String("\n")),
780
KGpgImport::getDetailedImportMessage(log).split(QLatin1Char( '\n' )));
783
void KeysManager::slotDelUid()
785
KGpgUidNode *nd = iview->selectedNode()->toUidNode();
787
KGpgDelUid *deluid = new KGpgDelUid(this, nd);
789
connect(deluid, SIGNAL(done(int)), SLOT(slotDelUidDone(int)));
793
void KeysManager::slotDelUidDone(int result)
795
sender()->deleteLater();
796
// FIXME: do something useful with result
800
void KeysManager::slotPrimUid()
802
KGpgPrimaryUid *puid = new KGpgPrimaryUid(this, iview->selectedNode()->toUidNode());
804
connect(puid, SIGNAL(done(int)), SLOT(slotPrimUidDone(int)));
809
void KeysManager::slotPrimUidDone(int result)
811
const QString kid(qobject_cast<KGpgPrimaryUid *>(sender())->getKeyId());
813
sender()->deleteLater();
816
imodel->refreshKey(kid);
817
// FIXME: some error reporting
820
void KeysManager::slotregenerate()
822
QString regID = iview->selectedNode()->getId();
823
KProcess *p1, *p2, *p3;
825
p1 = new KProcess(this);
826
*p1 << KGpgSettings::gpgBinaryPath() << QLatin1String( "--no-secmem-warning" ) << QLatin1String( "--export-secret-key" ) << regID;
827
p1->setOutputChannelMode(KProcess::OnlyStdoutChannel);
829
p2 = new KProcess(this);
830
*p2 << QLatin1String( "gpgsplit" ) << QLatin1String( "--no-split" ) << QLatin1String( "--secret-to-public" );
831
p2->setOutputChannelMode(KProcess::OnlyStdoutChannel);
833
p3 = new KProcess(this);
834
*p3 << KGpgSettings::gpgBinaryPath() << QLatin1String( "--import" );
836
p1->setStandardOutputProcess(p2);
837
p2->setStandardOutputProcess(p3);
843
p1->waitForFinished();
844
p2->waitForFinished();
845
p3->waitForFinished();
851
imodel->refreshKey(regID);
854
void KeysManager::slotAddUid()
857
KMessageBox::error(this, i18n("Another operation is still in progress.\nPlease wait a moment until this operation is complete."), i18n("Add New User Id"));
861
addUidWidget = new KDialog(this );
862
addUidWidget->setCaption( i18n("Add New User Id") );
863
addUidWidget->setButtons( KDialog::Ok | KDialog::Cancel );
864
addUidWidget->setDefaultButton( KDialog::Ok );
865
addUidWidget->setModal( true );
866
addUidWidget->enableButtonOk(false);
867
AddUid *keyUid = new AddUid(addUidWidget);
868
addUidWidget->setMainWidget(keyUid);
869
//keyUid->setMinimumSize(keyUid->sizeHint());
870
keyUid->setMinimumWidth(300);
872
connect(keyUid->kLineEdit1, SIGNAL(textChanged(QString)), this, SLOT(slotAddUidEnable(QString)));
873
if (addUidWidget->exec() != QDialog::Accepted)
876
m_adduid = new KGpgAddUid(this, iview->selectedNode()->getId(), keyUid->kLineEdit1->text(), keyUid->kLineEdit2->text(), keyUid->kLineEdit3->text());
877
connect(m_adduid, SIGNAL(done(int)), SLOT(slotAddUidFin(int)));
881
void KeysManager::slotAddUidFin(int res)
883
// TODO error reporting
885
imodel->refreshKey(m_adduid->getKeyid());
886
m_adduid->deleteLater();
890
void KeysManager::slotAddUidEnable(const QString & name)
892
addUidWidget->enableButtonOk(name.length() > 4);
895
void KeysManager::slotAddPhoto()
897
QString mess = i18n("The image must be a JPEG file. Remember that the image is stored within your public key, so "
898
"if you use a very large picture, your key will become very large as well. The size should not exceed 6 KiB. "
899
"An image size of around 240x288 is a good size to use.");
901
if (KMessageBox::warningContinueCancel(0, mess) != KMessageBox::Continue)
904
QString imagepath = KFileDialog::getOpenFileName(KUrl(), QLatin1String( "image/jpeg" ), 0);
905
if (imagepath.isEmpty())
908
KGpgAddPhoto *addphoto = new KGpgAddPhoto(this, iview->selectedNode()->getId(), imagepath);
909
connect(addphoto, SIGNAL(done(int)), SLOT(slotAddPhotoFinished(int)));
913
void KeysManager::slotAddPhotoFinished(int res)
915
sender()->deleteLater();
917
// TODO : add res == 3 (bad passphrase)
923
void KeysManager::slotDeletePhoto()
925
KGpgNode *nd = iview->selectedNode();
926
KGpgUatNode *und = nd->toUatNode();
927
KGpgKeyNode *parent = und->getParentKeyNode();
929
QString mess = i18n("<qt>Are you sure you want to delete Photo id <b>%1</b><br/>from key <b>%2 <%3></b>?</qt>",
930
und->getId(), parent->getName(), parent->getEmail());
932
KGpgDelUid *deluid = new KGpgDelUid(this, und);
933
connect(deluid, SIGNAL(done(int)), SLOT(slotDelPhotoFinished(int)));
938
void KeysManager::slotDelPhotoFinished(int res)
940
sender()->deleteLater();
942
// TODO : add res == 3 (bad passphrase)
945
KGpgNode *nd = iview->selectedNode();
946
imodel->refreshKey(nd->getParentKeyNode()->toKeyNode());
950
void KeysManager::slotUpdatePhoto()
952
KGpgNode *nd = iview->selectedNode();
953
imodel->refreshKey(nd->toKeyNode());
956
void KeysManager::slotSetPhotoSize(int size)
960
iproxy->setPreviewSize(22);
963
iproxy->setPreviewSize(42);
966
iproxy->setPreviewSize(65);
969
iproxy->setPreviewSize(0);
974
void KeysManager::addToKAB()
977
KGpgNode *nd = iview->selectedNode();
981
QString email(nd->getEmail());
983
KABC::AddressBook *ab = KABC::StdAddressBook::self();
985
KMessageBox::sorry(this, i18n("Unable to contact the address book. Please check your installation."));
989
KABC::Addressee::List addresseeList(ab->findByEmail(email));
990
KToolInvocation::startServiceByDesktopName( QLatin1String( "kaddressbook" ));
991
QDBusInterface kaddressbook(QLatin1String( "org.kde.kaddressbook" ), QLatin1String( "/KAddressBook" ), QLatin1String( "org.kde.KAddressbook.Core" ));
993
if(!addresseeList.isEmpty())
994
kaddressbook.call( QLatin1String( "showContactEditor" ), addresseeList.first().uid());
996
kaddressbook.call( QLatin1String( "addEmail" ), QString(nd->getName() + QLatin1String( " <" ) + email + QLatin1Char( '>' )));
999
void KeysManager::slotManpage()
1001
KToolInvocation::startServiceByDesktopName( QLatin1String( "khelpcenter" ), QLatin1String("man:/gpg"), 0, 0, 0, "" , true);
1004
void KeysManager::slotTip()
1006
KTipDialog::showTip(this, QLatin1String("kgpg/tips"), true);
1009
void KeysManager::showKeyServer()
1011
QPointer<KeyServer> ks = new KeyServer(this, imodel);
1012
connect(ks, SIGNAL(importFinished(QStringList)), imodel, SLOT(refreshKeys(QStringList)));
1019
void KeysManager::checkList()
1021
QList<KGpgNode *> exportList = iview->selectedNodes();
1023
switch (exportList.count()) {
1025
stateChanged("empty_list");
1028
if (exportList.at(0)->getType() == ITYPE_GROUP) {
1029
stateChanged(QLatin1String( "group_selected" ));
1031
stateChanged(QLatin1String( "single_selected" ));
1032
m_revokeKey->setEnabled(exportList.at(0)->getType() == ITYPE_PAIR);
1034
editKey->setEnabled(false);
1038
stateChanged(QLatin1String( "multi_selected" ));
1041
refreshKey->setEnabled(false);
1043
switch (exportList.at(0)->getType()) {
1045
changeMessage(i18n("Public Key"));
1048
changeMessage(i18n("Sub Key"));
1051
changeMessage(i18n("Secret Key Pair"));
1054
changeMessage(i18n("Key Group"));
1057
changeMessage(i18n("Signature"));
1060
changeMessage(i18n("User ID"));
1063
changeMessage(i18n("Revocation Signature"));
1066
changeMessage(i18n("Photo ID"));
1069
changeMessage(i18n("Orphaned Secret Key"));
1074
changeMessage(i18n("Group member"));
1077
kDebug(2100) << "Oops, unmatched type value" << exportList.at(0)->getType();
1081
void KeysManager::quitApp()
1088
void KeysManager::saveToggleOpts(void)
1090
KConfigGroup cg = KConfigGroup(KGlobal::config().data(), "KeyView");
1091
iview->saveLayout(cg);
1092
KGpgSettings::setPhotoProperties(photoProps->currentItem());
1093
KGpgSettings::setShowTrust(sTrust->isChecked());
1094
KGpgSettings::setShowExpi(sExpi->isChecked());
1095
KGpgSettings::setShowCreat(sCreat->isChecked());
1096
KGpgSettings::setShowSize(sSize->isChecked());
1097
KGpgSettings::setTrustLevel(trustProps->currentItem());
1098
KGpgSettings::setShowSecret(hPublic->isChecked());
1099
KGpgSettings::setShowLongKeyId(longId->isChecked());
1100
KGpgSettings::self()->writeConfig();
1103
void KeysManager::readOptions()
1105
m_clipboardmode = QClipboard::Clipboard;
1106
if (KGpgSettings::useMouseSelection() && (kapp->clipboard()->supportsSelection()))
1107
m_clipboardmode = QClipboard::Selection;
1109
// re-read groups in case the config file location was changed
1110
const QStringList groups(KgpgInterface::getGpgGroupNames(KGpgSettings::gpgConfigPath()));
1111
KGpgSettings::setGroups(groups.join( QLatin1String( "," )));
1113
updateStatusCounter();
1115
showTipOfDay = KGpgSettings::showTipOfDay();
1117
if (KGpgSettings::showSystray()) {
1125
void KeysManager::showOptions()
1127
if (KConfigDialog::showDialog(QLatin1String( "settings" )))
1130
QPointer<kgpgOptions> optionsDialog = new kgpgOptions(this, imodel);
1131
connect(optionsDialog, SIGNAL(settingsUpdated()), SLOT(readAllOptions()));
1132
connect(optionsDialog, SIGNAL(homeChanged()), imodel, SLOT(refreshKeys()));
1133
connect(optionsDialog, SIGNAL(refreshTrust(KgpgCore::KgpgKeyTrust,QColor)), imodel, SLOT(refreshTrust(KgpgCore::KgpgKeyTrust,QColor)));
1134
connect(optionsDialog, SIGNAL(changeFont(QFont)), SIGNAL(fontChanged(QFont)));
1135
optionsDialog->exec();
1136
delete optionsDialog;
1138
s_kgpgEditor->m_recentfiles->setMaxItems(KGpgSettings::recentFiles());
1141
void KeysManager::readAllOptions()
1144
emit readAgainOptions();
1147
void KeysManager::slotSetDefKey()
1149
setDefaultKeyNode(iview->selectedNode()->toKeyNode());
1152
void KeysManager::slotSetDefaultKey(const QString &newID)
1154
KGpgKeyNode *ndef = imodel->getRootNode()->findKey(newID);
1157
KGpgSettings::setDefaultKey(newID);
1158
KGpgSettings::self()->writeConfig();
1162
setDefaultKeyNode(ndef);
1165
void KeysManager::setDefaultKeyNode(KGpgKeyNode *key)
1167
const QString &newID(key->getId());
1169
if (newID == KGpgSettings::defaultKey())
1172
KGpgSettings::setDefaultKey(newID);
1173
KGpgSettings::self()->writeConfig();
1175
imodel->setDefaultKey(key);
1179
KeysManager::setActionDescriptions(int cnt)
1181
signUid->setText(i18np("&Sign User ID ...", "&Sign User IDs ...", cnt));
1182
signMailUid->setText(i18np("Sign and &Mail User ID ...", "Sign and &Mail User IDs ...", cnt));
1183
exportPublicKey->setText(i18np("E&xport Public Key...", "E&xport Public Keys...", cnt));
1184
refreshKey->setText(i18np("&Refresh Key From Keyserver", "&Refresh Keys From Keyserver", cnt));
1185
createGroup->setText(i18np("&Create Group with Selected Key...", "&Create Group with Selected Keys...", cnt));
1186
signKey->setText(i18np("&Sign Key...", "&Sign Keys...", cnt));
1187
delUid->setText(i18np("&Delete User ID", "&Delete User IDs", cnt));
1188
delSignKey->setText(i18np("Delete Sign&ature", "Delete Sign&atures", cnt));
1189
importSignatureKey->setText(i18np("Import Key From Keyserver", "Import Keys From Keyserver", cnt));
1190
deleteKey->setText(i18np("&Delete Key", "&Delete Keys", cnt));
1194
KeysManager::slotMenu(const QPoint &pos)
1196
QPoint globpos = iview->mapToGlobal(pos);
1199
QList<KGpgNode *> ndlist(iview->selectedNodes(&sametype, &itype));
1200
bool unksig = false;
1202
int cnt = ndlist.count();
1204
// find out if an item has unknown signatures. Only check if the item has been
1205
// expanded before as expansion is very expensive and can take several seconds
1206
// that will freeze the UI meanwhile.
1207
foreach (KGpgNode *nd, ndlist) {
1208
if (!nd->hasChildren())
1211
KGpgExpandableNode *exnd = nd->toExpandableNode();
1212
if (!exnd->wasExpanded()) {
1216
getMissingSigs(l, exnd);
1222
importAllSignKeys->setEnabled(unksig && m_online);
1224
signUid->setEnabled(!(itype & ~(ITYPE_PAIR | ITYPE_UID | ITYPE_UAT)));
1225
signMailUid->setEnabled(signUid->isEnabled());
1226
setActionDescriptions(cnt);
1228
if (itype == ITYPE_SIGN) {
1229
bool allunksig = true;
1230
foreach (KGpgNode *nd, ndlist) {
1231
allunksig = nd->toSignNode()->isUnknown();
1236
importSignatureKey->setEnabled(allunksig && m_online);
1237
delSignKey->setEnabled( (cnt == 1) );
1238
m_popupsig->exec(globpos);
1239
} else if (itype == ITYPE_UID) {
1241
KGpgKeyNode *knd = ndlist.at(0)->toUidNode()->getParentKeyNode();
1242
setPrimUid->setEnabled(knd->getType() & ITYPE_SECRET);
1244
m_popupuid->exec(globpos);
1245
} else if ((itype == ITYPE_UAT) && (cnt == 1)) {
1246
m_popupphoto->exec(globpos);
1247
} else if ((itype == ITYPE_PAIR) && (cnt == 1)) {
1248
m_popupsec->exec(globpos);
1249
} else if ((itype == ITYPE_SECRET) && (cnt == 1)) {
1250
m_popuporphan->exec(globpos);
1251
} else if (itype == ITYPE_GROUP) {
1252
delGroup->setEnabled( (cnt == 1) );
1253
editCurrentGroup->setEnabled( (cnt == 1) );
1254
m_groupRename->setEnabled( (cnt == 1) );
1255
m_popupgroup->exec(globpos);
1256
} else if (!(itype & ~(ITYPE_PAIR | ITYPE_GROUP))) {
1257
signKey->setEnabled(!(itype & ITYPE_GROUP));
1258
deleteKey->setEnabled(!(itype & ITYPE_GROUP));
1259
setDefaultKey->setEnabled( (cnt == 1) );
1260
m_popuppub->exec(globpos);
1261
} else if (!(itype & ~(ITYPE_UID | ITYPE_PAIR | ITYPE_UAT))) {
1262
setPrimUid->setEnabled(false);
1263
delUid->setEnabled(false);
1264
m_popupuid->exec(globpos);
1266
m_popupout->exec(globpos);
1270
void KeysManager::revokeWidget()
1272
KGpgNode *nd = iview->selectedNode();
1273
KDialog *keyRevokeDialog = new KGpgRevokeDialog(this, nd->toKeyNode());
1275
connect(keyRevokeDialog, SIGNAL(finished(int)), SLOT(slotRevokeDialogFinished(int)));
1277
keyRevokeDialog->open();
1280
void KeysManager::slotRevokeDialogFinished(int result)
1282
sender()->deleteLater();
1284
if (result != QDialog::Accepted)
1287
KGpgRevokeDialog *keyRevokeDialog = qobject_cast<KGpgRevokeDialog *>(sender());
1289
KGpgGenerateRevoke *genRev = new KGpgGenerateRevoke(this, keyRevokeDialog->getId(), keyRevokeDialog->saveUrl(),
1290
keyRevokeDialog->getReason(), keyRevokeDialog->getDescription());
1292
connect(genRev, SIGNAL(done(int)), SLOT(slotRevokeGenerated(int)));
1294
if (keyRevokeDialog->printChecked())
1295
connect(genRev, SIGNAL(revokeCertificate(QString)), SLOT(doPrint(QString)));
1296
if (keyRevokeDialog->importChecked())
1297
connect(genRev, SIGNAL(revokeCertificate(QString)), SLOT(slotImportRevokeTxt(QString)));
1302
void KeysManager::slotRevokeGenerated(int result)
1304
KGpgGenerateRevoke *genRev = qobject_cast<KGpgGenerateRevoke *>(sender());
1306
genRev->deleteLater();
1308
if (result != KGpgTransaction::TS_OK) {
1309
KMessageBox::detailedSorry(this, i18n("Creation of the revocation certificate failed..."), genRev->getOutput());
1314
void KeysManager::slotImportRevokeTxt(const QString &revokeText)
1316
KGpgImport *import = new KGpgImport(this, revokeText);
1317
connect(import, SIGNAL(done(int)), SLOT(slotImportDone(int)));
1321
void KeysManager::slotexportsec()
1323
// export secret key
1324
const QString warn(i18n("<qt>Secret keys <b>should not</b> be saved in an unsafe place.<br/>"
1325
"If someone else can access this file, encryption with this key will be compromised.<br/>Continue key export?</qt>"));
1326
int result = KMessageBox::warningContinueCancel(this, warn);
1327
if (result != KMessageBox::Continue)
1329
KGpgNode *nd = iview->selectedNode();
1331
QString sname(nd->getEmail().section(QLatin1Char( '@' ), 0, 0).section(QLatin1Char( '.' ), 0, 0));
1332
if (sname.isEmpty())
1333
sname = nd->getName().section(QLatin1Char( ' ' ), 0, 0);
1334
sname.append(QLatin1String( ".asc" ));
1335
sname.prepend(QDir::homePath() + QLatin1Char( '/' ));
1336
KUrl url(KFileDialog::getSaveUrl(sname, i18n( "*.asc|*.asc Files" ), this, i18n("Export PRIVATE KEY As")));
1338
if(!url.isEmpty()) {
1339
KGpgExport *exp = new KGpgExport(this, QStringList(nd->getId()), url.path(), QStringList(QLatin1String( "--armor" )), true);
1341
connect(exp, SIGNAL(done(int)), SLOT(slotExportSecFinished(int)));
1347
void KeysManager::slotExportSecFinished(int result)
1349
KGpgExport *exp = qobject_cast<KGpgExport *>(sender());
1350
Q_ASSERT(exp != NULL);
1352
if (result == KGpgTransaction::TS_OK) {
1353
KMessageBox::information(this,
1354
i18n("<qt>Your <b>private</b> key \"%1\" was successfully exported to<br/>%2.<br/><b>Do not</b> leave it in an insecure place.</qt>",
1355
exp->getKeyIds().first(), exp->getOutputFile()));
1357
KMessageBox::sorry(this, i18n("Your secret key could not be exported.\nCheck the key."));
1361
void KeysManager::slotexport()
1366
QList<KGpgNode *> ndlist(iview->selectedNodes(&same, &tp));
1367
if (ndlist.isEmpty())
1369
if (!(tp & ITYPE_PUBLIC) || (tp & ~ITYPE_GPAIR))
1374
if (ndlist.count() == 1) {
1375
sname = ndlist.at(0)->getEmail().section(QLatin1Char( '@' ), 0, 0).section(QLatin1Char( '.' ), 0, 0);
1376
if (sname.isEmpty())
1377
sname = ndlist.at(0)->getName().section(QLatin1Char(' '), 0, 0);
1379
sname = QLatin1String( "keyring" );
1382
for (int i = 0; i < ndlist.count(); ++i) {
1383
klist << ndlist.at(i)->getId();
1386
sname.append(QLatin1String( ".asc" ));
1387
sname.prepend(QDir::homePath() + QLatin1Char( '/' ));
1389
QStringList serverList(KGpgSettings::keyServers());
1390
serverList.replaceInStrings(QRegExp( QLatin1String( " .*") ), QLatin1String( "" ) ); // Remove kde 3.5 (Default) tag.
1391
if (!serverList.isEmpty()) {
1392
QString defaultServer = serverList.takeFirst();
1394
serverList.prepend(defaultServer);
1397
QPointer<KeyExport> page = new KeyExport(this, serverList);
1399
page->newFilename->setUrl(sname);
1402
page->checkServer->setEnabled(false);
1404
if (page->exec() == QDialog::Accepted) {
1408
if (page->checkAttrAll->isChecked()) {
1410
} else if (page->checkAttrPhoto->isChecked()) {
1411
exportAttr = QLatin1String( "no-export-attributes" );
1413
exportAttr = QLatin1String( "export-minimal" );
1415
QStringList expopts;
1417
if (!exportAttr.isEmpty())
1418
expopts << QLatin1String( "--export-options" ) << exportAttr;
1420
if (page->checkServer->isChecked()) {
1421
KeyServer *expServer = new KeyServer(0, imodel);
1422
expServer->slotSetExportAttribute(exportAttr);
1423
expServer->slotSetKeyserver(page->destServer->currentText());
1425
expServer->slotExport(klist);
1426
} else if (page->checkFile->isChecked()) {
1427
const QString expname(page->newFilename->url().path().simplified());
1428
if (!expname.isEmpty()) {
1430
expopts.append(QLatin1String( "--armor" ));
1432
KGpgExport *exp = new KGpgExport(this, klist, expname, expopts);
1434
connect(exp, SIGNAL(done(int)), SLOT(slotExportFinished(int)));
1439
KGpgExport *exp = new KGpgExport(this, klist, expopts);
1441
if (page->checkClipboard->isChecked())
1442
connect(exp, SIGNAL(done(int)), SLOT(slotProcessExportClip(int)));
1444
connect(exp, SIGNAL(done(int)), SLOT(slotProcessExportMail(int)));
1453
void KeysManager::slotExportFinished(int result)
1455
KGpgExport *exp = qobject_cast<KGpgExport *>(sender());
1456
Q_ASSERT(exp != NULL);
1458
if (result == KGpgTransaction::TS_OK) {
1459
KMessageBox::information(this,
1460
i18np("<qt>The public key was successfully exported to<br/>%2</qt>",
1461
"<qt>The %1 public keys were successfully exported to<br/>%2</qt>",
1462
exp->getKeyIds().count(), exp->getOutputFile()));
1464
KMessageBox::sorry(this, i18n("Your public key could not be exported\nCheck the key."));
1470
void KeysManager::slotProcessExportMail(int result)
1472
KGpgExport *exp = qobject_cast<KGpgExport *>(sender());
1473
Q_ASSERT(exp != NULL);
1475
// start default Mail application
1476
if (result == KGpgTransaction::TS_OK) {
1477
KToolInvocation::invokeMailer(QString(), QString(), QString(), QString(),QLatin1String( exp->getOutputData() ));
1479
KMessageBox::sorry(this, i18n("Your public key could not be exported\nCheck the key."));
1485
void KeysManager::slotProcessExportClip(int result)
1487
KGpgExport *exp = qobject_cast<KGpgExport *>(sender());
1488
Q_ASSERT(exp != NULL);
1490
if (result == KGpgTransaction::TS_OK) {
1491
kapp->clipboard()->setText(QLatin1String( exp->getOutputData() ), m_clipboardmode);
1493
KMessageBox::sorry(this, i18n("Your public key could not be exported\nCheck the key."));
1499
void KeysManager::showKeyInfo(const QString &keyID)
1501
KGpgKeyNode *key = imodel->getRootNode()->findKey(keyID);
1506
showProperties(key);
1509
void KeysManager::slotShowPhoto()
1511
KService::List list(KMimeTypeTrader::self()->query(QLatin1String( "image/jpeg" )));
1512
if (list.isEmpty()) {
1513
KMessageBox::sorry(NULL, i18n("<qt>A viewer for JPEG images is not specified.<br/>Please check your installation.</qt>"), i18n("Show photo"));
1516
KGpgNode *nd = iview->selectedNode();
1517
KGpgUatNode *und = nd->toUatNode();
1518
KGpgKeyNode *parent = und->getParentKeyNode();
1519
KService::Ptr ptr = list.first();
1522
p << KGpgSettings::gpgBinaryPath() << QLatin1String( "--no-tty" ) << QLatin1String( "--photo-viewer" ) << (ptr->desktopEntryName() + QLatin1String( " %i" )) << QLatin1String( "--edit-key" ) << parent->getId() << QLatin1String( "uid" ) << und->getId() << QLatin1String( "showphoto" ) << QLatin1String( "quit" );
1526
void KeysManager::defaultAction(const QModelIndex &index)
1528
KGpgNode *nd = iproxy->nodeForIndex(index);
1533
void KeysManager::slotDefaultAction()
1535
defaultAction(iview->selectedNode());
1538
void KeysManager::defaultAction(KGpgNode *nd)
1543
switch (nd->getType()) {
1554
iview->selectNode(nd->toRefNode()->getRefNode());
1567
KeysManager::showProperties(KGpgNode *n)
1569
switch (n->getType()) {
1574
KGpgKeyNode *k = n->toKeyNode();
1575
QPointer<KgpgKeyInfo> opts = new KgpgKeyInfo(k, imodel, this);
1576
connect(opts, SIGNAL(keyNeedsRefresh(KGpgKeyNode*)), imodel, SLOT(refreshKey(KGpgKeyNode*)));
1577
connect(opts->keychange, SIGNAL(keyNeedsRefresh(KGpgKeyNode*)), imodel, SLOT(refreshKey(KGpgKeyNode*)));
1586
void KeysManager::keyproperties()
1588
KGpgNode *cur = iview->selectedNode();
1594
switch (cur->getType()) {
1597
if (KMessageBox::questionYesNo(this,
1598
i18n("<p>This key is an orphaned secret key (secret key without public key.) It is currently not usable.</p>"
1599
"<p>Would you like to regenerate the public key?</p>"), QString(), KGuiItem(i18n("Generate")), KGuiItem(i18n("Do Not Generate"))) == KMessageBox::Yes)
1603
case ITYPE_PUBLIC: {
1604
kn = cur->toKeyNode();
1608
case ITYPE_GPUBLIC: {
1609
kn = cur->toGroupMemberNode()->getRefNode();
1613
kDebug(2100) << "Oops, called with invalid item type" << cur->getType();
1617
QPointer<KgpgKeyInfo> opts = new KgpgKeyInfo(kn, imodel, this);
1618
connect(opts, SIGNAL(keyNeedsRefresh(KGpgKeyNode*)), imodel, SLOT(refreshKey(KGpgKeyNode*)));
1623
void KeysManager::deleteGroup()
1625
KGpgNode *nd = iview->selectedNode();
1626
if (!nd || (nd->getType() != ITYPE_GROUP))
1629
int result = KMessageBox::warningContinueCancel(this, i18n("<qt>Are you sure you want to delete group <b>%1</b> ?</qt>",nd->getName()), QString(), KGuiItem(i18n("Delete"), QLatin1String( "edit-delete" )));
1630
if (result != KMessageBox::Continue)
1633
KgpgInterface::delGpgGroup(nd->getName(), KGpgSettings::gpgConfigPath());
1634
imodel->delNode(nd);
1636
const QStringList groups(KgpgInterface::getGpgGroupNames(KGpgSettings::gpgConfigPath()));
1637
KGpgSettings::setGroups(groups.join( QLatin1String( "," )));
1638
updateStatusCounter();
1641
void KeysManager::renameGroup()
1643
KGpgNode *nd = iview->selectedNode();
1644
if (!nd || (nd->getType() != ITYPE_GROUP))
1647
const QString groupName = KInputDialog::getText(i18n("Rename Group"),
1648
i18nc("Enter the new name for the key group being renamed", "Enter new group name:"),
1649
nd->getName(), 0, this);
1651
if ((groupName == nd->getName()) || groupName.isEmpty())
1654
nd->toGroupNode()->rename(groupName);
1657
void KeysManager::createNewGroup()
1659
QStringList badkeys;
1660
QStringList keysGroup;
1661
KGpgKeyNode::List keysList;
1663
KGpgNode::List ndlist(iview->selectedNodes(NULL, &tp));
1665
if (ndlist.isEmpty())
1667
if (tp & ~ITYPE_PAIR) {
1668
KMessageBox::sorry(this, i18n("<qt>You cannot create a group containing signatures, subkeys or other groups.</qt>"));
1672
KgpgKeyTrustFlag mintrust;
1673
if (KGpgSettings::allowUntrustedGroupMembers()) {
1674
mintrust = KgpgCore::TRUST_UNDEFINED;
1676
mintrust = KgpgCore::TRUST_FULL;
1679
foreach (KGpgNode *nd, ndlist) {
1680
if (nd->getTrust() >= mintrust) {
1681
keysGroup += nd->getId();
1682
keysList.append(nd->toKeyNode());
1684
badkeys += i18nc("<Name> (<Email>) ID: <KeyId>", "%1 (%2) ID: %3",
1685
nd->getName(), nd->getEmail(), nd->getId());
1689
QString groupName(KInputDialog::getText(i18n("Create New Group"),
1690
i18nc("Enter the name of the group you are creating now", "Enter new group name:"),
1691
QString(), 0, this));
1692
if (groupName.isEmpty())
1694
if (!keysGroup.isEmpty()) {
1695
if (!badkeys.isEmpty())
1696
KMessageBox::informationList(this, i18n("Following keys are not valid or not trusted and will not be added to the group:"), badkeys);
1698
KgpgInterface::setGpgGroupSetting(groupName, keysGroup, KGpgSettings::gpgConfigPath());
1699
const QStringList groups(KgpgInterface::getGpgGroupNames(KGpgSettings::gpgConfigPath()));
1701
iview->selectNode(imodel->addGroup(groupName, keysList));
1702
updateStatusCounter();
1704
KMessageBox::sorry(this,
1705
i18n("<qt>No valid or trusted key was selected. The group <b>%1</b> will not be created.</qt>",
1710
void KeysManager::editGroup()
1712
KGpgNode *nd = iview->selectedNode();
1713
if (!nd || (nd->getType() != ITYPE_GROUP))
1715
KGpgGroupNode *gnd = nd->toGroupNode();
1716
QPointer<KDialog> dialogGroupEdit = new KDialog(this );
1717
dialogGroupEdit->setCaption( i18n("Group Properties") );
1718
dialogGroupEdit->setButtons( KDialog::Ok | KDialog::Cancel );
1719
dialogGroupEdit->setDefaultButton( KDialog::Ok );
1720
dialogGroupEdit->setModal( true );
1722
QList<KGpgNode *> members(gnd->getChildren());
1724
groupEdit *gEdit = new groupEdit(dialogGroupEdit, &members);
1725
gEdit->setModel(imodel);
1727
dialogGroupEdit->setMainWidget(gEdit);
1730
if (dialogGroupEdit->exec() == QDialog::Accepted) {
1731
QStringList memberids;
1733
foreach (KGpgNode *knd, members)
1734
memberids << knd->getId();
1736
KgpgInterface::setGpgGroupSetting(nd->getName(), memberids, KGpgSettings::gpgConfigPath());
1737
imodel->changeGroup(gnd, members);
1739
delete dialogGroupEdit;
1742
void KeysManager::signkey()
1744
// another sign operation is still running
1745
if (!signList.isEmpty())
1749
QList<KGpgNode *> tmplist = iview->selectedNodes(NULL, &tp);
1750
if (tmplist.isEmpty())
1753
if (tp & ~ITYPE_PAIR) {
1754
KMessageBox::sorry(this, i18n("You can only sign primary keys. Please check your selection."));
1758
if (tmplist.count() == 1) {
1759
KGpgKeyNode *nd = tmplist.at(0)->toKeyNode();
1762
if (nd->getEmail().isEmpty())
1763
opt = i18n("<qt>You are about to sign key:<br /><br />%1<br />ID: %2<br />Fingerprint: <br /><b>%3</b>.<br /><br />"
1764
"You should check the key fingerprint by phoning or meeting the key owner to be sure that someone "
1765
"is not trying to intercept your communications.</qt>", nd->getName(), nd->getId().right(8), nd->getBeautifiedFingerprint());
1767
opt = i18n("<qt>You are about to sign key:<br /><br />%1 (%2)<br />ID: %3<br />Fingerprint: <br /><b>%4</b>.<br /><br />"
1768
"You should check the key fingerprint by phoning or meeting the key owner to be sure that someone "
1769
"is not trying to intercept your communications.</qt>", nd->getName(), nd->getEmail(), nd->getId().right(8), nd->getBeautifiedFingerprint());
1771
if (KMessageBox::warningContinueCancel(this, opt) != KMessageBox::Continue) {
1774
signList.append(nd);
1776
QStringList signKeyList;
1777
foreach (KGpgNode *n, tmplist) {
1778
const KGpgKeyNode *nd = n->toKeyNode();
1780
if (nd->getEmail().isEmpty())
1781
signKeyList += i18nc("Name: ID", "%1: %2", nd->getName(), nd->getBeautifiedFingerprint());
1783
signKeyList += i18nc("Name (Email): ID", "%1 (%2): %3", nd->getName(), nd->getEmail(), nd->getBeautifiedFingerprint());
1785
signList.append(n->toSignableNode());
1788
if (KMessageBox::Continue != KMessageBox::warningContinueCancelList(this,
1789
i18n("<qt>You are about to sign the following keys in one pass.<br/><b>If you have not carefully checked all fingerprints, the security of your communications may be compromised.</b></qt>"), signKeyList))
1793
QPointer<KgpgSelectSecretKey> opts = new KgpgSelectSecretKey(this, imodel, signList.count());
1794
if (opts->exec() != QDialog::Accepted) {
1800
globalkeyID = QString(opts->getKeyID());
1801
const bool localsign = opts->isLocalSign();
1802
const int checklevel = opts->getSignTrust();
1803
bool isterminal = opts->isTerminalSign();
1807
const QString keyid(signList.at(0)->getId());
1809
signKeyOpenConsole(globalkeyID, keyid, checklevel, localsign);
1813
signLoop(localsign, checklevel);
1817
void KeysManager::signuid()
1819
// another sign operation is still running
1820
if (!signList.isEmpty())
1824
KGpgNode::List tmplist = iview->selectedNodes(NULL, &tp);
1825
if (tmplist.isEmpty())
1828
if (tp & ~(ITYPE_PAIR | ITYPE_UID | ITYPE_UAT)) {
1829
KMessageBox::sorry(this, i18n("You can only sign user ids and photo ids. Please check your selection."));
1833
if (tmplist.count() == 1) {
1834
KGpgSignableNode *nd = tmplist.at(0)->toSignableNode();
1836
if (tp & ITYPE_PUBLIC)
1837
pnd = nd->toKeyNode();
1839
pnd = nd->getParentKeyNode()->toKeyNode();
1842
if (nd->getEmail().isEmpty())
1843
opt = i18n("<qt>You are about to sign user id:<br /><br />%1<br />ID: %2<br />Fingerprint: <br /><b>%3</b>.<br /><br />"
1844
"You should check the key fingerprint by phoning or meeting the key owner to be sure that someone "
1845
"is not trying to intercept your communications.</qt>", nd->getName(), nd->getId(), pnd->getBeautifiedFingerprint());
1847
opt = i18n("<qt>You are about to sign user id:<br /><br />%1 (%2)<br />ID: %3<br />Fingerprint: <br /><b>%4</b>.<br /><br />"
1848
"You should check the key fingerprint by phoning or meeting the key owner to be sure that someone "
1849
"is not trying to intercept your communications.</qt>", nd->getName(), nd->getEmail(), nd->getId(), pnd->getBeautifiedFingerprint());
1851
if (KMessageBox::warningContinueCancel(this, opt) != KMessageBox::Continue) {
1854
signList.append(nd);
1856
QStringList signKeyList;
1858
foreach (KGpgNode *nd, tmplist) {
1859
const KGpgKeyNode *pnd = (nd->getType() & (ITYPE_UID | ITYPE_UAT)) ?
1860
nd->getParentKeyNode()->toKeyNode() : nd->toKeyNode();
1862
if (nd->getEmail().isEmpty())
1863
signKeyList += i18nc("Name: ID", "%1: %2",
1864
nd->getName(), pnd->getBeautifiedFingerprint());
1866
signKeyList += i18nc("Name (Email): ID", "%1 (%2): %3",
1867
nd->getName(), nd->getEmail(), pnd->getBeautifiedFingerprint());
1869
signList.append(nd->toSignableNode());
1872
if (KMessageBox::warningContinueCancelList(this, i18n("<qt>You are about to sign the following user ids in one pass.<br/><b>If you have not carefully checked all fingerprints, the security of your communications may be compromised.</b></qt>"),
1873
signKeyList) != KMessageBox::Continue)
1877
QPointer<KgpgSelectSecretKey> opts = new KgpgSelectSecretKey(this, imodel, signList.count());
1878
if (opts->exec() != QDialog::Accepted) {
1884
globalkeyID = QString(opts->getKeyID());
1885
const bool localsign = opts->isLocalSign();
1886
const int checklevel = opts->getSignTrust();
1887
bool isterminal = opts->isTerminalSign();
1891
const QString keyid(signList.at(0)->getId());
1893
signKeyOpenConsole(globalkeyID, keyid, checklevel, localsign);
1897
signLoop(localsign, checklevel);
1901
void KeysManager::signLoop(const bool localsign, const int checklevel)
1903
Q_ASSERT(keyCount < signList.count());
1905
KGpgSignableNode *nd = signList.at(keyCount);
1908
const KGpgSignTransactionHelper::carefulCheck cc = static_cast<KGpgSignTransactionHelper::carefulCheck>(checklevel);
1909
KGpgTransaction *sta;
1912
sta = new KGpgSignUid(this, globalkeyID, nd, localsign, cc);
1914
sta = new KGpgSignKey(this, globalkeyID, nd->toKeyNode(), localsign, cc);
1917
connect(sta, SIGNAL(done(int)), SLOT(signatureResult(int)));
1921
void KeysManager::signatureResult(int success)
1923
KGpgSignTransactionHelper *ta;
1924
KGpgSignUid *suid = qobject_cast<KGpgSignUid *>(sender());
1926
ta = static_cast<KGpgSignTransactionHelper *>(suid);
1928
ta = static_cast<KGpgSignTransactionHelper *>(static_cast<KGpgSignKey *>(sender()));
1930
KGpgKeyNode *nd = const_cast<KGpgKeyNode *>(ta->getKey());
1931
const bool localsign = ta->getLocal();
1932
const int checklevel = ta->getChecking();
1933
const QString signer(ta->getSigner());
1934
sender()->deleteLater();
1937
case KGpgTransaction::TS_OK:
1938
if (refreshList.indexOf(nd) == -1)
1939
refreshList.append(nd);
1941
case KGpgTransaction::TS_BAD_PASSPHRASE:
1942
KMessageBox::sorry(this, i18n("<qt>Bad passphrase, key <b>%1 (%2)</b> not signed.</qt>",
1943
nd->getName(), nd->getEmail()));
1945
case KGpgSignTransactionHelper::TS_ALREADY_SIGNED:
1946
KMessageBox::sorry(this, i18n("<qt>The key <b>%1 (%2)</b> is already signed.</qt>",
1947
nd->getName(), nd->getEmail()));
1950
if (KMessageBox::questionYesNo(this,
1951
i18n("<qt>Signing key <b>%1</b> with key <b>%2</b> failed.<br />"
1952
"Do you want to try signing the key in console mode?</qt>",
1953
nd->getId(), signer)) == KMessageBox::Yes)
1954
signKeyOpenConsole(signer, nd->getId(), checklevel, localsign);
1957
if (++keyCount == signList.count()) {
1959
imodel->refreshKeys(refreshList);
1960
refreshList.clear();
1962
signLoop(localsign, checklevel);
1966
void KeysManager::caff()
1969
KGpgNode::List tmplist = iview->selectedNodes(NULL, &tp);
1970
KGpgSignableNode::List slist;
1971
if (tmplist.isEmpty())
1974
if (tp & ~(ITYPE_PAIR | ITYPE_UID | ITYPE_UAT)) {
1975
KMessageBox::sorry(this, i18n("You can only sign user ids and photo ids. Please check your selection."));
1979
foreach (KGpgNode *nd, tmplist) {
1980
switch (nd->getType()) {
1981
case KgpgCore::ITYPE_PAIR:
1982
case KgpgCore::ITYPE_PUBLIC: {
1983
KGpgKeyNode *knd = qobject_cast<KGpgKeyNode *>(nd);
1984
if (!knd->wasExpanded())
1985
knd->getChildCount();
1988
slist.append(nd->toSignableNode());
1991
QPointer<KgpgSelectSecretKey> opts = new KgpgSelectSecretKey(this, imodel, slist.count(), false, false);
1992
if (opts->exec() != QDialog::Accepted) {
1997
KGpgCaff *ca = new KGpgCaff(this, slist, QStringList(opts->getKeyID()), opts->getSignTrust());
2000
connect(ca, SIGNAL(done()), SLOT(slotCaffDone()));
2001
connect(ca, SIGNAL(aborted()), SLOT(slotCaffDone()));
2006
void KeysManager::slotCaffDone()
2008
Q_ASSERT(qobject_cast<KGpgCaff *>(sender()) != NULL);
2010
sender()->deleteLater();
2013
void KeysManager::signKeyOpenConsole(const QString &signer, const QString &keyid, const int checking, const bool local)
2015
KConfigGroup config(KGlobal::config(), "General");
2018
process << config.readPathEntry("TerminalApplication", QLatin1String( "konsole" ));
2019
process << QLatin1String( "-e" ) << KGpgSettings::gpgBinaryPath() << QLatin1String( "--no-secmem-warning" ) << QLatin1String( "-u" ) << signer;
2020
process << QLatin1String( "--default-cert-level" ) << QString(checking);
2023
process << QLatin1String( "--sign-key" ) << keyid;
2025
process << QLatin1String( "--lsign-key" ) << keyid;
2030
void KeysManager::getMissingSigs(QSet<QString> &missingKeys, const KGpgExpandableNode *nd)
2032
foreach (const KGpgNode *ch, nd->getChildren()) {
2033
if (ch->hasChildren()) {
2034
getMissingSigs(missingKeys, ch->toExpandableNode());
2036
} else if (ch->getType() == ITYPE_SIGN) {
2037
if (ch->toSignNode()->isUnknown())
2038
missingKeys << ch->getId();
2043
void KeysManager::importallsignkey()
2045
const QList<KGpgNode *> sel(iview->selectedNodes());
2046
QSet<QString> missingKeys;
2051
foreach (const KGpgNode *nd, sel) {
2052
if (nd->hasChildren()) {
2053
getMissingSigs(missingKeys, nd->toExpandableNode());
2054
} else if (nd->getType() == ITYPE_SIGN) {
2055
const KGpgSignNode *sn = nd->toSignNode();
2057
if (sn->isUnknown())
2058
missingKeys << sn->getId();
2062
if (missingKeys.isEmpty()) {
2063
KMessageBox::information(this,
2064
i18np("All signatures for this key are already in your keyring",
2065
"All signatures for this keys are already in your keyring", sel.count()));
2069
importRemoteKeys(missingKeys.toList());
2072
void KeysManager::preimportsignkey()
2074
const QList<KGpgNode *> exportList(iview->selectedNodes());
2077
if (exportList.empty())
2080
foreach (const KGpgNode *nd, exportList)
2081
idlist << nd->getId();
2083
importRemoteKeys(idlist);
2086
bool KeysManager::importRemoteKey(const QString &keyIDs)
2088
return importRemoteKeys(keyIDs.simplified().split(QLatin1Char( ' ' )), false);
2091
bool KeysManager::importRemoteKeys(const QStringList &keyIDs, const bool dialog)
2093
QStringList kservers(KeyServer::getServerList());
2094
if (kservers.isEmpty())
2097
KGpgReceiveKeys *proc = new KGpgReceiveKeys(this, kservers.first(), keyIDs, dialog, QLatin1String( qgetenv("http_proxy") ));
2098
connect(proc, SIGNAL(done(int)), SLOT(importRemoteFinished(int)));
2105
void KeysManager::importRemoteFinished(int result)
2107
KGpgReceiveKeys *t = qobject_cast<KGpgReceiveKeys *>(sender());
2108
Q_ASSERT(t != NULL);
2110
const QStringList keys(KGpgImport::getImportedIds(t->getLog()));
2114
if (result == KGpgTransaction::TS_OK)
2115
imodel->refreshKeys(keys);
2118
void KeysManager::refreshKeys(const QStringList& ids)
2120
imodel->refreshKeys(ids);
2123
void KeysManager::delsignkey()
2125
KGpgNode *nd = iview->selectedNode();
2132
KGpgExpandableNode *parent = nd->getParentKeyNode();
2133
switch (parent->getType()) {
2136
uid = QLatin1Char( '1' );
2137
parentKey = parent->getId();
2141
uid = parent->getId();
2142
parentKey = parent->getParentKeyNode()->getId();
2149
const QString signID(nd->getId());
2150
QString signMail(nd->getNameComment());
2151
QString parentMail(parent->getNameComment());
2153
if (!parent->getEmail().isEmpty())
2154
parentMail += QLatin1String( " <" ) + parent->getEmail() + QLatin1String( ">" );
2155
if (!nd->getEmail().isEmpty())
2156
signMail += QLatin1String( " <" ) + nd->getEmail() + QLatin1String( ">" );
2158
if (parentKey == signID) {
2159
KMessageBox::sorry(this, i18n("Edit key manually to delete a self-signature."));
2163
QString ask = i18n("<qt>Are you sure you want to delete signature<br /><b>%1</b><br />from user id <b>%2</b><br />of key: <b>%3</b>?</qt>", signMail, parentMail, parentKey);
2165
if (KMessageBox::questionYesNo(this, ask, QString(), KStandardGuiItem::del(), KStandardGuiItem::cancel()) != KMessageBox::Yes)
2168
KGpgDelSign *delsig = new KGpgDelSign(this, nd->toSignNode());
2169
connect(delsig, SIGNAL(done(int)), SLOT(delsignatureResult(int)));
2173
void KeysManager::delsignatureResult(int success)
2175
sender()->deleteLater();
2177
if (success == KGpgTransaction::TS_OK) {
2178
KGpgNode *nd = iview->selectedNode()->getParentKeyNode();
2180
while (!(nd->getType() & ITYPE_PAIR))
2181
nd = nd->getParentKeyNode();
2182
imodel->refreshKey(nd->toKeyNode());
2184
KMessageBox::sorry(this, i18n("Requested operation was unsuccessful, please edit the key manually."));
2188
void KeysManager::slotedit()
2190
KGpgNode *nd = iview->selectedNode();
2191
Q_ASSERT(nd != NULL);
2193
if (!(nd->getType() & ITYPE_PAIR))
2200
KProcess *kp = new KProcess(this);
2201
KConfigGroup config(KGlobal::config(), "General");
2202
*kp << config.readPathEntry("TerminalApplication",QLatin1String( "konsole" ));
2203
*kp << QLatin1String( "-e" ) << KGpgSettings::gpgBinaryPath() <<QLatin1String( "--no-secmem-warning" ) <<QLatin1String( "--edit-key" ) << nd->getId() << QLatin1String( "help" );
2204
terminalkey = nd->toKeyNode();
2205
editKey->setEnabled(false);
2207
connect(kp, SIGNAL(finished(int)), SLOT(slotEditDone(int)));
2211
void KeysManager::slotEditDone(int exitcode)
2214
imodel->refreshKey(terminalkey);
2217
editKey->setEnabled(true);
2220
void KeysManager::doPrint(const QString &txt)
2223
//kDebug(2100) << "Printing..." ;
2224
QPointer<QPrintDialog> printDialog = new QPrintDialog(&prt, this);
2225
if (printDialog->exec() == QDialog::Accepted) {
2226
QPainter painter(&prt);
2227
int width = painter.device()->width();
2228
int height = painter.device()->height();
2229
painter.drawText(0, 0, width, height, Qt::AlignLeft|Qt::AlignTop|Qt::TextDontClip, txt);
2234
void KeysManager::removeFromGroups(KGpgKeyNode *node)
2236
const QList<KGpgGroupNode *> groups(node->getGroups());
2237
if (groups.count() == 0)
2240
QStringList groupNames;
2242
foreach (const KGpgGroupNode *gnd, groups)
2243
groupNames << gnd->getName();
2245
QString ask = i18np("<qt>The key you are deleting is a member of the following key group. Do you want to remove it from this group?</qt>",
2246
"<qt>The key you are deleting is a member of the following key groups. Do you want to remove it from these groups?</qt>",
2247
groupNames.count());
2249
if (KMessageBox::questionYesNoList(this, ask, groupNames, i18n("Delete key")) != KMessageBox::Yes)
2252
QList<KGpgGroupMemberNode *> grefs(node->getGroupRefs());
2254
bool groupDeleted = false;
2256
foreach (KGpgGroupMemberNode *gref, grefs) {
2257
QStringList memberids;
2258
KGpgGroupNode *group = gref->getParentKeyNode();
2260
for (int j = group->getChildCount() - 1; j >= 0; j--) {
2261
KGpgGroupMemberNode *rn = group->getChild(j)->toGroupMemberNode();
2263
memberids << rn->getId();
2266
if (!memberids.isEmpty()) {
2267
KgpgInterface::setGpgGroupSetting(group->getName(), memberids, KGpgSettings::gpgConfigPath());
2268
imodel->deleteFromGroup(group, gref);
2270
KgpgInterface::delGpgGroup(group->getName(), KGpgSettings::gpgConfigPath());
2271
imodel->delNode(group);
2272
groupDeleted = true;
2277
QStringList groupnames = KgpgInterface::getGpgGroupNames(KGpgSettings::gpgConfigPath());
2278
KGpgSettings::setGroups(groupnames.join(QLatin1String(",")));
2279
updateStatusCounter();
2283
void KeysManager::deleteseckey()
2285
KGpgKeyNode *nd = iview->selectedNode()->toKeyNode();
2286
Q_ASSERT(nd != NULL);
2289
int result = KMessageBox::warningContinueCancel(this,
2290
i18n("<p>Delete <b>secret</b> key pair <b>%1</b>?</p>Deleting this key pair means you will never be able to decrypt files encrypted with this key again.", nd->getNameComment()),
2292
KGuiItem(i18n("Delete"), QLatin1String( "edit-delete" )));
2293
if (result != KMessageBox::Continue)
2296
if (terminalkey == nd)
2298
if (delkey != NULL) {
2299
KMessageBox::error(this, i18n("Another key delete operation is still in progress.\nPlease wait a moment until this operation is complete."), i18n("Delete key"));
2303
removeFromGroups(nd);
2306
m_delkey = new KGpgDelKey(this, nd->getId());
2307
connect(m_delkey, SIGNAL(done(int)), SLOT(secretKeyDeleted(int)));
2311
void KeysManager::secretKeyDeleted(int retcode)
2314
KMessageBox::information(this, i18n("Key <b>%1</b> deleted.", delkey->getBeautifiedFingerprint()), i18n("Delete key"));
2315
imodel->delNode(delkey);
2317
KMessageBox::error(this, i18n("Deleting key <b>%1</b> failed.", delkey->getBeautifiedFingerprint()), i18n("Delete key"));
2320
m_delkey->deleteLater();
2324
void KeysManager::confirmdeletekey()
2327
KMessageBox::error(this, i18n("Another key delete operation is still in progress.\nPlease wait a moment until this operation is complete."), i18n("Delete key"));
2331
Q_ASSERT(m_delkeys.isEmpty());
2333
KgpgCore::KgpgItemType pt;
2335
QList<KGpgNode *> ndlist(iview->selectedNodes(&same, &pt));
2336
if (ndlist.isEmpty())
2339
// do not delete a key currently edited in terminal
2340
if ((!(pt & ~ITYPE_PAIR)) && (ndlist.at(0) == terminalkey) && (ndlist.count() == 1)) {
2341
KMessageBox::error(this, i18n("Can not delete key <b>%1</b> while it is edited in terminal.", terminalkey->getBeautifiedFingerprint()), i18n("Delete key"));
2343
} else if (pt == ITYPE_GROUP) {
2346
} else if (!(pt & ITYPE_GROUP) && (pt & ITYPE_SECRET) && (ndlist.count() == 1)) {
2350
if (pt & ~ITYPE_PAIR) {
2351
KMessageBox::error(this, i18n("You have selected items that are not keys. They can not be deleted with this menu entry."), i18n("Delete key"));
2355
QStringList keysToDelete;
2356
QStringList deleteIds;
2357
QStringList secList;
2359
bool secretKeyInside = (pt & ITYPE_SECRET);
2360
foreach (KGpgNode *nd, ndlist) {
2361
KGpgKeyNode *ki = nd->toKeyNode();
2363
if (ki->getType() & ITYPE_SECRET) {
2364
secList += ki->getNameComment();
2365
} else if (ki != terminalkey) {
2366
keysToDelete += ki->getNameComment();
2367
deleteIds << ki->getId();
2372
if (secretKeyInside) {
2373
int result = KMessageBox::warningContinueCancel(this, i18n("<qt>The following are secret key pairs:<br/><b>%1</b><br/>They will not be deleted.</qt>", secList.join( QLatin1String( "<br />" ))));
2374
if (result != KMessageBox::Continue) {
2380
if (keysToDelete.isEmpty()) {
2381
Q_ASSERT(m_delkeys.isEmpty());
2385
int result = KMessageBox::warningContinueCancelList(this, i18np("<qt><b>Delete the following public key?</b></qt>", "<qt><b>Delete the following %1 public keys?</b></qt>", keysToDelete.count()), keysToDelete, QString(), KStandardGuiItem::del());
2386
if (result != KMessageBox::Continue) {
2391
foreach (KGpgNode *nd, ndlist)
2392
removeFromGroups(nd->toKeyNode());
2394
m_delkey = new KGpgDelKey(this, deleteIds);
2395
connect(m_delkey, SIGNAL(done(int)), SLOT(slotDelKeyDone(int)));
2399
void KeysManager::slotDelKeyDone(int res)
2402
foreach (KGpgKeyNode *kn, m_delkeys)
2403
imodel->delNode(kn);
2406
m_delkey->deleteLater();
2410
updateStatusCounter();
2413
void KeysManager::slotPreImportKey()
2415
QPointer<KDialog> dial = new KDialog(this);
2416
dial->setCaption(i18n("Key Import"));
2417
dial->setButtons(KDialog::Ok | KDialog::Cancel);
2418
dial->setDefaultButton(KDialog::Ok);
2419
dial->setModal(true);
2421
SrcSelect *page = new SrcSelect();
2422
dial->setMainWidget(page);
2423
page->newFilename->setWindowTitle(i18n("Open File"));
2424
page->newFilename->setMode(KFile::File);
2426
if (dial->exec() == QDialog::Accepted) {
2427
if (page->checkFile->isChecked()) {
2428
KUrl impname = page->newFilename->url();
2429
if (!impname.isEmpty())
2430
slotImport(KUrl::List(impname));
2431
} else if (page->checkServer->isChecked()) {
2432
const QString ids(page->keyIds->text().simplified());
2434
importRemoteKeys(ids.split(QLatin1Char( ' ' )));
2436
slotImport(kapp->clipboard()->text(m_clipboardmode));
2443
void KeysManager::slotImport(const QString &text)
2450
if (!KGpgImport::isKey(text) && KGpgDecrypt::isEncryptedText(text)) {
2451
if (KMessageBox::questionYesNo(this,
2452
i18n("<qt>The text in the clipboard does not look like a key, but like encrypted text.<br />Do you want to decrypt it first and then try importing it?</qt>"),
2453
i18n("Import from Clipboard")) != KMessageBox::Yes)
2456
imp = new KGpgImport(this);
2457
KGpgDecrypt *decr = new KGpgDecrypt(this, text);
2458
imp->setInputTransaction(decr);
2460
imp = new KGpgImport(this, text);
2466
void KeysManager::slotImport(const KUrl::List &files)
2468
startImport(new KGpgImport(this, files));
2471
void KeysManager::startImport(KGpgImport *import)
2473
changeMessage(i18n("Importing..."), true);
2474
connect(import, SIGNAL(done(int)), SLOT(slotImportDone(int)));
2478
void KeysManager::slotImportDone(int result)
2480
KGpgImport *import = qobject_cast<KGpgImport *>(sender());
2481
Q_ASSERT(import != NULL);
2482
const QStringList rawmsgs(import->getMessages());
2485
KMessageBox::detailedSorry(this, i18n("Key importing failed. Please see the detailed log for more information."),
2486
rawmsgs.join( QLatin1String( "\n")) , i18n("Key Import" ));
2489
QStringList keys(import->getImportedIds(0x1f));
2490
const bool needsRefresh = !keys.isEmpty();
2491
keys << import->getImportedIds(0);
2493
if (!keys.isEmpty()) {
2494
const QString msg(import->getImportMessage());
2495
const QStringList keynames(import->getImportedKeys());
2497
new KgpgDetailedInfo(this, msg, rawmsgs.join( QLatin1String( "\n") ), keynames, i18n("Key Import" ));
2499
imodel->refreshKeys(keys);
2501
changeMessage(i18nc("Application ready for user input", "Ready"));
2503
changeMessage(i18nc("Application ready for user input", "Ready"));
2506
import->deleteLater();
2509
void KeysManager::refreshkey()
2511
imodel->refreshKeys();
2512
updateStatusCounter();
2515
KGpgItemModel *KeysManager::getModel()
2521
KeysManager::slotNetworkUp()
2523
toggleNetworkActions(true);
2527
KeysManager::slotNetworkDown()
2529
toggleNetworkActions(false);
2533
KeysManager::toggleNetworkActions(bool online)
2536
kserver->setEnabled(online);
2537
importSignatureKey->setEnabled(online);
2538
importAllSignKeys->setEnabled(online);
2539
refreshKey->setEnabled(online);
2543
KeysManager::setupTrayIcon()
2545
bool newtray = (m_trayicon == NULL);
2548
m_trayicon = new KStatusNotifierItem(this);
2549
m_trayicon->setIconByName(QLatin1String( "kgpg" ));
2550
m_trayicon->setToolTip(QLatin1String( "kgpg" ), i18n("KGpg - encryption tool"), QString());
2553
switch (KGpgSettings::leftClick()) {
2554
case KGpgSettings::EnumLeftClick::Editor:
2555
m_trayicon->setAssociatedWidget(s_kgpgEditor);
2557
case KGpgSettings::EnumLeftClick::KeyManager:
2558
m_trayicon->setAssociatedWidget(this);
2562
m_trayicon->setCategory(KStatusNotifierItem::ApplicationStatus);
2567
KMenu *conf_menu = m_trayicon->contextMenu();
2569
QAction *KgpgOpenManager = actionCollection()->addAction(QLatin1String("kgpg_manager"), this, SLOT(show()));
2570
KgpgOpenManager->setIcon(KIcon( QLatin1String( "kgpg" )));
2571
KgpgOpenManager->setText(i18n("Ke&y Manager"));
2573
QAction *KgpgEncryptClipboard = actionCollection()->addAction(QLatin1String("clip_encrypt"), this, SLOT(clipEncrypt()));
2574
KgpgEncryptClipboard->setText(i18n("&Encrypt Clipboard"));
2576
QAction *KgpgDecryptClipboard = actionCollection()->addAction(QLatin1String("clip_decrypt"), this, SLOT(clipDecrypt()));
2577
KgpgDecryptClipboard->setText(i18n("&Decrypt Clipboard"));
2579
QAction *KgpgSignClipboard = actionCollection()->addAction(QLatin1String("clip_sign"), this, SLOT(clipSign()));
2580
KgpgSignClipboard->setText(i18n("&Sign/Verify Clipboard"));
2581
KgpgSignClipboard->setIcon(KIcon( QLatin1String( "document-sign-key" )));
2583
QAction *KgpgPreferences = KStandardAction::preferences(this, SLOT(showOptions()), actionCollection());
2585
conf_menu->addAction( KgpgEncryptClipboard );
2586
conf_menu->addAction( KgpgDecryptClipboard );
2587
conf_menu->addAction( KgpgSignClipboard );
2588
conf_menu->addAction( KgpgOpenManager );
2589
conf_menu->addAction( openEditor );
2590
conf_menu->addAction( kserver );
2591
conf_menu->addSeparator();
2592
conf_menu->addAction( KgpgPreferences );
2596
KeysManager::showTrayMessage(const QString &message)
2598
if (m_trayicon == NULL)
2601
m_trayicon->showMessage(QString(), message, QLatin1String( "kgpg" ));
2605
KeysManager::goDefaultShortcut() const
2607
return goToDefaultKey->shortcut();
2611
KeysManager::clipEncrypt()
2613
const QString cliptext(kapp->clipboard()->text(m_clipboardmode));
2615
if (cliptext.isEmpty()) {
2616
Q_ASSERT(m_trayicon != NULL);
2617
m_trayicon->showMessage(QString(), i18n("Clipboard is empty."), QLatin1String( "kgpg" ));
2621
QPointer<KgpgSelectPublicKeyDlg> dialog = new KgpgSelectPublicKeyDlg(this, imodel, goToDefaultKey->shortcut());
2622
if (dialog->exec() == KDialog::Accepted) {
2623
QStringList options;
2625
if (!dialog->getCustomOptions().isEmpty() && KGpgSettings::allowCustomEncryptionOptions())
2626
options = dialog->getCustomOptions().split(QLatin1Char( ' ' ), QString::SkipEmptyParts);
2628
if (dialog->getUntrusted())
2629
options.append(QLatin1String( "--always-trust" ));
2630
if (dialog->getArmor())
2631
options.append(QLatin1String( "--armor" ));
2632
if (dialog->getHideId())
2633
options.append(QLatin1String( "--throw-keyid" ));
2635
if (KGpgSettings::pgpCompatibility())
2636
options.append(QLatin1String( "--pgp6" ));
2638
options.append(QLatin1String( "--armor" ));
2641
if (!dialog->getSymmetric())
2642
selec = dialog->selectedKeys();
2644
KGpgTextInterface *txtEncrypt = new KGpgTextInterface();
2645
connect (txtEncrypt, SIGNAL(txtEncryptionFinished(QString)), SLOT(slotSetClip(QString)));
2646
m_trayicon->setStatus(KStatusNotifierItem::Active);
2647
txtEncrypt->encryptText(cliptext, selec, options);
2654
KeysManager::slotSetClip(const QString &newtxt)
2656
sender()->deleteLater();
2658
m_trayicon->setStatus(KStatusNotifierItem::Passive);
2660
if (newtxt.isEmpty())
2663
kapp->clipboard()->setText(newtxt, m_clipboardmode);
2665
Q_ASSERT(m_trayicon != NULL);
2666
m_trayicon->showMessage(QString(), i18n("Text successfully encrypted."), QLatin1String( "kgpg" ));
2670
KeysManager::clipDecrypt()
2672
const QString cliptext(kapp->clipboard()->text(m_clipboardmode).trimmed());
2674
if (cliptext.isEmpty()) {
2675
Q_ASSERT(m_trayicon != NULL);
2676
m_trayicon->showMessage(QString(), i18n("Clipboard is empty."), QLatin1String( "kgpg" ));
2680
KgpgEditor *kgpgtxtedit = new KgpgEditor(this, imodel, 0);
2681
kgpgtxtedit->setAttribute(Qt::WA_DeleteOnClose);
2682
connect(this, SIGNAL(fontChanged(QFont)), kgpgtxtedit, SLOT(slotSetFont(QFont)));
2683
kgpgtxtedit->m_editor->setPlainText(cliptext);
2684
kgpgtxtedit->m_editor->slotDecode();
2685
kgpgtxtedit->show();
2689
KeysManager::clipSign()
2691
QString cliptext = kapp->clipboard()->text(m_clipboardmode);
2692
if (cliptext.isEmpty()) {
2693
Q_ASSERT(m_trayicon != NULL);
2694
m_trayicon->showMessage(QString(), i18n("Clipboard is empty."), QLatin1String( "kgpg" ));
2698
KgpgEditor *kgpgtxtedit = new KgpgEditor(this, imodel, 0);
2699
kgpgtxtedit->setAttribute(Qt::WA_DeleteOnClose);
2700
connect(kgpgtxtedit->m_editor, SIGNAL(verifyFinished()), kgpgtxtedit, SLOT(closeWindow()));
2702
kgpgtxtedit->m_editor->signVerifyText(cliptext);
2703
kgpgtxtedit->show();
2706
#include "keysmanager.moc"