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 #include "ui/keylistview.h"
00043
00044 #include <klistview.h>
00045 #include <kdialog.h>
00046 #include <klocale.h>
00047 #include <kdebug.h>
00048 #include <kmessagebox.h>
00049 #include <kapplication.h>
00050 #include <dcopclient.h>
00051
00052 #include <qpushbutton.h>
00053 #include <qlayout.h>
00054 #include <qheader.h>
00055 #include <qtimer.h>
00056
00057 #include <assert.h>
00058
00059 namespace Kleo {
00060 class BackendListView;
00061 }
00062
00063 class Kleo::BackendConfigWidget::Private {
00064 public:
00065 Kleo::BackendListView * listView;
00066 QPushButton * configureButton;
00067 QPushButton * rescanButton;
00068 Kleo::CryptoBackendFactory * backendFactory;
00069 };
00070
00071 namespace Kleo {
00072 class BackendListViewItem;
00073 class ProtocolCheckListItem;
00074 }
00075
00076 class Kleo::BackendListView : public KListView
00077 {
00078 public:
00079 BackendListView( BackendConfigWidget* parent, const char* name = 0 )
00080 : KListView( parent, name ) {}
00081
00083 const Kleo::CryptoBackend* currentBackend() const;
00084
00086 const Kleo::CryptoBackend* chosenBackend( const char * protocol );
00087
00089 void deselectAll( const char * protocol, QCheckListItem* except );
00090
00091 void emitChanged() { static_cast<BackendConfigWidget *>( parentWidget() )->emitChanged( true ); }
00092 };
00093
00094
00095 class Kleo::BackendListViewItem : public QListViewItem
00096 {
00097 public:
00098 BackendListViewItem( KListView* lv, QListViewItem *prev, const CryptoBackend *cryptoBackend )
00099 : QListViewItem( lv, prev, cryptoBackend->displayName() ), mCryptoBackend( cryptoBackend )
00100 {}
00101
00102 const CryptoBackend *cryptoBackend() const { return mCryptoBackend; }
00103 enum { RTTI = 0x2EAE3BE0, RTTI_MASK = 0xFFFFFFFF };
00104 int rtti() const { return RTTI; }
00105
00106 private:
00107 const CryptoBackend *mCryptoBackend;
00108 };
00109
00110
00111
00112
00113 class Kleo::ProtocolCheckListItem : public QCheckListItem
00114 {
00115 public:
00116 ProtocolCheckListItem( BackendListViewItem* blvi,
00117 QListViewItem* prev, const char * protocolName,
00118 const CryptoBackend::Protocol* protocol )
00119 : QCheckListItem( blvi, prev, itemText( protocolName, protocol ),
00120 QCheckListItem::CheckBox ),
00121 mProtocol( protocol ), mProtocolName( protocolName )
00122 {}
00123
00124 enum { RTTI = 0x2EAE3BE1, RTTI_MASK = 0xFFFFFFFF };
00125 virtual int rtti() const { return RTTI; }
00126
00127
00128 const CryptoBackend::Protocol* protocol() const { return mProtocol; }
00129 const char * protocolName() const { return mProtocolName; }
00130
00131 protected:
00132 virtual void stateChange( bool b ) {
00133 BackendListView* lv = static_cast<BackendListView *>( listView() );
00134
00135 if ( b )
00136 lv->deselectAll( mProtocolName, this );
00137 lv->emitChanged();
00138 QCheckListItem::stateChange( b );
00139 }
00140
00141 private:
00142
00143 static QString itemText( const char * protocolName, const CryptoBackend::Protocol* protocol ) {
00144
00145 const QString protoName = qstricmp( protocolName, "openpgp" ) != 0
00146 ? qstricmp( protocolName, "smime" ) != 0
00147 ? QString::fromLatin1( protocolName )
00148 : i18n( "S/MIME" )
00149 : i18n( "OpenPGP" );
00150
00151 const QString impName = protocol ? protocol->displayName() : i18n( "failed" );
00152 return i18n( "Items in Kleo::BackendConfigWidget listview (1: protocol; 2: implementation name)",
00153 "%1 (%2)" ).arg( protoName, impName );
00154 }
00155
00156 const CryptoBackend::Protocol* mProtocol;
00157 const char * mProtocolName;
00158 };
00159
00160 const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const {
00161 const QListViewItem* curItem = currentItem();
00162 if ( !curItem )
00163 return 0;
00164 if ( lvi_cast<Kleo::ProtocolCheckListItem>( curItem ) )
00165 curItem = curItem->parent();
00166 if ( const Kleo::BackendListViewItem * blvi = lvi_cast<Kleo::BackendListViewItem>( curItem ) )
00167 return blvi->cryptoBackend();
00168 return 0;
00169 }
00170
00171
00172 const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( const char * protocolName )
00173 {
00174 for ( QListViewItemIterator it( this ) ;
00175 it.current() ; ++it )
00176 if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
00177 if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 ) {
00178
00179
00180 if ( const BackendListViewItem * parItem = lvi_cast<BackendListViewItem>( it.current()->parent() ) )
00181 return parItem->cryptoBackend();
00182 }
00183 return 0;
00184 }
00185
00186 void Kleo::BackendListView::deselectAll( const char * protocolName, QCheckListItem* except )
00187 {
00188 for ( QListViewItemIterator it( this ) ;
00189 it.current() ; ++it ) {
00190 if ( it.current() == except ) continue;
00191 if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
00192 if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 )
00193 p->setOn( false );
00194 }
00195 }
00196
00198
00199 Kleo::BackendConfigWidget::BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent, const char * name, WFlags f )
00200 : QWidget( parent, name, f ), d( 0 )
00201 {
00202 assert( factory );
00203 d = new Private();
00204 d->backendFactory = factory;
00205
00206 QHBoxLayout * hlay =
00207 new QHBoxLayout( this, 0, KDialog::spacingHint() );
00208
00209 d->listView = new BackendListView( this, "d->listView" );
00210 d->listView->addColumn( i18n("Available Backends") );
00211 d->listView->setAllColumnsShowFocus( true );
00212 d->listView->setSorting( -1 );
00213 d->listView->header()->setClickEnabled( false );
00214 d->listView->setFullWidth( true );
00215
00216 hlay->addWidget( d->listView, 1 );
00217
00218 connect( d->listView, SIGNAL(selectionChanged(QListViewItem*)),
00219 SLOT(slotSelectionChanged(QListViewItem*)) );
00220
00221 QVBoxLayout * vlay = new QVBoxLayout( hlay );
00222
00223 d->configureButton = new QPushButton( i18n("Confi&gure..."), this );
00224 d->configureButton->setAutoDefault( false );
00225 vlay->addWidget( d->configureButton );
00226
00227 connect( d->configureButton, SIGNAL(clicked()),
00228 SLOT(slotConfigureButtonClicked()) );
00229
00230 d->rescanButton = new QPushButton( i18n("Rescan"), this );
00231 d->rescanButton->setAutoDefault( false );
00232 vlay->addWidget( d->rescanButton );
00233
00234 connect( d->rescanButton, SIGNAL(clicked()),
00235 SLOT(slotRescanButtonClicked()) );
00236
00237 vlay->addStretch( 1 );
00238 }
00239
00240 Kleo::BackendConfigWidget::~BackendConfigWidget() {
00241 delete d; d = 0;
00242 }
00243
00244 void Kleo::BackendConfigWidget::load() {
00245 d->listView->clear();
00246
00247 unsigned int backendCount = 0;
00248
00249
00250 BackendListViewItem * top = 0;
00251 for ( unsigned int i = 0 ; const CryptoBackend * b = d->backendFactory->backend( i ) ; ++i ) {
00252
00253 top = new Kleo::BackendListViewItem( d->listView, top, b );
00254
00255 ProtocolCheckListItem * last = 0;
00256 for ( int i = 0 ; const char * name = b->enumerateProtocols( i ) ; ++i ) {
00257 const CryptoBackend::Protocol * protocol = b->protocol( name );
00258
00259 if ( protocol ) {
00260 last = new ProtocolCheckListItem( top, last, name, protocol );
00261 last->setOn( protocol == d->backendFactory->protocol( name ) );
00262 } else if ( b->supportsProtocol( name ) ) {
00263 last = new ProtocolCheckListItem( top, last, name, 0 );
00264 last->setOn( false );
00265 last->setEnabled( false );
00266 }
00267 }
00268
00269 top->setOpen( true );
00270 ++backendCount;
00271 }
00272
00273 if ( backendCount ) {
00274 d->listView->setCurrentItem( d->listView->firstChild() );
00275 d->listView->setSelected( d->listView->firstChild(), true );
00276 }
00277
00278 slotSelectionChanged( d->listView->firstChild() );
00279 }
00280
00281 void Kleo::BackendConfigWidget::slotSelectionChanged( QListViewItem * ) {
00282 const CryptoBackend* backend = d->listView->currentBackend();
00283 if ( backend && !backend->config() )
00284 kdDebug(5150) << "Backend w/o config object!" << endl;
00285 d->configureButton->setEnabled( backend && backend->config() );
00286 }
00287
00288
00289 void Kleo::BackendConfigWidget::slotRescanButtonClicked() {
00290 QStringList reasons;
00291 d->backendFactory->scanForBackends( &reasons );
00292 if ( !reasons.empty() )
00293 KMessageBox::informationList( this,
00294 i18n("The following problems where encountered during scanning:"),
00295 reasons, i18n("Scan Results") );
00296 load();
00297 emit changed( true );
00298 }
00299
00300 void Kleo::BackendConfigWidget::slotConfigureButtonClicked() {
00301 const CryptoBackend* backend = d->listView->currentBackend();
00302 if ( backend && backend->config() ) {
00303 Kleo::CryptoConfigDialog dlg( backend->config(), this );
00304 int result = dlg.exec();
00305 if ( result == QDialog::Accepted ) {
00306
00307 kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
00308
00309 QTimer::singleShot( 0, this, SLOT(slotRescanButtonClicked()) );
00310 }
00311 }
00312 else
00313 kdWarning(5150) << "Can't configure backend, no config object available" << endl;
00314 }
00315
00316 void Kleo::BackendConfigWidget::save() const {
00317 for ( int i = 0 ; const char * name = d->backendFactory->enumerateProtocols( i ) ; ++i )
00318 d->backendFactory->setProtocolBackend( name, d->listView->chosenBackend( name ) );
00319 }
00320
00321 void Kleo::BackendConfigWidget::virtual_hook( int, void* ) {}
00322
00323 #include "backendconfigwidget.moc"