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