• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kleopatra

certificateselectiondialog.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset:4 -*-
00002     dialogs/certificateselectiondialog.cpp
00003 
00004     This file is part of Kleopatra, the KDE keymanager
00005     Copyright (c) 2008 Klarälvdalens Datakonsult AB
00006 
00007     Kleopatra is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     Kleopatra is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021     In addition, as a special exception, the copyright holders give
00022     permission to link the code of this program with any edition of
00023     the Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), and distribute linked
00025     combinations including the two.  You must obey the GNU General
00026     Public License in all respects for all of the code used other than
00027     Qt.  If you modify this file, you may extend this exception to
00028     your version of the file, but you are not obligated to do so.  If
00029     you do not wish to do so, delete this exception statement from
00030     your version.
00031 */
00032 
00033 #include <config-kleopatra.h>
00034 
00035 #include "certificateselectiondialog.h"
00036 
00037 #include <view/searchbar.h>
00038 #include <view/tabwidget.h>
00039 
00040 #include <models/keylistmodel.h>
00041 #include <models/keycache.h>
00042 
00043 #include <commands/reloadkeyscommand.h>
00044 #include <commands/lookupcertificatescommand.h>
00045 #include <commands/newcertificatecommand.h>
00046 
00047 #include <gpgme++/key.h>
00048 
00049 #include <KLocale>
00050 #include <KConfigGroup>
00051 #include <KSharedConfig>
00052 #include <KDebug>
00053 
00054 #include <QLabel>
00055 #include <QPushButton>
00056 #include <QDialogButtonBox>
00057 #include <QLayout>
00058 #include <QItemSelectionModel>
00059 #include <QAbstractItemView>
00060 #include <QPointer>
00061 
00062 #include <boost/bind.hpp>
00063 
00064 #include <algorithm>
00065 
00066 using namespace Kleo;
00067 using namespace Kleo::Dialogs;
00068 using namespace Kleo::Commands;
00069 using namespace boost;
00070 using namespace GpgME;
00071 
00072 class CertificateSelectionDialog::Private {
00073     friend class ::Kleo::Dialogs::CertificateSelectionDialog;
00074     CertificateSelectionDialog * const q;
00075 public:
00076     explicit Private( CertificateSelectionDialog * qq );
00077 
00078 
00079 private:
00080     void reload() {
00081         ( new ReloadKeysCommand( 0 ) )->start();
00082     }
00083     void create() {
00084         NewCertificateCommand * cmd = new NewCertificateCommand( 0 );
00085         if ( ( options & AnyFormat ) != AnyFormat )
00086             cmd->setProtocol( (options & OpenPGPFormat) ? OpenPGP : CMS );
00087         cmd->start();
00088     }
00089     void lookup() {
00090         ( new LookupCertificatesCommand( 0 ) )->start();
00091     }
00092     void slotKeysMayHaveChanged();
00093     void slotCurrentViewChanged( QAbstractItemView * newView );
00094     void slotSelectionChanged();
00095     void slotDoubleClicked( const QModelIndex & idx );
00096 
00097 private:
00098     bool acceptable( const std::vector<Key> & keys ) {
00099         return !keys.empty();
00100     }
00101     void filterAllowedKeys( std::vector<Key> & keys );
00102     void updateLabelText() {
00103         ui.label.setText( !customLabelText.isEmpty() ? customLabelText :
00104                           (options & MultiSelection)
00105                           ? i18n( "Please select one or more of the following certificates:" )
00106                           : i18n( "Please select one of the following certificates:" ) );
00107     }
00108 
00109 private:
00110     QPointer<QAbstractItemView> lastView;
00111     QString customLabelText;
00112     Options options;
00113 
00114     struct UI {
00115         QLabel label;
00116         SearchBar searchBar;
00117         TabWidget tabWidget;
00118         QDialogButtonBox buttonBox;
00119         QVBoxLayout vlay;
00120 
00121         explicit UI( CertificateSelectionDialog * q )
00122             : label( q ),
00123               searchBar( q ),
00124               tabWidget( q ),
00125               buttonBox( q ),
00126               vlay( q )
00127         {
00128             KDAB_SET_OBJECT_NAME( label );
00129             KDAB_SET_OBJECT_NAME( searchBar );
00130             KDAB_SET_OBJECT_NAME( tabWidget );
00131             KDAB_SET_OBJECT_NAME( buttonBox );
00132             KDAB_SET_OBJECT_NAME( vlay );
00133 
00134             vlay.addWidget( &label );
00135             vlay.addWidget( &searchBar );
00136             vlay.addWidget( &tabWidget, 1 );
00137             vlay.addWidget( &buttonBox );
00138 
00139             QPushButton * const ok = buttonBox.addButton( QDialogButtonBox::Ok );
00140             ok->setEnabled( false );
00141             QPushButton * const cancel = buttonBox.addButton( QDialogButtonBox::Close );
00142             QPushButton * const reload = buttonBox.addButton( i18n("Reload"),    QDialogButtonBox::ActionRole );
00143             QPushButton * const lookup = buttonBox.addButton( i18n("Lookup..."), QDialogButtonBox::ActionRole );
00144             QPushButton * const create = buttonBox.addButton( i18n("New..."),    QDialogButtonBox::ActionRole );
00145 
00146             lookup->setToolTip( i18nc("@info:tooltip","Lookup certificates on server") );
00147             reload->setToolTip( i18nc("@info:tooltip","Refresh certificate list") );
00148             create->setToolTip( i18nc("@info:tooltip","Create a new certificate") );
00149 
00150             connect( &buttonBox, SIGNAL(accepted()), q, SLOT(accept()) );
00151             connect( &buttonBox, SIGNAL(rejected()), q, SLOT(reject()) );
00152             connect( reload,     SIGNAL(clicked()),  q, SLOT(reload()) );
00153             connect( lookup,     SIGNAL(clicked()),  q, SLOT(lookup()) );
00154             connect( create,     SIGNAL(clicked()),  q, SLOT(create()) );
00155             connect( KeyCache::instance().get(), SIGNAL(keysMayHaveChanged()),
00156                      q, SLOT(slotKeysMayHaveChanged()) );
00157         }
00158     } ui;
00159 };
00160 
00161 
00162 CertificateSelectionDialog::Private::Private( CertificateSelectionDialog * qq )
00163     : q( qq ),
00164       ui( q )
00165 {
00166     ui.tabWidget.setFlatModel( AbstractKeyListModel::createFlatKeyListModel() );
00167     ui.tabWidget.setHierarchicalModel( AbstractKeyListModel::createHierarchicalKeyListModel() );
00168     ui.tabWidget.connectSearchBar( &ui.searchBar );
00169 
00170     connect( &ui.tabWidget, SIGNAL(currentViewChanged(QAbstractItemView*)),
00171              q, SLOT(slotCurrentViewChanged(QAbstractItemView*)) );
00172 
00173     updateLabelText();
00174     q->setWindowTitle( i18n( "Certificate Selection" ) );
00175 }
00176 
00177 CertificateSelectionDialog::CertificateSelectionDialog( QWidget * parent, Qt::WindowFlags f )
00178     : QDialog( parent, f ), d( new Private( this ) )
00179 {
00180     const KSharedConfig::Ptr config = KSharedConfig::openConfig( "kleopatracertificateselectiondialogrc" );
00181     d->ui.tabWidget.loadViews( config.data() );
00182     const KConfigGroup geometry( config, "Geometry" );
00183     resize( geometry.readEntry( "size", size() ) );
00184     d->slotKeysMayHaveChanged();
00185 }
00186 
00187 CertificateSelectionDialog::~CertificateSelectionDialog() {}
00188 
00189 void CertificateSelectionDialog::setCustomLabelText( const QString & txt ) {
00190     if ( txt == d->customLabelText )
00191         return;
00192     d->customLabelText = txt;
00193     d->updateLabelText();
00194 }
00195 
00196 QString CertificateSelectionDialog::customLabelText() const {
00197     return d->customLabelText;
00198 }
00199 
00200 void CertificateSelectionDialog::setOptions( Options options ) {
00201     if ( d->options == options )
00202         return;
00203     d->options = options;
00204 
00205     d->ui.tabWidget.setMultiSelection( options & MultiSelection );
00206 
00207     d->slotKeysMayHaveChanged();
00208 }
00209 
00210 CertificateSelectionDialog::Options CertificateSelectionDialog::options() const {
00211     return d->options;
00212 }
00213 
00214 void CertificateSelectionDialog::setStringFilter( const QString & filter ) {
00215     d->ui.tabWidget.setStringFilter( filter );
00216 }
00217 
00218 void CertificateSelectionDialog::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
00219     d->ui.tabWidget.setKeyFilter( filter );
00220 }
00221 
00222 void CertificateSelectionDialog::selectCertificates( const std::vector<Key> & keys ) {
00223     const QAbstractItemView * const view = d->ui.tabWidget.currentView();
00224     if ( !view )
00225         return;
00226     const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
00227     assert( model );
00228     QItemSelectionModel * const sm = view->selectionModel();
00229     assert( sm );
00230 
00231     Q_FOREACH( const QModelIndex & idx, model->indexes( keys ) )
00232         if ( idx.isValid() )
00233             sm->select( idx, QItemSelectionModel::Select | QItemSelectionModel::Rows );
00234 }
00235 
00236 void CertificateSelectionDialog::selectCertificate( const Key & key ) {
00237     selectCertificates( std::vector<Key>( 1, key ) );
00238 }
00239 
00240 std::vector<Key> CertificateSelectionDialog::selectedCertificates() const {
00241     const QAbstractItemView * const view = d->ui.tabWidget.currentView();
00242     if ( !view )
00243         return std::vector<Key>();
00244     const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
00245     assert( model );
00246     const QItemSelectionModel * const sm = view->selectionModel();
00247     assert( sm );
00248     return model->keys( sm->selectedRows() );
00249 }
00250 
00251 Key CertificateSelectionDialog::selectedCertificate() const {
00252     const std::vector<Key> keys = selectedCertificates();
00253     return keys.empty() ? Key() : keys.front() ;
00254 }
00255 
00256 void CertificateSelectionDialog::hideEvent( QHideEvent * e ) {
00257     KSharedConfig::Ptr config = KSharedConfig::openConfig( "kleopatracertificateselectiondialogrc" );
00258     d->ui.tabWidget.saveViews( config.data() );
00259     KConfigGroup geometry( config, "Geometry" );
00260     geometry.writeEntry( "size", size() );
00261     QDialog::hideEvent( e );
00262 }
00263 
00264 void CertificateSelectionDialog::Private::slotKeysMayHaveChanged() {
00265     q->setEnabled( true );
00266     std::vector<Key> keys = (options & SecretKeys) ? KeyCache::instance()->secretKeys() : KeyCache::instance()->keys() ;
00267     filterAllowedKeys( keys );
00268     const std::vector<Key> selected = q->selectedCertificates();
00269     if ( AbstractKeyListModel * const model = ui.tabWidget.flatModel() )
00270         model->setKeys( keys );
00271     if ( AbstractKeyListModel * const model = ui.tabWidget.hierarchicalModel() )
00272         model->setKeys( keys );
00273     q->selectCertificates( selected );
00274 }
00275 
00276 void CertificateSelectionDialog::Private::filterAllowedKeys( std::vector<Key> & keys ) {
00277     std::vector<Key>::iterator end = keys.end();
00278 
00279     switch ( options & AnyFormat ) {
00280     case OpenPGPFormat:
00281         end = std::remove_if( keys.begin(), end, bind( &Key::protocol, _1 ) != GpgME::OpenPGP );
00282         break;
00283     case CMSFormat:
00284         end = std::remove_if( keys.begin(), end, bind( &Key::protocol, _1 ) != GpgME::CMS );
00285         break;
00286     default:
00287     case AnyFormat:
00288         ;
00289     }
00290 
00291     switch ( options & AnyCertificate ) {
00292     case SignOnly:
00293         end = std::remove_if( keys.begin(), end, !bind( &Key::canSign, _1 ) );
00294         break;
00295     case EncryptOnly:
00296         end = std::remove_if( keys.begin(), end, !bind( &Key::canEncrypt, _1 ) );
00297         break;
00298     default:
00299     case AnyCertificate:
00300         ;
00301     }
00302 
00303     if ( options & SecretKeys )
00304         end = std::remove_if( keys.begin(), end, !bind( &Key::hasSecret, _1 ) );
00305 
00306     keys.erase( end, keys.end() );
00307 }
00308 
00309 void CertificateSelectionDialog::Private::slotCurrentViewChanged( QAbstractItemView * newView ) {
00310     if ( lastView ) {
00311         disconnect( lastView, SIGNAL(doubleClicked(QModelIndex)),
00312                     q, SLOT(slotDoubleClicked(QModelIndex)) );
00313         assert( lastView->selectionModel() );
00314         disconnect( lastView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
00315                     q, SLOT(slotSelectionChanged()) );
00316     }
00317     lastView = newView;
00318     if ( newView ) {
00319         connect( newView, SIGNAL(doubleClicked(QModelIndex)),
00320                  q, SLOT(slotDoubleClicked(QModelIndex)) );
00321         assert( newView->selectionModel() );
00322         connect( newView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
00323                  q, SLOT(slotSelectionChanged()) );
00324     }
00325     slotSelectionChanged();
00326 }
00327 
00328 void CertificateSelectionDialog::Private::slotSelectionChanged() {
00329     if ( QPushButton * const pb = ui.buttonBox.button( QDialogButtonBox::Ok ) )
00330         pb->setEnabled( acceptable( q->selectedCertificates() ) );
00331 }
00332 
00333 void CertificateSelectionDialog::Private::slotDoubleClicked( const QModelIndex & idx ) {
00334     QAbstractItemView * const view = ui.tabWidget.currentView();
00335     assert( view );
00336     const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
00337     assert( model );
00338     QItemSelectionModel * const sm = view->selectionModel();
00339     assert( sm );
00340     sm->select( idx, QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows );
00341     QMetaObject::invokeMethod( q, "accept", Qt::QueuedConnection );
00342 }
00343 
00344 void CertificateSelectionDialog::accept() {
00345     if ( d->acceptable( selectedCertificates() ) )
00346         QDialog::accept();
00347 }
00348 
00349 #include "moc_certificateselectiondialog.cpp"

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal