diff --git a/kwatchgnupg/aboutdata.cpp b/aboutdata.cpp
similarity index 57%
copy from kwatchgnupg/aboutdata.cpp
copy to aboutdata.cpp
index 68c918e9d..fb5813ec4 100644
--- a/kwatchgnupg/aboutdata.cpp
+++ b/aboutdata.cpp
@@ -1,73 +1,93 @@
/*
aboutdata.cpp
This file is part of Kleopatra, the KDE keymanager
- Copyright (c) 2004 Klar�vdalens Datakonsult AB
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
#include "aboutdata.h"
#include
-static const char kwatchgnupg_version[] = "1.0";
-static const char description[] = I18N_NOOP("GnuPG log viewer");
+static const char kleopatra_version[] = "0.40";
+static const char description[] = I18N_NOOP("KDE Key Manager");
struct about_data {
const char * name;
const char * desc;
const char * email;
const char * web;
};
static const about_data authors[] = {
- { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 },
+ { "Marc Mutz", I18N_NOOP("Current Maintainer"), "mutz@kde.org", 0 },
+ { "Steffen Hansen", I18N_NOOP("Former Maintainer"), "hansen@kde.org", 0 },
+ { "Kalle Dalheimer", I18N_NOOP("Original Author"), "kalle@kde.org", 0 },
+ { "Jesper Petersen", I18N_NOOP("Original Author"), "blackie@kde.org", 0 },
};
-#if 0
-// can't create zero size array - doesn't compile
+
static const about_data credits[] = {
- // PENDING(steffen) add stuff
+ { "David Faure",
+ I18N_NOOP("Backend configuration framework, KIO integration"),
+ "faure@kde.org", 0 },
+ { "Michel Boyer de la Giroday",
+ I18N_NOOP("Key-state dependant colors and fonts in the key list"),
+ "michel@klaralvdalens-datakonsult.se", 0 },
+ { "Daniel Molkentin",
+ I18N_NOOP("Certificate Wizard KIOSK integration, infrastructure"),
+ "molkentin@kde.org", 0 },
+ { "Ralf Nolden",
+ I18N_NOOP("Support for obsolete EMAIL RDN in Certificate Wizard"),
+ "nolden@kde.org", 0 },
+ { "Karl-Heinz Zimmer",
+ I18N_NOOP("DN display ordering support, infrastructure"),
+ "khz@kde.org", 0 },
};
-#endif
+
AboutData::AboutData()
- : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"),
- kwatchgnupg_version, description, License_GPL,
- "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" )
+ : KAboutData( "kleopatra", I18N_NOOP("Kleopatra"),
+ kleopatra_version, description, License_GPL,
+ "(c) 2002 Steffen Hansen, Jesper Pedersen,\n"
+ "Kalle Dalheimer, Klar\xC3\xA4lvdalens Datakonsult AB\n\n"
+ "(c) 2004 Marc Mutz, Klar\xC3\xA4lvdalens Datakonsult AB" )
{
using ::authors;
- //using ::credits;
+ using ::credits;
for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i )
addAuthor( authors[i].name, authors[i].desc,
authors[i].email, authors[i].web );
-#if 0
for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i )
addCredit( credits[i].name, credits[i].desc,
credits[i].email, credits[i].web );
-#endif
}
diff --git a/lib/kleo/cryptobackend.cpp b/aboutdata.h
similarity index 57%
copy from lib/kleo/cryptobackend.cpp
copy to aboutdata.h
index 6da71bc9e..29e516f5c 100644
--- a/lib/kleo/cryptobackend.cpp
+++ b/aboutdata.h
@@ -1,36 +1,43 @@
/*
- kleo/cryptobackend.cpp
+ aboutdata.h
- This file is part of libkleopatra, the KDE keymanagement library
- Copyright (c) 2005 Klarälvdalens Datakonsult AB
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
- Libkleopatra is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- Libkleopatra is distributed in the hope that it will be useful,
+ Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#include "cryptobackend.h"
+#ifndef __ABOUTDATA_H__
+#define __ABOUTDATA_H__
-const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP";
-const char Kleo::CryptoBackend::SMIME[] = "SMIME";
+#include
+
+class AboutData : public KAboutData {
+public:
+ AboutData();
+};
+
+#endif // __ABOUTDATA_H__
diff --git a/certificateinfowidgetimpl.cpp b/certificateinfowidgetimpl.cpp
index 596133819..082c035ba 100644
--- a/certificateinfowidgetimpl.cpp
+++ b/certificateinfowidgetimpl.cpp
@@ -1,221 +1,438 @@
-/* -*- Mode: C -*-
+/*
+ certificateinfowidgetimpl.cpp
- $Id$
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
- Copyright (C) 2001 by Klarälvdalens Datakonsult AB
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- GPGMEPLUG is free software; you can redistribute it and/or modify
- it under the terms of GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
- GPGMEPLUG is distributed in the hope that it will be useful,
- it under the terms of GNU General Public License as published by
- the Free Software Foundation; version 2 of the License
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
*/
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include "certificateinfowidgetimpl.h"
+
+// libkleopatra
+#include
+#include
+#include
+
+#include
+
+// gpgme++
+#include
+
+// KDE
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Qt
#include
#include
#include
#include
#include
#include
+#include
-#include
-#include
-#include
-#include
-
-#include "certificateinfowidgetimpl.h"
-#include "certmanager.h"
+// other
+#include
+#include
-CertificateInfoWidgetImpl::CertificateInfoWidgetImpl( CertManager* manager, bool external,
- QWidget* parent, const char* name )
- : CertificateInfoWidget( parent, name ), _manager(manager), _external( external )
+CertificateInfoWidgetImpl::CertificateInfoWidgetImpl( const GpgME::Key & key, bool external,
+ QWidget * parent, const char * name )
+ : CertificateInfoWidget( parent, name ),
+ mExternal( external ),
+ mFoundIssuer( true ),
+ mHaveKeyLocally( false )
{
- if( !external ) importButton->setEnabled(false);
- listView->setColumnWidthMode( 1, QListView::Manual );
- listView->setResizeMode( QListView::LastColumn );
+ importButton->setEnabled( false );
+
+ listView->setColumnWidthMode( 1, QListView::Maximum );
QFontMetrics fm = fontMetrics();
listView->setColumnWidth( 1, fm.width( i18n("Information") ) * 5 );
listView->header()->setClickEnabled( false );
listView->setSorting( -1 );
connect( listView, SIGNAL( selectionChanged( QListViewItem* ) ),
this, SLOT( slotShowInfo( QListViewItem* ) ) );
- pathView->setColumnWidthMode( 0, QListView::Manual );
- pathView->setResizeMode( QListView::LastColumn );
+ pathView->setColumnWidthMode( 0, QListView::Maximum );
pathView->header()->hide();
connect( pathView, SIGNAL( doubleClicked( QListViewItem* ) ),
this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) );
connect( pathView, SIGNAL( returnPressed( QListViewItem* ) ),
this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) );
connect( importButton, SIGNAL( clicked() ),
this, SLOT( slotImportCertificate() ) );
+
+ dumpView->setFont( KGlobalSettings::fixedFont() );
+
+ if ( !key.isNull() )
+ setKey( key );
}
-void CertificateInfoWidgetImpl::setCert( const CryptPlugWrapper::CertificateInfo& info )
-{
+static QString time_t2string( time_t t ) {
+ QDateTime dt;
+ dt.setTime_t( t );
+ return dt.toString();
+}
+
+void CertificateInfoWidgetImpl::setKey( const GpgME::Key & key ) {
+ mChain.clear();
+ mFoundIssuer = true;
+ mHaveKeyLocally = false;
+
listView->clear();
pathView->clear();
- _info = info;
+ importButton->setEnabled( false );
- /* Check if we already have the cert in question */
- if( _manager ) {
- importButton->setEnabled( !_manager->haveCertificate( info.fingerprint ) );
- } else {
- importButton->setEnabled( false );
+ if ( key.isNull() )
+ return;
+
+ mChain.push_front( key );
+ startKeyExistanceCheck(); // starts a local keylisting to enable the
+ // importButton if needed
+
+ QListViewItem * item = 0;
+ item = new QListViewItem( listView, item, i18n("Valid"), QString("From %1 to %2")
+ .arg( time_t2string( key.subkey(0).creationTime() ),
+ time_t2string( key.subkey(0).expirationTime() ) ) );
+ item = new QListViewItem( listView, item, i18n("Can be used for signing"),
+ key.canSign() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for encryption"),
+ key.canEncrypt() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for certification"),
+ key.canCertify() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for authentication"),
+ key.canAuthenticate() ? i18n("Yes") : i18n("No" ) );
+ item = new QListViewItem( listView, item, i18n("Fingerprint"), key.primaryFingerprint() );
+ item = new QListViewItem( listView, item, i18n("Issuer"), Kleo::DN( key.issuerName() ).prettyDN() );
+ item = new QListViewItem( listView, item, i18n("Serial Number"), key.issuerSerial() );
+
+ const Kleo::DN dn = key.userID(0).id();
+
+ // FIXME: use the attributeLabelMap from certificatewizardimpl.cpp:
+ static QMap dnComponentNames;
+ if ( dnComponentNames.isEmpty() ) {
+ dnComponentNames["C"] = i18n("Country");
+ dnComponentNames["OU"] = i18n("Organizational Unit");
+ dnComponentNames["O"] = i18n("Organization");
+ dnComponentNames["L"] = i18n("Location");
+ dnComponentNames["CN"] = i18n("Common Name");
+ dnComponentNames["EMAIL"] = i18n("Email");
}
- // These will show in the opposite order
- // disabled until supported
- //new QListViewItem( listView, i18n("CRL Dist. Point"), info.crl );
- new QListViewItem( listView, i18n("Fingerprint"), info.fingerprint );
- new QListViewItem( listView, i18n("Can be used for certification"),
- info.certify?i18n("Yes"):i18n("No") );
- new QListViewItem( listView, i18n("Can be used for encryption"),
- info.encrypt?i18n("Yes"):i18n("No") );
- new QListViewItem( listView, i18n("Can be used for signing"),
- info.sign?i18n("Yes"):i18n("No") );
-
- new QListViewItem( listView, i18n("Valid"), QString("From %1 to %2")
- .arg( info.created.toString() ).arg(info.expire.toString()) );
-
-
- //new QListViewItem( listView, i18n("Email"), info.dn["1.2.840.113549.1.9.1"] );
- new QListViewItem( listView, i18n("Country"), info.dn["C"] );
- new QListViewItem( listView, i18n("Organizational Unit"), info.dn["OU"] );
- new QListViewItem( listView, i18n("Organization"), info.dn["O"] );
- new QListViewItem( listView, i18n("Location"), info.dn["L"] );
- new QListViewItem( listView, i18n("Serial Number"), info.serial );
- new QListViewItem( listView, i18n("Name"), info.dn["CN"] );
- new QListViewItem( listView, i18n("Issuer"), info.issuer.stripWhiteSpace() );
-
- QStringList::ConstIterator it = info.userid.begin();
- QListViewItem* item = new QListViewItem( listView, i18n("Subject"),
- (*it).stripWhiteSpace() );
- ++it;
- while( it != info.userid.end() ) {
- if( (*it)[0] == '<' ) {
- item = new QListViewItem( listView, item, i18n("Email"), (*it).mid(1,(*it).length()-2));
- } else {
- item = new QListViewItem( listView, item, i18n("Aka"), (*it).stripWhiteSpace() );
- }
- ++it;
- }
-
- // Set up cert. path
- if( !_manager ) return;
- const CryptPlugWrapper::CertificateInfoList& lst = _manager->certList();
- QString issuer = info.issuer;
- QStringList items;
- items << info.userid[0];
- bool root_found = false;
- while( true ) {
- bool found = false;
- CryptPlugWrapper::CertificateInfo info;
- for( CryptPlugWrapper::CertificateInfoList::ConstIterator it = lst.begin();
- it != lst.end(); ++it ) {
- if( (*it).userid[0] == issuer && !items.contains( info.userid[0] ) ) {
- info = (*it);
- found = true;
- break;
- }
+
+ for ( Kleo::DN::const_iterator dnit = dn.begin() ; dnit != dn.end() ; ++dnit ) {
+ QString displayName = (*dnit).name();
+ if( dnComponentNames.contains(displayName) ) displayName = dnComponentNames[displayName];
+ item = new QListViewItem( listView, item, displayName, (*dnit).value() );
+ }
+
+ const std::vector uids = key.userIDs();
+ if ( !uids.empty() ) {
+ item = new QListViewItem( listView, item, i18n("Subject"),
+ Kleo::DN( uids.front().id() ).prettyDN() );
+ for ( std::vector::const_iterator it = uids.begin() + 1 ; it != uids.end() ; ++it ) {
+ if ( !(*it).id() )
+ continue;
+ const QString email = QString::fromUtf8( (*it).id() ).stripWhiteSpace();
+ if ( email.isEmpty() )
+ continue;
+ if ( email.startsWith( "<" ) )
+ item = new QListViewItem( listView, item, i18n("Email"),
+ email.mid( 1, email.length()-2 ) );
+ else
+ item = new QListViewItem( listView, item, i18n("A.k.a."), email );
}
- if( found ) {
- items.prepend( info.userid[0] );
- issuer = info.issuer;
- // FIXME(steffen): Use real DN comparison
- if( info.userid[0] == info.issuer ) {
- // Root item
- root_found = true;
- break;
- }
- } else break;
}
- item = 0;
- if( !root_found ) {
- if( items.count() > 0 ) items.prepend( QString::fromUtf8("Root certificate not found (%1)").arg( issuer ) );
- else items.prepend( "Root certificate not found" );
+
+ updateChainView();
+ startCertificateChainListing();
+ startCertificateDump();
+}
+
+static void showChainListError( QWidget * parent, const GpgME::Error & err, const char * subject ) {
+ assert( err );
+ const QString msg = i18n("An error occurred while fetching "
+ "the certificate %1 from the backend:
"
+ "%2
")
+ .arg( subject ? QString::fromUtf8( subject ) : QString::null,
+ QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n("Certificate Listing Failed" ) );
+}
+
+void CertificateInfoWidgetImpl::startCertificateChainListing() {
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing()" << endl;
+
+ if ( mChain.empty() ) {
+ // we need a seed...
+ kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): mChain is empty!" << endl;
+ return;
}
- for( QStringList::Iterator it = items.begin(); it != items.end(); ++it ) {
- if( item ) item = new QListViewItem( item, (*it) );
- else item = new QListViewItem( pathView, (*it) );
- item->setOpen( true );
+ const char * chainID = mChain.front().chainID();
+ if ( !chainID || !*chainID ) {
+ // cert not found:
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): empty chain ID - root not found" << endl;
+ return;
+ }
+ const char * fpr = mChain.front().primaryFingerprint();
+ if ( qstricmp( fpr, chainID ) == 0 ) {
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): chain_id equals fingerprint -> found root" << endl;
+ return;
+ }
+ if ( mChain.size() > 100 ) {
+ // safe guard against certificate loops (paranoia factor 8 out of 10)...
+ kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): maximum chain length of 100 exceeded!" << endl;
+ return;
+ }
+ if ( !mFoundIssuer ) {
+ // key listing failed. Don't end up in endless loop
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): issuer not found - giving up" << endl;
+ return;
+ }
+
+ mFoundIssuer = false;
+
+ // gpgsm / dirmngr / LDAP / whoever doesn't support looking up
+ // external keys by fingerprint. Furthermore, since we actually got
+ // a chain-id set on the key, we know that we have the issuer's cert
+ // in the local keyring, so just use local keylisting.
+ Kleo::KeyListJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotCertificateChainListingResult(const GpgME::KeyListResult&)) );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotNextKey(const GpgME::Key&)) );
+
+ kdDebug() << "Going to fetch" << endl
+ << " issuer : \"" << mChain.front().issuerName() << "\"" << endl
+ << " chain id: " << mChain.front().chainID() << endl
+ << "for" << endl
+ << " subject : \"" << mChain.front().userID(0).id() << "\"" << endl
+ << " subj.fpr: " << mChain.front().primaryFingerprint() << endl;
+
+ const GpgME::Error err = job->start( mChain.front().chainID() );
+
+ if ( err )
+ showChainListError( this, err, mChain.front().issuerName() );
+ else
+ (void)new Kleo::ProgressDialog( job, i18n("Fetching Certificate Chain"), this );
+}
+
+void CertificateInfoWidgetImpl::startCertificateDump() {
+ KProcess* proc = new KProcess( this );
+ (*proc) << "gpgsm"; // must be in the PATH
+ (*proc) << "--dump-keys";
+ (*proc) << mChain.front().primaryFingerprint();
+
+ QObject::connect( proc, SIGNAL( receivedStdout(KProcess *, char *, int) ),
+ this, SLOT( slotCollectStdout(KProcess *, char *, int) ) );
+ QObject::connect( proc, SIGNAL( receivedStderr(KProcess *, char *, int) ),
+ this, SLOT( slotCollectStderr(KProcess *, char *, int) ) );
+ QObject::connect( proc, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotDumpProcessExited(KProcess*) ) );
+
+ if ( !proc->start( KProcess::NotifyOnExit, (KProcess::Communication)(KProcess::Stdout | KProcess::Stderr) ) ) {
+ QString wmsg = i18n("Failed to execute gpgsm:\n%1").arg( i18n( "program not found" ) );
+ dumpView->setText( wmsg );
}
}
-void CertificateInfoWidgetImpl::slotShowInfo( QListViewItem* item )
+void CertificateInfoWidgetImpl::slotCollectStdout(KProcess *, char *buffer, int buflen)
{
- textView->setText( item->text(1) );
+ mDumpOutput += QCString(buffer, buflen+1); // like KProcIO does
}
-void CertificateInfoWidgetImpl::slotShowCertPathDetails( QListViewItem* item )
+void CertificateInfoWidgetImpl::slotCollectStderr(KProcess *, char *buffer, int buflen)
{
- if( !_manager ) return;
- const CryptPlugWrapper::CertificateInfoList& lst = _manager->certList();
- for( CryptPlugWrapper::CertificateInfoList::ConstIterator it = lst.begin();
- it != lst.end(); ++it ) {
- if( (*it).userid[0] == item->text(0) ) {
- KDialogBase* dialog = new KDialogBase( this, "dialog", true, i18n("Additional Information for Key"), KDialogBase::Close, KDialogBase::Close );
-
- CertificateInfoWidgetImpl* top = new CertificateInfoWidgetImpl( _manager, _manager->isRemote(), dialog );
- dialog->setMainWidget( top );
- top->setCert( *it );
- dialog->exec();
- delete dialog;
+ mDumpError += QCString(buffer, buflen+1); // like KProcIO does
+}
+
+void CertificateInfoWidgetImpl::slotDumpProcessExited(KProcess* proc) {
+ int rc = ( proc->normalExit() ) ? proc->exitStatus() : -1 ;
+
+ if ( rc == 0 ) {
+ dumpView->setText( QString::fromUtf8( mDumpOutput ) );
+ } else {
+ if ( !mDumpError.isEmpty() ) {
+ dumpView->setText( QString::fromUtf8( mDumpError ) );
+ } else
+ {
+ QString wmsg = i18n("Failed to execute gpgsm:\n%1");
+ if ( rc == -1 )
+ wmsg = wmsg.arg( i18n( "program cannot be executed" ) );
+ else
+ wmsg = wmsg.arg( strerror(rc) );
+ dumpView->setText( wmsg );
}
}
+
+ proc->deleteLater();
}
+void CertificateInfoWidgetImpl::slotNextKey( const GpgME::Key & key ) {
+ kdDebug() << "CertificateInfoWidgetImpl::slotNextKey( \""
+ << key.userID(0).id() << "\" )" << endl;
+ if ( key.isNull() )
+ return;
-static QString parseXMLInfo( const QString& info )
-{
- QString result;
- QDomDocument doc;
- if( !doc.setContent( info ) ) {
- kdDebug() << "xml parser error in CertificateInfoWidgetImpl::slotImportCertificate()" << endl;
+ mFoundIssuer = true;
+ mChain.push_front( key );
+ updateChainView();
+ // FIXME: cancel the keylisting. We're only interested in _one_ key.
+}
+
+void CertificateInfoWidgetImpl::updateChainView() {
+ pathView->clear();
+ if ( mChain.empty() )
+ return;
+ QListViewItem * item = 0;
+
+ QValueList::const_iterator it = mChain.begin();
+ // root item:
+ if ( (*it).chainID() && qstrcmp( (*it).chainID(), (*it).primaryFingerprint() ) == 0 )
+ item = new QListViewItem( pathView, Kleo::DN( (*it++).userID(0).id() ).prettyDN() );
+ else {
+ item = new QListViewItem( pathView, i18n("Issuer certificate not found ( %1)")
+ .arg( Kleo::DN( (*it).issuerName() ).prettyDN() ) );
+ item->setOpen( true ); // Qt bug: doesn't open after setEnabled( false ) :/
+ item->setEnabled( false );
}
- QDomNode importinfo = doc.documentElement().namedItem("importResult");
- result = i18n("Name | Value |
");
- for( QDomNode n = importinfo.firstChild(); !n.isNull(); n = n.nextSibling() ) {
- if( n.isElement() ) {
- QDomElement elem = n.toElement();
- if( elem.tagName() == "count" || elem.text().toInt() != 0 ) {
- result += ""+ elem.tagName() + " | "
- + elem.text().stripWhiteSpace() + " |
";
- }
- }
+ item->setOpen( true );
+
+ // subsequent items:
+ while ( it != mChain.end() ) {
+ item = new QListViewItem( item, Kleo::DN( (*it++).userID(0).id() ).prettyDN() );
+ item->setOpen( true );
}
- result += "
";
- return result;
}
+void CertificateInfoWidgetImpl::slotCertificateChainListingResult( const GpgME::KeyListResult & res ) {
+ if ( res.error() )
+ return showChainListError( this, res.error(), mChain.front().issuerName() );
+ else
+ startCertificateChainListing();
+}
+
+void CertificateInfoWidgetImpl::slotShowInfo( QListViewItem * item ) {
+ textView->setText( item->text(1) );
+}
+
+void CertificateInfoWidgetImpl::slotShowCertPathDetails( QListViewItem * item ) {
+ if ( !item )
+ return;
+
+ // find the key corresponding to "item". This hack would not be
+ // necessary if pathView was a Kleo::KeyListView, but it's
+ // Qt-Designer-generated and I don't feel like creating a custom
+ // widget spec for Kleo::KeyListView.
+ unsigned int totalCount = 0;
+ int itemIndex = -1;
+ for ( const QListViewItem * i = pathView->firstChild() ; i ; i = i->firstChild() ) {
+ if ( i == item )
+ itemIndex = totalCount;
+ ++totalCount;
+ }
+
+ assert( totalCount == mChain.size() || totalCount == mChain.size() + 1 );
+
+ // skip pseudo root item with "not found message":
+ if ( totalCount == mChain.size() + 1 )
+ --itemIndex;
+
+ assert( itemIndex >= 0 );
+
+ KDialogBase * dialog =
+ new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"),
+ KDialogBase::Close, KDialogBase::Close );
+ CertificateInfoWidgetImpl * top =
+ new CertificateInfoWidgetImpl( mChain[itemIndex], mExternal, dialog );
+ dialog->setMainWidget( top );
+ // proxy the signal to our receiver:
+ connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)),
+ SIGNAL(requestCertificateDownload(const QString&, const QString&)) );
+ dialog->show();
+}
+
+
void CertificateInfoWidgetImpl::slotImportCertificate()
{
- if( !_manager ) return;
- QApplication::setOverrideCursor( QCursor::WaitCursor );
- QString info;
- int retval = _manager->importCertificateWithFingerprint( _info.fingerprint, &info );
- info = parseXMLInfo( info );
-
- QApplication::restoreOverrideCursor();
-
- if( retval == -42 ) {
- KMessageBox::error( this, i18n("CryptPlug returned success, but no certificate was imported.
You may need to import the issuer certificate %1 first.
Additional info:
%2").arg( _info.issuer ).arg(info),
- i18n("Import Error") );
- } else if( retval ) {
- KMessageBox::error( this, i18n("Error importing certificate.
CryptPlug returned %1. Additional info:
%2").arg(retval).arg( info ), i18n("Import Error") );
- } else {
- KMessageBox::information( this, i18n("Certificate %1 with fingerprint %2 is imported to the local database.
Additional info:
%3").arg(_info.userid[0]).arg(_info.fingerprint).arg( info ), i18n("Certificate Imported") );
- importButton->setEnabled( false );
- }
+ if ( mChain.empty() || mChain.back().isNull() )
+ return;
+ const Kleo::DN dn = mChain.back().userID( 0 ).id();
+ emit requestCertificateDownload( mChain.back().primaryFingerprint(), dn.prettyDN() );
+ importButton->setEnabled( false );
}
+
+void CertificateInfoWidgetImpl::startKeyExistanceCheck() {
+ if ( !mExternal )
+ // we already have it if it's from a local keylisting :)
+ return;
+ if ( mChain.empty() || mChain.back().isNull() )
+ // need a key to look for
+ return;
+ const QString fingerprint = mChain.back().primaryFingerprint();
+ if ( fingerprint.isEmpty() )
+ // empty pattern means list all keys. We don't want that
+ return;
+
+ // start _local_ keylistjob (no progressdialog needed here):
+ Kleo::KeyListJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false );
+ assert( job );
+
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotKeyExistanceCheckNextCandidate(const GpgME::Key&)) );
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotKeyExistanceCheckFinished()) );
+ // nor to check for errors:
+ job->start( fingerprint );
+}
+
+void CertificateInfoWidgetImpl::slotKeyExistanceCheckNextCandidate( const GpgME::Key & key ) {
+ if ( key.isNull() || mChain.empty() || !key.primaryFingerprint() )
+ return;
+
+ if ( qstrcmp( key.primaryFingerprint(),
+ mChain.back().primaryFingerprint() ) == 0 )
+ mHaveKeyLocally = true;
+}
+
+void CertificateInfoWidgetImpl::slotKeyExistanceCheckFinished() {
+ importButton->setEnabled( !mHaveKeyLocally );
+}
+
+
#include "certificateinfowidgetimpl.moc"
diff --git a/certificateinfowidgetimpl.h b/certificateinfowidgetimpl.h
index 26df7fc1c..961d67c39 100644
--- a/certificateinfowidgetimpl.h
+++ b/certificateinfowidgetimpl.h
@@ -1,49 +1,87 @@
-/* -*- Mode: C -*-
+/*
+ certificateinfowidgetimpl.h
- $Id$
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2004 Klarälvdalens Datakonsult AB
- Copyright (C) 2001 by Klarälvdalens Datakonsult AB
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- GPGMEPLUG is free software; you can redistribute it and/or modify
- it under the terms of GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
- GPGMEPLUG is distributed in the hope that it will be useful,
- it under the terms of GNU General Public License as published by
- the Free Software Foundation; version 2 of the License
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
*/
#ifndef CERTIFICATEINFOWIDGETIMPL_H
#define CERTIFICATEINFOWIDGETIMPL_H
#include "certificateinfowidget.h"
-#include
+#include
+
+#include
+
+class KProcess;
class QListViewItem;
-class CertManager;
+
+namespace GpgME {
+ class KeyListResult;
+}
class CertificateInfoWidgetImpl : public CertificateInfoWidget {
Q_OBJECT
public:
- CertificateInfoWidgetImpl( CertManager* manager, bool external,
- QWidget* parent = 0, const char* name = 0);
+ CertificateInfoWidgetImpl( const GpgME::Key & key, bool external,
+ QWidget * parent=0, const char * name=0);
+
+ void setKey( const GpgME::Key & key );
- void setCert( const CryptPlugWrapper::CertificateInfo& info );
-protected slots:
+signals:
+ void requestCertificateDownload( const QString & fingerprint, const QString& displayName );
+
+private slots:
void slotShowInfo( QListViewItem* );
- void slotShowCertPathDetails( QListViewItem* );
+ void slotShowCertPathDetails( QListViewItem* );
void slotImportCertificate();
+ void slotCertificateChainListingResult( const GpgME::KeyListResult & res );
+ void slotNextKey( const GpgME::Key & key );
+ void slotKeyExistanceCheckNextCandidate( const GpgME::Key & key );
+ void slotKeyExistanceCheckFinished();
+ void slotCollectStdout(KProcess *, char *, int);
+ void slotCollectStderr(KProcess *, char *, int);
+ void slotDumpProcessExited(KProcess*);
+
+private:
+ void startCertificateChainListing();
+ void startCertificateDump();
+ void startKeyExistanceCheck();
+ void updateChainView();
+
private:
- CertManager* _manager;
- CryptPlugWrapper::CertificateInfo _info;
- bool _external;
+ QCString mDumpOutput;
+ QCString mDumpError;
+ QValueList mChain;
+ bool mExternal;
+ bool mFoundIssuer;
+ bool mHaveKeyLocally;
};
#endif // CERTIFICATEINFOWIDGETIMPL_H
diff --git a/certificatewizardimpl.cpp b/certificatewizardimpl.cpp
index 24f41276f..8c2d6a8ac 100644
--- a/certificatewizardimpl.cpp
+++ b/certificatewizardimpl.cpp
@@ -1,515 +1,515 @@
/*
certificatewizardimpl.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include "certificatewizardimpl.h"
#include "storedtransferjob.h"
// libkleopatra
#include
#include
#include
#include
#include
// gpgme++
#include
// KDE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Qt
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const unsigned int keyLengths[] = {
1024, 1532, 2048, 3072, 4096
};
static const unsigned int numKeyLengths = sizeof keyLengths / sizeof *keyLengths;
static QString attributeLabel( const QString & attr, bool required ) {
if ( attr.isEmpty() )
return QString::null;
const QString label = Kleo::DNAttributeMapper::instance()->name2label( attr );
if ( !label.isEmpty() )
if ( required )
return i18n("Format string for the labels in the \"Your Personal Data\" page - required field",
"*%1 (%2):").arg( label, attr );
else
return i18n("Format string for the labels in the \"Your Personal Data\" page",
"%1 (%2):").arg( label, attr );
else if ( required )
return '*' + attr + ':';
else
return attr + ':';
}
static QString attributeFromKey( QString key ) {
return key.remove( '!' );
}
static bool availForMod( const QLineEdit * le ) {
return le && le->isEnabled();
}
/*
* Constructs a CertificateWizardImpl which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The wizard will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal wizard.
*/
CertificateWizardImpl::CertificateWizardImpl( QWidget* parent, const char* name, bool modal, WFlags fl )
: CertificateWizard( parent, name, modal, fl )
{
// don't allow to go to last page until a key has been generated
setNextEnabled( generatePage, false );
// setNextEnabled( personalDataPage, false ); // ## disable again once we have a criteria when to enable again
createPersonalDataPage();
// Allow to select remote URLs
storeUR->setMode( KFile::File );
storeUR->setFilter( "application/pkcs10" );
connect( storeUR, SIGNAL( urlSelected( const QString& ) ),
this, SLOT( slotURLSelected( const QString& ) ) );
const KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" );
caEmailED->setText( config.readEntry( "CAEmailAddress" ) );
connect( this, SIGNAL( helpClicked() ),
this, SLOT( slotHelpClicked() ) );
connect( insertAddressButton, SIGNAL( clicked() ),
this, SLOT( slotSetValuesFromWhoAmI() ) );
for ( unsigned int i = 0 ; i < numKeyLengths ; ++i )
keyLengthCB->insertItem( i18n("%n bit", "%n bits", keyLengths[i] ) );
}
static bool requirementsAreMet( const CertificateWizardImpl::AttrPairList & list ) {
for ( CertificateWizardImpl::AttrPairList::const_iterator it = list.begin() ;
it != list.end() ; ++it ) {
const QLineEdit * le = (*it).second;
if ( !le )
continue;
const QString key = (*it).first;
#ifndef NDEBUG
kdbgstream s = kdDebug();
#else
kndbgstream s = kdDebug();
#endif
s << "requirementsAreMet(): checking \"" << key << "\" against \"" << le->text() << "\": ";
if ( key.endsWith("!") && le->text().stripWhiteSpace().isEmpty() ) {
s << "required field is empty!" << endl;
return false;
}
s << "ok" << endl;
}
return true;
}
/*
This slot is called when the user changes the text.
*/
void CertificateWizardImpl::slotEnablePersonalDataPageExit() {
setNextEnabled( personalDataPage, requirementsAreMet( _attrPairList ) );
}
/*
* Destroys the object and frees any allocated resources
*/
CertificateWizardImpl::~CertificateWizardImpl()
{
// no need to delete child widgets, Qt does it all for us
}
static const char * oidForAttributeName( const QString & attr ) {
QCString attrUtf8 = attr.utf8();
for ( unsigned int i = 0 ; i < numOidMaps ; ++i )
if ( qstricmp( attrUtf8, oidmap[i].name ) == 0 )
return oidmap[i].oid;
return 0;
}
/*
* protected slot
*/
void CertificateWizardImpl::slotGenerateCertificate()
{
// Ask gpgme to generate a key and return it
QString certParms;
certParms += "\n";
certParms += "Key-Type: RSA\n";
certParms += QString( "Key-Length: %1\n" ).arg( keyLengths[keyLengthCB->currentItem()] );
certParms += "Key-Usage: ";
if ( signOnlyCB->isChecked() )
certParms += "Sign";
else if ( encryptOnlyCB->isChecked() )
certParms += "Encrypt";
else
certParms += "Sign, Encrypt";
certParms += "\n";
certParms += "name-dn: ";
QString email;
QStringList rdns;
for( AttrPairList::const_iterator it = _attrPairList.begin(); it != _attrPairList.end(); ++it ) {
const QString attr = attributeFromKey( (*it).first.upper() );
const QLineEdit * le = (*it).second;
if ( !le )
continue;
const QString value = le->text().stripWhiteSpace();
if ( value.isEmpty() )
continue;
if ( attr == "EMAIL" ) {
// EMAIL is special, since it shouldn't be part of the DN,
// except for non-RFC-conformant CAs that require it to be
// there.
email = value;
if ( !brokenCA->isChecked() )
continue;
}
if ( const char * oid = oidForAttributeName( attr ) ) {
// we need to translate the attribute name for the backend:
rdns.push_back( QString::fromUtf8( oid ) + '=' + value );
} else {
rdns.push_back( attr + '=' + value );
}
}
certParms += rdns.join(",");
if( !email.isEmpty() )
certParms += "\nname-email: " + email;
certParms += "\n\n";
kdDebug() << certParms << endl;
Kleo::KeyGenerationJob * job =
Kleo::CryptoBackendFactory::instance()->smime()->keyGenerationJob();
assert( job );
connect( job, SIGNAL(result(const GpgME::KeyGenerationResult&,const QByteArray&)),
SLOT(slotResult(const GpgME::KeyGenerationResult&,const QByteArray&)) );
certificateTE->setText( certParms );
const GpgME::Error err = job->start( certParms );
if ( err )
KMessageBox::error( this,
i18n( "Could not start certificate generation: %1" )
.arg( QString::fromLocal8Bit( err.asString() ) ),
i18n( "Certificate Manager Error" ) );
else {
generatePB->setEnabled( false );
setBackEnabled( generatePage, false );
(void)new Kleo::ProgressDialog( job, i18n("Generating key"), this );
}
}
void CertificateWizardImpl::slotResult( const GpgME::KeyGenerationResult & res,
const QByteArray & keyData ) {
//kdDebug() << "keyData.size(): " << keyData.size() << endl;
_keyData = keyData;
if ( res.error().isCanceled() || res.error() ) {
setNextEnabled( generatePage, false );
setBackEnabled( generatePage, true );
setFinishEnabled( finishPage, false );
generatePB->setEnabled( true );
if ( !res.error().isCanceled() )
KMessageBox::error( this,
i18n( "Could not generate certificate: %1" )
.arg( QString::fromLatin1( res.error().asString() ) ),
i18n( "Certificate Manager Error" ) );
} else {
// next will stay enabled until the user clicks Generate
// Certificate again
setNextEnabled( generatePage, true );
setFinishEnabled( finishPage, true );
}
}
void CertificateWizardImpl::slotHelpClicked()
{
kapp->invokeHelp( "newcert" );
}
void CertificateWizardImpl::slotSetValuesFromWhoAmI()
{
const KABC::Addressee a = KABC::StdAddressBook::self( true )->whoAmI();
if ( a.isEmpty() )
return;
const KABC::Address adr = a.address(KABC::Address::Work);
for ( AttrPairList::const_iterator it = _attrPairList.begin() ;
it != _attrPairList.end() ; ++it ) {
QLineEdit * le = (*it).second;
if ( !availForMod( le ) )
continue;
const QString attr = attributeFromKey( (*it).first.upper() );
if ( attr == "CN" )
le->setText( a.formattedName() );
else if ( attr == "EMAIL" )
le->setText( a.preferredEmail() );
else if ( attr == "O" )
le->setText( a.organization() );
else if ( attr == "OU" )
le->setText( a.custom( "KADDRESSBOOK", "X-Department" ) );
else if ( attr == "L" )
le->setText( adr.locality() );
else if ( attr == "SP" )
le->setText( adr.region() );
else if ( attr == "PC" )
le->setText( adr.postalCode() );
else if ( attr == "SN" )
le->setText( a.familyName() );
else if ( attr == "GN" )
le->setText( a.givenName() );
else if ( attr == "T" )
le->setText( a.title() );
else if ( attr == "BC" )
le->setText( a.role() ); // correct mapping?
}
}
void CertificateWizardImpl::createPersonalDataPage()
{
QGridLayout* grid = new QGridLayout( edContainer, 2, 1,
KDialog::marginHint(), KDialog::spacingHint() );
KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" );
QStringList attrOrder = config.readListEntry( "DNAttributeOrder" );
if ( attrOrder.empty() )
attrOrder << "CN!" << "L" << "OU" << "O!" << "C!" << "EMAIL!";
int row = 0;
for ( QStringList::const_iterator it = attrOrder.begin() ; it != attrOrder.end() ; ++it, ++row ) {
const QString key = (*it).stripWhiteSpace().upper();
const QString attr = attributeFromKey( key );
if ( attr.isEmpty() ) {
--row;
continue;
}
const QString preset = config.readEntry( attr );
const QString label = config.readEntry( attr + "_label",
attributeLabel( attr, key.endsWith("!") ) );
QLineEdit * le = new QLineEdit( edContainer );
grid->addWidget( le, row, 1 );
grid->addWidget( new QLabel( le, label.isEmpty() ? attr : label, edContainer ), row, 0 );
le->setText( preset );
if ( config.entryIsImmutable( attr ) )
le->setEnabled( false );
_attrPairList.append(qMakePair(key, le));
connect( le, SIGNAL(textChanged(const QString&)),
SLOT(slotEnablePersonalDataPageExit()) );
}
// enable button only if administrator wants to allow it
if (KABC::StdAddressBook::self( true )->whoAmI().isEmpty() ||
!config.readBoolEntry("ShowSetWhoAmI", true))
insertAddressButton->setEnabled( false );
slotEnablePersonalDataPageExit();
}
bool CertificateWizardImpl::sendToCA() const {
return sendToCARB->isChecked();
}
QString CertificateWizardImpl::caEMailAddress() const {
return caEmailED->text().stripWhiteSpace();
}
void CertificateWizardImpl::slotURLSelected( const QString& _url )
{
KURL url = KURL::fromPathOrURL( _url.stripWhiteSpace() );
#if ! KDE_IS_VERSION(3,2,90)
// The application/pkcs10 mimetype didn't have a native extension,
// so the filedialog didn't have the checkbox for auto-adding it.
QString fileName = url.fileName();
int pos = fileName.findRev( '.' );
if ( pos < 0 ) // no extension
url.setFileName( fileName + ".p10" );
#endif
storeUR->setURL( url.prettyURL() );
}
KURL CertificateWizardImpl::saveFileUrl() const {
return KURL::fromPathOrURL( storeUR->url().stripWhiteSpace() );
}
void CertificateWizardImpl::showPage( QWidget * page )
{
CertificateWizard::showPage( page );
if ( page == generatePage ) {
// Initial settings for the generation page: focus the correct lineedit
// and disable the other one
if ( storeInFileRB->isChecked() ) {
storeUR->setEnabled( true );
caEmailED->setEnabled( false );
storeUR->setFocus();
} else {
storeUR->setEnabled( false );
caEmailED->setEnabled( true );
caEmailED->setFocus();
}
}
}
static const char* const dcopObjectId = "KMailIface";
/**
Send the new certificate by mail using KMail
*/
void CertificateWizardImpl::sendCertificate( const QString& email, const QByteArray& certificateData )
{
QString error;
QCString dcopService;
int result = KDCOPServiceStarter::self()->
findServiceFor( "DCOP/Mailer", QString::null,
QString::null, &error, &dcopService );
if ( result != 0 ) {
kdDebug() << "Couldn't connect to KMail\n";
KMessageBox::error( this,
i18n( "DCOP Communication Error, unable to send certificate using KMail.\n%1" ).arg( error ) );
return;
}
QCString dummy;
// OK, so kmail (or kontact) is running. Now ensure the object we want is available.
// [that's not the case when kontact was already running, but kmail not loaded into it... in theory.]
if ( !kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) ) {
DCOPRef ref( dcopService, dcopService ); // talk to the KUniqueApplication or its kontact wrapper
DCOPReply reply = ref.call( "load()" );
if ( reply.isValid() && (bool)reply ) {
Q_ASSERT( kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) );
} else
kdWarning() << "Error loading " << dcopService << endl;
}
DCOPClient* dcopClient = kapp->dcopClient();
QByteArray data;
QDataStream arg( data, IO_WriteOnly );
arg << email;
arg << certificateData;
if( !dcopClient->send( dcopService, dcopObjectId,
"sendCertificate(QString,QByteArray)", data ) ) {
KMessageBox::error( this,
i18n( "DCOP Communication Error, unable to send certificate using KMail." ) );
return;
}
// All good, close dialog
CertificateWizard::accept();
}
// Called when pressing Finish
// We want to do the emailing/uploading first, before closing the dialog,
// in case of errors during the upload.
void CertificateWizardImpl::accept()
{
if( sendToCA() ) {
// Ask KMail to send this key to the CA.
sendCertificate( caEMailAddress(), _keyData );
} else {
// Save in file/URL
KURL url = saveFileUrl();
bool overwrite = false;
if ( KIO::NetAccess::exists( url, false /*dest*/, this ) ) {
if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel(
this,
i18n( "A file named \"%1\" already exists. "
"Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
i18n( "Overwrite File?" ),
i18n( "&Overwrite" ) ) )
return;
overwrite = true;
}
KIO::Job* uploadJob = KIOext::put( _keyData, url, -1, overwrite, false /*resume*/ );
uploadJob->setWindow( this );
connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
this, SLOT( slotUploadResult( KIO::Job* ) ) );
// Can't press finish again during the upload
setFinishEnabled( finishPage, false );
}
}
/**
This slot is invoked by the KIO job used in newCertificate
to save/upload the certificate, when finished (success or error).
*/
void CertificateWizardImpl::slotUploadResult( KIO::Job* job )
{
if ( job->error() ) {
job->showErrorDialog();
setFinishEnabled( finishPage, true );
} else {
// All good, close dialog
CertificateWizard::accept();
}
}
#include "certificatewizardimpl.moc"
diff --git a/certificatewizardimpl.h b/certificatewizardimpl.h
index bbd49673d..d275cbc72 100644
--- a/certificatewizardimpl.h
+++ b/certificatewizardimpl.h
@@ -1,27 +1,88 @@
+/*
+ certificatewizardimpl.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
#ifndef CERTIFICATEWIZARDIMPL_H
#define CERTIFICATEWIZARDIMPL_H
#include "certificatewizard.h"
#include
+#include
+#include
+#include
+
+namespace GpgME {
+ class KeyGenerationResult;
+}
+namespace KIO {
+ class Job;
+}
class CertificateWizardImpl : public CertificateWizard
{
Q_OBJECT
public:
CertificateWizardImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
~CertificateWizardImpl();
- QByteArray keyData() const { return _keyData; }
+ bool sendToCA() const;
+ QString caEMailAddress() const;
+ KURL saveFileUrl() const;
-protected slots:
+ typedef QPair StringLEPair;
+ typedef QValueVector< StringLEPair > AttrPairList;
+
+public:
+ virtual void showPage( QWidget * page );
+ virtual void accept();
+
+private slots:
void slotGenerateCertificate();
- void slotEmailAddressChanged( const QString& text );
+ void slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData );
+ void slotSetValuesFromWhoAmI();
+ void slotEnablePersonalDataPageExit();
+ void slotURLSelected( const QString& );
void slotHelpClicked();
+ void slotUploadResult( KIO::Job* );
+
+private:
+ void createPersonalDataPage();
+ void sendCertificate( const QString& email, const QByteArray& certificateData );
+
private:
+ AttrPairList _attrPairList;
QByteArray _keyData;
};
#endif // CERTIFICATEWIZARDIMPL_H
diff --git a/certmanager.cpp b/certmanager.cpp
index 509c45f12..a94b47e12 100644
--- a/certmanager.cpp
+++ b/certmanager.cpp
@@ -1,1382 +1,1382 @@
/*
certmanager.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include "certmanager.h"
#include "certlistview.h"
#include "certificatewizardimpl.h"
#include "certificateinfowidgetimpl.h"
#include "crlview.h"
#include "customactions.h"
#include "hierarchyanalyser.h"
#include "storedtransferjob.h"
#include "conf/configuredialog.h"
// libkleopatra
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// GPGME++
#include
#include
#include
// KDE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Qt
#include
#include
// other
#include
#include
#include
namespace {
class KDE_EXPORT DisplayStrategy : public Kleo::KeyListView::DisplayStrategy{
public:
~DisplayStrategy() {}
virtual QFont keyFont( const GpgME::Key& key, const QFont& font ) const {
const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
return filter ? filter->font( font ) : font;
}
virtual QColor keyForeground( const GpgME::Key& key, const QColor& c ) const {
const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
if ( filter && filter->fgColor().isValid() )
return filter->fgColor();
return c;
}
virtual QColor keyBackground( const GpgME::Key& key, const QColor& c ) const {
const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
if ( filter && filter->bgColor().isValid() )
return filter->bgColor();
return c;
}
};
class KDE_EXPORT ColumnStrategy : public Kleo::KeyListView::ColumnStrategy {
public:
~ColumnStrategy() {}
QString title( int col ) const;
QString text( const GpgME::Key & key, int col ) const;
int width( int col, const QFontMetrics & fm ) const;
};
QString ColumnStrategy::title( int col ) const {
switch ( col ) {
case 0: return i18n("Subject");
case 1: return i18n("Issuer");
case 2: return i18n("Serial");
default: return QString::null;
}
}
QString ColumnStrategy::text( const GpgME::Key & key, int col ) const {
switch ( col ) {
case 0: return Kleo::DN( key.userID(0).id() ).prettyDN();
case 1: return Kleo::DN( key.issuerName() ).prettyDN();
case 2: return key.issuerSerial() ? QString::fromUtf8( key.issuerSerial() ) : QString::null ;
default: return QString::null;
}
}
int ColumnStrategy::width( int col, const QFontMetrics & fm ) const {
int factor = -1;
switch ( col ) {
case 0: factor = 6; break;
case 1: factor = 4; break;
default: return -1;
}
return fm.width( title( col ) ) * factor;
}
} // anon namespace
CertManager::CertManager( bool remote, const QString& query, const QString & import,
QWidget* parent, const char* name, WFlags f )
: KMainWindow( parent, name, f|WDestructiveClose ),
mCrlView( 0 ),
mDirmngrProc( 0 ),
mHierarchyAnalyser( 0 ),
mLineEditAction( 0 ),
mComboAction( 0 ),
mFindAction( 0 ),
mImportCertFromFileAction( 0 ),
mImportCRLFromFileAction( 0 ),
mNextFindRemote( false ),
mRemote( remote ),
mDirMngrFound( false )
{
createStatusBar();
createActions();
createGUI();
setAutoSaveSettings();
// Main Window --------------------------------------------------
mKeyListView = new CertKeyListView( new ColumnStrategy(), new DisplayStrategy(), this, "mKeyListView" );
mKeyListView->setSelectionMode( QListView::Extended );
setCentralWidget( mKeyListView );
connect( mKeyListView, SIGNAL(doubleClicked(Kleo::KeyListViewItem*,const QPoint&,int)),
SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
connect( mKeyListView, SIGNAL(returnPressed(Kleo::KeyListViewItem*)),
SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
connect( mKeyListView, SIGNAL(selectionChanged()),
SLOT(slotSelectionChanged()) );
connect( mKeyListView, SIGNAL(contextMenu(Kleo::KeyListViewItem*, const QPoint&)),
SLOT(slotContextMenu(Kleo::KeyListViewItem*, const QPoint&)) );
connect( mKeyListView, SIGNAL(dropped(const KURL::List&) ),
SLOT( slotDropped(const KURL::List&) ) );
mLineEditAction->setText(query);
if ( !mRemote || !query.isEmpty() )
slotSearch();
if ( !import.isEmpty() )
slotImportCertFromFile( KURL( import ) );
readConfig();
updateStatusBarLabels();
slotSelectionChanged(); // initial state for selection-dependent actions
}
CertManager::~CertManager() {
writeConfig();
delete mDirmngrProc; mDirmngrProc = 0;
delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
}
void CertManager::readConfig() {
KConfig config( "kleopatrarc" );
config.setGroup( "Display Options" );
slotToggleHierarchicalView( config.readBoolEntry( "hierarchicalView", false ) );
}
void CertManager::writeConfig() {
KConfig config( "kleopatrarc" );
config.setGroup( "Display Options" );
config.writeEntry( "hierarchicalView", mKeyListView->hierarchical() );
}
void CertManager::createStatusBar() {
KStatusBar * bar = statusBar();
mProgressBar = new Kleo::ProgressBar( bar, "mProgressBar" );
mProgressBar->reset();
mProgressBar->setFixedSize( QSize( 100, mProgressBar->height() * 3 / 5 ) );
bar->addWidget( mProgressBar, 0, true );
mStatusLabel = new QLabel( bar, "mStatusLabel" );
bar->addWidget( mStatusLabel, 1, false );
}
static inline void connectEnableOperationSignal( QObject * s, QObject * d ) {
QObject::connect( s, SIGNAL(enableOperations(bool)),
d, SLOT(setEnabled(bool)) );
}
void CertManager::createActions() {
KAction * action = 0;
(void)KStdAction::quit( this, SLOT(close()), actionCollection() );
action = KStdAction::redisplay( this, SLOT(slotRedisplay()), actionCollection() );
// work around the fact that the stdaction has no shortcut
KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload);
reloadShortcut.append(KKey(CTRL + Key_R));
action->setShortcut( reloadShortcut );
connectEnableOperationSignal( this, action );
action = new KAction( i18n("Stop Operation"), "stop", Key_Escape,
this, SIGNAL(stopOperations()),
actionCollection(), "view_stop_operations" );
action->setEnabled( false );
(void) new KAction( i18n("New Key Pair..."), "filenew", 0,
this, SLOT(newCertificate()),
actionCollection(), "file_new_certificate" );
connect( new KToggleAction( i18n("Hierarchical Key List"), 0,
actionCollection(), "view_hierarchical" ),
SIGNAL(toggled(bool)), SLOT(slotToggleHierarchicalView(bool)) );
action = new KAction( i18n("Expand All"), 0, CTRL+Key_Period,
this, SLOT(slotExpandAll()),
actionCollection(), "view_expandall" );
action = new KAction( i18n("Collapse All"), 0, CTRL+Key_Comma,
this, SLOT(slotCollapseAll()),
actionCollection(), "view_collapseall" );
(void) new KAction( i18n("Refresh CRLs"), 0, 0,
this, SLOT(slotRefreshKeys()),
actionCollection(), "certificates_refresh_clr" );
#ifdef NOT_IMPLEMENTED_ANYWAY
mRevokeCertificateAction = new KAction( i18n("Revoke"), 0,
this, SLOT(revokeCertificate()),
actionCollection(), "edit_revoke_certificate" );
connectEnableOperationSignal( this, mRevokeCertificateAction );
mExtendCertificateAction = new KAction( i18n("Extend"), 0,
this, SLOT(extendCertificate()),
actionCollection(), "edit_extend_certificate" );
connectEnableOperationSignal( this, mExtendCertificateAction );
#endif
mDeleteCertificateAction = new KAction( i18n("Delete"), "editdelete", Key_Delete,
this, SLOT(slotDeleteCertificate()),
actionCollection(), "edit_delete_certificate" );
connectEnableOperationSignal( this, mDeleteCertificateAction );
mValidateCertificateAction = new KAction( i18n("Validate"), "reload", SHIFT + Key_F5,
this, SLOT(slotValidate()),
actionCollection(), "certificates_validate" );
connectEnableOperationSignal( this, mValidateCertificateAction );
mImportCertFromFileAction = new KAction( i18n("Import Certificates..."), 0,
this, SLOT(slotImportCertFromFile()),
actionCollection(), "file_import_certificates" );
connectEnableOperationSignal( this, mImportCertFromFileAction );
mImportCRLFromFileAction = new KAction( i18n("Import CRLs..."), 0,
this, SLOT(importCRLFromFile()),
actionCollection(), "file_import_crls" );
connectEnableOperationSignal( this, mImportCRLFromFileAction );
mExportCertificateAction = new KAction( i18n("Export Certificates..."), "export", 0,
this, SLOT(slotExportCertificate()),
actionCollection(), "file_export_certificate" );
mExportSecretKeyAction = new KAction( i18n("Export Secret Key..."), "export", 0,
this, SLOT(slotExportSecretKey()),
actionCollection(), "file_export_secret_keys" );
connectEnableOperationSignal( this, mExportSecretKeyAction );
mViewCertDetailsAction = new KAction( i18n("Certificate Details..."), 0, 0,
this, SLOT(slotViewDetails()), actionCollection(),
"view_certificate_details" );
mDownloadCertificateAction = new KAction( i18n( "Download"), 0, 0,
this, SLOT(slotDownloadCertificate()), actionCollection(),
"download_certificate" );
const QString dirmngr = KStandardDirs::findExe( "gpgsm" );
mDirMngrFound = !dirmngr.isEmpty();
action = new KAction( i18n("Dump CRL Cache..."), 0,
this, SLOT(slotViewCRLs()),
actionCollection(), "crl_dump_crl_cache" );
action->setEnabled( mDirMngrFound ); // we also need dirmngr for this
action = new KAction( i18n("Clear CRL Cache..."), 0,
this, SLOT(slotClearCRLs()),
actionCollection(), "crl_clear_crl_cache" );
action->setEnabled( mDirMngrFound ); // we also need dirmngr for this
action = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
// disable action if no kwatchgnupg binary is around
if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) action->setEnabled(false);
(void)new LabelAction( i18n("Search:"), actionCollection(), "label_action" );
mLineEditAction = new LineEditAction( QString::null, actionCollection(), this,
SLOT(slotSearch()),
"query_lineedit_action");
QStringList lst;
lst << i18n("In Local Certificates") << i18n("In External Certificates");
mComboAction = new ComboAction( lst, actionCollection(), this, SLOT( slotToggleRemote(int) ),
"location_combo_action");
mFindAction = new KAction( i18n("Find"), "find", 0, this, SLOT(slotSearch()),
actionCollection(), "find" );
KStdAction::keyBindings( this, SLOT(slotEditKeybindings()), actionCollection() );
KStdAction::preferences( this, SLOT(slotShowConfigurationDialog()), actionCollection() );
new KAction( i18n( "Configure &GpgME Backend" ), 0, 0, this, SLOT(slotConfigureGpgME()),
actionCollection(), "configure_gpgme" );
createStandardStatusBarAction();
updateImportActions( true );
}
void CertManager::updateImportActions( bool enable ) {
mImportCRLFromFileAction->setEnabled( mDirMngrFound && enable );
mImportCertFromFileAction->setEnabled( enable );
}
void CertManager::slotEditKeybindings() {
KKeyDialog::configure( actionCollection(), true );
}
void CertManager::slotShowConfigurationDialog() {
ConfigureDialog dlg( this );
connect( &dlg, SIGNAL( configCommitted() ), SLOT( slotRepaint() ) );
dlg.exec();
}
void CertManager::slotConfigureGpgME() {
Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
if ( config ) {
Kleo::CryptoConfigDialog dlg( config );
int result = dlg.exec();
// Forget all data parsed from gpgconf, so that we show updated information
// when reopening the configuration dialog.
config->clear();
if ( result == QDialog::Accepted )
{
// Tell other apps (e.g. kmail) that the gpgconf data might have changed
kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
}
}
}
void CertManager::slotRepaint()
{
mKeyListView->repaintContents();
}
void CertManager::slotToggleRemote( int idx ) {
mNextFindRemote = idx != 0;
}
void CertManager::slotToggleHierarchicalView( bool hier ) {
mKeyListView->setHierarchical( hier );
mKeyListView->setRootIsDecorated( hier );
if ( KAction * act = action("view_expandall") )
act->setEnabled( hier );
if ( KAction * act = action("view_collapseall" ) )
act->setEnabled( hier );
if ( KToggleAction * act =
static_cast( action("view_hierarchical") ) )
act->setChecked( hier );
if ( hier && !mCurrentQuery.isEmpty() )
startRedisplay( false );
}
void CertManager::slotExpandAll() {
for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
it.current()->setOpen( true );
}
void CertManager::slotCollapseAll() {
for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
it.current()->setOpen( false );
}
void CertManager::connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText ) {
assert( mProgressBar );
if ( !job )
return;
if ( !initialText.isEmpty() )
statusBar()->message( initialText );
connect( job, SIGNAL(progress(const QString&,int,int)),
mProgressBar, SLOT(slotProgress(const QString&,int,int)) );
connect( job, SIGNAL(done()), mProgressBar, SLOT(reset()) );
connect( this, SIGNAL(stopOperations()), job, SLOT(slotCancel()) );
action("view_stop_operations")->setEnabled( true );
emit enableOperations( false );
}
void CertManager::disconnectJobFromStatusBarProgress( const GpgME::Error & err ) {
updateStatusBarLabels();
const QString msg = err.isCanceled() ? i18n("Canceled.")
: err ? i18n("Failed.")
: i18n("Done.") ;
statusBar()->message( msg, 4000 );
action("view_stop_operations")->setEnabled( false );
emit enableOperations( true );
slotSelectionChanged();
}
void CertManager::updateStatusBarLabels() {
mKeyListView->flushKeys();
int total = 0;
for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
++total;
mStatusLabel->setText( i18n( "%n Key.","%n Keys.", total ) );
}
//
//
// Key Listing:
//
//
static std::set extractKeyFingerprints( const QPtrList & items ) {
std::set result;
for ( QPtrListIterator it( items ) ; it.current() ; ++it )
if ( const char * fpr = it.current()->key().primaryFingerprint() )
result.insert( fpr );
return result;
}
static QStringList stringlistFromSet( const std::set & set ) {
// ARGH. This is madness. Shitty Qt containers don't support QStringList( patterns.begin(), patterns.end() ) :/
QStringList sl;
for ( std::set::const_iterator it = set.begin() ; it != set.end() ; ++it )
// let's make extra sure, maybe someone tries to make Qt not support std::string->QString conversion
sl.push_back( QString::fromLatin1( it->c_str() ) );
return sl;
}
void CertManager::slotRefreshKeys() {
const QStringList keys = stringlistFromSet( extractKeyFingerprints( mKeyListView->selectedItems() ) );
Kleo::RefreshKeysJob * job = Kleo::CryptoBackendFactory::instance()->smime()->refreshKeysJob();
assert( job );
connect( job, SIGNAL(result(const GpgME::Error&)),
this, SLOT(slotRefreshKeysResult(const GpgME::Error&)) );
connectJobToStatusBarProgress( job, i18n("Refreshing keys...") );
if ( const GpgME::Error err = job->start( keys ) )
slotRefreshKeysResult( err );
}
void CertManager::slotRefreshKeysResult( const GpgME::Error & err ) {
disconnectJobFromStatusBarProgress( err );
if ( err.isCanceled() )
return;
if ( err )
KMessageBox::error( this, i18n("An error occurred while trying to refresh "
"keys:\n%1").arg( QString::fromLocal8Bit( err.asString() ) ),
i18n("Refreshing Keys Failed") );
}
static void showKeyListError( QWidget * parent, const GpgME::Error & err ) {
assert( err );
const QString msg = i18n( "An error occurred while fetching "
"the certificates from the backend:
"
"%1
" )
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n( "Certificate Listing Failed" ) );
}
void CertManager::slotSearch() {
mPreviouslySelectedFingerprints.clear();
// Clear display
mKeyListView->clear();
mCurrentQuery = mLineEditAction->text();
startKeyListing( false, false, mCurrentQuery );
}
void CertManager::startRedisplay( bool validate ) {
mPreviouslySelectedFingerprints = extractKeyFingerprints( mKeyListView->selectedItems() );
if ( mPreviouslySelectedFingerprints.empty() )
startKeyListing( validate, true, mCurrentQuery );
else
startKeyListing( validate, true, mPreviouslySelectedFingerprints );
}
void CertManager::startKeyListing( bool validating, bool refresh, const std::set & patterns ) {
startKeyListing( validating, refresh, stringlistFromSet( patterns ) );
}
void CertManager::startKeyListing( bool validating, bool refresh, const QStringList & patterns ) {
mRemote = mNextFindRemote;
mLineEditAction->setEnabled( false );
mComboAction->setEnabled( false );
mFindAction->setEnabled( false );
Kleo::KeyListJob * job = 0;
if ( !validating && !refresh && mKeyListView->hierarchical() && !patterns.empty() )
job = new Kleo::HierarchicalKeyListJob( Kleo::CryptoBackendFactory::instance()->smime(),
mRemote, false, validating );
else
job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( mRemote, false, validating );
assert( job );
connect( job, SIGNAL(nextKey(const GpgME::Key&)),
mKeyListView, refresh ? SLOT(slotRefreshKey(const GpgME::Key&)) : SLOT(slotAddKey(const GpgME::Key&)) );
connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
this, SLOT(slotKeyListResult(const GpgME::KeyListResult&)) );
connectJobToStatusBarProgress( job, i18n("Fetching keys...") );
const GpgME::Error err = job->start( patterns ) ;
if ( err ) {
showKeyListError( this, err );
return;
}
mProgressBar->setProgress( 0, 0 ); // enable busy indicator
}
static void selectKeys( Kleo::KeyListView * lv, const std::set & fprs ) {
if ( !lv || fprs.empty() )
return;
for ( QListViewItemIterator it( lv ) ; it.current() ; ++it )
if ( Kleo::KeyListViewItem * item = Kleo::lvi_cast( it.current() ) ) {
const char * fpr = item->key().primaryFingerprint();
item->setSelected( fpr && fprs.find( fpr ) != fprs.end() );
}
}
void CertManager::slotKeyListResult( const GpgME::KeyListResult & res ) {
if ( res.error() )
showKeyListError( this, res.error() );
else if ( res.isTruncated() )
KMessageBox::information( this,
i18n("The query result has been truncated.\n"
"Either the local or a remote limit on "
"the maximum number of returned hits has "
"been exceeded.\n"
"You can try to increase the local limit "
"in the configuration dialog, but if one "
"of the configured servers is the limiting "
"factor, you have to refine your search.") );
mLineEditAction->setEnabled( true );
mComboAction->setEnabled( true );
mFindAction->setEnabled( true );
mLineEditAction->focusAll();
disconnectJobFromStatusBarProgress( res.error() );
selectKeys( mKeyListView, mPreviouslySelectedFingerprints );
}
void CertManager::slotContextMenu(Kleo::KeyListViewItem* item, const QPoint& point) {
if ( !item )
return;
if ( QPopupMenu * popup = static_cast(factory()->container("listview_popup",this)) )
popup->exec( point );
}
/**
This slot is invoked when the user selects "New certificate"
*/
void CertManager::newCertificate()
{
CertificateWizardImpl wizard( this );
wizard.exec();
}
/**
This slot is invoked when the user selects revoke certificate.
The slot will revoke the selected certificates
*/
void CertManager::revokeCertificate()
{
qDebug("Not Yet Implemented");
}
/**
This slot is invoked when the user selects extend certificate.
It will send an extension request for the selected certificates
*/
void CertManager::extendCertificate()
{
qDebug("Not Yet Implemented");
}
//
//
// Downloading / Importing Certificates
//
//
/**
This slot is invoked when the user selects Certificates/Import/From File.
*/
void CertManager::slotImportCertFromFile()
{
const QString filter = "application/x-x509-ca-cert application/x-pkcs12 application/pkcs7-mime";
//const QString filter = QString("*.pem *.der *.p7c *.p12|") + i18n("Certificates (*.pem *.der *.p7c *.p12)");
slotImportCertFromFile( KFileDialog::getOpenURL( QString::null, filter, this,
i18n( "Select Certificate File" ) ) );
}
void CertManager::slotImportCertFromFile( const KURL & certURL )
{
if ( !certURL.isValid() ) // empty or malformed
return;
mPreviouslySelectedFingerprints.clear();
// Prevent two simultaneous imports
updateImportActions( false );
// Download the cert
KIOext::StoredTransferJob* importJob = KIOext::storedGet( certURL );
importJob->setWindow( this );
connect( importJob, SIGNAL(result(KIO::Job*)), SLOT(slotImportResult(KIO::Job*)) );
}
void CertManager::slotImportResult( KIO::Job* job )
{
if ( job->error() ) {
job->showErrorDialog();
} else {
KIOext::StoredTransferJob* trJob = static_cast( job );
startCertificateImport( trJob->data(), trJob->url().fileName() );
}
updateImportActions( true );
}
static void showCertificateDownloadError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) {
assert( err );
const QString msg = i18n( "An error occurred while trying "
"to download the certificate %1:
"
"%2
" )
.arg( certDisplayName )
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n( "Certificate Download Failed" ) );
}
void CertManager::slotDownloadCertificate() {
mPreviouslySelectedFingerprints.clear();
QPtrList items = mKeyListView->selectedItems();
for ( QPtrListIterator it( items ) ; it.current() ; ++it )
if ( !it.current()->key().isNull() )
if ( const char * fpr = it.current()->key().primaryFingerprint() )
slotStartCertificateDownload( fpr, it.current()->text(0) );
}
// Called from slotDownloadCertificate and from the certificate-details widget
void CertManager::slotStartCertificateDownload( const QString& fingerprint, const QString& displayName ) {
if ( fingerprint.isEmpty() )
return;
Kleo::DownloadJob * job =
Kleo::CryptoBackendFactory::instance()->smime()->downloadJob( false /* no armor */ );
assert( job );
connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
SLOT(slotCertificateDownloadResult(const GpgME::Error&,const QByteArray&)) );
connectJobToStatusBarProgress( job, i18n("Fetching certificate from server...") );
const GpgME::Error err = job->start( fingerprint );
if ( err )
showCertificateDownloadError( this, err, displayName );
else {
mProgressBar->setProgress( 0, 0 );
mJobsDisplayNameMap.insert( job, displayName );
}
}
QString CertManager::displayNameForJob( const Kleo::Job *job )
{
JobsDisplayNameMap::iterator it = mJobsDisplayNameMap.find( job );
QString displayName;
if ( it != mJobsDisplayNameMap.end() ) {
displayName = *it;
mJobsDisplayNameMap.remove( it );
} else {
kdWarning() << "Job not found in map: " << job << endl;
}
return displayName;
}
// Don't call directly!
void CertManager::slotCertificateDownloadResult( const GpgME::Error & err, const QByteArray & keyData ) {
QString displayName = displayNameForJob( static_cast( sender() ) );
if ( err )
showCertificateDownloadError( this, err, displayName );
else
startCertificateImport( keyData, displayName );
disconnectJobFromStatusBarProgress( err );
}
static void showCertificateImportError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) {
assert( err );
const QString msg = i18n( "An error occurred while trying "
"to import the certificate %1:
"
"%2
" )
.arg( certDisplayName )
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n( "Certificate Import Failed" ) );
}
void CertManager::startCertificateImport( const QByteArray & keyData, const QString& certDisplayName ) {
Kleo::ImportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->importJob();
assert( job );
connect( job, SIGNAL(result(const GpgME::ImportResult&)),
SLOT(slotCertificateImportResult(const GpgME::ImportResult&)) );
connectJobToStatusBarProgress( job, i18n("Importing certificates...") );
kdDebug() << "Importing certificate. keyData size:" << keyData.size() << endl;
const GpgME::Error err = job->start( keyData );
if ( err )
showCertificateImportError( this, err, certDisplayName );
else {
mProgressBar->setProgress( 0, 0 );
mJobsDisplayNameMap.insert( job, certDisplayName );
}
}
void CertManager::slotCertificateImportResult( const GpgME::ImportResult & res ) {
QString displayName = displayNameForJob( static_cast( sender() ) );
if ( res.error().isCanceled() ) {
// do nothing
} else if ( res.error() ) {
showCertificateImportError( this, res.error(), displayName );
} else {
const QString normalLine = i18n("%1 | %2 |
");
const QString boldLine = i18n("%1 | %2 |
");
QStringList lines;
lines.push_back( normalLine.arg( i18n("Total number processed:"),
QString::number( res.numConsidered() ) ) );
lines.push_back( normalLine.arg( i18n("Imported:"),
QString::number( res.numImported() ) ) );
if ( res.newSignatures() )
lines.push_back( normalLine.arg( i18n("New signatures:"),
QString::number( res.newSignatures() ) ) );
if ( res.newUserIDs() )
lines.push_back( normalLine.arg( i18n("New user IDs:"),
QString::number( res.newUserIDs() ) ) );
if ( res.numKeysWithoutUserID() )
lines.push_back( normalLine.arg( i18n("Keys without user IDs:"),
QString::number( res.numKeysWithoutUserID() ) ) );
if ( res.newSubkeys() )
lines.push_back( normalLine.arg( i18n("New subkeys:"),
QString::number( res.newSubkeys() ) ) );
if ( res.newRevocations() )
lines.push_back( boldLine.arg( i18n("Newly revoked:"),
QString::number( res.newRevocations() ) ) );
if ( res.notImported() )
lines.push_back( boldLine.arg( i18n("Not imported:"),
QString::number( res.notImported() ) ) );
if ( res.numUnchanged() )
lines.push_back( normalLine.arg( i18n("Unchanged:"),
QString::number( res.numUnchanged() ) ) );
if ( res.numSecretKeysConsidered() )
lines.push_back( normalLine.arg( i18n("Secret keys processed:"),
QString::number( res.numSecretKeysConsidered() ) ) );
if ( res.numSecretKeysImported() )
lines.push_back( normalLine.arg( i18n("Secret keys imported:"),
QString::number( res.numSecretKeysImported() ) ) );
if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
lines.push_back( boldLine.arg( i18n("Secret keys not imported:"),
QString::number( res.numSecretKeysConsidered()
- res.numSecretKeysImported()
- res.numSecretKeysUnchanged() ) ) );
if ( res.numSecretKeysUnchanged() )
lines.push_back( normalLine.arg( i18n("Secret keys unchanged:"),
QString::number( res.numSecretKeysUnchanged() ) ) );
KMessageBox::information( this,
i18n( "Detailed results of importing %1:
"
"" )
.arg( displayName ).arg( lines.join( QString::null ) ),
i18n( "Certificate Import Result" ) );
disconnectJobFromStatusBarProgress( res.error() );
// save the fingerprints of imported certs for later selection:
const std::vector imports = res.imports();
for ( std::vector::const_iterator it = imports.begin() ; it != imports.end() ; ++it )
mPreviouslySelectedFingerprints.insert( it->fingerprint() );
}
importNextURLOrRedisplay();
}
/**
This slot is called when the dirmngr process that imports a
certificate file exists.
*/
void CertManager::slotDirmngrExited() {
if ( !mDirmngrProc->normalExit() )
KMessageBox::error( this, i18n( "The GpgSM process that tried to import the CRL file ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
else if ( mDirmngrProc->exitStatus() )
KMessageBox::error( this, i18n( "An error occurred when trying to import the CRL file. The output from GpgSM was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) );
else
KMessageBox::information( this, i18n( "CRL file imported successfully." ), i18n( "Certificate Manager Information" ) );
delete mDirmngrProc; mDirmngrProc = 0;
if ( !mImportCRLTempFile.isEmpty() )
QFile::remove( mImportCRLTempFile );
updateImportActions( true );
}
/**
This slot will import CRLs from a file.
*/
void CertManager::importCRLFromFile() {
QString filter = QString("*.crl *.arl *-crl.der *-arl.der|") + i18n("Certificate Revocation List (*.crl *.arl *-crl.der *-arl.der)");
KURL url = KFileDialog::getOpenURL( QString::null,
filter,
this,
i18n( "Select CRL File" ) );
if ( url.isValid() ) {
updateImportActions( false );
if ( url.isLocalFile() ) {
startImportCRL( url.path(), false );
updateImportActions( true );
} else {
KTempFile tempFile;
KURL destURL;
destURL.setPath( tempFile.name() );
KIO::Job* copyJob = KIO::file_copy( url, destURL, 0600, true, false );
copyJob->setWindow( this );
connect( copyJob, SIGNAL( result( KIO::Job * ) ),
SLOT( slotImportCRLJobFinished( KIO::Job * ) ) );
}
}
}
void CertManager::slotImportCRLJobFinished( KIO::Job *job )
{
KIO::FileCopyJob* fcjob = static_cast( job );
QString tempFilePath = fcjob->destURL().path();
if ( job->error() ) {
job->showErrorDialog();
QFile::remove( tempFilePath ); // unlink tempfile
updateImportActions( true );
return;
}
startImportCRL( tempFilePath, true );
}
bool CertManager::connectAndStartDirmngr( const char * slot, const char * processname ) {
assert( slot );
assert( processname );
assert( mDirmngrProc );
mErrorbuffer = QString::null;
connect( mDirmngrProc, SIGNAL(processExited(KProcess*)), slot );
connect( mDirmngrProc, SIGNAL(receivedStderr(KProcess*,char*,int) ),
this, SLOT(slotStderr(KProcess*,char*,int)) );
if( !mDirmngrProc->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) {
delete mDirmngrProc; mDirmngrProc = 0;
KMessageBox::error( this, i18n( "Unable to start %1 process. Please check your installation." ).arg( processname ), i18n( "Certificate Manager Error" ) );
return false;
}
return true;
}
void CertManager::startImportCRL( const QString& filename, bool isTempFile )
{
assert( !mDirmngrProc );
mImportCRLTempFile = isTempFile ? filename : QString::null;
mDirmngrProc = new KProcess();
*mDirmngrProc << "gpgsm" << "--call-dirmngr" << "loadcrl" << filename;
if ( !connectAndStartDirmngr( SLOT(slotDirmngrExited()), "gpgsm" ) ) {
updateImportActions( true );
if ( isTempFile )
QFile::remove( mImportCRLTempFile ); // unlink tempfile
}
}
void CertManager::startClearCRLs() {
assert( !mDirmngrProc );
mDirmngrProc = new KProcess();
*mDirmngrProc << "dirmngr" << "--flush";
//*mDirmngrProc << "gpgsm" << "--call-dimngr" << "flush"; // use this once it's implemented!
connectAndStartDirmngr( SLOT(slotClearCRLsResult()), "dirmngr" );
}
void CertManager::slotStderr( KProcess*, char* buf, int len ) {
mErrorbuffer += QString::fromLocal8Bit( buf, len );
}
/**
This slot will import CRLs from an LDAP server.
*/
void CertManager::importCRLFromLDAP()
{
qDebug("Not Yet Implemented");
}
void CertManager::slotViewCRLs() {
if ( !mCrlView )
mCrlView = new CRLView( this );
mCrlView->show();
mCrlView->slotUpdateView();
}
void CertManager::slotClearCRLs() {
startClearCRLs();
}
void CertManager::slotClearCRLsResult() {
assert( mDirmngrProc );
if ( !mDirmngrProc->normalExit() )
KMessageBox::error( this, i18n( "The DirMngr process that tried to clear the CRL cache ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
else if ( mDirmngrProc->exitStatus() )
KMessageBox::error( this, i18n( "An error occurred when trying to clear the CRL cache. The output from DirMngr was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) );
else
KMessageBox::information( this, i18n( "CRL cache cleared successfully." ), i18n( "Certificate Manager Information" ) );
delete mDirmngrProc; mDirmngrProc = 0;
}
static void showDeleteError( QWidget * parent, const GpgME::Error & err ) {
assert( err );
const QString msg = i18n("An error occurred while trying to delete "
"the certificates:
"
"%1
")
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n("Certificate Deletion Failed") );
}
static bool ByFingerprint( const GpgME::Key & left, const GpgME::Key & right ) {
return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) < 0 ;
}
static bool WithRespectToFingerprints( const GpgME::Key & left, const GpgME::Key & right ) {
return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) == 0;
}
void CertManager::slotDeleteCertificate() {
mItemsToDelete = mKeyListView->selectedItems();
if ( mItemsToDelete.isEmpty() )
return;
std::vector keys;
keys.reserve( mItemsToDelete.count() );
QStringList keyDisplayNames;
for ( QPtrListIterator it( mItemsToDelete ) ; it.current() ; ++it )
if ( !it.current()->key().isNull() ) {
keys.push_back( it.current()->key() );
keyDisplayNames.push_back( it.current()->text( 0 ) );
}
if ( keys.empty() )
return;
if ( !mHierarchyAnalyser ) {
mHierarchyAnalyser = new HierarchyAnalyser( this, "mHierarchyAnalyser" );
Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob();
assert( job );
connect( job, SIGNAL(nextKey(const GpgME::Key&)),
mHierarchyAnalyser, SLOT(slotNextKey(const GpgME::Key&)) );
connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
this, SLOT(slotDeleteCertificate()) );
connectJobToStatusBarProgress( job, i18n("Checking key dependencies...") );
if ( const GpgME::Error error = job->start( QStringList() ) ) {
showKeyListError( this, error );
delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
}
return;
} else
disconnectJobFromStatusBarProgress( 0 );
std::vector keysToDelete = keys;
for ( std::vector::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
if ( !it->isNull() ) {
const std::vector subjects
= mHierarchyAnalyser->subjectsForIssuerRecursive( it->primaryFingerprint() );
keysToDelete.insert( keysToDelete.end(), subjects.begin(), subjects.end() );
}
std::sort( keysToDelete.begin(), keysToDelete.end(), ByFingerprint );
keysToDelete.erase( std::unique( keysToDelete.begin(), keysToDelete.end(),
WithRespectToFingerprints ),
keysToDelete.end() );
delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
if ( keysToDelete.size() > keys.size() )
if ( KMessageBox::warningContinueCancel( this,
i18n("Some or all of the selected "
"certificates are issuers (CA certificates) "
"for other, non-selected certificates.\n"
"Deleting a CA certificate will also delete "
"all certificates issued by it."),
i18n("Deleting CA Certificates") )
!= KMessageBox::Continue )
return;
const QString msg = keysToDelete.size() > keys.size()
? i18n("Do you really want to delete this certificate and the %1 certificates it certified?",
"Do you really want to delete these %n certificates and the %1 certificates they certified?",
keys.size() ).arg( keysToDelete.size() - keys.size() )
: i18n("Do you really want to delete this certificate?",
"Do you really want to delete these %n certificates?", keys.size() ) ;
if ( KMessageBox::warningContinueCancelList( this, msg, keyDisplayNames,
i18n( "Delete Certificates" ),
KGuiItem( i18n( "Delete" ), "editdelete" ),
"ConfirmDeleteCert", KMessageBox::Dangerous )
!= KMessageBox::Continue )
return;
if ( Kleo::DeleteJob * job = Kleo::CryptoBackendFactory::instance()->smime()->deleteJob() )
job->slotCancel();
else {
QString str = keys.size() == 1
? i18n("An error occurred while trying to delete "
"the certificate:
"
"%1
" )
: i18n( "An error occurred while trying to delete "
"the certificates:
"
"%1
" );
KMessageBox::error( this,
str.arg( i18n("Operation not supported by the backend.") ),
i18n("Certificate Deletion Failed") );
}
mItemsToDelete.clear(); // re-create according to the real selection
for ( std::vector::const_iterator it = keysToDelete.begin() ; it != keysToDelete.end() ; ++it )
if ( Kleo::KeyListViewItem * item = mKeyListView->itemByFingerprint( it->primaryFingerprint() ) )
mItemsToDelete.append( item );
Kleo::MultiDeleteJob * job = new Kleo::MultiDeleteJob( Kleo::CryptoBackendFactory::instance()->smime() );
assert( job );
connect( job, SIGNAL(result(const GpgME::Error&,const GpgME::Key&)),
SLOT(slotDeleteResult(const GpgME::Error&,const GpgME::Key&)) );
connectJobToStatusBarProgress( job, i18n("Deleting keys...") );
const GpgME::Error err = job->start( keys, true );
if ( err )
showDeleteError( this, err );
else
mProgressBar->setProgress( 0, 0 );
}
void CertManager::slotDeleteResult( const GpgME::Error & err, const GpgME::Key & ) {
if ( err )
showDeleteError( this, err );
else {
const int infinity = 100; // infinite loop guard...
mItemsToDelete.setAutoDelete( true );
for ( int i = 0 ; i < infinity ; ++i ) {
QPtrListIterator it( mItemsToDelete );
while ( Kleo::KeyListViewItem * cur = it.current() ) {
++it;
if ( cur->childCount() == 0 ) {
mItemsToDelete.remove( cur );
}
}
if ( mItemsToDelete.isEmpty() )
break;
}
mItemsToDelete.setAutoDelete( false );
Q_ASSERT( mItemsToDelete.isEmpty() );
mItemsToDelete.clear();
}
disconnectJobFromStatusBarProgress( err );
}
void CertManager::slotViewDetails( Kleo::KeyListViewItem * item ) {
if ( !item || item->key().isNull() )
return;
//
KDialogBase * dialog = new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"), KDialogBase::Close, KDialogBase::Close );
CertificateInfoWidgetImpl * top = new CertificateInfoWidgetImpl( item->key(), isRemote(), dialog );
dialog->setMainWidget( top );
//
connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)),
SLOT(slotStartCertificateDownload(const QString&, const QString&)) );
dialog->show();
}
void CertManager::slotViewDetails()
{
QPtrList items = mKeyListView->selectedItems();
if ( items.isEmpty() )
return;
// selectedItem() doesn't work in Extended mode.
// But we only want to show the details of one item...
slotViewDetails( items.first() );
}
void CertManager::slotSelectionChanged()
{
mKeyListView->flushKeys();
bool b = mKeyListView->hasSelection();
mExportCertificateAction->setEnabled( b );
mViewCertDetailsAction->setEnabled( b );
mDeleteCertificateAction->setEnabled( b );
#ifdef NOT_IMPLEMENTED_ANYWAY
mRevokeCertificateAction->setEnabled( b );
mExtendCertificateAction->setEnabled( b );
#endif
mDownloadCertificateAction->setEnabled( b && mRemote );
mValidateCertificateAction->setEnabled( !mRemote );
}
void CertManager::slotExportCertificate() {
QPtrList items = mKeyListView->selectedItems();
if ( items.isEmpty() )
return;
QStringList fingerprints;
for ( QPtrListIterator it( items ) ; it.current() ; ++it )
if ( !it.current()->key().isNull() )
if ( const char * fpr = it.current()->key().primaryFingerprint() )
fingerprints.push_back( fpr );
startCertificateExport( fingerprints );
}
static void showCertificateExportError( QWidget * parent, const GpgME::Error & err ) {
assert( err );
const QString msg = i18n("An error occurred while trying to export "
"the certificate:
"
"%1
")
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n("Certificate Export Failed") );
}
void CertManager::startCertificateExport( const QStringList & fingerprints ) {
if ( fingerprints.empty() )
return;
// we need to use PEM (ascii armoured) format, since DER (binary)
// can't transport more than one certificate *sigh* this is madness :/
Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->publicKeyExportJob( true );
assert( job );
connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
SLOT(slotCertificateExportResult(const GpgME::Error&,const QByteArray&)) );
connectJobToStatusBarProgress( job, i18n("Exporting certificate...") );
const GpgME::Error err = job->start( fingerprints );
if ( err )
showCertificateExportError( this, err );
else
mProgressBar->setProgress( 0, 0 );
}
// return true if we should proceed, false if we should abort
static bool checkOverwrite( const KURL& url, bool& overwrite, QWidget* w )
{
if ( KIO::NetAccess::exists( url, false /*dest*/, w ) ) {
if ( KMessageBox::Cancel ==
KMessageBox::warningContinueCancel(
w,
i18n( "A file named \"%1\" already exists. "
"Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
i18n( "Overwrite File?" ),
i18n( "&Overwrite" ) ) )
return false;
overwrite = true;
}
return true;
}
void CertManager::slotCertificateExportResult( const GpgME::Error & err, const QByteArray & data ) {
disconnectJobFromStatusBarProgress( err );
if ( err ) {
showCertificateExportError( this, err );
return;
}
kdDebug() << "CertManager::slotCertificateExportResult(): got " << data.size() << " bytes" << endl;
const QString filter = QString("*.pem|") + i18n("ASCII Armored Certificate Bundles (*.pem)");
const KURL url = KFileDialog::getOpenURL( QString::null,
filter,
this,
i18n( "Save Certificate" ) );
if ( !url.isValid() )
return;
bool overwrite = false;
if ( !checkOverwrite( url, overwrite, this ) )
return;
KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ );
uploadJob->setWindow( this );
connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
this, SLOT( slotUploadResult( KIO::Job* ) ) );
}
void CertManager::slotExportSecretKey() {
Kleo::KeySelectionDialog dlg( i18n("Secret Key Export"),
i18n("Select the secret key to export "
"(Warning: The PKCS#12 format is insecure; "
"exporting secret keys is discouraged):"),
std::vector(),
Kleo::KeySelectionDialog::SecretKeys|Kleo::KeySelectionDialog::SMIMEKeys,
false /* no multiple selection */,
false /* no remember choice box */,
this, "secret key export key selection dialog" );
//dlg.setHideInvalidKeys( false );
if ( dlg.exec() != QDialog::Accepted )
return;
startSecretKeyExport( dlg.fingerprint() );
}
static void showSecretKeyExportError( QWidget * parent, const GpgME::Error & err ) {
assert( err );
const QString msg = i18n("An error occurred while trying to export "
"the secret key:
"
"%1
")
.arg( QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( parent, msg, i18n("Secret-Key Export Failed") );
}
void CertManager::startSecretKeyExport( const QString & fingerprint ) {
if ( fingerprint.isEmpty() )
return;
// PENDING(marc): let user choose between binary and PEM format?
Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->secretKeyExportJob( false );
assert( job );
connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
SLOT(slotSecretKeyExportResult(const GpgME::Error&,const QByteArray&)) );
connectJobToStatusBarProgress( job, i18n("Exporting secret key...") );
const GpgME::Error err = job->start( fingerprint );
if ( err )
showSecretKeyExportError( this, err );
else
mProgressBar->setProgress( 0, 0 );
}
void CertManager::slotSecretKeyExportResult( const GpgME::Error & err, const QByteArray & data ) {
disconnectJobFromStatusBarProgress( err );
if ( err ) {
showSecretKeyExportError( this, err );
return;
}
kdDebug() << "CertManager::slotSecretKeyExportResult(): got " << data.size() << " bytes" << endl;
QString filter = QString("*.p12|") + i18n("PKCS#12 Key Bundle (*.p12)");
KURL url = KFileDialog::getOpenURL( QString::null,
filter,
this,
i18n( "Save Certificate" ) );
if ( !url.isValid() )
return;
bool overwrite = false;
if ( !checkOverwrite( url, overwrite, this ) )
return;
KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ );
uploadJob->setWindow( this );
connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
this, SLOT( slotUploadResult( KIO::Job* ) ) );
}
void CertManager::slotUploadResult( KIO::Job* job )
{
if ( job->error() )
job->showErrorDialog();
}
void CertManager::slotDropped(const KURL::List& lst)
{
mURLsToImport = lst;
if ( !lst.empty() )
importNextURLOrRedisplay();
}
void CertManager::importNextURLOrRedisplay()
{
if ( !mURLsToImport.empty() ) {
// We can only import them one by one, otherwise the jobs would run into each other
KURL url = mURLsToImport.front();
mURLsToImport.pop_front();
slotImportCertFromFile( url );
} else {
if ( isRemote() )
return;
startKeyListing( false, true, mPreviouslySelectedFingerprints );
}
}
void CertManager::slotStartWatchGnuPG()
{
KProcess certManagerProc;
certManagerProc << "kwatchgnupg";
if( !certManagerProc.start( KProcess::DontCare ) )
KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg). "
"Please check your installation!" ),
i18n( "Kleopatra Error" ) );
}
#include "certmanager.moc"
diff --git a/certmanager.h b/certmanager.h
index d9d4b8199..50e87712f 100644
--- a/certmanager.h
+++ b/certmanager.h
@@ -1,216 +1,216 @@
/* -*- mode: c++; c-basic-offset:4 -*-
certmanager.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef _CERTMANAGER_H_
#define _CERTMANAGER_H_
//#include
#include
#include
#include
#include
#include
#include
#include
namespace Kleo {
class KeyListView;
class KeyListViewItem;
class ProgressBar;
class Job;
}
namespace KIO {
class Job;
}
class KProcess;
class KToolBar;
class KAction;
class CRLView;
class HierarchyAnalyser;
class LineEditAction;
class ComboAction;
class KURL;
class QFile;
class QStringList;
class QLabel;
namespace GpgME {
class ImportResult;
class KeyListResult;
class Error;
class Key;
}
class KDE_EXPORT CertManager : public KMainWindow {
Q_OBJECT
public:
CertManager( bool remote = false, const QString& query = QString::null,
const QString& import=QString::null,
QWidget * parent=0, const char * name=0, WFlags f=0 );
~CertManager();
bool isRemote() const { return mRemote; }
signals:
void stopOperations();
void enableOperations( bool );
private slots:
void slotStartCertificateDownload( const QString & fingerprint, const QString& displayName );
void newCertificate();
void revokeCertificate();
void extendCertificate();
void slotDeleteCertificate();
void slotExportSecretKey();
void slotExportCertificate();
void slotUploadResult( KIO::Job* job );
void slotImportCertFromFile();
void slotImportCertFromFile( const KURL & filename );
void slotImportResult( KIO::Job* );
void slotCertificateImportResult( const GpgME::ImportResult & result );
void slotCertificateDownloadResult( const GpgME::Error & error, const QByteArray & keyData );
void slotKeyListResult( const GpgME::KeyListResult & result );
void slotDeleteResult( const GpgME::Error & error, const GpgME::Key & );
void slotSecretKeyExportResult( const GpgME::Error & error, const QByteArray & keyData );
void slotCertificateExportResult( const GpgME::Error & error, const QByteArray & keyData );
void slotClearCRLsResult();
void importCRLFromFile();
void importCRLFromLDAP();
void slotImportCRLJobFinished( KIO::Job * );
void slotDirmngrExited();
void slotStderr( KProcess*, char*, int );
void slotToggleRemote(int idx);
void slotToggleHierarchicalView( bool );
void slotViewCRLs();
void slotClearCRLs();
void slotViewDetails();
void slotViewDetails( Kleo::KeyListViewItem * item );
void slotSelectionChanged();
void slotDownloadCertificate();
void slotStartWatchGnuPG();
void slotEditKeybindings();
void slotShowConfigurationDialog();
void slotConfigureGpgME();
void slotContextMenu(Kleo::KeyListViewItem*, const QPoint& point);
void slotDropped(const KURL::List&);
/** Schedule a repaint for the listview items. E.g. when the
colour config has changed */
void slotRepaint();
/** Schedule a validating keylisting for the selected items (or
all items, if none is selected). */
void slotValidate() { startRedisplay( true ); }
/** Schedule a non-validating keylisting for the selected items
(or all items, if none are selected). */
void slotRedisplay() { startRedisplay( false ); }
/** Start a keylisting with the current value of the query text as
pattern. */
void slotSearch();
void slotExpandAll();
void slotCollapseAll();
void slotRefreshKeys();
void slotRefreshKeysResult( const GpgME::Error & );
private:
void createStatusBar();
void createActions();
void updateStatusBarLabels();
void updateImportActions( bool enable );
void startKeyListing( bool, bool, const QStringList & );
void startKeyListing( bool, bool, const std::set & );
void startCertificateImport( const QByteArray & keyData, const QString& certDisplayName );
void startImportCRL( const QString& fileName, bool isTempFile );
void startClearCRLs();
void startSecretKeyExport( const QString & fingerprint );
void startCertificateExport( const QStringList & fingerprints );
bool connectAndStartDirmngr( const char*, const char* );
void connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText );
void disconnectJobFromStatusBarProgress( const GpgME::Error & err );
void importNextURLOrRedisplay();
void startRedisplay( bool validating );
QString displayNameForJob( const Kleo::Job *job );
void readConfig();
void writeConfig();
private:
Kleo::KeyListView * mKeyListView;
CRLView * mCrlView;
Kleo::ProgressBar * mProgressBar;
QLabel * mStatusLabel;
KProcess * mDirmngrProc;
QString mErrorbuffer;
QPtrList mItemsToDelete;
KURL::List mURLsToImport;
typedef QMap JobsDisplayNameMap;
JobsDisplayNameMap mJobsDisplayNameMap;
HierarchyAnalyser * mHierarchyAnalyser;
LineEditAction * mLineEditAction;
ComboAction * mComboAction;
KAction * mFindAction;
KAction * mImportCertFromFileAction;
KAction * mImportCRLFromFileAction;
KAction * mExportCertificateAction;
KAction * mViewCertDetailsAction;
KAction * mDeleteCertificateAction;
#ifdef NOT_IMPLEMENTED_ANYWAY
KAction * mRevokeCertificateAction;
KAction * mExtendCertificateAction;
#endif
KAction * mExportSecretKeyAction;
KAction * mDownloadCertificateAction;
KAction * mValidateCertificateAction;
QString mImportCRLTempFile;
QString mCurrentQuery;
std::set mPreviouslySelectedFingerprints;
bool mNextFindRemote : 1; // state of the combo, i.e. whether the next find action will be remote
bool mRemote : 1; // whether the currently displayed items are from a remote listing
bool mDirMngrFound : 1;
};
#endif // _CERTMANAGER_H_
diff --git a/conf/appearanceconfigpage.cpp b/conf/appearanceconfigpage.cpp
new file mode 100644
index 000000000..5d2a434cc
--- /dev/null
+++ b/conf/appearanceconfigpage.cpp
@@ -0,0 +1,87 @@
+/*
+ appearanceconfigpage.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "appearanceconfigpage.h"
+#include
+#include "appearanceconfigwidget.h"
+#include
+#include
+#include
+
+#include
+
+AppearanceConfigurationPage::AppearanceConfigurationPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ QVBoxLayout* lay = new QVBoxLayout( this );
+ mWidget = new Kleo::AppearanceConfigWidget( this );
+ lay->addWidget( mWidget );
+ connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+
+void AppearanceConfigurationPage::load()
+{
+ mWidget->load();
+}
+
+void AppearanceConfigurationPage::save()
+{
+ mWidget->save();
+
+}
+
+void AppearanceConfigurationPage::defaults()
+{
+ mWidget->defaults();
+}
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kleopatra_config_appear( QWidget *parent, const char * )
+ {
+ AppearanceConfigurationPage *page =
+ new AppearanceConfigurationPage( parent, "kleopatra_config_appear" );
+ return page;
+ }
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void AppearanceConfigurationPage::slotChanged()
+{
+ emit changed(true);
+}
+
+#include "appearanceconfigpage.moc"
diff --git a/lib/ui/cryptoconfigmodule.h b/conf/appearanceconfigpage.h
similarity index 55%
copy from lib/ui/cryptoconfigmodule.h
copy to conf/appearanceconfigpage.h
index df01d5d8a..c3acea007 100644
--- a/lib/ui/cryptoconfigmodule.h
+++ b/conf/appearanceconfigpage.h
@@ -1,68 +1,60 @@
/*
- cryptoconfigmodule.h
+ appearanceconfigpage.h
- This file is part of libkleopatra
- Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
Libkleopatra is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License,
version 2, as published by the Free Software Foundation.
Libkleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#ifndef CRYPTOCONFIGMODULE_H
-#define CRYPTOCONFIGMODULE_H
+#ifndef _APPEARANCE_CONFIGURE_PAGE_H_
+#define _APPEARANCE_CONFIGURE_PAGE_H_
-#include
-
-#include
+#include
namespace Kleo {
+ class AppearanceConfigWidget;
+}
- class CryptoConfig;
- class CryptoConfigComponentGUI;
-
- /**
- * Crypto Config Module widget, dynamically generated from CryptoConfig
- * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule.
- */
- class CryptoConfigModule : public KJanusWidget {
- Q_OBJECT
- public:
- CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 );
-
- void save();
- void reset(); // i.e. reload current settings, discarding user input
- void defaults();
- void cancel();
+/**
+ * "Appearance" configuration page for kleopatra's configuration dialog
+ */
+class AppearanceConfigurationPage : public KCModule {
+ Q_OBJECT
+public:
+ AppearanceConfigurationPage( QWidget * parent=0, const char * name=0 );
- signals:
- void changed();
+ virtual void load();
+ virtual void save();
+ virtual void defaults();
- private:
- Kleo::CryptoConfig* mConfig;
- QValueList mComponentGUIs;
- };
+private slots:
+ void slotChanged();
-}
+private:
+ Kleo::AppearanceConfigWidget* mWidget;
+};
-#endif
+#endif // _APPEARANCE_CONFIGURE_DIALOG_PRIVATE_H_
diff --git a/conf/appearanceconfigwidget.cpp b/conf/appearanceconfigwidget.cpp
new file mode 100644
index 000000000..a3d177c2a
--- /dev/null
+++ b/conf/appearanceconfigwidget.cpp
@@ -0,0 +1,358 @@
+/*
+ appearanceconfigwidget.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include "appearanceconfigwidget.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace Kleo;
+
+class CategoryListViewItem : public QListViewItem
+{
+public:
+ CategoryListViewItem( QListView* lv, QListViewItem* prev, const KConfigBase& config )
+ : QListViewItem( lv, prev ) {
+
+ setName( config.readEntry( "Name", i18n("") ) );
+ mForegroundColor = config.readColorEntry( "foreground-color" );
+ mBackgroundColor = config.readColorEntry( "background-color" );
+ mHasFont = config.hasKey( "font" );
+ if ( mHasFont ) {
+ setFont( config.readFontEntry( "font" ) ); // sets mItalic and mBold
+ }
+ else {
+ mItalic = config.readBoolEntry( "font-italic", false );
+ mBold = config.readBoolEntry( "font-bold", false );
+ }
+ mStrikeOut = config.readBoolEntry( "font-strikeout", false );
+ mIsExpired = config.readBoolEntry( "is-expired", false );
+ mDirty = false;
+ }
+
+ void save( KConfigBase& config ) {
+ config.writeEntry( "Name", text( 0 ) );
+ config.writeEntry( "foreground-color", mForegroundColor );
+ config.writeEntry( "background-color", mBackgroundColor );
+ if ( mHasFont )
+ config.writeEntry( "font", mFont );
+ else {
+ config.deleteEntry( "font" );
+ config.writeEntry( "font-italic", mItalic );
+ config.writeEntry( "font-bold", mBold );
+ }
+ config.writeEntry( "font-strikeout", mStrikeOut );
+ }
+
+ void setForegroundColor( const QColor& foreground ) { mForegroundColor = foreground; mDirty = true; }
+ void setBackgroundColor( const QColor& background ) { mBackgroundColor = background; mDirty = true; }
+ void setFont( const QFont& font ) {
+ mFont = font;
+ mHasFont = true;
+ mItalic = font.italic();
+ mBold = font.bold();
+ mDirty = true;
+ }
+
+ QColor foregroundColor() const { return mForegroundColor; }
+ QColor backgroundColor() const { return mBackgroundColor; }
+ QFont font() const { return mFont; }
+
+ void setDefaultAppearance() {
+ mForegroundColor = mIsExpired ? Qt::red : QColor();
+ mBackgroundColor = QColor();
+ mHasFont = false;
+ mFont = QFont();
+ mBold = false;
+ mItalic = false;
+ mStrikeOut = false;
+ mDirty = true;
+ }
+
+ bool isDirty() const { return mDirty; }
+ bool isItalic() const { return mItalic; }
+ bool isBold() const { return mBold; }
+ bool isStrikeout() const { return mStrikeOut; }
+ bool hasFont() const { return mHasFont; }
+
+ void toggleItalic() { mItalic = !mItalic; if ( mHasFont ) mFont.setItalic( mItalic ); mDirty = true; }
+ void toggleBold() { mBold = !mBold; if ( mHasFont ) mFont.setBold( mBold ); mDirty = true; }
+ void toggleStrikeout() { mStrikeOut = !mStrikeOut; mDirty = true; }
+
+private:
+ void setName( const QString& name ) {
+ setText( 0, name );
+ }
+
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+
+private:
+ QColor mForegroundColor, mBackgroundColor;
+ QFont mFont;
+ bool mHasFont;
+ bool mIsExpired; // used for default settings
+ bool mItalic;
+ bool mBold;
+ bool mStrikeOut;
+ bool mDirty;
+};
+
+void CategoryListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ QColorGroup _cg = cg;
+ QFont font = p->font();
+ if ( mHasFont )
+ font = mFont;
+ else {
+ if ( mItalic )
+ font.setItalic( true );
+ if ( mBold )
+ font.setBold( true );
+ }
+ if ( mStrikeOut )
+ font.setStrikeOut( true );
+ p->setFont( font );
+
+ if ( mForegroundColor.isValid() )
+ _cg.setColor( QColorGroup::Text, mForegroundColor );
+ if ( mBackgroundColor.isValid() )
+ _cg.setColor( QColorGroup::Base, mBackgroundColor );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+////
+
+Kleo::AppearanceConfigWidget::AppearanceConfigWidget (
+ QWidget* parent, const char* name, WFlags fl )
+ : AppearanceConfigWidgetBase( parent, name, fl )
+{
+ categoriesLV->setSorting( -1 );
+ load();
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+
+AppearanceConfigWidget::~AppearanceConfigWidget()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void AppearanceConfigWidget::slotSelectionChanged( QListViewItem* item )
+{
+ bool sel = item != 0;
+ foregroundButton->setEnabled( sel );
+ backgroundButton->setEnabled( sel );
+ fontButton->setEnabled( sel );
+ italicCB->setEnabled( item );
+ boldCB->setEnabled( item );
+ strikeoutCB->setEnabled( item );
+ defaultLookPB->setEnabled( sel );
+ if ( item ) {
+ CategoryListViewItem* clvi = static_cast( item );
+ italicCB->setChecked( clvi->isItalic() );
+ boldCB->setChecked( clvi->isBold() );
+ strikeoutCB->setChecked( clvi->isStrikeout() );
+ } else {
+ italicCB->setChecked( false );
+ boldCB->setChecked( false );
+ strikeoutCB->setChecked( false );
+ }
+}
+
+/*
+ * set default appearance for selected category
+ */
+void AppearanceConfigWidget::slotDefaultClicked()
+{
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ if ( !item )
+ return;
+ item->setDefaultAppearance();
+ item->repaint();
+ slotSelectionChanged( item );
+ emit changed();
+}
+
+void AppearanceConfigWidget::load()
+{
+ categoriesLV->clear();
+ KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject();
+ if ( !config )
+ return;
+ QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) );
+ for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
+ KConfigGroup cfg( config, *it );
+ (void) new CategoryListViewItem( categoriesLV, categoriesLV->lastItem(), cfg );
+ }
+}
+
+void AppearanceConfigWidget::save()
+{
+ KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject();
+ if ( !config )
+ return;
+ // We know (assume) that the groups in the config object haven't changed,
+ // so we just iterate over them and over the listviewitems, and map one-to-one.
+ QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) );
+ if ( groups.isEmpty() ) {
+ // If we created the default categories ourselves just now, then we need to make up their list
+ QListViewItemIterator lvit( categoriesLV );
+ for ( ; lvit.current() ; ++lvit )
+ groups << lvit.current()->text( 0 );
+ }
+
+ QListViewItemIterator lvit( categoriesLV );
+ for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() && lvit.current(); ++it, ++lvit ) {
+ CategoryListViewItem* item = static_cast(lvit.current() );
+ KConfigGroup cfg( config, *it );
+ item->save( cfg );
+ }
+ config->sync();
+ Kleo::KeyFilterManager::instance()->reload();
+}
+
+
+void AppearanceConfigWidget::slotForegroundClicked() {
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QColor fg = item->foregroundColor();
+ int result = KColorDialog::getColor( fg );
+ if ( result == KColorDialog::Accepted ) {
+ item->setForegroundColor( fg );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotBackgroundClicked() {
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QColor bg = item->backgroundColor();
+ int result = KColorDialog::getColor( bg );
+ if ( result == KColorDialog::Accepted ) {
+ item->setBackgroundColor( bg );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotFontClicked() {
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QFont font = item->font();
+ int result = KFontDialog::getFont( font );
+ if ( result == KFontDialog::Accepted ) {
+ item->setFont( font );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::defaults()
+{
+ // This simply means "default look for every category"
+ QListViewItemIterator lvit( categoriesLV );
+ for ( ; lvit.current() ; ++lvit ) {
+ CategoryListViewItem* item = static_cast( lvit.current() );
+ item->setDefaultAppearance();
+ item->repaint();
+ }
+ emit changed();
+}
+
+void AppearanceConfigWidget::slotItalicClicked()
+{
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleItalic();
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotBoldClicked()
+{
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleBold();
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotStrikeoutClicked()
+{
+ CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleStrikeout();
+ item->repaint();
+ emit changed();
+ }
+}
+
+#include "appearanceconfigwidget.moc"
diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/conf/appearanceconfigwidget.h
similarity index 53%
copy from lib/backends/chiasmus/chiasmuslibrary.h
copy to conf/appearanceconfigwidget.h
index 1759b4fc7..dc5c79766 100644
--- a/lib/backends/chiasmus/chiasmuslibrary.h
+++ b/conf/appearanceconfigwidget.h
@@ -1,68 +1,73 @@
-/* -*- mode: C++; c-file-style: "gnu" -*-
- chiasmuslibrary.h
+/*
+ appearanceconfigwidget.h
- This file is part of libkleopatra, the KDE keymanagement library
- Copyright (c) 2005 Klarälvdalens Datakonsult AB
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz
Libkleopatra is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
Libkleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
-*/
+ */
+#ifndef APPEARANCECONFIGWIDGET_H
+#define APPEARANCECONFIGWIDGET_H
-#ifndef __KLEO_CHIASMUSLIBRARY_H__
-#define __KLEO_CHIASMUSLIBRARY_H__
-
-#include
-#include
-
-class KLibrary;
+#include "appearanceconfigwidgetbase.h"
+#include
+class KConfig;
namespace Kleo {
- /**
- @short small helper class to load xia.o through xia.so and make
- the functionality available.
- */
- class ChiasmusLibrary {
- ChiasmusLibrary();
- ~ChiasmusLibrary();
- public:
- static const ChiasmusLibrary * instance();
- static void deleteInstance();
-
- int perform( const QValueVector & args ) const;
- private:
- typedef int ( *main_func )( int, char** );
- main_func chiasmus( QString * reason=0 ) const;
+ class AppearanceConfigWidget : public AppearanceConfigWidgetBase {
+ Q_OBJECT
- private:
- static ChiasmusLibrary * self;
- mutable KLibrary * mXiaLibrary;
+ public:
+ AppearanceConfigWidget(
+ QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~AppearanceConfigWidget();
+
+ void load();
+ void save();
+
+ public slots:
+ void defaults();
+
+ signals:
+ void changed();
+
+ protected slots:
+ // reimplemented from the base class
+ virtual void slotDefaultClicked();
+ virtual void slotSelectionChanged( QListViewItem * );
+ virtual void slotForegroundClicked();
+ virtual void slotBackgroundClicked();
+ virtual void slotFontClicked();
+ virtual void slotItalicClicked();
+ virtual void slotBoldClicked();
+ virtual void slotStrikeoutClicked();
};
-
}
-
-#endif // __KLEO_CHIASMUSLIBRARY_H__
+#endif // APPEARANCECONFIGWIDGET_H
diff --git a/conf/configuredialog.cpp b/conf/configuredialog.cpp
new file mode 100644
index 000000000..87976f106
--- /dev/null
+++ b/conf/configuredialog.cpp
@@ -0,0 +1,73 @@
+/*
+ configuredialog.cpp
+
+ This file is part of kleopatra
+ Copyright (C) 2000 Espen Sand, espen@kde.org
+ Copyright (C) 2001-2002 Marc Mutz
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "configuredialog.h"
+
+#include
+#include
+#include
+#include
+
+ConfigureDialog::ConfigureDialog( QWidget *parent, const char *name, bool modal )
+ : KCMultiDialog( KDialogBase::IconList, i18n( "Configure" ), parent, name, modal )
+{
+ KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
+ showButton( User1, true );
+
+ addModule( "kleopatra_config_dirserv", false );
+ addModule( "kleopatra_config_appear", false );
+ addModule( "kleopatra_config_dnorder", false );
+
+ // We store the size of the dialog on hide, because otherwise
+ // the KCMultiDialog starts with the size of the first kcm, not
+ // the largest one. This way at least after the first showing of
+ // the largest kcm the size is kept.
+ const KConfigGroup geometry( KGlobal::config(), "Geometry" );
+ const int width = geometry.readNumEntry( "ConfigureDialogWidth" );
+ const int height = geometry.readNumEntry( "ConfigureDialogHeight" );
+ if ( width != 0 && height != 0 ) {
+ setMinimumSize( width, height );
+ }
+
+}
+
+void ConfigureDialog::hideEvent( QHideEvent * ) {
+ KConfigGroup geometry( KGlobal::config(), "Geometry" );
+ geometry.writeEntry( "ConfigureDialogWidth", width() );
+ geometry.writeEntry( "ConfigureDialogHeight",height() );
+}
+
+ConfigureDialog::~ConfigureDialog() {
+}
+
+#include "configuredialog.moc"
diff --git a/lib/kleo/cryptobackend.cpp b/conf/configuredialog.h
similarity index 59%
copy from lib/kleo/cryptobackend.cpp
copy to conf/configuredialog.h
index 6da71bc9e..40b7e371b 100644
--- a/lib/kleo/cryptobackend.cpp
+++ b/conf/configuredialog.h
@@ -1,36 +1,52 @@
/*
- kleo/cryptobackend.cpp
+ configuredialog.cpp
- This file is part of libkleopatra, the KDE keymanagement library
- Copyright (c) 2005 Klarälvdalens Datakonsult AB
+ This file is part of kleopatra
+ Copyright (C) 2000 Espen Sand, espen@kde.org
+ Copyright (C) 2001-2002 Marc Mutz
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
Libkleopatra is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
Libkleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#include "cryptobackend.h"
+#ifndef _CONFIGURE_DIALOG_H_
+#define _CONFIGURE_DIALOG_H_
-const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP";
-const char Kleo::CryptoBackend::SMIME[] = "SMIME";
+#include
+
+class ConfigureDialog : public KCMultiDialog
+{
+ Q_OBJECT
+
+public:
+ ConfigureDialog( QWidget *parent=0, const char *name=0, bool modal=true );
+ ~ConfigureDialog();
+
+protected:
+ void hideEvent( QHideEvent *i );
+
+};
+
+#endif
diff --git a/conf/dirservconfigpage.cpp b/conf/dirservconfigpage.cpp
new file mode 100644
index 000000000..30b21005d
--- /dev/null
+++ b/conf/dirservconfigpage.cpp
@@ -0,0 +1,291 @@
+/*
+ dirservconfigpage.cpp
+
+ This file is part of kleopatra
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "dirservconfigpage.h"
+#include "directoryserviceswidget.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+// For sync'ing kabldaprc
+class KABSynchronizer
+{
+public:
+ KABSynchronizer()
+ : mConfig( "kabldaprc" ) {
+ mConfig.setGroup( "LDAP" );
+ }
+
+ KURL::List readCurrentList() const {
+
+ KURL::List lst;
+ // stolen from kabc/ldapclient.cpp
+ const uint numHosts = mConfig.readUnsignedNumEntry( "NumSelectedHosts" );
+ for ( uint j = 0; j < numHosts; j++ ) {
+ const QString num = QString::number( j );
+
+ KURL url;
+ url.setProtocol( "ldap" );
+ url.setPath( "/" ); // workaround KURL parsing bug
+ const QString host = mConfig.readEntry( QString( "SelectedHost" ) + num ).stripWhiteSpace();
+ url.setHost( host );
+
+ const int port = mConfig.readUnsignedNumEntry( QString( "SelectedPort" ) + num );
+ if ( port != 0 )
+ url.setPort( port );
+
+ const QString base = mConfig.readEntry( QString( "SelectedBase" ) + num ).stripWhiteSpace();
+ url.setQuery( base );
+
+ const QString bindDN = mConfig.readEntry( QString( "SelectedBind" ) + num ).stripWhiteSpace();
+ url.setUser( bindDN );
+
+ const QString pwdBindDN = mConfig.readEntry( QString( "SelectedPwdBind" ) + num ).stripWhiteSpace();
+ url.setPass( pwdBindDN );
+ lst.append( url );
+ }
+ return lst;
+ }
+
+ void writeList( const KURL::List& lst ) {
+
+ mConfig.writeEntry( "NumSelectedHosts", lst.count() );
+
+ KURL::List::const_iterator it = lst.begin();
+ KURL::List::const_iterator end = lst.end();
+ unsigned j = 0;
+ for( ; it != end; ++it, ++j ) {
+ const QString num = QString::number( j );
+ KURL url = *it;
+
+ Q_ASSERT( url.protocol() == "ldap" );
+ mConfig.writeEntry( QString( "SelectedHost" ) + num, url.host() );
+ mConfig.writeEntry( QString( "SelectedPort" ) + num, url.port() );
+
+ // KURL automatically encoded the query (e.g. for spaces inside it),
+ // so decode it before writing it out
+ const QString base = KURL::decode_string( url.query().mid(1) );
+ mConfig.writeEntry( QString( "SelectedBase" ) + num, base );
+ mConfig.writeEntry( QString( "SelectedBind" ) + num, url.user() );
+ mConfig.writeEntry( QString( "SelectedPwdBind" ) + num, url.pass() );
+ }
+ mConfig.sync();
+ }
+
+private:
+ KConfig mConfig;
+};
+
+static const char s_dirserv_componentName[] = "dirmngr";
+static const char s_dirserv_groupName[] = "LDAP";
+static const char s_dirserv_entryName[] = "LDAP Server";
+
+static const char s_timeout_componentName[] = "dirmngr";
+static const char s_timeout_groupName[] = "LDAP";
+static const char s_timeout_entryName[] = "ldaptimeout";
+
+static const char s_maxitems_componentName[] = "dirmngr";
+static const char s_maxitems_groupName[] = "LDAP";
+static const char s_maxitems_entryName[] = "max-replies";
+
+static const char s_addnewservers_componentName[] = "dirmngr";
+static const char s_addnewservers_groupName[] = "LDAP";
+static const char s_addnewservers_entryName[] = "add-servers";
+
+DirectoryServicesConfigurationPage::DirectoryServicesConfigurationPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ mConfig = Kleo::CryptoBackendFactory::instance()->config();
+ QVBoxLayout* lay = new QVBoxLayout( this, 0, KDialog::spacingHint() );
+ Kleo::CryptoConfigEntry* entry = configEntry( s_dirserv_componentName, s_dirserv_groupName, s_dirserv_entryName,
+ Kleo::CryptoConfigEntry::ArgType_LDAPURL, true );
+ mWidget = new Kleo::DirectoryServicesWidget( entry, this );
+ lay->addWidget( mWidget );
+ connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+
+ // LDAP timeout
+ QHBox* box = new QHBox( this );
+ box->setSpacing( KDialog::spacingHint() );
+ lay->addWidget( box );
+ QLabel* label = new QLabel( i18n( "LDAP &timeout (minutes:seconds)" ), box );
+ mTimeout = new QTimeEdit( box );
+ mTimeout->setDisplay( QTimeEdit::Minutes | QTimeEdit::Seconds );
+ connect( mTimeout, SIGNAL( valueChanged( const QTime& ) ), this, SLOT( slotChanged() ) );
+ label->setBuddy( mTimeout );
+ QWidget* stretch = new QWidget( box );
+ box->setStretchFactor( stretch, 2 );
+
+ // Max number of items returned by queries
+ box = new QHBox( this );
+ box->setSpacing( KDialog::spacingHint() );
+ lay->addWidget( box );
+ mMaxItems = new KIntNumInput( box );
+ mMaxItems->setLabel( i18n( "&Maximum number of items returned by query" ), Qt::AlignLeft | Qt::AlignVCenter );
+ mMaxItems->setMinValue( 0 );
+ connect( mMaxItems, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) );
+ stretch = new QWidget( box );
+ box->setStretchFactor( stretch, 2 );
+
+#ifdef NOT_USEFUL_CURRENTLY
+ mAddNewServersCB = new QCheckBox( i18n( "Automatically add &new servers discovered in CRL distribution points" ), this );
+ connect( mAddNewServersCB, SIGNAL( clicked() ), this, SLOT( slotChanged() ) );
+ lay->addWidget( mAddNewServersCB );
+#endif
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+void DirectoryServicesConfigurationPage::load()
+{
+ mWidget->load();
+
+ mTimeoutConfigEntry = configEntry( s_timeout_componentName, s_timeout_groupName, s_timeout_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
+ if ( mTimeoutConfigEntry ) {
+ QTime time = QTime().addSecs( mTimeoutConfigEntry->uintValue() );
+ //kdDebug() << "timeout:" << mTimeoutConfigEntry->uintValue() << " -> " << time << endl;
+ mTimeout->setTime( time );
+ }
+
+ mMaxItemsConfigEntry = configEntry( s_maxitems_componentName, s_maxitems_groupName, s_maxitems_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
+ if ( mMaxItemsConfigEntry ) {
+ mMaxItems->blockSignals( true ); // KNumInput emits valueChanged from setValue!
+ mMaxItems->setValue( mMaxItemsConfigEntry->uintValue() );
+ mMaxItems->blockSignals( false );
+ }
+
+#ifdef NOT_USEFUL_CURRENTLY
+ mAddNewServersConfigEntry = configEntry( s_addnewservers_componentName, s_addnewservers_groupName, s_addnewservers_entryName, Kleo::CryptoConfigEntry::ArgType_None, false );
+ if ( mAddNewServersConfigEntry ) {
+ mAddNewServersCB->setChecked( mAddNewServersConfigEntry->boolValue() );
+ }
+#endif
+}
+
+void DirectoryServicesConfigurationPage::save()
+{
+ mWidget->save();
+
+ QTime time( mTimeout->time() );
+ unsigned int timeout = time.minute() * 60 + time.second();
+ if ( mTimeoutConfigEntry && mTimeoutConfigEntry->uintValue() != timeout )
+ mTimeoutConfigEntry->setUIntValue( timeout );
+ if ( mMaxItemsConfigEntry && mMaxItemsConfigEntry->uintValue() != (uint)mMaxItems->value() )
+ mMaxItemsConfigEntry->setUIntValue( mMaxItems->value() );
+#ifdef NOT_USEFUL_CURRENTLY
+ if ( mAddNewServersConfigEntry && mAddNewServersConfigEntry->boolValue() != mAddNewServersCB->isChecked() )
+ mAddNewServersConfigEntry->setBoolValue( mAddNewServersCB->isChecked() );
+#endif
+
+ mConfig->sync( true );
+
+ // Also write the LDAP URLs to kabldaprc so that they are used by kaddressbook
+ KABSynchronizer sync;
+ const KURL::List toAdd = mWidget->urlList();
+ KURL::List currentList = sync.readCurrentList();
+
+ KURL::List::const_iterator it = toAdd.begin();
+ KURL::List::const_iterator end = toAdd.end();
+ for( ; it != end; ++it ) {
+ // check if the URL is already in currentList
+ if ( currentList.find( *it ) == currentList.end() )
+ // if not, add it
+ currentList.append( *it );
+ }
+ sync.writeList( currentList );
+}
+
+void DirectoryServicesConfigurationPage::defaults()
+{
+ mWidget->defaults();
+ if ( mTimeoutConfigEntry )
+ mTimeoutConfigEntry->resetToDefault();
+ if ( mMaxItemsConfigEntry )
+ mMaxItemsConfigEntry->resetToDefault();
+#ifdef NOT_USEFUL_CURRENTLY
+ if ( mAddNewServersConfigEntry )
+ mAddNewServersConfigEntry->resetToDefault();
+#endif
+ load();
+}
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kleopatra_config_dirserv( QWidget *parent, const char * )
+ {
+ DirectoryServicesConfigurationPage *page =
+ new DirectoryServicesConfigurationPage( parent, "kleopatra_config_dirserv" );
+ return page;
+ }
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void DirectoryServicesConfigurationPage::slotChanged()
+{
+ emit changed(true);
+}
+
+
+// Find config entry for ldap servers. Implements runtime checks on the configuration option.
+Kleo::CryptoConfigEntry* DirectoryServicesConfigurationPage::configEntry( const char* componentName,
+ const char* groupName,
+ const char* entryName,
+ Kleo::CryptoConfigEntry::ArgType argType,
+ bool isList )
+{
+ Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName );
+ if ( !entry ) {
+ KMessageBox::error( this, i18n( "Backend error: gpgconf does not seem to know the entry for %1/%2/%3" ).arg( componentName, groupName, entryName ) );
+ return 0;
+ }
+ if( entry->argType() != argType || entry->isList() != isList ) {
+ KMessageBox::error( this, i18n( "Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5" ).arg( componentName, groupName, entryName ).arg( entry->argType() ).arg( entry->isList() ) );
+ return 0;
+ }
+ return entry;
+}
+
+#include "dirservconfigpage.moc"
diff --git a/conf/dirservconfigpage.h b/conf/dirservconfigpage.h
new file mode 100644
index 000000000..8c7c75439
--- /dev/null
+++ b/conf/dirservconfigpage.h
@@ -0,0 +1,84 @@
+/*
+ dirservconfigpage.h
+
+ This file is part of kleopatra
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef DIRSERVCONFIGPAGE_H
+#define DIRSERVCONFIGPAGE_H
+
+#include
+#include
+#include
+
+class QCheckBox;
+class QTimeEdit;
+class KIntNumInput;
+namespace Kleo {
+ class CryptoConfig;
+ class CryptoConfigEntry;
+ class DirectoryServicesWidget;
+}
+
+/**
+ * "Directory Services" configuration page for kleopatra's configuration dialog
+ * The user can configure LDAP servers in this page, to be used for listing/fetching
+ * remote certificates in kleopatra.
+ */
+class KDE_EXPORT DirectoryServicesConfigurationPage : public KCModule {
+ Q_OBJECT
+public:
+ DirectoryServicesConfigurationPage( QWidget * parent=0, const char * name=0 );
+
+ virtual void load();
+ virtual void save();
+ virtual void defaults();
+
+private slots:
+ void slotChanged();
+
+private:
+ Kleo::CryptoConfigEntry* configEntry( const char* componentName,
+ const char* groupName,
+ const char* entryName,
+ Kleo::CryptoConfigEntry::ArgType argType,
+ bool isList );
+
+ Kleo::DirectoryServicesWidget* mWidget;
+ QTimeEdit* mTimeout;
+ KIntNumInput* mMaxItems;
+ QCheckBox* mAddNewServersCB;
+
+ Kleo::CryptoConfigEntry* mTimeoutConfigEntry;
+ Kleo::CryptoConfigEntry* mMaxItemsConfigEntry;
+ Kleo::CryptoConfigEntry* mAddNewServersConfigEntry;
+
+ Kleo::CryptoConfig* mConfig;
+};
+
+#endif
diff --git a/conf/dnorderconfigpage.cpp b/conf/dnorderconfigpage.cpp
new file mode 100644
index 000000000..44b86b5b8
--- /dev/null
+++ b/conf/dnorderconfigpage.cpp
@@ -0,0 +1,77 @@
+/*
+ dnorderconfigpage.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "dnorderconfigpage.h"
+
+#include
+#include
+
+#include
+
+#include
+
+DNOrderConfigPage::DNOrderConfigPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ QVBoxLayout * vlay = new QVBoxLayout( this );
+ mWidget = Kleo::DNAttributeMapper::instance()->configWidget( this, "mWidget" );
+ vlay->addWidget( mWidget );
+
+ connect( mWidget, SIGNAL(changed()), SLOT(slotChanged()) );
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+
+void DNOrderConfigPage::load() {
+ mWidget->load();
+}
+
+void DNOrderConfigPage::save() {
+ mWidget->save();
+}
+
+void DNOrderConfigPage::defaults() {
+ mWidget->defaults();
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void DNOrderConfigPage::slotChanged() {
+ emit changed(true);
+}
+
+extern "C" KDE_EXPORT KCModule * create_kleopatra_config_dnorder( QWidget * parent, const char * ) {
+ return new DNOrderConfigPage( parent, "kleopatra_config_dnorder" );
+}
+
+#include "dnorderconfigpage.moc"
diff --git a/lib/ui/cryptoconfigmodule.h b/conf/dnorderconfigpage.h
similarity index 55%
copy from lib/ui/cryptoconfigmodule.h
copy to conf/dnorderconfigpage.h
index df01d5d8a..c874c7527 100644
--- a/lib/ui/cryptoconfigmodule.h
+++ b/conf/dnorderconfigpage.h
@@ -1,68 +1,63 @@
/*
- cryptoconfigmodule.h
+ dnorderconfigpage.h
- This file is part of libkleopatra
- Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
Libkleopatra is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License,
version 2, as published by the Free Software Foundation.
Libkleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#ifndef CRYPTOCONFIGMODULE_H
-#define CRYPTOCONFIGMODULE_H
+#ifndef __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
+#define __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
-#include
-
-#include
+#include
namespace Kleo {
-
- class CryptoConfig;
- class CryptoConfigComponentGUI;
-
- /**
- * Crypto Config Module widget, dynamically generated from CryptoConfig
- * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule.
- */
- class CryptoConfigModule : public KJanusWidget {
- Q_OBJECT
- public:
- CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 );
-
- void save();
- void reset(); // i.e. reload current settings, discarding user input
- void defaults();
- void cancel();
-
- signals:
- void changed();
-
- private:
- Kleo::CryptoConfig* mConfig;
- QValueList mComponentGUIs;
- };
-
+ class DNAttributeOrderConfigWidget;
}
-#endif
+/**
+ * "DN Order" configuration page for kleopatra's configuration dialog
+ */
+class DNOrderConfigPage : public KCModule {
+ Q_OBJECT
+public:
+ DNOrderConfigPage( QWidget * parent=0, const char * name=0 );
+
+ /*! reimplementation */
+ void load();
+ /*! reimplementation */
+ void save();
+ /*! reimplementation */
+ void defaults();
+
+private slots:
+ void slotChanged();
+
+private:
+ Kleo::DNAttributeOrderConfigWidget * mWidget;
+};
+
+#endif // __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
diff --git a/crlview.cpp b/crlview.cpp
index dc743646f..6cf7ddeaa 100644
--- a/crlview.cpp
+++ b/crlview.cpp
@@ -1,78 +1,138 @@
-#include
-#include
-#include
+/*
+ crlview.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include "crlview.h"
#include
#include
#include
#include
#include
+#include
-#include "crlview.h"
-#include "crlview.moc"
+#include
+#include
+#include
+#include
+#include
CRLView::CRLView( QWidget* parent, const char* name, bool modal )
: QDialog( parent, name, modal ), _process(0)
{
QVBoxLayout* topLayout = new QVBoxLayout( this, 10, 4 );
topLayout->addWidget( new QLabel( i18n("CRL cache dump:"), this ) );
- _textView = new QTextView( this );
- _textView->setWordWrap( QTextEdit::NoWrap );
+ _textView = new QTextEdit( this );
+ _textView->setFont( KGlobalSettings::fixedFont() );
+ _textView->setTextFormat( QTextEdit::LogText );
topLayout->addWidget( _textView );
QHBoxLayout* hbLayout = new QHBoxLayout( topLayout );
_updateButton = new KPushButton( i18n("&Update"), this );
_closeButton = new KPushButton( KStdGuiItem::close(), this );
hbLayout->addWidget( _updateButton );
hbLayout->addStretch();
hbLayout->addWidget( _closeButton );
// connections:
connect( _updateButton, SIGNAL( clicked() ),
this, SLOT( slotUpdateView() ) );
connect( _closeButton, SIGNAL( clicked() ),
this, SLOT( close() ) );
+
+ resize( _textView->fontMetrics().width( 'M' ) * 80,
+ _textView->fontMetrics().lineSpacing() * 25 );
+
+ _timer = new QTimer( this );
+ connect( _timer, SIGNAL(timeout()), SLOT(slotAppendBuffer()) );
}
CRLView::~CRLView()
{
- delete _process;
+ delete _process; _process = 0;
+}
+
+void CRLView::closeEvent( QCloseEvent * e ) {
+ QDialog::closeEvent( e );
+ delete _process; _process = 0;
}
void CRLView::slotUpdateView()
{
_updateButton->setEnabled( false );
_textView->clear();
+ _buffer = QString::null;
if( _process == 0 ) {
_process = new KProcess();
- *_process << "dirmngr";
- *_process << "--list-crls";
+ *_process << "gpgsm" << "--call-dirmngr" << "listcrls";
connect( _process, SIGNAL( receivedStdout( KProcess*, char*, int) ),
this, SLOT( slotReadStdout( KProcess*, char*, int ) ) );
connect( _process, SIGNAL( processExited( KProcess* ) ),
this, SLOT( slotProcessExited() ) );
}
if( _process->isRunning() ) _process->kill();
if( !_process->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) {
- KMessageBox::error( this, i18n( "Unable to start dirmngr process. Please check your installation." ), i18n( "Certificate Manager Error" ) );
+ KMessageBox::error( this, i18n( "Unable to start gpgsm process. Please check your installation." ), i18n( "Certificate Manager Error" ) );
slotProcessExited();
}
+ _timer->start( 1000 );
}
void CRLView::slotReadStdout( KProcess*, char* buf, int len)
{
- _textView->append( QString::fromUtf8( buf, len ) );
+ _buffer.append( QString::fromUtf8( buf, len ) );
+}
+
+void CRLView::slotAppendBuffer() {
+ _textView->append( _buffer );
+ _buffer = QString::null;
}
void CRLView::slotProcessExited()
{
+ _timer->stop();
+ slotAppendBuffer();
_updateButton->setEnabled( true );
if( !_process->normalExit() ) {
- KMessageBox::error( this, i18n( "The Dirmngr process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
+ KMessageBox::error( this, i18n( "The GpgSM process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
}
}
+
+#include "crlview.moc"
diff --git a/crlview.h b/crlview.h
index ac1016ae1..55828a90f 100644
--- a/crlview.h
+++ b/crlview.h
@@ -1,29 +1,69 @@
+/*
+ crlview.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
#ifndef CRLVIEW_H
#define CRLVIEW_H
#include
+#include
-class QTextView;
+class QTextEdit;
class QPushButton;
class KProcess;
+class QTimer;
class CRLView : public QDialog {
Q_OBJECT
public:
CRLView( QWidget* parent = 0, const char* name = 0, bool modal = false );
~CRLView();
public slots:
void slotUpdateView();
protected slots:
void slotReadStdout( KProcess*, char* buf, int len);
void slotProcessExited();
+ void slotAppendBuffer();
+
+protected:
+ void closeEvent( QCloseEvent * );
private:
- QTextView* _textView;
+ QTextEdit* _textView;
QPushButton* _updateButton;
QPushButton* _closeButton;
KProcess* _process;
+ QTimer* _timer;
+ QString _buffer;
};
#endif // CRLVIEW_H
diff --git a/customactions.cpp b/customactions.cpp
new file mode 100644
index 000000000..6a48a4768
--- /dev/null
+++ b/customactions.cpp
@@ -0,0 +1,134 @@
+/*
+ customactions.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "customactions.h"
+
+#include
+#include
+
+#include
+#include
+
+
+LabelAction::LabelAction( const QString & text, KActionCollection * parent,
+ const char* name )
+ : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name )
+{
+
+}
+
+int LabelAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar * bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ QLabel* label = new QLabel( text(), bar, "kde toolbar widget" );
+ bar->insertWidget( id_, label->width(), label, index );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+LineEditAction::LineEditAction( const QString & text, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name )
+ : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name ),
+ _le(0), _receiver(receiver), _member(member)
+{
+
+}
+
+int LineEditAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar *bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ // The toolbar trick doesn't seem to work for lineedits
+ //_le = new QLineEdit( bar, "kde toolbar widget" );
+ _le = new QLineEdit( bar );
+ bar->insertWidget( id_, _le->width(), _le, index );
+ bar->setStretchableWidget( _le );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ connect( _le, SIGNAL( returnPressed() ), _receiver, _member );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+void LineEditAction::clear() {
+ _le->clear();
+}
+
+void LineEditAction::focusAll() {
+ _le->selectAll();
+ _le->setFocus();
+}
+
+QString LineEditAction::text() const {
+ return _le->text();
+}
+
+void LineEditAction::setText( const QString & txt ) {
+ _le->setText(txt);
+}
+
+
+ComboAction::ComboAction( const QStringList & lst, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name )
+ : KAction( QString::null, QIconSet(), KShortcut(), 0, 0, parent, name ),
+ _lst(lst), _receiver(receiver), _member(member)
+{
+
+}
+
+int ComboAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar *bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ bar->insertCombo( _lst, id_, false, SIGNAL( highlighted(int) ), _receiver, _member );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+#include "customactions.moc"
diff --git a/kwatchgnupg/aboutdata.cpp b/customactions.h
similarity index 52%
copy from kwatchgnupg/aboutdata.cpp
copy to customactions.h
index 68c918e9d..dfbaf5461 100644
--- a/kwatchgnupg/aboutdata.cpp
+++ b/customactions.h
@@ -1,73 +1,84 @@
/*
- aboutdata.cpp
+ customactions.h
This file is part of Kleopatra, the KDE keymanager
- Copyright (c) 2004 Klar�vdalens Datakonsult AB
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#include "aboutdata.h"
+#ifndef __CUSTOMACTIONS_H__
+#define __CUSTOMACTIONS_H__
-#include
+#include
-static const char kwatchgnupg_version[] = "1.0";
-static const char description[] = I18N_NOOP("GnuPG log viewer");
+#include
-struct about_data {
- const char * name;
- const char * desc;
- const char * email;
- const char * web;
+class QLineEdit;
+
+class LabelAction : public KAction {
+ Q_OBJECT
+public:
+ LabelAction( const QString & text, KActionCollection * parent,
+ const char* name );
+
+ int plug( QWidget * widget, int index=-1 );
};
-static const about_data authors[] = {
- { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 },
+class LineEditAction : public KAction {
+ Q_OBJECT
+public:
+ LineEditAction( const QString & text, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name );
+
+ int plug( QWidget * widget, int index=-1 );
+ void clear();
+ void focusAll();
+ QString text() const;
+ void setText( const QString & txt );
+private:
+ QLineEdit* _le;
+ QObject * _receiver;
+ const char * _member;
};
-#if 0
-// can't create zero size array - doesn't compile
-static const about_data credits[] = {
- // PENDING(steffen) add stuff
+class ComboAction : public KAction {
+ Q_OBJECT
+public:
+ ComboAction( const QStringList & lst, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name );
+
+ int plug( QWidget * widget, int index=-1 );
+
+private:
+ QStringList _lst;
+ QObject * _receiver;
+ const char * _member;
};
-#endif
-
-AboutData::AboutData()
- : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"),
- kwatchgnupg_version, description, License_GPL,
- "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" )
-{
- using ::authors;
- //using ::credits;
- for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i )
- addAuthor( authors[i].name, authors[i].desc,
- authors[i].email, authors[i].web );
-#if 0
- for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i )
- addCredit( credits[i].name, credits[i].desc,
- credits[i].email, credits[i].web );
-#endif
-}
+
+
+
+#endif // __CUSTOMACTIONS_H__
diff --git a/hierarchyanalyser.cpp b/hierarchyanalyser.cpp
new file mode 100644
index 000000000..8e8c13803
--- /dev/null
+++ b/hierarchyanalyser.cpp
@@ -0,0 +1,81 @@
+/*
+ hierarchyanalyser.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include "hierarchyanalyser.h"
+
+#include
+#include
+
+HierarchyAnalyser::HierarchyAnalyser( QObject * parent, const char * name )
+ : QObject( parent, name )
+{
+
+}
+
+HierarchyAnalyser::~HierarchyAnalyser() {
+
+}
+
+void HierarchyAnalyser::slotNextKey( const GpgME::Key & key ) {
+ if ( key.isNull() )
+ return;
+ if ( key.isRoot() || !key.chainID() || !*key.chainID() )
+ // root keys have themselves as issuer - we don't want them to
+ // have parents, though:
+ mSubjectsByIssuer[0].push_back( key );
+ else
+ mSubjectsByIssuer[key.chainID()].push_back( key );
+}
+
+const std::vector & HierarchyAnalyser::subjectsForIssuer( const char * issuer_dn ) const {
+ static const std::vector empty;
+ std::map< QCString, std::vector >::const_iterator it =
+ mSubjectsByIssuer.find( issuer_dn );
+ return it == mSubjectsByIssuer.end() ? empty : it->second ;
+}
+
+std::vector HierarchyAnalyser::subjectsForIssuerRecursive( const char * issuer_dn ) const {
+ std::vector keys = subjectsForIssuer( issuer_dn );
+ for ( unsigned int i = 0 ; i < keys.size() ; ++i ) // can't use iterators here, since appending would invalidate them
+ if ( const char * fpr = keys[i].primaryFingerprint() ) {
+ const std::vector & tmp = subjectsForIssuer( fpr );
+ std::copy( tmp.begin(), tmp.end(), std::back_inserter( keys ) );
+ }
+ return keys;
+}
+
+
+#include "hierarchyanalyser.moc"
diff --git a/kwatchgnupg/aboutdata.cpp b/hierarchyanalyser.h
similarity index 51%
copy from kwatchgnupg/aboutdata.cpp
copy to hierarchyanalyser.h
index 68c918e9d..ccf07d4f3 100644
--- a/kwatchgnupg/aboutdata.cpp
+++ b/hierarchyanalyser.h
@@ -1,73 +1,66 @@
-/*
- aboutdata.cpp
+/* -*- mode: c++ -*-
+ hierarchyanalyser.h
This file is part of Kleopatra, the KDE keymanager
- Copyright (c) 2004 Klar�vdalens Datakonsult AB
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
-#include "aboutdata.h"
+#ifndef __HIERARCHYANALYSER_H__
+#define __HIERARCHYANALYSER_H__
-#include
+#include
-static const char kwatchgnupg_version[] = "1.0";
-static const char description[] = I18N_NOOP("GnuPG log viewer");
+#include
+#include
-struct about_data {
- const char * name;
- const char * desc;
- const char * email;
- const char * web;
-};
+#include