00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
00111
00112 class Kleo::ProtocolCheckListItem : public QCheckListItem
00113 {
00114 public:
00115 ProtocolCheckListItem( BackendListViewItem* blvi,
00116 QListViewItem* prev,
00117 ProtocolType protocolType,
00118 const CryptoBackend::Protocol* protocol )
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
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
00135 if ( b )
00136 lv->deselectAll( mProtocolType, this );
00137 lv->emitChanged();
00138 QCheckListItem::stateChange( b );
00139 }
00140
00141 private:
00142
00143 static QString itemText( ProtocolType protocolType, const CryptoBackend::Protocol* protocol ) {
00144
00145 QString protoTypeName = protocolType == OpenPGP ? i18n( "OpenPGP" ) : i18n( "S/MIME" );
00146
00147 QString impName = protocol ? protocol->displayName() : i18n( "failed" );
00148 return QString( "%1 (%2)" ).arg( protoTypeName ).arg( impName );
00149 }
00150
00151 const CryptoBackend::Protocol* mProtocol;
00152 ProtocolType mProtocolType;
00153 };
00154
00155 const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const {
00156 QListViewItem* curItem = currentItem();
00157 if ( !curItem )
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
00167 const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( ProtocolType protocolType )
00168 {
00169 QListViewItemIterator it( this );
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
00175
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 );
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 );
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
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
00312 kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
00313 }
00314 }
00315 else
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"