certmanager Library API Documentation

backendconfigwidget.cpp

00001 /*  -*- c++ -*-
00002     backendconfigwidget.cpp
00003 
00004     This file is part of libkleopatra, the KDE keymanagement library
00005     Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
00006     Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
00007 
00008     Libkleopatra is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU General Public License as
00010     published by the Free Software Foundation; either version 2 of the
00011     License, or (at your option) any later version.
00012 
00013     Libkleopatra is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022     In addition, as a special exception, the copyright holders give
00023     permission to link the code of this program with any edition of
00024     the Qt library by Trolltech AS, Norway (or with modified versions
00025     of Qt that use the same license as Qt), and distribute linked
00026     combinations including the two.  You must obey the GNU General
00027     Public License in all respects for all of the code used other than
00028     Qt.  If you modify this file, you may extend this exception to
00029     your version of the file, but you are not obligated to do so.  If
00030     you do not wish to do so, delete this exception statement from
00031     your version.
00032  */
00033 
00034 #ifdef HAVE_CONFIG_H
00035 #include <config.h>
00036 #endif
00037 
00038 #include "backendconfigwidget.h"
00039 #include "cryptoconfigdialog.h"
00040 
00041 #include "kleo/cryptobackendfactory.h"
00042 
00043 #include <klistview.h>
00044 #include <kdialog.h>
00045 #include <klocale.h>
00046 #include <kdebug.h>
00047 #include <kmessagebox.h>
00048 #include <kapplication.h>
00049 #include <dcopclient.h>
00050 
00051 #include <qpushbutton.h>
00052 #include <qlayout.h>
00053 #include <qheader.h>
00054 
00055 #include <assert.h>
00056 
00057 namespace Kleo {
00058   class BackendListView;
00059 }
00060 
00061 class Kleo::BackendConfigWidget::Private {
00062 public:
00063   Kleo::BackendListView * listView;
00064   QPushButton * configureButton;
00065   QPushButton * rescanButton;
00066   Kleo::CryptoBackendFactory * backendFactory;
00067 };
00068 
00069 namespace Kleo {
00070   class BackendListViewItem;
00071   class ProtocolCheckListItem;
00072   enum ProtocolType { OpenPGP, SMIME };
00073 }
00074 
00075 class Kleo::BackendListView : public KListView
00076 {
00077 public:
00078   BackendListView( BackendConfigWidget* parent, const char* name = 0 )
00079     : KListView( parent, name ) {}
00080 
00082   const Kleo::CryptoBackend* currentBackend() const;
00083 
00085   const Kleo::CryptoBackend* chosenBackend( ProtocolType protocolType );
00086 
00088   void deselectAll( ProtocolType protocolType, QCheckListItem* except );
00089 
00090   void emitChanged() { static_cast<BackendConfigWidget *>( parentWidget() )->emitChanged( true ); }
00091 };
00092 
00093 // Toplevel listviewitem for a given backend (e.g. "GpgME", "Kgpg/gpg v2")
00094 class Kleo::BackendListViewItem : public QListViewItem
00095 {
00096 public:
00097   BackendListViewItem( KListView* lv, QListViewItem *prev, const CryptoBackend *cryptoBackend )
00098     : QListViewItem( lv, prev, cryptoBackend->displayName() ), mCryptoBackend( cryptoBackend )
00099     {}
00100 
00101   const CryptoBackend *cryptoBackend() const { return mCryptoBackend; }
00102   static const int RTTI = 20001;
00103   virtual int rtti() const { return RTTI; }
00104 
00105 private:
00106   const CryptoBackend *mCryptoBackend;
00107 };
00108 
00109 
00110 // Checklist item under a BackendListViewItem
00111 // (e.g. "GpgME supports protocol OpenPGP")
00112 class Kleo::ProtocolCheckListItem : public QCheckListItem
00113 {
00114 public:
00115   ProtocolCheckListItem( BackendListViewItem* blvi,
00116                          QListViewItem* prev,
00117                          ProtocolType protocolType,
00118                          const CryptoBackend::Protocol* protocol ) // can be 0
00119     : QCheckListItem( blvi, prev, itemText( protocolType, protocol ),
00120                       QCheckListItem::CheckBox ),
00121       mProtocol( protocol ), mProtocolType( protocolType )
00122     {}
00123 
00124   static const int RTTI = 20002;
00125   virtual int rtti() const { return RTTI; }
00126 
00127   // can be 0
00128   const CryptoBackend::Protocol* protocol() const { return mProtocol; }
00129   ProtocolType protocolType() const { return mProtocolType; }
00130 
00131 protected:
00132   virtual void stateChange( bool b ) {
00133     BackendListView* lv = static_cast<BackendListView *>( listView() );
00134     // "radio-button-like" behavior for the protocol checkboxes
00135     if ( b )
00136       lv->deselectAll( mProtocolType, this );
00137     lv->emitChanged();
00138     QCheckListItem::stateChange( b );
00139   }
00140 
00141 private:
00142   // Helper for the constructor.
00143   static QString itemText( ProtocolType protocolType, const CryptoBackend::Protocol* protocol ) {
00144     // First one is the generic name (OpenPGP, SMIME)
00145     QString protoTypeName = protocolType == OpenPGP ? i18n( "OpenPGP" ) : i18n( "S/MIME" );
00146     // second one is implementation name (gpg, gpgsm...)
00147     QString impName = protocol ? protocol->displayName() : i18n( "failed" );
00148     return QString( "%1 (%2)" ).arg( protoTypeName ).arg( impName );
00149   }
00150 
00151   const CryptoBackend::Protocol* mProtocol; // can be 0
00152   ProtocolType mProtocolType;
00153 };
00154 
00155 const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const {
00156   QListViewItem* curItem = currentItem();
00157   if ( !curItem ) // can't happen
00158     return 0;
00159   if ( curItem->rtti() == Kleo::ProtocolCheckListItem::RTTI )
00160     curItem = curItem->parent();
00161   if ( curItem && curItem->rtti() == Kleo::BackendListViewItem::RTTI )
00162     return static_cast<Kleo::BackendListViewItem *>( curItem )->cryptoBackend();
00163   return 0;
00164 }
00165 
00166 // can't be const method due to QListViewItemIterator (why?)
00167 const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( ProtocolType protocolType )
00168 {
00169   QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ );
00170   for ( ; it.current() ; ++it ) {
00171     if( it.current()->rtti() == Kleo::ProtocolCheckListItem::RTTI ) {
00172       Kleo::ProtocolCheckListItem* p = static_cast<Kleo::ProtocolCheckListItem *>( it.current() );
00173       if ( p->isOn() && p->protocolType() == protocolType ) {
00174         // OK that's the one. Now go up to the parent backend
00175         // (need to do that in the listview since Protocol doesn't know it)
00176         QListViewItem* parItem = it.current()->parent();
00177         if ( parItem && parItem->rtti() == Kleo::BackendListViewItem::RTTI )
00178           return static_cast<Kleo::BackendListViewItem *>( parItem )->cryptoBackend();
00179       }
00180     }
00181   }
00182   return 0;
00183 }
00184 
00185 void Kleo::BackendListView::deselectAll( ProtocolType protocolType, QCheckListItem* except )
00186 {
00187   QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ );
00188   for ( ; it.current() ; ++it ) {
00189     if( it.current() != except &&
00190         it.current()->rtti() == Kleo::ProtocolCheckListItem::RTTI ) {
00191       Kleo::ProtocolCheckListItem* p = static_cast<Kleo::ProtocolCheckListItem *>( it.current() );
00192       if ( p->isOn() && p->protocolType() == protocolType )
00193         p->setOn( false );
00194     }
00195   }
00196 }
00197 
00199 
00200 Kleo::BackendConfigWidget::BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent, const char * name, WFlags f )
00201   : QWidget( parent, name, f ), d( 0 )
00202 {
00203   assert( factory );
00204   d = new Private();
00205   d->backendFactory = factory;
00206 
00207   QHBoxLayout * hlay =
00208     new QHBoxLayout( this, 0, KDialog::spacingHint() );
00209 
00210   d->listView = new BackendListView( this, "d->listView" );
00211   d->listView->addColumn( i18n("Available Backends") );
00212   d->listView->setAllColumnsShowFocus( true );
00213   d->listView->setSorting( -1 );
00214   d->listView->header()->setClickEnabled( false );
00215   d->listView->setFullWidth( true );
00216 
00217   hlay->addWidget( d->listView, 1 );
00218 
00219   connect( d->listView, SIGNAL(selectionChanged(QListViewItem*)),
00220        SLOT(slotSelectionChanged(QListViewItem*)) );
00221 
00222   QVBoxLayout * vlay = new QVBoxLayout( hlay ); // inherits spacing
00223 
00224   d->configureButton = new QPushButton( i18n("Confi&gure..."), this );
00225   d->configureButton->setAutoDefault( false );
00226   vlay->addWidget( d->configureButton );
00227 
00228   connect( d->configureButton, SIGNAL(clicked()),
00229        SLOT(slotConfigureButtonClicked()) );
00230 
00231   d->rescanButton = new QPushButton( i18n("Rescan"), this );
00232   d->rescanButton->setAutoDefault( false );
00233   vlay->addWidget( d->rescanButton );
00234 
00235   connect( d->rescanButton, SIGNAL(clicked()),
00236        SLOT(slotRescanButtonClicked()) );
00237 
00238   vlay->addStretch( 1 );
00239 }
00240 
00241 Kleo::BackendConfigWidget::~BackendConfigWidget() {
00242   delete d; d = 0;
00243 }
00244 
00245 void Kleo::BackendConfigWidget::load() {
00246   d->listView->clear();
00247 
00248   unsigned int backendCount = 0;
00249 
00250   // populate the plugin list:
00251   BackendListViewItem * top = 0;
00252   for ( unsigned int i = 0 ; const CryptoBackend * b = d->backendFactory->backend( i ) ; ++i ) {
00253     const CryptoBackend::Protocol * openpgp = b->openpgp();
00254     const CryptoBackend::Protocol * smime = b->smime();
00255 
00256     top = new Kleo::BackendListViewItem( d->listView, top, b );
00257     ProtocolCheckListItem * last = 0;
00258     if ( openpgp ) {
00259       last = new ProtocolCheckListItem( top, last, Kleo::OpenPGP, openpgp );
00260       last->setOn( openpgp == d->backendFactory->openpgp() );
00261     } else if ( b->supportsOpenPGP() ) {
00262       last = new ProtocolCheckListItem( top, last, Kleo::OpenPGP, 0 );
00263       last->setOn( false );
00264       last->setEnabled( false );
00265     }
00266     if ( smime ) {
00267       last = new ProtocolCheckListItem( top, last, Kleo::SMIME, smime );
00268       last->setOn( smime == d->backendFactory->smime() );
00269     } else if ( b->supportsSMIME() ) {
00270       last = new ProtocolCheckListItem( top, last, Kleo::SMIME, 0 );
00271       last->setOn( false );
00272       last->setEnabled( false );
00273     }
00274     top->setOpen( true );
00275 
00276     ++backendCount;
00277   }
00278 
00279   if ( backendCount ) {
00280     d->listView->setCurrentItem( d->listView->firstChild() );
00281     d->listView->setSelected( d->listView->firstChild(), true );
00282   }
00283 
00284   slotSelectionChanged( d->listView->firstChild() );
00285 }
00286 
00287 void Kleo::BackendConfigWidget::slotSelectionChanged( QListViewItem * ) {
00288   const CryptoBackend* backend = d->listView->currentBackend();
00289   d->configureButton->setEnabled( backend && backend->config() );
00290 }
00291 
00292 
00293 void Kleo::BackendConfigWidget::slotRescanButtonClicked() {
00294   QStringList reasons;
00295   d->backendFactory->scanForBackends( &reasons );
00296   if ( !reasons.empty() )
00297     KMessageBox::informationList( this,
00298                   i18n("The following problems where encountered during scanning:"),
00299                   reasons, i18n("Scan Results") );
00300   load();
00301   emit changed( true );
00302 }
00303 
00304 void Kleo::BackendConfigWidget::slotConfigureButtonClicked() {
00305   const CryptoBackend* backend = d->listView->currentBackend();
00306   if ( backend && backend->config() ) {
00307     Kleo::CryptoConfigDialog dlg( backend->config() );
00308     int result = dlg.exec();
00309     if ( result == QDialog::Accepted )
00310     {
00311       // Tell other users of gpgconf (e.g. the s/mime page) that the gpgconf data might have changed
00312       kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
00313     }
00314   }
00315   else // shouldn't happen, button is disabled
00316     kdWarning(5150) << "Can't configure backend, no config object available" << endl;
00317 }
00318 
00319 void Kleo::BackendConfigWidget::save() const {
00320   d->backendFactory->setSMIMEBackend( d->listView->chosenBackend( Kleo::SMIME ) );
00321   d->backendFactory->setOpenPGPBackend( d->listView->chosenBackend( Kleo::OpenPGP ) );
00322 }
00323 
00324 void Kleo::BackendConfigWidget::virtual_hook( int, void* ) {}
00325 
00326 #include "backendconfigwidget.moc"
KDE Logo
This file is part of the documentation for certmanager Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:39:31 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003