33 #include <config-kleopatra.h>
37 #include "ui_certificatedetailsdialog.h"
53 #include <kleo/cryptobackendfactory.h>
54 #include <kleo/cryptobackend.h>
55 #include <kleo/keylistjob.h>
58 #include <gpgme++/key.h>
59 #include <gpgme++/keylistresult.h>
62 #include <KMessageBox>
63 #include <KLocalizedString>
64 #include <KGlobalSettings>
67 #include <QHeaderView>
70 #include <boost/mem_fn.hpp>
77 using namespace Kleo::Dialogs;
78 using namespace Kleo::Commands;
79 using namespace GpgME;
80 using namespace boost;
82 static bool own(
const std::vector<UserID::Signature> & sigs ) {
84 Q_FOREACH(
const UserID::Signature & sig, sigs ) {
85 const Key signer = kc->findByKeyIDOrFingerprint( sig.signerKeyID() );
86 if ( signer.isNull() || !signer.hasSecret() )
92 class CertificateDetailsDialog::Private {
93 friend class ::Kleo::Dialogs::CertificateDetailsDialog;
99 certificationsModel(),
103 ui.certificationsTV->setModel( &certificationsModel );
105 q, SLOT(slotCertificationSelectionChanged()) );
106 connect( ui.changePassphrasePB, SIGNAL(clicked()),
107 q, SLOT(slotChangePassphraseClicked()) );
108 connect( ui.changeTrustLevelPB, SIGNAL(clicked()),
109 q, SLOT(slotChangeTrustLevelClicked()) );
110 connect( ui.changeExpiryDatePB, SIGNAL(clicked()),
111 q, SLOT(slotChangeExpiryDateClicked()) );
112 connect( ui.revokeCertificationPB, SIGNAL(clicked()),
113 q, SLOT(slotRevokeCertificationClicked()) );
114 connect( ui.addUserIDPB, SIGNAL(clicked()),
115 q, SLOT(slotAddUserIDClicked()) );
116 connect( ui.revokeUserIDPB, SIGNAL(clicked()),
117 q, SLOT(slotRevokeUserIDClicked()) );
118 connect( ui.certifyUserIDPB, SIGNAL(clicked()),
119 q, SLOT(slotCertifyUserIDClicked()) );
120 connect( ui.revokeCertificationPB, SIGNAL(clicked()),
121 q, SLOT(slotRevokeCertificationClicked()) );
122 connect( ui.showCertificationsPB, SIGNAL(clicked()),
123 q, SLOT(slotShowCertificationsClicked()) );
126 ui.subkeyTV->setModel( &subkeysModel );
130 q, SLOT(slotKeysMayHaveChanged()) );
135 KConfigGroup dialog( KGlobal::config(),
"CertificateDetailsDialog" );
136 const QSize size = dialog.readEntry(
"Size",
QSize(600, 400) );
144 KConfigGroup dialog( KGlobal::config(),
"CertificateDetailsDialog" );
145 dialog.writeEntry(
"Size",
q->size() );
151 connect( ptr, SIGNAL(finished()),
q, slot );
153 enableDisableWidgets();
155 template <
typename T,
typename A>
160 startCommandImplementation( ptr, slot );
162 template <
typename T>
164 startCommand<T>( ptr, this->key,
slot );
168 enableDisableWidgets();
171 void slotChangePassphraseClicked() {
172 startCommand<ChangePassphraseCommand>( changePassphraseCommand, SLOT(slotChangePassphraseCommandFinished()) );
174 void slotChangePassphraseCommandFinished() {
175 commandFinished( changePassphraseCommand );
178 void slotChangeTrustLevelClicked() {
179 startCommand<ChangeOwnerTrustCommand>( changeOwnerTrustCommand, SLOT(slotChangeOwnerTrustCommandFinished()) );
181 void slotChangeOwnerTrustCommandFinished() {
182 commandFinished( changeOwnerTrustCommand );
185 void slotChangeExpiryDateClicked() {
186 startCommand<ChangeExpiryCommand>( changeExpiryDateCommand, SLOT(slotChangeExpiryDateCommandFinished()) );
188 void slotChangeExpiryDateCommandFinished() {
189 commandFinished( changeExpiryDateCommand );
192 void slotAddUserIDClicked() {
193 startCommand<AddUserIDCommand>( addUserIDCommand, SLOT(slotAddUserIDCommandFinished()) );
195 void slotAddUserIDCommandFinished() {
196 commandFinished( addUserIDCommand );
199 void slotCertifyUserIDClicked() {
200 const std::vector<UserID> uids = selectedUserIDs();
203 startCommand<CertifyCertificateCommand>( signCertificateCommand, uids, SLOT(slotSignCertificateCommandFinished()) );
205 void slotSignCertificateCommandFinished() {
206 commandFinished( signCertificateCommand );
209 void slotRevokeCertificateClicked() {
213 void slotRevokeUserIDClicked() {
217 void slotRevokeCertificationClicked() {
221 void slotShowCertificationsClicked() {
222 startSignatureListing();
223 enableDisableWidgets();
226 void startSignatureListing() {
229 const CryptoBackend::Protocol *
const protocol = CryptoBackendFactory::instance()->protocol( key.protocol() );
232 KeyListJob *
const job = protocol->keyListJob(
false,
true,
true );
235 connect( job, SIGNAL(result(GpgME::KeyListResult)),
236 q, SLOT(slotSignatureListingDone(GpgME::KeyListResult)) );
237 connect( job, SIGNAL(nextKey(GpgME::Key)),
238 q, SLOT(slotSignatureListingNextKey(GpgME::Key)) );
240 showSignatureListingErrorDialog( err );
244 void slotSignatureListingNextKey(
const Key & key ) {
247 merged.mergeWith( this->key );
251 ui.certificationsTV->expandAll();
252 ui.certificationsTV->header()->resizeSections( QHeaderView::ResizeToContents );
254 void slotSignatureListingDone(
const KeyListResult & result ) {
255 if ( result.error().isCanceled() )
257 else if ( result.error() )
258 showSignatureListingErrorDialog( result.error() );
263 enableDisableWidgets();
265 void showSignatureListingErrorDialog(
const Error & err ) {
266 KMessageBox::information(
q, i18nc(
"@info",
267 "<para>An error occurred while loading the certifications: "
268 "<message>%1</message></para>",
270 i18nc(
"@title",
"Certifications Loading Failed") );
273 void slotCertificationSelectionChanged() {
274 enableDisableWidgets();
277 void slotKeysMayHaveChanged() {
278 if (
const char *
const fpr = key.primaryFingerprint() )
279 if ( !(key.keyListMode() & Extern) )
283 void slotDumpCertificate() {
285 if ( dumpCertificateCommand )
288 if ( key.protocol() !=
CMS ) {
293 ui.dumpLTW->setLines(
QStringList( i18n(
"Please wait while generating the dump...") ) );
296 dumpCertificateCommand->setUseDialog(
false );
298 startCommandImplementation( cmd, SLOT(slotDumpCertificateCommandFinished()) );
301 void slotDumpCertificateCommandFinished() {
302 ui.dumpLTW->setLines( dumpCertificateCommand->output() );
306 void updateWidgetVisibility() {
307 const bool x509 = key.protocol() ==
CMS;
308 const bool pgp = key.protocol() ==
OpenPGP;
309 const bool secret = key.hasSecret();
310 const bool sigs = (key.keyListMode() & Signatures);
311 const bool ultimateTrust = key.ownerTrust() == Key::Ultimate;
312 const bool external = (key.keyListMode() & Extern);
315 ui.overviewActionsGB->setVisible( !external );
316 ui.changePassphrasePB->setVisible( secret );
317 ui.changeTrustLevelPB->setVisible( pgp && ( !secret || !ultimateTrust ) );
318 ui.changeExpiryDatePB->setVisible( pgp && secret );
321 ui.userIDsActionsGB->setVisible( !external && pgp );
322 ui.certificationsActionGB->setVisible( !external && pgp );
323 ui.addUserIDPB->setVisible( secret );
324 ui.expandAllCertificationsPB->setVisible( pgp && sigs );
325 ui.collapseAllCertificationsPB->setVisible( pgp && sigs );
326 ui.showCertificationsPB->setVisible( !external && pgp && !sigs );
329 ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.detailsTab ), pgp );
332 ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.chainTab ), x509 );
335 ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.dumpTab ), x509 );
338 ui.revokeCertificatePB->hide();
339 ui.revokeUserIDPB->hide();
340 ui.certificationsActionGB->hide();
343 QModelIndexList selectedCertificationsIndexes()
const {
344 return ui.certificationsTV->selectionModel()->selectedRows();
347 std::vector<UserID> selectedUserIDs()
const {
348 const QModelIndexList mil = selectedCertificationsIndexes();
349 std::vector<UserID> uids = certificationsModel.userIDs( mil,
true );
350 uids.erase( std::remove_if( uids.begin(), uids.end(), mem_fn( &UserID::isNull ) ), uids.end() );
354 std::vector<UserID::Signature> selectedSignatures()
const {
355 const QModelIndexList mil = selectedCertificationsIndexes();
356 std::vector<UserID::Signature> sigs = certificationsModel.signatures( mil );
357 sigs.erase( std::remove_if( sigs.begin(), sigs.end(), mem_fn( &UserID::Signature::isNull ) ), sigs.end() );
361 void enableDisableWidgets() {
363 ui.changePassphrasePB->setEnabled( !changePassphraseCommand );
364 ui.changeTrustLevelPB->setEnabled( !changeOwnerTrustCommand );
365 ui.changeExpiryDatePB->setEnabled( !changeExpiryDateCommand );
368 ui.addUserIDPB->setEnabled( !addUserIDCommand );
369 ui.showCertificationsPB->setEnabled( !keyListJob );
370 ui.showCertificationsPB->setText( keyListJob
371 ? i18n(
"(please wait while certifications are being loaded)")
372 : i18n(
"Load Certifications (may take a while)") );
374 const std::vector<UserID> uids = selectedUserIDs();
375 const std::vector<UserID::Signature> sigs = selectedSignatures();
377 ui.certifyUserIDPB->setEnabled( !uids.empty() && sigs.empty() && !signCertificateCommand );
378 ui.revokeUserIDPB->setEnabled( !uids.empty() && sigs.empty() );
379 ui.revokeCertificationPB->setEnabled( uids.empty() && !sigs.empty() &&
own( sigs ) );
386 void updateChainTab() {
389 if ( key.protocol() !=
CMS )
396 if ( !chain.back().isRoot() ) {
398 last->
setText( 0, i18n(
"Issuer Certificate Not Found (%1)",
399 DN( chain.back().issuerName() ).prettyDN() ) );
401 const QBrush & fg = ui.chainTW->palette().brush( QPalette::Disabled, QPalette::WindowText );
404 for ( std::vector<Key>::const_reverse_iterator it = chain.rbegin(), end = chain.rend() ; it != end ; ++it ) {
405 last = last ?
new QTreeWidgetItem( last ) : new QTreeWidgetItem( ui.chainTW ) ;
406 last->
setText( 0, DN( it->userID(0).id() ).prettyDN() );
409 ui.chainTW->expandAll();
412 void propagateKey() {
413 certificationsModel.setKey( key );
414 const QModelIndexList uidIndexes = certificationsModel.indexes( key.userIDs() );
416 ui.certificationsTV->setFirstColumnSpanned( idx.row(), idx.parent(), true );
418 subkeysModel.setKey( key );
419 ui.subkeyTV->header()->resizeSections(
QHeaderView::ResizeToContents );
422 slotDumpCertificate();
442 struct UI : public Ui_CertificateDetailsDialog {
444 : Ui_CertificateDetailsDialog()
446 setupUi( qq->mainWidget() );
447 qq->setButtons( KDialog::Help | KDialog::Close );
449 chainTW->header()->setResizeMode( 0, QHeaderView::Stretch );
451 dumpLTW->setFont( KGlobalSettings::fixedFont() );
452 dumpLTW->setMinimumVisibleLines( 15 );
453 dumpLTW->setMinimumVisibleColumns( 40 );
455 subkeyHLine->setTitle( i18nc(
"@title",
"Subkeys") );
461 :
KDialog( p, f ),
d( new Private( this ) )
474 d->updateWidgetVisibility();
477 d->enableDisableWidgets();
485 #include "moc_certificatedetailsdialog.cpp"
void setKey(const GpgME::Key &key)
CertificateDetailsDialog(QWidget *parent=0, Qt::WindowFlags f=0)
QString fromLocal8Bit(const char *str, int size)
static bool own(const std::vector< UserID::Signature > &sigs)
~CertificateDetailsDialog()
void setText(int column, const QString &text)
static boost::shared_ptr< const KeyCache > instance()
QString fromLatin1(const char *str, int size)