You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
12 KiB
324 lines
12 KiB
/* -*- c++ -*-
|
|
backendconfigwidget.cpp
|
|
|
|
This file is part of libkleopatra, the KDE keymanagement library
|
|
Copyright (c) 2002,2004,2005 Klarälvdalens Datakonsult AB
|
|
Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
|
|
|
|
Libkleopatra is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
Libkleopatra is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
In addition, as a special exception, the copyright holders give
|
|
permission to link the code of this program with any edition of
|
|
the TQt library by Trolltech AS, Norway (or with modified versions
|
|
of TQt that use the same license as TQt), and distribute linked
|
|
combinations including the two. You must obey the GNU General
|
|
Public License in all respects for all of the code used other than
|
|
TQt. If you modify this file, you may extend this exception to
|
|
your version of the file, but you are not obligated to do so. If
|
|
you do not wish to do so, delete this exception statement from
|
|
your version.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include "backendconfigwidget.h"
|
|
#include "cryptoconfigdialog.h"
|
|
|
|
#include "kleo/cryptobackendfactory.h"
|
|
#include "ui/keylistview.h" // for lvi_cast<>
|
|
|
|
#include <klistview.h>
|
|
#include <kdialog.h>
|
|
#include <klocale.h>
|
|
#include <kdebug.h>
|
|
#include <kmessagebox.h>
|
|
#include <kapplication.h>
|
|
#include <dcopclient.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
#include <tqlayout.h>
|
|
#include <tqheader.h>
|
|
#include <tqtimer.h>
|
|
|
|
#include <assert.h>
|
|
|
|
namespace Kleo {
|
|
class BackendListView;
|
|
}
|
|
|
|
class Kleo::BackendConfigWidget::Private {
|
|
public:
|
|
Kleo::BackendListView * listView;
|
|
TQPushButton * configureButton;
|
|
TQPushButton * rescanButton;
|
|
Kleo::CryptoBackendFactory * backendFactory;
|
|
};
|
|
|
|
namespace Kleo {
|
|
class BackendListViewItem;
|
|
class ProtocolCheckListItem;
|
|
}
|
|
|
|
class Kleo::BackendListView : public KListView
|
|
{
|
|
public:
|
|
BackendListView( BackendConfigWidget* tqparent, const char* name = 0 )
|
|
: KListView( tqparent, name ) {}
|
|
|
|
/// return backend for currently selected (/current) item. Used by Configure button.
|
|
const Kleo::CryptoBackend* currentBackend() const;
|
|
|
|
/// return which protocol implementation was chosen (checked) for each type (used when saving)
|
|
const Kleo::CryptoBackend* chosenBackend( const char * protocol );
|
|
|
|
/// deselect all except one for a given protocol type (radiobutton-like exclusivity)
|
|
void deselectAll( const char * protocol, TQCheckListItem* except );
|
|
|
|
void emitChanged() { static_cast<BackendConfigWidget *>( tqparentWidget() )->emitChanged( true ); }
|
|
};
|
|
|
|
// Toplevel listviewitem for a given backend (e.g. "GpgME", "Kgpg/gpg v2")
|
|
class Kleo::BackendListViewItem : public TQListViewItem
|
|
{
|
|
public:
|
|
BackendListViewItem( KListView* lv, TQListViewItem *prev, const CryptoBackend *cryptoBackend )
|
|
: TQListViewItem( lv, prev, cryptoBackend->displayName() ), mCryptoBackend( cryptoBackend )
|
|
{}
|
|
|
|
const CryptoBackend *cryptoBackend() const { return mCryptoBackend; }
|
|
enum { RTTI = 0x2EAE3BE0, RTTI_MASK = 0xFFFFFFFF };
|
|
int rtti() const { return RTTI; }
|
|
|
|
private:
|
|
const CryptoBackend *mCryptoBackend;
|
|
};
|
|
|
|
|
|
// Checklist item under a BackendListViewItem
|
|
// (e.g. "GpgME supports protocol OpenPGP")
|
|
class Kleo::ProtocolCheckListItem : public TQCheckListItem
|
|
{
|
|
public:
|
|
ProtocolCheckListItem( BackendListViewItem* blvi,
|
|
TQListViewItem* prev, const char * protocolName,
|
|
const CryptoBackend::Protocol* protocol ) // can be 0
|
|
: TQCheckListItem( blvi, prev, itemText( protocolName, protocol ),
|
|
TQCheckListItem::CheckBox ),
|
|
mProtocol( protocol ), mProtocolName( protocolName )
|
|
{}
|
|
|
|
enum { RTTI = 0x2EAE3BE1, RTTI_MASK = 0xFFFFFFFF };
|
|
virtual int rtti() const { return RTTI; }
|
|
|
|
// can be 0
|
|
const CryptoBackend::Protocol* protocol() const { return mProtocol; }
|
|
const char * protocolName() const { return mProtocolName; }
|
|
|
|
protected:
|
|
virtual void stateChange( bool b ) {
|
|
BackendListView* lv = static_cast<BackendListView *>( listView() );
|
|
// "radio-button-like" behavior for the protocol checkboxes
|
|
if ( b )
|
|
lv->deselectAll( mProtocolName, this );
|
|
lv->emitChanged();
|
|
TQCheckListItem::stateChange( b );
|
|
}
|
|
|
|
private:
|
|
// Helper for the constructor.
|
|
static TQString itemText( const char * protocolName, const CryptoBackend::Protocol* protocol ) {
|
|
// First one is the generic name (find a nice one for OpenPGP, SMIME)
|
|
const TQString protoName = qstricmp( protocolName, "openpgp" ) != 0
|
|
? qstricmp( protocolName, "smime" ) != 0
|
|
? TQString::tqfromLatin1( protocolName )
|
|
: i18n( "S/MIME" )
|
|
: i18n( "OpenPGP" );
|
|
// second one is implementation name (gpg, gpgsm...)
|
|
const TQString impName = protocol ? protocol->displayName() : i18n( "failed" );
|
|
return i18n( "Items in Kleo::BackendConfigWidget listview (1: protocol; 2: implementation name)",
|
|
"%1 (%2)" ).tqarg( protoName, impName );
|
|
}
|
|
|
|
const CryptoBackend::Protocol* mProtocol; // can be 0
|
|
const char * mProtocolName;
|
|
};
|
|
|
|
const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const {
|
|
const TQListViewItem* curItem = currentItem();
|
|
if ( !curItem ) // can't happen
|
|
return 0;
|
|
if ( lvi_cast<Kleo::ProtocolCheckListItem>( curItem ) )
|
|
curItem = curItem->tqparent();
|
|
if ( const Kleo::BackendListViewItem * blvi = lvi_cast<Kleo::BackendListViewItem>( curItem ) )
|
|
return blvi->cryptoBackend();
|
|
return 0;
|
|
}
|
|
|
|
// can't be const method due to TQListViewItemIterator (why?)
|
|
const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( const char * protocolName )
|
|
{
|
|
for ( TQListViewItemIterator it( this /*, TQListViewItemIterator::Checked doesn't work*/ ) ;
|
|
it.current() ; ++it )
|
|
if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
|
|
if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 ) {
|
|
// OK that's the one. Now go up to the tqparent backend
|
|
// (need to do that in the listview since Protocol doesn't know it)
|
|
if ( const BackendListViewItem * parItem = lvi_cast<BackendListViewItem>( it.current()->tqparent() ) )
|
|
return parItem->cryptoBackend();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Kleo::BackendListView::deselectAll( const char * protocolName, TQCheckListItem* except )
|
|
{
|
|
for ( TQListViewItemIterator it( this /*, TQListViewItemIterator::Checked doesn't work*/ ) ;
|
|
it.current() ; ++it ) {
|
|
if ( it.current() == except ) continue;
|
|
if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
|
|
if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 )
|
|
p->setOn( false );
|
|
}
|
|
}
|
|
|
|
////
|
|
|
|
Kleo::BackendConfigWidget::BackendConfigWidget( CryptoBackendFactory * factory, TQWidget * tqparent, const char * name, WFlags f )
|
|
: TQWidget( tqparent, name, f ), d( 0 )
|
|
{
|
|
assert( factory );
|
|
d = new Private();
|
|
d->backendFactory = factory;
|
|
|
|
TQHBoxLayout * hlay =
|
|
new TQHBoxLayout( this, 0, KDialog::spacingHint() );
|
|
|
|
d->listView = new BackendListView( this, "d->listView" );
|
|
d->listView->addColumn( i18n("Available Backends") );
|
|
d->listView->setAllColumnsShowFocus( true );
|
|
d->listView->setSorting( -1 );
|
|
d->listView->header()->setClickEnabled( false );
|
|
d->listView->setFullWidth( true );
|
|
|
|
hlay->addWidget( d->listView, 1 );
|
|
|
|
connect( d->listView, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
|
|
TQT_SLOT(slotSelectionChanged(TQListViewItem*)) );
|
|
|
|
TQVBoxLayout * vlay = new TQVBoxLayout( hlay ); // inherits spacing
|
|
|
|
d->configureButton = new TQPushButton( i18n("Confi&gure..."), this );
|
|
d->configureButton->setAutoDefault( false );
|
|
vlay->addWidget( d->configureButton );
|
|
|
|
connect( d->configureButton, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(slotConfigureButtonClicked()) );
|
|
|
|
d->rescanButton = new TQPushButton( i18n("Rescan"), this );
|
|
d->rescanButton->setAutoDefault( false );
|
|
vlay->addWidget( d->rescanButton );
|
|
|
|
connect( d->rescanButton, TQT_SIGNAL(clicked()),
|
|
TQT_SLOT(slotRescanButtonClicked()) );
|
|
|
|
vlay->addStretch( 1 );
|
|
}
|
|
|
|
Kleo::BackendConfigWidget::~BackendConfigWidget() {
|
|
delete d; d = 0;
|
|
}
|
|
|
|
void Kleo::BackendConfigWidget::load() {
|
|
d->listView->clear();
|
|
|
|
unsigned int backendCount = 0;
|
|
|
|
// populate the plugin list:
|
|
BackendListViewItem * top = 0;
|
|
for ( unsigned int i = 0 ; const CryptoBackend * b = d->backendFactory->backend( i ) ; ++i ) {
|
|
|
|
top = new Kleo::BackendListViewItem( d->listView, top, b );
|
|
|
|
ProtocolCheckListItem * last = 0;
|
|
for ( int i = 0 ; const char * name = b->enumerateProtocols( i ) ; ++i ) {
|
|
const CryptoBackend::Protocol * protocol = b->protocol( name );
|
|
|
|
if ( protocol ) {
|
|
last = new ProtocolCheckListItem( top, last, name, protocol );
|
|
last->setOn( protocol == d->backendFactory->protocol( name ) );
|
|
} else if ( b->supportsProtocol( name ) ) {
|
|
last = new ProtocolCheckListItem( top, last, name, 0 );
|
|
last->setOn( false );
|
|
last->setEnabled( false );
|
|
}
|
|
}
|
|
|
|
top->setOpen( true );
|
|
++backendCount;
|
|
}
|
|
|
|
if ( backendCount ) {
|
|
d->listView->setCurrentItem( d->listView->firstChild() );
|
|
d->listView->setSelected( d->listView->firstChild(), true );
|
|
}
|
|
|
|
slotSelectionChanged( d->listView->firstChild() );
|
|
}
|
|
|
|
void Kleo::BackendConfigWidget::slotSelectionChanged( TQListViewItem * ) {
|
|
const CryptoBackend* backend = d->listView->currentBackend();
|
|
if ( backend && !backend->config() )
|
|
kdDebug(5150) << "Backend w/o config object!" << endl;
|
|
d->configureButton->setEnabled( backend && backend->config() );
|
|
}
|
|
|
|
|
|
void Kleo::BackendConfigWidget::slotRescanButtonClicked() {
|
|
TQStringList reasons;
|
|
d->backendFactory->scanForBackends( &reasons );
|
|
if ( !reasons.empty() )
|
|
KMessageBox::informationList( this,
|
|
i18n("The following problems where encountered during scanning:"),
|
|
reasons, i18n("Scan Results") );
|
|
load();
|
|
emit changed( true );
|
|
}
|
|
|
|
void Kleo::BackendConfigWidget::slotConfigureButtonClicked() {
|
|
const CryptoBackend* backend = d->listView->currentBackend();
|
|
if ( backend && backend->config() ) {
|
|
Kleo::CryptoConfigDialog dlg( backend->config(), this );
|
|
int result = dlg.exec();
|
|
if ( result == TQDialog::Accepted ) {
|
|
// Tell other users of gpgconf (e.g. the s/mime page) that the gpgconf data might have changed
|
|
kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", TQByteArray() );
|
|
// and schedule a rescan, in case the updates make a backend valid
|
|
TQTimer::singleShot( 0, this, TQT_SLOT(slotRescanButtonClicked()) );
|
|
}
|
|
}
|
|
else // shouldn't happen, button is disabled
|
|
kdWarning(5150) << "Can't configure backend, no config object available" << endl;
|
|
}
|
|
|
|
void Kleo::BackendConfigWidget::save() const {
|
|
for ( int i = 0 ; const char * name = d->backendFactory->enumerateProtocols( i ) ; ++i )
|
|
d->backendFactory->setProtocolBackend( name, d->listView->chosenBackend( name ) );
|
|
}
|
|
|
|
void Kleo::BackendConfigWidget::virtual_hook( int, void* ) {}
|
|
|
|
#include "backendconfigwidget.moc"
|