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 #include <config-kleopatra.h>
00034
00035 #ifdef QT_NO_STL
00036 #undef QT_NO_STL
00037 #undef QT_STL
00038 #define QT_STL
00039 #endif
00040
00041 #include "resolverecipientspage.h"
00042 #include "resolverecipientspage_p.h"
00043
00044 #include <dialogs/certificateselectiondialog.h>
00045
00046 #include <crypto/certificateresolver.h>
00047
00048 #include <models/keycache.h>
00049
00050 #include <utils/formatting.h>
00051
00052 #include <kmime/kmime_header_parsing.h>
00053
00054 #include <gpgme++/key.h>
00055
00056 #include <KLocalizedString>
00057
00058 #include <QButtonGroup>
00059 #include <QComboBox>
00060 #include <QHBoxLayout>
00061 #include <QLabel>
00062 #include <QListWidget>
00063 #include <QPointer>
00064 #include <QPushButton>
00065 #include <QRadioButton>
00066 #include <QToolButton>
00067 #include <QSignalMapper>
00068 #include <QStringList>
00069 #include <QVBoxLayout>
00070
00071 #include <boost/bind.hpp>
00072 #include <boost/shared_ptr.hpp>
00073
00074 #include <cassert>
00075
00076 using namespace GpgME;
00077 using namespace boost;
00078 using namespace Kleo;
00079 using namespace Kleo::Dialogs;
00080 using namespace Kleo::Crypto;
00081 using namespace Kleo::Crypto::Gui;
00082 using namespace KMime::Types;
00083
00084 ResolveRecipientsPage::ListWidget::ListWidget( QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags ), m_protocol( UnknownProtocol )
00085 {
00086 m_listWidget = new QListWidget;
00087 m_listWidget->setSelectionMode( QAbstractItemView::MultiSelection );
00088 QVBoxLayout * const layout = new QVBoxLayout( this );
00089 layout->addWidget( m_listWidget );
00090 connect( m_listWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChange() ) );
00091 }
00092
00093 ResolveRecipientsPage::ListWidget::~ListWidget()
00094 {
00095 }
00096
00097 void ResolveRecipientsPage::ListWidget::onSelectionChange()
00098 {
00099 Q_FOREACH ( const QString& i, widgets.keys() )
00100 {
00101 assert( items.contains( i ) );
00102 widgets[i]->setSelected( items[i]->isSelected() );
00103 }
00104 emit selectionChanged();
00105 }
00106
00107 void ResolveRecipientsPage::ListWidget::addEntry( const Mailbox& mbox )
00108 {
00109 addEntry( mbox.prettyAddress(), mbox.prettyAddress(), mbox );
00110 }
00111
00112 void ResolveRecipientsPage::ListWidget::addEntry( const QString& id, const QString& name )
00113 {
00114 addEntry( id, name, Mailbox() );
00115 }
00116
00117 void ResolveRecipientsPage::ListWidget::addEntry( const QString& id, const QString& name, const Mailbox& mbox )
00118 {
00119 assert( !widgets.contains( id ) && !items.contains( id ) );
00120 QListWidgetItem* item = new QListWidgetItem;
00121 item->setData( IdRole, id );
00122 ItemWidget* wid = new ItemWidget( id, name, mbox, this );
00123 connect( wid, SIGNAL( changed() ), this, SIGNAL( completeChanged() ) );
00124 wid->setProtocol( m_protocol );
00125 item->setSizeHint( wid->sizeHint() );
00126 m_listWidget->addItem( item );
00127 m_listWidget->setItemWidget( item, wid );
00128 widgets[id] = wid;
00129 items[id] = item;
00130 }
00131
00132 Mailbox ResolveRecipientsPage::ListWidget::mailbox( const QString& id ) const
00133 {
00134 return widgets.contains( id ) ? widgets[id]->mailbox() : Mailbox();
00135 }
00136
00137 void ResolveRecipientsPage::ListWidget::setCertificates( const QString& id, const std::vector<Key>& pgp, const std::vector<Key>& cms )
00138 {
00139 assert( widgets.contains( id ) );
00140 widgets[id]->setCertificates( pgp, cms );
00141 }
00142
00143 Key ResolveRecipientsPage::ListWidget::selectedCertificate( const QString& id ) const
00144 {
00145 return widgets.contains( id ) ? widgets[id]->selectedCertificate() : Key();
00146 }
00147
00148
00149 GpgME::Key ResolveRecipientsPage::ListWidget::selectedCertificate( const QString& id, GpgME::Protocol prot ) const
00150 {
00151 return widgets.contains( id ) ? widgets[id]->selectedCertificate( prot ) : Key();
00152 }
00153
00154 QStringList ResolveRecipientsPage::ListWidget::identifiers() const
00155 {
00156 return widgets.keys();
00157 }
00158
00159 void ResolveRecipientsPage::ListWidget::setProtocol( GpgME::Protocol prot )
00160 {
00161 if ( m_protocol == prot )
00162 return;
00163 m_protocol = prot;
00164 Q_FOREACH ( ItemWidget* i, widgets.values() )
00165 i->setProtocol( prot );
00166 }
00167
00168 void ResolveRecipientsPage::ListWidget::removeEntry( const QString& id )
00169 {
00170 if ( !widgets.contains( id ) )
00171 return;
00172 delete items[id];
00173 items.remove( id );
00174 delete widgets[id];
00175 widgets.remove( id );
00176 }
00177
00178 void ResolveRecipientsPage::ListWidget::showSelectionDialog( const QString& id )
00179 {
00180 if ( !widgets.contains( id ) )
00181 return;
00182 widgets[id]->showSelectionDialog();
00183 }
00184
00185 QStringList ResolveRecipientsPage::ListWidget::selectedEntries() const
00186 {
00187 QStringList entries;
00188 const QList<QListWidgetItem*> items = m_listWidget->selectedItems();
00189 Q_FOREACH ( const QListWidgetItem* i, items )
00190 {
00191 entries.append( i->data( IdRole ).toString() );
00192 }
00193 return entries;
00194 }
00195
00196 ResolveRecipientsPage::ItemWidget::ItemWidget( const QString& id, const QString& name, const Mailbox& mbox,
00197 QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags ), m_id( id ), m_mailbox( mbox ), m_protocol( UnknownProtocol ), m_selected( false )
00198 {
00199 assert( !m_id.isEmpty() );
00200 setAutoFillBackground( true );
00201 QHBoxLayout* layout = new QHBoxLayout( this );
00202 layout->setMargin( 0 );
00203 layout->addSpacing( 15 );
00204 m_nameLabel = new QLabel;
00205 m_nameLabel->setText( name );
00206 layout->addWidget( m_nameLabel );
00207 layout->addStretch();
00208 m_certLabel = new QLabel;
00209 m_certLabel->setText( i18n( "<i>No certificate selected</i>" ) );
00210 layout->addWidget( m_certLabel );
00211 m_certCombo = new QComboBox;
00212 connect( m_certCombo, SIGNAL( currentIndexChanged( int ) ),
00213 this, SIGNAL( changed() ) );
00214 layout->addWidget( m_certCombo );
00215 m_selectButton = new QToolButton;
00216 m_selectButton->setText( i18n( "..." ) );
00217 connect( m_selectButton, SIGNAL( clicked() ),
00218 this, SLOT( showSelectionDialog() ) );
00219 layout->addWidget( m_selectButton );
00220 layout->addSpacing( 15 );
00221 setCertificates( std::vector<Key>(), std::vector<Key>() );
00222 }
00223
00224 void ResolveRecipientsPage::ItemWidget::updateVisibility()
00225 {
00226 m_certLabel->setVisible( m_certCombo->count() == 0 );
00227 m_certCombo->setVisible( m_certCombo->count() > 0 );
00228 }
00229
00230 ResolveRecipientsPage::ItemWidget::~ItemWidget()
00231 {
00232 }
00233
00234 QString ResolveRecipientsPage::ItemWidget::id() const
00235 {
00236 return m_id;
00237 }
00238
00239 void ResolveRecipientsPage::ItemWidget::setSelected( bool selected )
00240 {
00241 if ( m_selected == selected )
00242 return;
00243 m_selected = selected;
00244 setBackgroundRole( selected ? QPalette::Highlight : QPalette::Base );
00245 const QPalette::ColorRole foreground = selected ? QPalette::HighlightedText : QPalette::Text;
00246 setForegroundRole( foreground );
00247 m_nameLabel->setForegroundRole( foreground );
00248 m_certLabel->setForegroundRole( foreground );
00249 }
00250
00251 bool ResolveRecipientsPage::ItemWidget::isSelected() const
00252 {
00253 return m_selected;
00254 }
00255
00256 static CertificateSelectionDialog::Option protocol2option( GpgME::Protocol proto ) {
00257 switch ( proto ) {
00258 case OpenPGP: return CertificateSelectionDialog::OpenPGPFormat;
00259 case CMS: return CertificateSelectionDialog::CMSFormat;
00260 default: return CertificateSelectionDialog::AnyFormat;
00261 }
00262 }
00263
00264 static CertificateSelectionDialog * createCertificateSelectionDialog( QWidget* parent, GpgME::Protocol prot ) {
00265 CertificateSelectionDialog * const dlg = new CertificateSelectionDialog( parent );
00266 const CertificateSelectionDialog::Options options =
00267 CertificateSelectionDialog::SingleSelection |
00268 CertificateSelectionDialog::EncryptOnly |
00269 CertificateSelectionDialog::MultiSelection |
00270 protocol2option( prot );
00271 dlg->setOptions( options );
00272 return dlg;
00273 }
00274
00275 void ResolveRecipientsPage::ItemWidget::showSelectionDialog()
00276 {
00277 QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog( this, m_protocol );
00278
00279 if ( dlg->exec() == QDialog::Accepted && dlg ) {
00280 const GpgME::Key cert = dlg->selectedCertificate();
00281 if ( !cert.isNull() ) {
00282 addCertificateToComboBox( cert );
00283 selectCertificateInComboBox( cert );
00284 }
00285 }
00286 delete dlg;
00287 }
00288
00289 Mailbox ResolveRecipientsPage::ItemWidget::mailbox() const
00290 {
00291 return m_mailbox;
00292 }
00293
00294 void ResolveRecipientsPage::ItemWidget::selectCertificateInComboBox( const Key& key )
00295 {
00296 m_certCombo->setCurrentIndex( m_certCombo->findData( key.keyID() ) );
00297 }
00298
00299 void ResolveRecipientsPage::ItemWidget::addCertificateToComboBox( const GpgME::Key& key )
00300 {
00301 m_certCombo->addItem( Formatting::formatForComboBox( key ), QByteArray( key.keyID() ) );
00302 if ( m_certCombo->count() == 1 )
00303 m_certCombo->setCurrentIndex( 0 );
00304 updateVisibility();
00305 }
00306
00307 void ResolveRecipientsPage::ItemWidget::resetCertificates()
00308 {
00309 std::vector<Key> certs;
00310 Key selected;
00311 switch ( m_protocol )
00312 {
00313 case OpenPGP:
00314 certs = m_pgp;
00315 break;
00316 case CMS:
00317 certs = m_cms;
00318 break;
00319 case UnknownProtocol:
00320 certs = m_cms;
00321 certs.insert( certs.end(), m_pgp.begin(), m_pgp.end() );
00322 }
00323
00324 m_certCombo->clear();
00325 Q_FOREACH ( const Key& i, certs )
00326 addCertificateToComboBox( i );
00327 if ( !m_selectedCertificates[m_protocol].isNull() )
00328 selectCertificateInComboBox( m_selectedCertificates[m_protocol] );
00329 else if ( m_certCombo->count() > 0 )
00330 m_certCombo->setCurrentIndex( 0 );
00331 updateVisibility();
00332 emit changed();
00333 }
00334
00335 void ResolveRecipientsPage::ItemWidget::setProtocol( Protocol prot )
00336 {
00337 if ( m_protocol == prot )
00338 return;
00339 m_selectedCertificates[m_protocol] = selectedCertificate();
00340 if ( m_protocol != UnknownProtocol )
00341 ( m_protocol == OpenPGP ? m_pgp : m_cms ) = certificates();
00342 m_protocol = prot;
00343 resetCertificates();
00344 }
00345
00346 void ResolveRecipientsPage::ItemWidget::setCertificates( const std::vector<Key>& pgp, const std::vector<Key>& cms )
00347 {
00348 m_pgp = pgp;
00349 m_cms = cms;
00350 resetCertificates();
00351 }
00352
00353 Key ResolveRecipientsPage::ItemWidget::selectedCertificate() const
00354 {
00355 return KeyCache::instance()->findByKeyIDOrFingerprint( m_certCombo->itemData( m_certCombo->currentIndex(), ListWidget::IdRole ).toString().toStdString() );
00356 }
00357
00358
00359 GpgME::Key ResolveRecipientsPage::ItemWidget::selectedCertificate( GpgME::Protocol prot ) const
00360 {
00361 return prot == m_protocol ? selectedCertificate() : m_selectedCertificates.value( prot );
00362 }
00363
00364 std::vector<Key> ResolveRecipientsPage::ItemWidget::certificates() const
00365 {
00366 std::vector<Key> certs;
00367 for ( int i = 0; i < m_certCombo->count(); ++i )
00368 certs.push_back( KeyCache::instance()->findByKeyIDOrFingerprint( m_certCombo->itemData( i, ListWidget::IdRole ).toString().toStdString() ) );
00369 return certs;
00370 }
00371
00372 class ResolveRecipientsPage::Private {
00373 friend class ::Kleo::Crypto::Gui::ResolveRecipientsPage;
00374 ResolveRecipientsPage * const q;
00375 public:
00376 explicit Private( ResolveRecipientsPage * qq );
00377 ~Private();
00378
00379 void setSelectedProtocol( Protocol protocol );
00380 void selectionChanged();
00381 void removeSelectedEntries();
00382 void addRecipient();
00383 void addRecipient( const Mailbox& mbox );
00384 void addRecipient( const QString& id, const QString& name );
00385 void updateProtocolRBVisibility();
00386 void protocolSelected( int prot );
00387 void writeSelectedCertificatesToPreferences();
00388 void completeChangedInternal();
00389
00390 private:
00391 ListWidget* m_listWidget;
00392 QPushButton* m_addButton;
00393 QPushButton* m_removeButton;
00394 QRadioButton* m_pgpRB;
00395 QRadioButton* m_cmsRB;
00396 QLabel* m_additionalRecipientsLabel;
00397 Protocol m_presetProtocol;
00398 Protocol m_selectedProtocol;
00399 bool m_multipleProtocolsAllowed;
00400 boost::shared_ptr<RecipientPreferences> m_recipientPreferences;
00401 };
00402
00403 ResolveRecipientsPage::Private::Private( ResolveRecipientsPage * qq )
00404 : q( qq ), m_presetProtocol( UnknownProtocol ), m_selectedProtocol( m_presetProtocol ), m_multipleProtocolsAllowed( false ), m_recipientPreferences()
00405 {
00406 connect( q, SIGNAL(completeChanged()), q, SLOT(completeChangedInternal()) );
00407 q->setTitle( i18n( "<b>Recipients</b>" ) );
00408 QVBoxLayout* const layout = new QVBoxLayout( q );
00409 m_listWidget = new ListWidget;
00410 connect( m_listWidget, SIGNAL( selectionChanged() ), q, SLOT( selectionChanged() ) );
00411 connect( m_listWidget, SIGNAL( completeChanged() ), q, SIGNAL( completeChanged() ) );
00412 layout->addWidget( m_listWidget );
00413 m_additionalRecipientsLabel = new QLabel;
00414 m_additionalRecipientsLabel->setWordWrap( true );
00415 layout->addWidget( m_additionalRecipientsLabel );
00416 m_additionalRecipientsLabel->setVisible( false );
00417 QWidget* buttonWidget = new QWidget;
00418 QHBoxLayout* buttonLayout = new QHBoxLayout( buttonWidget );
00419 buttonLayout->setMargin( 0 );
00420 m_addButton = new QPushButton;
00421 connect( m_addButton, SIGNAL( clicked() ), q, SLOT( addRecipient() ) );
00422 m_addButton->setText( i18n( "Add Recipient..." ) );
00423 buttonLayout->addWidget( m_addButton );
00424 m_removeButton = new QPushButton;
00425 m_removeButton->setEnabled( false );
00426 m_removeButton->setText( i18n( "Remove Selected" ) );
00427 connect( m_removeButton, SIGNAL( clicked() ),
00428 q, SLOT( removeSelectedEntries() ) );
00429 buttonLayout->addWidget( m_removeButton );
00430 buttonLayout->addStretch();
00431 layout->addWidget( buttonWidget );
00432 QWidget* protocolWidget = new QWidget;
00433 QHBoxLayout* protocolLayout = new QHBoxLayout( protocolWidget );
00434 QButtonGroup* protocolGroup = new QButtonGroup( q );
00435 connect( protocolGroup, SIGNAL( buttonClicked( int ) ), q, SLOT( protocolSelected( int ) ) );
00436 m_pgpRB = new QRadioButton;
00437 m_pgpRB->setText( i18n( "OpenPGP" ) );
00438 protocolGroup->addButton( m_pgpRB, OpenPGP );
00439 protocolLayout->addWidget( m_pgpRB );
00440 m_cmsRB = new QRadioButton;
00441 m_cmsRB->setText( i18n( "S/MIME" ) );
00442 protocolGroup->addButton( m_cmsRB, CMS );
00443 protocolLayout->addWidget( m_cmsRB );
00444 protocolLayout->addStretch();
00445 layout->addWidget( protocolWidget );
00446 }
00447
00448 ResolveRecipientsPage::Private::~Private() {}
00449
00450 void ResolveRecipientsPage::Private::completeChangedInternal()
00451 {
00452 const bool isComplete = q->isComplete();
00453 const std::vector<Key> keys = q->resolvedCertificates();
00454 const bool haveSecret = std::find_if( keys.begin(), keys.end(), bind( &Key::hasSecret, _1 ) ) != keys.end();
00455 if ( isComplete && !haveSecret )
00456 q->setExplanation( i18n( "<b>Warning:</b> None of the selected certificates seems to be your own certificate. You will not be able to decrypt the encrypted data again." ) );
00457 else
00458 q->setExplanation( QString() );
00459 }
00460
00461 void ResolveRecipientsPage::Private::updateProtocolRBVisibility()
00462 {
00463 const bool visible = !m_multipleProtocolsAllowed && m_presetProtocol == UnknownProtocol;
00464 m_cmsRB->setVisible( visible );
00465 m_pgpRB->setVisible( visible );
00466 if ( visible )
00467 {
00468 if ( m_selectedProtocol == CMS )
00469 m_cmsRB->click();
00470 else
00471 m_pgpRB->click();
00472 }
00473 }
00474
00475 bool ResolveRecipientsPage::isComplete() const
00476 {
00477 const QStringList ids = d->m_listWidget->identifiers();
00478 if ( ids.isEmpty() )
00479 return false;
00480
00481 Q_FOREACH ( const QString& i, ids )
00482 {
00483 if ( d->m_listWidget->selectedCertificate( i ).isNull() )
00484 return false;
00485 }
00486
00487 return true;
00488 }
00489
00490 ResolveRecipientsPage::ResolveRecipientsPage( QWidget * parent )
00491 : WizardPage( parent ), d( new Private( this ) )
00492 {
00493 }
00494
00495 ResolveRecipientsPage::~ResolveRecipientsPage() {}
00496
00497 Protocol ResolveRecipientsPage::selectedProtocol() const
00498 {
00499 return d->m_selectedProtocol;
00500 }
00501
00502 void ResolveRecipientsPage::Private::setSelectedProtocol( Protocol protocol )
00503 {
00504 if ( m_selectedProtocol == protocol )
00505 return;
00506 m_selectedProtocol = protocol;
00507 m_listWidget->setProtocol( m_selectedProtocol );
00508 emit q->selectedProtocolChanged();
00509 }
00510
00511 void ResolveRecipientsPage::Private::protocolSelected( int p )
00512 {
00513 const Protocol protocol = static_cast<Protocol>( p );
00514 assert( protocol != UnknownProtocol );
00515 setSelectedProtocol( protocol );
00516 }
00517
00518 void ResolveRecipientsPage::setPresetProtocol( Protocol prot )
00519 {
00520 if ( d->m_presetProtocol == prot )
00521 return;
00522 d->m_presetProtocol = prot;
00523 d->setSelectedProtocol( prot );
00524 if ( prot != UnknownProtocol )
00525 d->m_multipleProtocolsAllowed = false;
00526 d->updateProtocolRBVisibility();
00527 }
00528
00529 Protocol ResolveRecipientsPage::presetProtocol() const
00530 {
00531 return d->m_presetProtocol;
00532 }
00533
00534 bool ResolveRecipientsPage::multipleProtocolsAllowed() const
00535 {
00536 return d->m_multipleProtocolsAllowed;
00537 }
00538
00539 void ResolveRecipientsPage::setMultipleProtocolsAllowed( bool allowed )
00540 {
00541 if ( d->m_multipleProtocolsAllowed == allowed )
00542 return;
00543 d->m_multipleProtocolsAllowed = allowed;
00544 if ( d->m_multipleProtocolsAllowed )
00545 {
00546 setPresetProtocol( UnknownProtocol );
00547 d->setSelectedProtocol( UnknownProtocol );
00548 }
00549 d->updateProtocolRBVisibility();
00550 }
00551
00552
00553 void ResolveRecipientsPage::Private::addRecipient( const QString& id, const QString& name )
00554 {
00555 m_listWidget->addEntry( id, name );
00556 }
00557
00558 void ResolveRecipientsPage::Private::addRecipient( const Mailbox& mbox )
00559 {
00560 m_listWidget->addEntry( mbox );
00561 }
00562
00563 void ResolveRecipientsPage::Private::addRecipient()
00564 {
00565 QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog( q, q->selectedProtocol() );
00566 if ( dlg->exec() != QDialog::Accepted || !dlg )
00567 return;
00568 const std::vector<Key> keys = dlg->selectedCertificates();
00569
00570 int i = 0;
00571 Q_FOREACH( const Key & key, keys ) {
00572 const QStringList existing = m_listWidget->identifiers();
00573 QString rec = i18n( "Recipient" );
00574 while ( existing.contains( rec ) )
00575 rec = i18nc( "%1 == number", "Recipient (%1)", ++i );
00576 addRecipient( rec, rec );
00577 const std::vector<Key> pgp = key.protocol() == OpenPGP ? std::vector<Key>( 1, key ) : std::vector<Key>();
00578 const std::vector<Key> cms = key.protocol() == CMS ? std::vector<Key>( 1, key ) : std::vector<Key>();
00579 m_listWidget->setCertificates( rec, pgp, cms );
00580 }
00581 emit q->completeChanged();
00582 }
00583
00584 namespace {
00585
00586 std::vector<Key> makeSuggestions( const boost::shared_ptr<RecipientPreferences>& prefs, const Mailbox& mb, GpgME::Protocol prot )
00587 {
00588 std::vector<Key> suggestions;
00589 const Key remembered = prefs ? prefs->preferredCertificate( mb, prot ) : Key();
00590 if ( !remembered.isNull() )
00591 suggestions.push_back( remembered );
00592 else
00593 suggestions = CertificateResolver::resolveRecipient( mb, prot );
00594 return suggestions;
00595 }
00596 }
00597
00598 static QString listKeysForInfo( const std::vector<Key> & keys ) {
00599 QStringList list;
00600 std::transform( keys.begin(), keys.end(), list.begin(), &Formatting::formatKeyLink );
00601 return list.join( "<br/>" );
00602 }
00603
00604 void ResolveRecipientsPage::setAdditionalRecipientsInfo( const std::vector<Key> & recipients ) {
00605 d->m_additionalRecipientsLabel->setVisible( !recipients.empty() );
00606 if ( recipients.empty() )
00607 return;
00608 d->m_additionalRecipientsLabel->setText( i18n( "<qt><p>Recipients predefined via GnuPG settings:</p>%1", listKeysForInfo( recipients ) ) );
00609 }
00610
00611 void ResolveRecipientsPage::setRecipients( const std::vector<Mailbox>& recipients )
00612 {
00613 uint cmsCount = 0;
00614 uint pgpCount = 0;
00615 Q_FOREACH( const Mailbox& i, recipients )
00616 {
00617
00618 const QString address = i.prettyAddress();
00619 d->addRecipient( i );
00620 const std::vector<Key> pgp = makeSuggestions( d->m_recipientPreferences, i, OpenPGP );
00621 const std::vector<Key> cms = makeSuggestions( d->m_recipientPreferences, i, CMS );
00622 pgpCount += pgp.empty() ? 0 : 1;
00623 cmsCount += cms.empty() ? 0 : 1;
00624 d->m_listWidget->setCertificates( address, pgp, cms );
00625 }
00626 if ( d->m_presetProtocol == UnknownProtocol && !d->m_multipleProtocolsAllowed )
00627 ( cmsCount > pgpCount ? d->m_cmsRB : d->m_pgpRB )->click();
00628 }
00629
00630 std::vector<Key> ResolveRecipientsPage::resolvedCertificates() const
00631 {
00632 std::vector<Key> certs;
00633 Q_FOREACH( const QString& i, d->m_listWidget->identifiers() )
00634 {
00635 const GpgME::Key cert = d->m_listWidget->selectedCertificate( i );
00636 if ( !cert.isNull() )
00637 certs.push_back( cert );
00638 }
00639 return certs;
00640 }
00641
00642 void ResolveRecipientsPage::Private::selectionChanged()
00643 {
00644 m_removeButton->setEnabled( !m_listWidget->selectedEntries().isEmpty() );
00645 }
00646
00647 void ResolveRecipientsPage::Private::removeSelectedEntries()
00648 {
00649 Q_FOREACH ( const QString& i, m_listWidget->selectedEntries() )
00650 m_listWidget->removeEntry( i );
00651 emit q->completeChanged();
00652 }
00653
00654 void ResolveRecipientsPage::setRecipientsUserMutable( bool isMutable )
00655 {
00656 d->m_addButton->setVisible( isMutable );
00657 d->m_removeButton->setVisible( isMutable );
00658 }
00659
00660 bool ResolveRecipientsPage::recipientsUserMutable() const
00661 {
00662 return d->m_addButton->isVisible();
00663 }
00664
00665
00666 boost::shared_ptr<RecipientPreferences> ResolveRecipientsPage::recipientPreferences() const
00667 {
00668 return d->m_recipientPreferences;
00669 }
00670
00671 void ResolveRecipientsPage::setRecipientPreferences( const boost::shared_ptr<RecipientPreferences>& prefs )
00672 {
00673 d->m_recipientPreferences = prefs;
00674 }
00675
00676 void ResolveRecipientsPage::Private::writeSelectedCertificatesToPreferences()
00677 {
00678 if ( !m_recipientPreferences )
00679 return;
00680
00681 Q_FOREACH ( const QString& i, m_listWidget->identifiers() )
00682 {
00683 const Mailbox mbox = m_listWidget->mailbox( i );
00684 if ( !mbox.hasAddress() )
00685 continue;
00686 const Key pgp = m_listWidget->selectedCertificate( i, OpenPGP );
00687 if ( !pgp.isNull() )
00688 m_recipientPreferences->setPreferredCertificate( mbox, OpenPGP, pgp );
00689 const Key cms = m_listWidget->selectedCertificate( i, CMS );
00690 if ( !cms.isNull() )
00691 m_recipientPreferences->setPreferredCertificate( mbox, CMS, cms );
00692 }
00693 }
00694
00695 void ResolveRecipientsPage::onNext() {
00696 d->writeSelectedCertificatesToPreferences();
00697 }
00698
00699 #include "moc_resolverecipientspage_p.cpp"
00700 #include "moc_resolverecipientspage.cpp"