37#include "certmanager.h" 
   39#include "certlistview.h" 
   40#include "certificatewizardimpl.h" 
   41#include "certificateinfowidgetimpl.h" 
   43#include "customactions.h" 
   44#include "hierarchyanalyser.h" 
   45#include "storedtransferjob.h" 
   46#include "conf/configuredialog.h" 
   49#include <kleo/cryptobackendfactory.h> 
   50#include <kleo/downloadjob.h> 
   51#include <kleo/importjob.h> 
   52#include <kleo/exportjob.h> 
   53#include <kleo/multideletejob.h> 
   54#include <kleo/deletejob.h> 
   55#include <kleo/keylistjob.h> 
   57#include <kleo/keyfilter.h> 
   58#include <kleo/keyfiltermanager.h> 
   59#include <kleo/hierarchicalkeylistjob.h> 
   60#include <kleo/refreshkeysjob.h> 
   61#include <kleo/cryptoconfig.h> 
   63#include <ui/progressdialog.h> 
   64#include <ui/progressbar.h> 
   65#include <ui/keyselectiondialog.h> 
   66#include <ui/cryptoconfigdialog.h> 
   69#include <gpgmepp/importresult.h> 
   70#include <gpgmepp/keylistresult.h> 
   71#include <gpgmepp/key.h> 
   74#include <tdefiledialog.h> 
   75#include <tdeprocess.h> 
   77#include <tdeapplication.h> 
   79#include <tdemessagebox.h> 
   80#include <dcopclient.h> 
   81#include <tdetoolbar.h> 
   82#include <kstatusbar.h> 
   83#include <tdestandarddirs.h> 
   85#include <kdialogbase.h> 
   86#include <kkeydialog.h> 
   87#include <tdetempfile.h> 
   89#include <tdeio/netaccess.h> 
   90#include <tdestdaccel.h> 
   93#include <tqfontmetrics.h> 
   94#include <tqpopupmenu.h> 
  100#include <kinputdialog.h> 
  103  class TDE_EXPORT DisplayStrategy : 
public Kleo::KeyListView::DisplayStrategy{
 
  105    ~DisplayStrategy() {}
 
  107    virtual TQFont keyFont( 
const GpgME::Key& key, 
const TQFont& font )
 const {
 
  108      const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
 
  109      return filter ? filter->font( font ) : font;
 
  111    virtual TQColor keyForeground( 
const GpgME::Key& key, 
const TQColor& c )
 const {
 
  112      const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
 
  113      if ( filter && filter->fgColor().isValid() )
 
  114        return filter->fgColor();
 
  117    virtual TQColor keyBackground( 
const GpgME::Key& key, 
const TQColor& c  )
 const {
 
  118      const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
 
  119      if ( filter && filter->bgColor().isValid() )
 
  120        return filter->bgColor();
 
  125  class TDE_EXPORT ColumnStrategy : 
public Kleo::KeyListView::ColumnStrategy {
 
  129    TQString title( 
int col ) 
const;
 
  130    TQString text( 
const GpgME::Key & key, 
int col ) 
const;
 
  131    int width( 
int col, 
const TQFontMetrics & fm ) 
const;
 
  134  TQString ColumnStrategy::title( 
int col )
 const {
 
  136    case 0: 
return i18n(
"Subject");
 
  137    case 1: 
return i18n(
"Issuer");
 
  138    case 2: 
return i18n(
"Serial");
 
  139    default: 
return TQString();
 
  143  TQString ColumnStrategy::text( 
const GpgME::Key & key, 
int col )
 const {
 
  145    case 0: 
return Kleo::DN( key.userID(0).id() ).prettyDN();
 
  146    case 1: 
return Kleo::DN( key.issuerName() ).prettyDN();
 
  147    case 2: 
return key.issuerSerial() ? TQString::fromUtf8( key.issuerSerial() ) : TQString() ;
 
  148    default: 
return TQString();
 
  152  int ColumnStrategy::width( 
int col, 
const TQFontMetrics & fm )
 const {
 
  155    case 0: factor = 6; 
break;
 
  156    case 1: factor = 4; 
break;
 
  159    return fm.width( title( col ) ) * factor;
 
  163CertManager::CertManager( 
bool remote, 
const TQString& query, 
const TQString & 
import,
 
  164              TQWidget* parent, 
const char* name, WFlags f )
 
  165  : TDEMainWindow( parent, name, f|WDestructiveClose ),
 
  168    mHierarchyAnalyser( 0 ),
 
  169    mLineEditAction( 0 ),
 
  172    mImportCertFromFileAction( 0 ),
 
  173    mImportCRLFromFileAction( 0 ),
 
  174    mNextFindRemote( remote ),
 
  176    mDirMngrFound( false )
 
  178  readConfig( query.isEmpty() );
 
  183  setAutoSaveSettings();
 
  186  mKeyListView = 
new CertKeyListView( 
new ColumnStrategy(), 
new DisplayStrategy(), 
this, 
"mKeyListView" );
 
  187  mKeyListView->setSelectionMode( TQListView::Extended );
 
  188  setCentralWidget( mKeyListView );
 
  190  connect( mKeyListView, TQ_SIGNAL(doubleClicked(Kleo::KeyListViewItem*,
const TQPoint&,
int)),
 
  191       TQ_SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
 
  192  connect( mKeyListView, TQ_SIGNAL(returnPressed(Kleo::KeyListViewItem*)),
 
  193       TQ_SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
 
  194  connect( mKeyListView, TQ_SIGNAL(selectionChanged()),
 
  195       TQ_SLOT(slotSelectionChanged()) );
 
  196  connect( mKeyListView, TQ_SIGNAL(contextMenu(Kleo::KeyListViewItem*, 
const TQPoint&)),
 
  197           TQ_SLOT(slotContextMenu(Kleo::KeyListViewItem*, 
const TQPoint&)) );
 
  199  connect( mKeyListView, TQ_SIGNAL(dropped(
const KURL::List&) ),
 
  200           TQ_SLOT( slotDropped(
const KURL::List&) ) );
 
  202  mLineEditAction->setText(query);
 
  203  if ( !mRemote && !mNextFindRemote || !query.isEmpty() )
 
  206  if ( !
import.isEmpty() )
 
  207    slotImportCertFromFile( KURL( 
import ) );
 
  209  slotToggleHierarchicalView( mHierarchicalView );
 
  210  updateStatusBarLabels();
 
  211  slotSelectionChanged(); 
 
  214CertManager::~CertManager() {
 
  216  delete mDirmngrProc; mDirmngrProc = 0;
 
  217  delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
 
  220void CertManager::readConfig( 
bool noQueryGiven ) {
 
  221  TDEConfig config( 
"kleopatrarc" );
 
  222  config.setGroup( 
"Display Options" );
 
  223  mHierarchicalView = config.readBoolEntry( 
"hierarchicalView", 
false );
 
  224  if ( noQueryGiven ) {
 
  225    mNextFindRemote = config.readBoolEntry( 
"startInRemoteMode", 
false );
 
  229void CertManager::writeConfig() {
 
  230  TDEConfig config( 
"kleopatrarc" );
 
  231  config.setGroup( 
"Display Options" );
 
  232  config.writeEntry( 
"hierarchicalView", mKeyListView->hierarchical() );
 
  233  config.writeEntry( 
"startInRemoteMode", mNextFindRemote );
 
  236void CertManager::createStatusBar() {
 
  237  KStatusBar * bar = statusBar();
 
  238  mProgressBar = 
new Kleo::ProgressBar( bar, 
"mProgressBar" );
 
  239  mProgressBar->reset();
 
  240  mProgressBar->setFixedSize( TQSize( 100, mProgressBar->height() * 3 / 5 ) );
 
  241  bar->addWidget( mProgressBar, 0, 
true );
 
  242  mStatusLabel = 
new TQLabel( bar, 
"mStatusLabel" );
 
  243  bar->addWidget( mStatusLabel, 1, 
false );
 
  246static inline void connectEnableOperationSignal( TQObject * s, TQObject * d ) {
 
  247  TQObject::connect( s, TQ_SIGNAL(enableOperations(
bool)),
 
  248            d, TQ_SLOT(setEnabled(
bool)) );
 
  252void CertManager::createActions() {
 
  253  TDEAction * action = 0;
 
  255  (void)KStdAction::quit( 
this, TQ_SLOT(close()), actionCollection() );
 
  257  action = KStdAction::redisplay( 
this, TQ_SLOT(slotRedisplay()), actionCollection() );
 
  259  TDEShortcut reloadShortcut = TDEStdAccel::shortcut(TDEStdAccel::Reload);
 
  260  reloadShortcut.append(KKey(CTRL + Key_R));
 
  261  action->setShortcut( reloadShortcut );
 
  263  connectEnableOperationSignal( 
this, action );
 
  265  action = 
new TDEAction( i18n(
"Stop Operation"), 
"process-stop", Key_Escape,
 
  266            this, TQ_SIGNAL(stopOperations()),
 
  267            actionCollection(), 
"view_stop_operations" );
 
  268  action->setEnabled( 
false );
 
  270  (void)   
new TDEAction( i18n(
"New Key Pair..."), 
"document-new", 0,
 
  271            this, TQ_SLOT(newCertificate()),
 
  272            actionCollection(), 
"file_new_certificate" );
 
  274  connect( 
new TDEToggleAction( i18n(
"Hierarchical Key List"), 0,
 
  275                  actionCollection(), 
"view_hierarchical" ),
 
  276       TQ_SIGNAL(toggled(
bool)), TQ_SLOT(slotToggleHierarchicalView(
bool)) );
 
  278  action = 
new TDEAction( i18n(
"Expand All"), 0, CTRL+Key_Period,
 
  279            this, TQ_SLOT(slotExpandAll()),
 
  280            actionCollection(), 
"view_expandall" );
 
  281  action = 
new TDEAction( i18n(
"Collapse All"), 0, CTRL+Key_Comma,
 
  282            this, TQ_SLOT(slotCollapseAll()),
 
  283            actionCollection(), 
"view_collapseall" );
 
  285  (void)   
new TDEAction( i18n(
"Refresh CRLs"), 0, 0,
 
  286            this, TQ_SLOT(slotRefreshKeys()),
 
  287            actionCollection(), 
"certificates_refresh_clr" );
 
  289#ifdef NOT_IMPLEMENTED_ANYWAY 
  290  mRevokeCertificateAction = 
new TDEAction( i18n(
"Revoke"), 0,
 
  291                                          this, TQ_SLOT(revokeCertificate()),
 
  292                                          actionCollection(), 
"edit_revoke_certificate" );
 
  293  connectEnableOperationSignal( 
this, mRevokeCertificateAction );
 
  295  mExtendCertificateAction = 
new TDEAction( i18n(
"Extend"), 0,
 
  296                                          this, TQ_SLOT(extendCertificate()),
 
  297                                          actionCollection(), 
"edit_extend_certificate" );
 
  298  connectEnableOperationSignal( 
this, mExtendCertificateAction );
 
  301  mDeleteCertificateAction = 
new TDEAction( i18n(
"Delete"), 
"edit-delete", Key_Delete,
 
  302                                    this, TQ_SLOT(slotDeleteCertificate()),
 
  303                                    actionCollection(), 
"edit_delete_certificate" );
 
  304  connectEnableOperationSignal( 
this, mDeleteCertificateAction );
 
  306  mValidateCertificateAction = 
new TDEAction( i18n(
"Validate"), 
"reload", SHIFT + Key_F5,
 
  307                        this, TQ_SLOT(slotValidate()),
 
  308                        actionCollection(), 
"certificates_validate" );
 
  309  connectEnableOperationSignal( 
this, mValidateCertificateAction );
 
  311  mImportCertFromFileAction = 
new TDEAction( i18n(
"Import Certificates..."), 0,
 
  312                       this, TQ_SLOT(slotImportCertFromFile()),
 
  313                       actionCollection(), 
"file_import_certificates" );
 
  314  connectEnableOperationSignal( 
this, mImportCertFromFileAction );
 
  316  mImportCRLFromFileAction = 
new TDEAction( i18n(
"Import CRLs..."), 0,
 
  317                      this, TQ_SLOT(importCRLFromFile()),
 
  318                      actionCollection(), 
"file_import_crls" );
 
  319  connectEnableOperationSignal( 
this, mImportCRLFromFileAction );
 
  321  mExportCertificateAction = 
new TDEAction( i18n(
"Export Certificates..."), 
"export", 0,
 
  322                      this, TQ_SLOT(slotExportCertificate()),
 
  323                      actionCollection(), 
"file_export_certificate" );
 
  325  mExportSecretKeyAction = 
new TDEAction( i18n(
"Export Secret Key..."), 
"export", 0,
 
  326                                        this, TQ_SLOT(slotExportSecretKey()),
 
  327                                        actionCollection(), 
"file_export_secret_keys" );
 
  328  connectEnableOperationSignal( 
this, mExportSecretKeyAction );
 
  330  mViewCertDetailsAction = 
new TDEAction( i18n(
"Certificate Details..."), 0, 0,
 
  331                                        this, TQ_SLOT(slotViewDetails()), actionCollection(),
 
  332                                        "view_certificate_details" );
 
  333  mDownloadCertificateAction = 
new TDEAction( i18n( 
"Download"), 0, 0,
 
  334                                        this, TQ_SLOT(slotDownloadCertificate()), actionCollection(),
 
  335                                        "download_certificate" );
 
  337  const TQString dirmngr = TDEStandardDirs::findExe( 
"gpgsm" );
 
  338  mDirMngrFound = !dirmngr.isEmpty();
 
  340  action = 
new TDEAction( i18n(
"Dump CRL Cache..."), 0,
 
  341            this, TQ_SLOT(slotViewCRLs()),
 
  342            actionCollection(), 
"crl_dump_crl_cache" );
 
  343  action->setEnabled( mDirMngrFound ); 
 
  345  action = 
new TDEAction( i18n(
"Clear CRL Cache..."), 0,
 
  346            this, TQ_SLOT(slotClearCRLs()),
 
  347            actionCollection(), 
"crl_clear_crl_cache" );
 
  348  action->setEnabled( mDirMngrFound ); 
 
  350  action = 
new TDEAction( i18n(
"GnuPG Log Viewer..."), 
"pgp-keys", 0, 
this,
 
  351                        TQ_SLOT(slotStartWatchGnuPG()), actionCollection(), 
"tools_start_kwatchgnupg");
 
  353  if (TDEStandardDirs::findExe(
"kwatchgnupg").isEmpty()) action->setEnabled(
false);
 
  355  (void)
new LabelAction( i18n(
"Search:"), actionCollection(), 
"label_action" );
 
  357  mLineEditAction = 
new LineEditAction( TQString(), actionCollection(), 
this,
 
  358                    TQ_SLOT(slotSearch()),
 
  359                    "query_lineedit_action");
 
  362  lst << i18n(
"In Local Certificates") << i18n(
"In External Certificates");
 
  363  mComboAction = 
new ComboAction( lst, actionCollection(), 
this, TQ_SLOT( slotToggleRemote(
int) ),
 
  364                                  "location_combo_action", mNextFindRemote? 1 : 0 );
 
  366  mFindAction = 
new TDEAction( i18n(
"Find"), 
"edit-find", 0, 
this, TQ_SLOT(slotSearch()),
 
  367                 actionCollection(), 
"find" );
 
  369  KStdAction::keyBindings( 
this, TQ_SLOT(slotEditKeybindings()), actionCollection() );
 
  370  KStdAction::preferences( 
this, TQ_SLOT(slotShowConfigurationDialog()), actionCollection() );
 
  372  new TDEAction( i18n( 
"Configure &GpgME Backend" ), 0, 0, 
this, TQ_SLOT(slotConfigureGpgME()),
 
  373               actionCollection(), 
"configure_gpgme" );
 
  375  createStandardStatusBarAction();
 
  376  updateImportActions( 
true );
 
  379void CertManager::updateImportActions( 
bool enable ) {
 
  380  mImportCRLFromFileAction->setEnabled( mDirMngrFound && enable );
 
  381  mImportCertFromFileAction->setEnabled( enable );
 
  384void CertManager::slotEditKeybindings() {
 
  385  KKeyDialog::configure( actionCollection(), 
true );
 
  388void CertManager::slotShowConfigurationDialog() {
 
  389  ConfigureDialog dlg( 
this );
 
  390  connect( &dlg, TQ_SIGNAL( configCommitted() ), TQ_SLOT( slotRepaint() ) );
 
  394void CertManager::slotConfigureGpgME() {
 
  395  Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
 
  397    Kleo::CryptoConfigDialog dlg( config );
 
  399    int result = dlg.exec();
 
  405    if ( result == TQDialog::Accepted )
 
  408      tdeApp->dcopClient()->emitDCOPSignal( 
"KPIM::CryptoConfig", 
"changed()", TQByteArray() );
 
  413void CertManager::slotRepaint()
 
  415  mKeyListView->repaintContents();
 
  418void CertManager::slotToggleRemote( 
int idx ) {
 
  419  mNextFindRemote = idx != 0;
 
  422void CertManager::slotToggleHierarchicalView( 
bool hier ) {
 
  423  mHierarchicalView = hier;
 
  424  mKeyListView->setHierarchical( hier );
 
  425  mKeyListView->setRootIsDecorated( hier );
 
  426  if ( TDEAction * act = action(
"view_expandall") )
 
  427    act->setEnabled( hier );
 
  428  if ( TDEAction * act = action(
"view_collapseall" ) )
 
  429    act->setEnabled( hier );
 
  430  if ( TDEToggleAction * act =
 
  431      static_cast<TDEToggleAction*
>( action(
"view_hierarchical") ) )
 
  432    act->setChecked( hier );
 
  434  if ( hier && !mCurrentQuery.isEmpty() )
 
  435    startRedisplay( 
false );
 
  438void CertManager::slotExpandAll() {
 
  439  for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
 
  440    it.current()->setOpen( 
true );
 
  443void CertManager::slotCollapseAll() {
 
  444  for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
 
  445    it.current()->setOpen( 
false );
 
  448void CertManager::connectJobToStatusBarProgress( Kleo::Job * job, 
const TQString & initialText ) {
 
  449  assert( mProgressBar );
 
  452  if ( !initialText.isEmpty() )
 
  453    statusBar()->message( initialText );
 
  454  connect( job, TQ_SIGNAL(progress(
const TQString&,
int,
int)),
 
  455       mProgressBar, TQ_SLOT(slotProgress(
const TQString&,
int,
int)) );
 
  456  connect( job, TQ_SIGNAL(done()), mProgressBar, TQ_SLOT(reset()) );
 
  457  connect( 
this, TQ_SIGNAL(stopOperations()), job, TQ_SLOT(slotCancel()) );
 
  459  action(
"view_stop_operations")->setEnabled( 
true );
 
  460  emit enableOperations( 
false );
 
  463void CertManager::disconnectJobFromStatusBarProgress( 
const GpgME::Error & err ) {
 
  464  updateStatusBarLabels();
 
  465  const TQString msg = err.isCanceled() ? i18n(
"Canceled.")
 
  466    : err ? i18n(
"Failed.")
 
  468  statusBar()->message( msg, 4000 );
 
  470  action(
"view_stop_operations")->setEnabled( 
false );
 
  471  emit enableOperations( 
true );
 
  472  slotSelectionChanged();
 
  475void CertManager::updateStatusBarLabels() {
 
  476  mKeyListView->flushKeys();
 
  478  for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
 
  480  mStatusLabel->setText( i18n( 
"%n Key.",
"%n Keys.", total ) );
 
  490static std::set<std::string> extractKeyFingerprints( 
const TQPtrList<Kleo::KeyListViewItem> & items ) {
 
  491  std::set<std::string> result;
 
  492  for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
 
  493    if ( 
const char * fpr = it.current()->key().primaryFingerprint() )
 
  494      result.insert( fpr );
 
  498static TQStringList stringlistFromSet( 
const std::set<std::string> & set ) {
 
  501  for ( std::set<std::string>::const_iterator it = set.begin() ; it != set.end() ; ++it )
 
  503    sl.push_back( TQString::fromLatin1( it->c_str() ) );
 
  507void CertManager::slotRefreshKeys() {
 
  508  const TQStringList keys = stringlistFromSet( extractKeyFingerprints( mKeyListView->selectedItems() ) );
 
  509  Kleo::RefreshKeysJob * job = Kleo::CryptoBackendFactory::instance()->smime()->refreshKeysJob();
 
  512  connect( job, TQ_SIGNAL(result(
const GpgME::Error&)),
 
  513       this, TQ_SLOT(slotRefreshKeysResult(
const GpgME::Error&)) );
 
  515  connectJobToStatusBarProgress( job, i18n(
"Refreshing keys...") );
 
  516  if ( 
const GpgME::Error err = job->start( keys ) )
 
  517    slotRefreshKeysResult( err );
 
  520void CertManager::slotRefreshKeysResult( 
const GpgME::Error & err ) {
 
  521  disconnectJobFromStatusBarProgress( err );
 
  522  if ( err.isCanceled() )
 
  525    KMessageBox::error( 
this, i18n(
"An error occurred while trying to refresh " 
  526                   "keys:\n%1").arg( TQString::fromLocal8Bit( err.asString() ) ),
 
  527            i18n(
"Refreshing Keys Failed") );
 
  530static void showKeyListError( TQWidget * parent, 
const GpgME::Error & err ) {
 
  532  const TQString msg = i18n( 
"<qt><p>An error occurred while fetching " 
  533                "the certificates from the backend:</p>" 
  534                "<p><b>%1</b></p></qt>" )
 
  535    .arg( TQString::fromLocal8Bit( err.asString() ) );
 
  537  KMessageBox::error( parent, msg, i18n( 
"Certificate Listing Failed" ) );
 
  540void CertManager::slotSearch() {
 
  541  mPreviouslySelectedFingerprints.clear();
 
  543  mKeyListView->clear();
 
  544  mCurrentQuery = mLineEditAction->text();
 
  545  startKeyListing( 
false, 
false, mCurrentQuery );
 
  548void CertManager::startRedisplay( 
bool validate ) {
 
  549  mPreviouslySelectedFingerprints = extractKeyFingerprints( mKeyListView->selectedItems() );
 
  550  if ( mPreviouslySelectedFingerprints.empty() )
 
  551    startKeyListing( validate, 
true, mCurrentQuery );
 
  553    startKeyListing( validate, 
true, mPreviouslySelectedFingerprints );
 
  556void CertManager::startKeyListing( 
bool validating, 
bool refresh, 
const std::set<std::string> & patterns ) {
 
  557  startKeyListing( validating, refresh, stringlistFromSet( patterns ) );
 
  560void CertManager::startKeyListing( 
bool validating, 
bool refresh, 
const TQStringList & patterns ) {
 
  561  mRemote = mNextFindRemote;
 
  562  mLineEditAction->setEnabled( 
false );
 
  563  mComboAction->setEnabled( 
false );
 
  564  mFindAction->setEnabled( 
false );
 
  566  Kleo::KeyListJob * job = 0;
 
  567  if ( !validating && !refresh && mKeyListView->hierarchical() && !patterns.empty() )
 
  568    job = 
new Kleo::HierarchicalKeyListJob( Kleo::CryptoBackendFactory::instance()->smime(),
 
  569                        mRemote, 
false, validating );
 
  571    job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( mRemote, 
false, validating );
 
  574  connect( job, TQ_SIGNAL(nextKey(
const GpgME::Key&)),
 
  575       mKeyListView, refresh ? TQ_SLOT(slotRefreshKey(
const GpgME::Key&)) : TQ_SLOT(slotAddKey(
const GpgME::Key&)) );
 
  576  connect( job, TQ_SIGNAL(result(
const GpgME::KeyListResult&)),
 
  577       this, TQ_SLOT(slotKeyListResult(
const GpgME::KeyListResult&)) );
 
  579  connectJobToStatusBarProgress( job, i18n(
"Fetching keys...") );
 
  581  const GpgME::Error err = job->start( patterns ) ;
 
  583    showKeyListError( 
this, err );
 
  586  mProgressBar->setProgress( 0, 0 ); 
 
  589static void selectKeys( Kleo::KeyListView * lv, 
const std::set<std::string> & fprs ) {
 
  590  if ( !lv || fprs.empty() )
 
  592  for  ( TQListViewItemIterator it( lv ) ; it.current() ; ++it )
 
  593    if ( Kleo::KeyListViewItem * item = Kleo::lvi_cast<Kleo::KeyListViewItem>( it.current() ) ) {
 
  594      const char * fpr = item->key().primaryFingerprint();
 
  595      item->setSelected( fpr && fprs.find( fpr ) != fprs.end() );
 
  599void CertManager::slotKeyListResult( 
const GpgME::KeyListResult & res ) {
 
  601    showKeyListError( 
this, res.error() );
 
  602  else if ( res.isTruncated() )
 
  603    KMessageBox::information( 
this,
 
  604                  i18n(
"The query result has been truncated.\n" 
  605                   "Either the local or a remote limit on " 
  606                   "the maximum number of returned hits has " 
  608                   "You can try to increase the local limit " 
  609                   "in the configuration dialog, but if one " 
  610                   "of the configured servers is the limiting " 
  611                   "factor, you have to refine your search.") );
 
  613  mLineEditAction->setEnabled( 
true );
 
  614  mComboAction->setEnabled( 
true );
 
  615  mFindAction->setEnabled( 
true );
 
  617  mLineEditAction->focusAll();
 
  618  disconnectJobFromStatusBarProgress( res.error() );
 
  619  selectKeys( mKeyListView, mPreviouslySelectedFingerprints );
 
  622void CertManager::slotContextMenu(Kleo::KeyListViewItem* item, 
const TQPoint& point) {
 
  625  if ( TQPopupMenu * popup = 
static_cast<TQPopupMenu*
>(factory()->container(
"listview_popup",
this)) )
 
  626    popup->exec( point );
 
  632void CertManager::newCertificate()
 
  634  CertificateWizardImpl wizard( 
this );
 
  642void CertManager::revokeCertificate()
 
  644  tqDebug(
"Not Yet Implemented");
 
  651void CertManager::extendCertificate()
 
  653  tqDebug(
"Not Yet Implemented");
 
  667void CertManager::slotImportCertFromFile()
 
  669  const TQString filter = 
"application/x-x509-ca-cert application/x-pkcs12 application/pkcs7-mime";
 
  671  slotImportCertFromFile( KFileDialog::getOpenURL( TQString(), filter, 
this,
 
  672                                                   i18n( 
"Select Certificate File" ) ) );
 
  675void CertManager::slotImportCertFromFile( 
const KURL & certURL )
 
  677  if ( !certURL.isValid() ) 
 
  680  mPreviouslySelectedFingerprints.clear();
 
  683  updateImportActions( 
false );
 
  687  importJob->setWindow( 
this );
 
  688  connect( importJob, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotImportResult(TDEIO::Job*)) );
 
  691void CertManager::slotImportResult( TDEIO::Job* job )
 
  693  if ( job->error() ) {
 
  694    job->showErrorDialog();
 
  697    startCertificateImport( trJob->
data(), trJob->url().fileName() );
 
  700  updateImportActions( 
true );
 
  703static void showCertificateDownloadError( TQWidget * parent, 
const GpgME::Error & err, 
const TQString& certDisplayName ) {
 
  705  const TQString msg = i18n( 
"<qt><p>An error occurred while trying " 
  706                "to download the certificate %1:</p>" 
  707                "<p><b>%2</b></p></qt>" )
 
  708                      .arg( certDisplayName )
 
  709                      .arg( TQString::fromLocal8Bit( err.asString() ) );
 
  711  KMessageBox::error( parent, msg, i18n( 
"Certificate Download Failed" ) );
 
  714void CertManager::slotDownloadCertificate() {
 
  715  mPreviouslySelectedFingerprints.clear();
 
  716  TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
 
  717  for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
 
  718    if ( !it.current()->key().isNull() )
 
  719      if ( 
const char * fpr = it.current()->key().primaryFingerprint() )
 
  720        slotStartCertificateDownload( fpr, it.current()->text(0) );
 
  724void CertManager::slotStartCertificateDownload( 
const TQString& fingerprint, 
const TQString& displayName ) {
 
  725  if ( fingerprint.isEmpty() )
 
  728  Kleo::DownloadJob * job =
 
  729    Kleo::CryptoBackendFactory::instance()->smime()->downloadJob( 
false  );
 
  732  connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
 
  733       TQ_SLOT(slotCertificateDownloadResult(
const GpgME::Error&,
const TQByteArray&)) );
 
  735  connectJobToStatusBarProgress( job, i18n(
"Fetching certificate from server...") );
 
  737  const GpgME::Error err = job->start( fingerprint );
 
  739    showCertificateDownloadError( 
this, err, displayName );
 
  741    mProgressBar->setProgress( 0, 0 );
 
  742    mJobsDisplayNameMap.insert( job, displayName );
 
  746TQString CertManager::displayNameForJob( 
const Kleo::Job *job )
 
  748  JobsDisplayNameMap::iterator it = mJobsDisplayNameMap.find( job );
 
  749  TQString displayName;
 
  750  if ( it != mJobsDisplayNameMap.end() ) {
 
  752    mJobsDisplayNameMap.remove( it );
 
  754    kdWarning() << 
"Job not found in map: " << job << endl;
 
  760void CertManager::slotCertificateDownloadResult( 
const GpgME::Error & err, 
const TQByteArray & keyData ) {
 
  762  TQString displayName = displayNameForJob( 
static_cast<const Kleo::Job *
>( sender() ) );
 
  765    showCertificateDownloadError( 
this, err, displayName );
 
  767    startCertificateImport( keyData, displayName );
 
  768  disconnectJobFromStatusBarProgress( err );
 
  771static void showCertificateImportError( TQWidget * parent, 
const GpgME::Error & err, 
const TQString& certDisplayName ) {
 
  773  const TQString msg = i18n( 
"<qt><p>An error occurred while trying " 
  774                "to import the certificate %1:</p>" 
  775                "<p><b>%2</b></p></qt>" )
 
  776                      .arg( certDisplayName )
 
  777                      .arg( TQString::fromLocal8Bit( err.asString() ) );
 
  778  KMessageBox::error( parent, msg, i18n( 
"Certificate Import Failed" ) );
 
  781void CertManager::startCertificateImport( 
const TQByteArray & keyData, 
const TQString& certDisplayName ) {
 
  782  Kleo::ImportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->importJob();
 
  785  connect( job, TQ_SIGNAL(result(
const GpgME::ImportResult&)),
 
  786       TQ_SLOT(slotCertificateImportResult(
const GpgME::ImportResult&)) );
 
  788  connectJobToStatusBarProgress( job, i18n(
"Importing certificates...") );
 
  790  kdDebug() << 
"Importing certificate. keyData size:" << keyData.size() << endl;
 
  791  const GpgME::Error err = job->start( keyData );
 
  793    showCertificateImportError( 
this, err, certDisplayName );
 
  795    mProgressBar->setProgress( 0, 0 );
 
  796    mJobsDisplayNameMap.insert( job, certDisplayName );
 
  800void CertManager::slotCertificateImportResult( 
const GpgME::ImportResult & res ) {
 
  801  TQString displayName = displayNameForJob( 
static_cast<const Kleo::Job *
>( sender() ) );
 
  803  if ( res.error().isCanceled() ) {
 
  805  } 
else if ( res.error() ) {
 
  806    showCertificateImportError( 
this, res.error(), displayName );
 
  809    const TQString normalLine = i18n(
"<tr><td align=\"right\">%1</td><td>%2</td></tr>");
 
  810    const TQString boldLine = i18n(
"<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>");
 
  813    lines.push_back( normalLine.arg( i18n(
"Total number processed:"),
 
  814                     TQString::number( res.numConsidered() ) ) );
 
  815    lines.push_back( normalLine.arg( i18n(
"Imported:"),
 
  816                     TQString::number( res.numImported() ) ) );
 
  817    if ( res.newSignatures() )
 
  818      lines.push_back( normalLine.arg( i18n(
"New signatures:"),
 
  819                       TQString::number( res.newSignatures() ) ) );
 
  820    if ( res.newUserIDs() )
 
  821      lines.push_back( normalLine.arg( i18n(
"New user IDs:"),
 
  822                       TQString::number( res.newUserIDs() ) ) );
 
  823    if ( res.numKeysWithoutUserID() )
 
  824      lines.push_back( normalLine.arg( i18n(
"Keys without user IDs:"),
 
  825                       TQString::number( res.numKeysWithoutUserID() ) ) );
 
  826    if ( res.newSubkeys() )
 
  827      lines.push_back( normalLine.arg( i18n(
"New subkeys:"),
 
  828                       TQString::number( res.newSubkeys() ) ) );
 
  829    if ( res.newRevocations() )
 
  830      lines.push_back( boldLine.arg( i18n(
"Newly revoked:"),
 
  831                     TQString::number( res.newRevocations() ) ) );
 
  832    if ( res.notImported() )
 
  833      lines.push_back( boldLine.arg( i18n(
"Not imported:"),
 
  834                     TQString::number( res.notImported() ) ) );
 
  835    if ( res.numUnchanged() )
 
  836      lines.push_back( normalLine.arg( i18n(
"Unchanged:"),
 
  837                       TQString::number( res.numUnchanged() ) ) );
 
  838    if ( res.numSecretKeysConsidered() )
 
  839      lines.push_back( normalLine.arg( i18n(
"Secret keys processed:"),
 
  840                       TQString::number( res.numSecretKeysConsidered() ) ) );
 
  841    if ( res.numSecretKeysImported() )
 
  842      lines.push_back( normalLine.arg( i18n(
"Secret keys imported:"),
 
  843                       TQString::number( res.numSecretKeysImported() ) ) );
 
  844    if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
 
  845      lines.push_back( boldLine.arg( i18n(
"Secret keys <em>not</em> imported:"),
 
  846                     TQString::number( res.numSecretKeysConsidered()
 
  847                              - res.numSecretKeysImported()
 
  848                              - res.numSecretKeysUnchanged() ) ) );
 
  849    if ( res.numSecretKeysUnchanged() )
 
  850      lines.push_back( normalLine.arg( i18n(
"Secret keys unchanged:"),
 
  851                       TQString::number( res.numSecretKeysUnchanged() ) ) );
 
  853    KMessageBox::information( 
this,
 
  854                  i18n( 
"<qt><p>Detailed results of importing %1:</p>" 
  855                    "<table>%2</table></qt>" )
 
  856                  .arg( displayName ).arg( lines.join( TQString() ) ),
 
  857                  i18n( 
"Certificate Import Result" ) );
 
  859    disconnectJobFromStatusBarProgress( res.error() );
 
  861    const std::vector<GpgME::Import> imports = res.imports();
 
  862    for ( std::vector<GpgME::Import>::const_iterator it = imports.begin() ; it != imports.end() ; ++it )
 
  863      mPreviouslySelectedFingerprints.insert( it->fingerprint() );
 
  865  importNextURLOrRedisplay();
 
  874void CertManager::slotDirmngrExited() {
 
  875    if ( !mDirmngrProc->normalExit() )
 
  876        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" ) );
 
  877    else if ( mDirmngrProc->exitStatus() )
 
  878      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" ) );
 
  880      KMessageBox::information( 
this, i18n( 
"CRL file imported successfully." ), i18n( 
"Certificate Manager Information" ) );
 
  882    delete mDirmngrProc; mDirmngrProc = 0;
 
  883    if ( !mImportCRLTempFile.isEmpty() )
 
  884      TQFile::remove( mImportCRLTempFile );
 
  885    updateImportActions( 
true );
 
  891void CertManager::importCRLFromFile() {
 
  893  TQString filter = TQString(
"*.crl *.arl *-crl.der *-arl.der|") + i18n(
"Certificate Revocation List, DER encoded (*.crl *.arl *-crl.der *-arl.der)");
 
  894  KURL url = KFileDialog::getOpenURL( TQString(),
 
  897                                      i18n( 
"Select CRL File" ) );
 
  898  if ( url.isValid() ) {
 
  899    updateImportActions( 
false );
 
  900    if ( url.isLocalFile() ) {
 
  901      startImportCRL( url.path(), 
false );
 
  902      updateImportActions( 
true );
 
  906      destURL.setPath( tempFile.name() );
 
  907      TDEIO::Job* copyJob = TDEIO::file_copy( url, destURL, 0600, 
true, 
false );
 
  908      copyJob->setWindow( 
this );
 
  909      connect( copyJob, TQ_SIGNAL( result( TDEIO::Job * ) ),
 
  910               TQ_SLOT( slotImportCRLJobFinished( TDEIO::Job * ) ) );
 
  915void CertManager::slotImportCRLJobFinished( TDEIO::Job *job )
 
  917  TDEIO::FileCopyJob* fcjob = 
static_cast<TDEIO::FileCopyJob*
>( job );
 
  918  TQString tempFilePath = fcjob->destURL().path();
 
  919  if ( job->error() ) {
 
  920    job->showErrorDialog();
 
  921    TQFile::remove( tempFilePath ); 
 
  922    updateImportActions( 
true );
 
  925  startImportCRL( tempFilePath, 
true );
 
  928bool CertManager::connectAndStartDirmngr( 
const char * slot, 
const char * processname ) {
 
  930  assert( processname );
 
  931  assert( mDirmngrProc );
 
  932  mErrorbuffer = TQString();
 
  933  connect( mDirmngrProc, TQ_SIGNAL(processExited(TDEProcess*)), slot );
 
  934  connect( mDirmngrProc, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int) ),
 
  935           this, TQ_SLOT(slotStderr(TDEProcess*,
char*,
int)) );
 
  936  if( !mDirmngrProc->start( TDEProcess::NotifyOnExit, TDEProcess::Stderr ) ) {
 
  937    delete mDirmngrProc; mDirmngrProc = 0;
 
  938    KMessageBox::error( 
this, i18n( 
"Unable to start %1 process. Please check your installation." ).arg( processname ), i18n( 
"Certificate Manager Error" ) );
 
  944void CertManager::startImportCRL( 
const TQString& filename, 
bool isTempFile )
 
  946  assert( !mDirmngrProc );
 
  947  mImportCRLTempFile = isTempFile ? filename : TQString();
 
  948  mDirmngrProc = 
new TDEProcess();
 
  949  *mDirmngrProc << 
"gpgsm" << 
"--call-dirmngr" << 
"loadcrl" << filename;
 
  950  if ( !connectAndStartDirmngr( TQ_SLOT(slotDirmngrExited()), 
"gpgsm" ) ) {
 
  951    updateImportActions( 
true );
 
  953      TQFile::remove( mImportCRLTempFile ); 
 
  957void CertManager::startClearCRLs() {
 
  958  assert( !mDirmngrProc );
 
  959  mDirmngrProc = 
new TDEProcess();
 
  960  *mDirmngrProc << 
"dirmngr" << 
"--flush";
 
  962  connectAndStartDirmngr( TQ_SLOT(slotClearCRLsResult()), 
"dirmngr" );
 
  965void CertManager::slotStderr( TDEProcess*, 
char* buf, 
int len ) {
 
  966  mErrorbuffer += TQString::fromLocal8Bit( buf, len );
 
  972void CertManager::importCRLFromLDAP()
 
  974  tqDebug(
"Not Yet Implemented");
 
  977void CertManager::slotViewCRLs() {
 
  979    mCrlView = 
new CRLView( 
this );
 
  982  mCrlView->slotUpdateView();
 
  986void CertManager::slotClearCRLs() {
 
  990void CertManager::slotClearCRLsResult() {
 
  991  assert( mDirmngrProc );
 
  992  if ( !mDirmngrProc->normalExit() )
 
  993    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" ) );
 
  994  else if ( mDirmngrProc->exitStatus() )
 
  995    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" ) );
 
  997    KMessageBox::information( 
this, i18n( 
"CRL cache cleared successfully." ), i18n( 
"Certificate Manager Information" ) );
 
  998  delete mDirmngrProc; mDirmngrProc = 0;
 
 1001static void showDeleteError( TQWidget * parent, 
const GpgME::Error & err ) {
 
 1003  const TQString msg = i18n(
"<qt><p>An error occurred while trying to delete " 
 1004               "the certificates:</p>" 
 1005               "<p><b>%1</b></p></qt>")
 
 1006    .arg( TQString::fromLocal8Bit( err.asString() ) );
 
 1007  KMessageBox::error( parent, msg, i18n(
"Certificate Deletion Failed") );
 
 1010static bool ByFingerprint( 
const GpgME::Key & left, 
const GpgME::Key & right ) {
 
 1011  return tqstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) < 0 ;
 
 1014static bool WithRespectToFingerprints( 
const GpgME::Key & left, 
const GpgME::Key & right ) {
 
 1015  return tqstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) == 0;
 
 1018void CertManager::slotDeleteCertificate() {
 
 1019  mItemsToDelete = mKeyListView->selectedItems();
 
 1020  if ( mItemsToDelete.isEmpty() )
 
 1022  std::vector<GpgME::Key> keys;
 
 1023  keys.reserve( mItemsToDelete.count() );
 
 1024  TQStringList keyDisplayNames;
 
 1025  for ( TQPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete ) ; it.current() ; ++it )
 
 1026    if ( !it.current()->key().isNull() ) {
 
 1027      keys.push_back( it.current()->key() );
 
 1028      keyDisplayNames.push_back( it.current()->text( 0 ) );
 
 1033  if ( !mHierarchyAnalyser ) {
 
 1034    mHierarchyAnalyser = 
new HierarchyAnalyser( 
this, 
"mHierarchyAnalyser" );
 
 1035    Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob();
 
 1037    connect( job, TQ_SIGNAL(nextKey(
const GpgME::Key&)),
 
 1038         mHierarchyAnalyser, TQ_SLOT(slotNextKey(
const GpgME::Key&)) );
 
 1039    connect( job, TQ_SIGNAL(result(
const GpgME::KeyListResult&)),
 
 1040         this, TQ_SLOT(slotDeleteCertificate()) );
 
 1041    connectJobToStatusBarProgress( job, i18n(
"Checking key dependencies...") );
 
 1042    if ( 
const GpgME::Error error = job->start( TQStringList() ) ) {
 
 1043      showKeyListError( 
this, error );
 
 1044      delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
 
 1048    disconnectJobFromStatusBarProgress( 0 );
 
 1050  std::vector<GpgME::Key> keysToDelete = keys;
 
 1051  for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
 
 1052    if ( !it->isNull() ) {
 
 1053      const std::vector<GpgME::Key> subjects
 
 1054    = mHierarchyAnalyser->subjectsForIssuerRecursive( it->primaryFingerprint() );
 
 1055      keysToDelete.insert( keysToDelete.end(), subjects.begin(), subjects.end() );
 
 1058  std::sort( keysToDelete.begin(), keysToDelete.end(), ByFingerprint );
 
 1059  keysToDelete.erase( std::unique( keysToDelete.begin(), keysToDelete.end(),
 
 1060                   WithRespectToFingerprints ),
 
 1061              keysToDelete.end() );
 
 1063  delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
 
 1065  if ( keysToDelete.size() > keys.size() )
 
 1066    if ( KMessageBox::warningContinueCancel( 
this,
 
 1067                         i18n(
"Some or all of the selected " 
 1068                          "certificates are issuers (CA certificates) " 
 1069                          "for other, non-selected certificates.\n" 
 1070                          "Deleting a CA certificate will also delete " 
 1071                          "all certificates issued by it."),
 
 1072                         i18n(
"Deleting CA Certificates") )
 
 1073     != KMessageBox::Continue )
 
 1076  const TQString msg = keysToDelete.size() > keys.size()
 
 1077    ? i18n(
"Do you really want to delete this certificate and the %1 certificates it certified?",
 
 1078       "Do you really want to delete these %n certificates and the %1 certificates they certified?",
 
 1079       keys.size() ).arg( keysToDelete.size() - keys.size() )
 
 1080    : i18n(
"Do you really want to delete this certificate?",
 
 1081       "Do you really want to delete these %n certificates?", keys.size() ) ;
 
 1083  if ( KMessageBox::warningContinueCancelList( 
this, msg, keyDisplayNames,
 
 1084                           i18n( 
"Delete Certificates" ),
 
 1085                           KGuiItem( i18n( 
"Delete" ), 
"edit-delete" ),
 
 1086                           "ConfirmDeleteCert", KMessageBox::Dangerous )
 
 1087       != KMessageBox::Continue )
 
 1090  if ( Kleo::DeleteJob * job = Kleo::CryptoBackendFactory::instance()->smime()->deleteJob() )
 
 1093    TQString str = keys.size() == 1
 
 1094                  ? i18n(
"<qt><p>An error occurred while trying to delete " 
 1095                         "the certificate:</p>" 
 1096                         "<p><b>%1</b><p></qt>" )
 
 1097                  : i18n( 
"<qt><p>An error occurred while trying to delete " 
 1098                          "the certificates:</p>" 
 1099                          "<p><b>%1</b><p></qt>" );
 
 1100    KMessageBox::error( 
this,
 
 1101            str.arg( i18n(
"Operation not supported by the backend.") ),
 
 1102            i18n(
"Certificate Deletion Failed") );
 
 1105  mItemsToDelete.clear(); 
 
 1106  for ( std::vector<GpgME::Key>::const_iterator it = keysToDelete.begin() ; it != keysToDelete.end() ; ++it )
 
 1107    if ( Kleo::KeyListViewItem * item = mKeyListView->itemByFingerprint( it->primaryFingerprint() ) )
 
 1108      mItemsToDelete.append( item );
 
 1110  Kleo::MultiDeleteJob * job = 
new Kleo::MultiDeleteJob( Kleo::CryptoBackendFactory::instance()->smime() );
 
 1113  connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const GpgME::Key&)),
 
 1114       TQ_SLOT(slotDeleteResult(
const GpgME::Error&,
const GpgME::Key&)) );
 
 1116  connectJobToStatusBarProgress( job, i18n(
"Deleting keys...") );
 
 1118  const GpgME::Error err = job->start( keys, 
true );
 
 1120    showDeleteError( 
this, err );
 
 1122    mProgressBar->setProgress( 0, 0 );
 
 1125void CertManager::slotDeleteResult( 
const GpgME::Error & err, 
const GpgME::Key & ) {
 
 1127    showDeleteError( 
this, err );
 
 1129    const int infinity = 100; 
 
 1130    mItemsToDelete.setAutoDelete( 
true );
 
 1131    for ( 
int i = 0 ; i < infinity ; ++i ) {
 
 1132      TQPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete );
 
 1133      while ( Kleo::KeyListViewItem * cur = it.current() ) {
 
 1135    if ( cur->childCount() == 0 ) {
 
 1136      mItemsToDelete.remove( cur );
 
 1139      if ( mItemsToDelete.isEmpty() )
 
 1142    mItemsToDelete.setAutoDelete( 
false );
 
 1143    Q_ASSERT( mItemsToDelete.isEmpty() );
 
 1144    mItemsToDelete.clear();
 
 1146  disconnectJobFromStatusBarProgress( err );
 
 1149void CertManager::slotViewDetails( Kleo::KeyListViewItem * item ) {
 
 1150  if ( !item || item->key().isNull() )
 
 1154  KDialogBase * dialog = 
new KDialogBase( 
this, 
"dialog", 
false, i18n(
"Additional Information for Key"), KDialogBase::Close, KDialogBase::Close );
 
 1156  CertificateInfoWidgetImpl * top = 
new CertificateInfoWidgetImpl( item->key(), isRemote(), dialog );
 
 1157  dialog->setMainWidget( top );
 
 1159  connect( top, TQ_SIGNAL(requestCertificateDownload(
const TQString&, 
const TQString&)),
 
 1160       TQ_SLOT(slotStartCertificateDownload(
const TQString&, 
const TQString&)) );
 
 1164void CertManager::slotViewDetails()
 
 1166  TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
 
 1167  if ( items.isEmpty() )
 
 1172  slotViewDetails( items.first() );
 
 1175void CertManager::slotSelectionChanged()
 
 1177  mKeyListView->flushKeys();
 
 1178  bool b = mKeyListView->hasSelection();
 
 1179  mExportCertificateAction->setEnabled( b );
 
 1180  mViewCertDetailsAction->setEnabled( b );
 
 1181  mDeleteCertificateAction->setEnabled( b );
 
 1182#ifdef NOT_IMPLEMENTED_ANYWAY 
 1183  mRevokeCertificateAction->setEnabled( b );
 
 1184  mExtendCertificateAction->setEnabled( b );
 
 1186  mDownloadCertificateAction->setEnabled( b && mRemote );
 
 1187  mValidateCertificateAction->setEnabled( !mRemote );
 
 1190void CertManager::slotExportCertificate() {
 
 1191  TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
 
 1192  if ( items.isEmpty() )
 
 1195  TQStringList fingerprints;
 
 1196  for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
 
 1197    if ( !it.current()->key().isNull() )
 
 1198      if ( 
const char * fpr = it.current()->key().primaryFingerprint() )
 
 1199    fingerprints.push_back( fpr );
 
 1201  startCertificateExport( fingerprints );
 
 1204static void showCertificateExportError( TQWidget * parent, 
const GpgME::Error & err ) {
 
 1206  const TQString msg = i18n(
"<qt><p>An error occurred while trying to export " 
 1207               "the certificate:</p>" 
 1208               "<p><b>%1</b></p></qt>")
 
 1209    .arg( TQString::fromLocal8Bit( err.asString() ) );
 
 1210  KMessageBox::error( parent, msg, i18n(
"Certificate Export Failed") );
 
 1213void CertManager::startCertificateExport( 
const TQStringList & fingerprints ) {
 
 1214  if ( fingerprints.empty() )
 
 1219  Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->publicKeyExportJob( 
true );
 
 1222  connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
 
 1223       TQ_SLOT(slotCertificateExportResult(
const GpgME::Error&,
const TQByteArray&)) );
 
 1225  connectJobToStatusBarProgress( job, i18n(
"Exporting certificate...") );
 
 1227  const GpgME::Error err = job->start( fingerprints );
 
 1229    showCertificateExportError( 
this, err );
 
 1231    mProgressBar->setProgress( 0, 0 );
 
 1235static bool checkOverwrite( 
const KURL& url, 
bool& overwrite, TQWidget* w )
 
 1237  if ( TDEIO::NetAccess::exists( url, 
false , w ) ) {
 
 1238    if ( KMessageBox::Cancel ==
 
 1239         KMessageBox::warningContinueCancel(
 
 1241                                            i18n( 
"A file named \"%1\" already exists. " 
 1242                                                  "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
 
 1243                                            i18n( 
"Overwrite File?" ),
 
 1244                                            i18n( 
"&Overwrite" ) ) )
 
 1251void CertManager::slotCertificateExportResult( 
const GpgME::Error & err, 
const TQByteArray & data ) {
 
 1252  disconnectJobFromStatusBarProgress( err );
 
 1254    showCertificateExportError( 
this, err );
 
 1258  kdDebug() << 
"CertManager::slotCertificateExportResult(): got " << data.size() << 
" bytes" << endl;
 
 1260  const TQString filter = TQString(
"*.pem|") + i18n(
"ASCII Armored Certificate Bundles (*.pem)");
 
 1261  const KURL url = KFileDialog::getOpenURL( TQString(),
 
 1264                                      i18n( 
"Save Certificate" ) );
 
 1265  if ( !url.isValid() )
 
 1268  bool overwrite = 
false;
 
 1269  if ( !checkOverwrite( url, overwrite, 
this ) )
 
 1272  TDEIO::Job* uploadJob = TDEIOext::put( data, url, -1, overwrite, 
false  );
 
 1273  uploadJob->setWindow( 
this );
 
 1274  connect( uploadJob, TQ_SIGNAL( result( TDEIO::Job* ) ),
 
 1275           this, TQ_SLOT( slotUploadResult( TDEIO::Job* ) ) );
 
 1279void CertManager::slotExportSecretKey() {
 
 1280  Kleo::KeySelectionDialog dlg( i18n(
"Secret Key Export"),
 
 1282                                i18n(
"Select the secret key to export " 
 1283                     "(<b>Warning: The PKCS#12 format is insecure; " 
 1284                     "exporting secret keys is discouraged</b>):") +
 
 1286                std::vector<GpgME::Key>(),
 
 1287                Kleo::KeySelectionDialog::SecretKeys|Kleo::KeySelectionDialog::SMIMEKeys,
 
 1290                this, 
"secret key export key selection dialog" );
 
 1293  if ( dlg.exec() != TQDialog::Accepted )
 
 1296  startSecretKeyExport( dlg.fingerprint() );
 
 1299static void showSecretKeyExportError( TQWidget * parent, 
const GpgME::Error & err ) {
 
 1301  const TQString msg = i18n(
"<qt><p>An error occurred while trying to export " 
 1302               "the secret key:</p>" 
 1303               "<p><b>%1</b></p></qt>")
 
 1304    .arg( TQString::fromLocal8Bit( err.asString() ) );
 
 1305  KMessageBox::error( parent, msg, i18n(
"Secret-Key Export Failed") );
 
 1308void CertManager::startSecretKeyExport( 
const TQString & fingerprint ) {
 
 1309  if ( fingerprint.isEmpty() )
 
 1315  Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
 
 1317  if ( config && config->entry( 
"gpgsm", 
"Configuration", 
"p12-charset" ) ) {
 
 1320    static const char *charsets[] = {
 
 1339    TQStringList charsetList;
 
 1340    for ( 
const char** c = charsets; *c; ++c ) {
 
 1341      charsetList.append( TQString::fromLatin1( *c ) );
 
 1347    charset = KInputDialog::getItem( i18n(
"Exporting secret key..."),
 
 1348                                     i18n(
"Choose a charset for encoding the pkcs#12 passphrase (utf8 is recommended)"),
 
 1356  Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->secretKeyExportJob( 
false, charset );
 
 1359  connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
 
 1360       TQ_SLOT(slotSecretKeyExportResult(
const GpgME::Error&,
const TQByteArray&)) );
 
 1362  connectJobToStatusBarProgress( job, i18n(
"Exporting secret key...") );
 
 1364  const GpgME::Error err = job->start( fingerprint );
 
 1366    showSecretKeyExportError( 
this, err );
 
 1368    mProgressBar->setProgress( 0, 0 );
 
 1371void CertManager::slotSecretKeyExportResult( 
const GpgME::Error & err, 
const TQByteArray & data ) {
 
 1372  disconnectJobFromStatusBarProgress( err );
 
 1374    showSecretKeyExportError( 
this, err );
 
 1378  kdDebug() << 
"CertManager::slotSecretKeyExportResult(): got " << data.size() << 
" bytes" << endl;
 
 1379  TQString filter = TQString(
"*.p12|") + i18n(
"PKCS#12 Key Bundle (*.p12)");
 
 1380  KURL url = KFileDialog::getOpenURL( TQString(),
 
 1383                                      i18n( 
"Save Certificate" ) );
 
 1384  if ( !url.isValid() )
 
 1387  bool overwrite = 
false;
 
 1388  if ( !checkOverwrite( url, overwrite, 
this ) )
 
 1391  TDEIO::Job* uploadJob = TDEIOext::put( data, url, -1, overwrite, 
false  );
 
 1392  uploadJob->setWindow( 
this );
 
 1393  connect( uploadJob, TQ_SIGNAL( result( TDEIO::Job* ) ),
 
 1394           this, TQ_SLOT( slotUploadResult( TDEIO::Job* ) ) );
 
 1397void CertManager::slotUploadResult( TDEIO::Job* job )
 
 1400    job->showErrorDialog();
 
 1403void CertManager::slotDropped(
const KURL::List& lst)
 
 1405  mURLsToImport = lst;
 
 1407    importNextURLOrRedisplay();
 
 1410void CertManager::importNextURLOrRedisplay()
 
 1412  if ( !mURLsToImport.empty() ) {
 
 1414    KURL url = mURLsToImport.front();
 
 1415    mURLsToImport.pop_front();
 
 1416    slotImportCertFromFile( url );
 
 1420    startKeyListing( 
false, 
true, mPreviouslySelectedFingerprints );
 
 1424void CertManager::slotStartWatchGnuPG()
 
 1426  TDEProcess certManagerProc;
 
 1427  certManagerProc << 
"kwatchgnupg";
 
 1429  if( !certManagerProc.start( TDEProcess::DontCare ) )
 
 1430    KMessageBox::error( 
this, i18n( 
"Could not start GnuPG LogViewer (kwatchgnupg). " 
 1431                                    "Please check your installation!" ),
 
 1432                                    i18n( 
"Kleopatra Error" ) );
 
 1435#include "certmanager.moc" 
We need to derive from Kleo::KeyListView simply to add support for drop events.
 
StoredTransferJob is a TransferJob (for downloading or uploading data) that also stores a TQByteArray...
 
TQByteArray data() const
Get hold of the downloaded data.