33 #include <config-kleopatra.h> 
   53 #include <kleo/stl_util.h> 
   54 #include <ui/filenamerequester.h> 
   59 #include <KMessageBox> 
   62 #include <QWizardPage> 
   63 #include <QRadioButton> 
   65 #include <QPushButton> 
   66 #include <QDialogButtonBox> 
   68 #include <QListWidget> 
   75 #include <gpgme++/key.h> 
   77 #include <boost/shared_ptr.hpp> 
   78 #include <boost/bind.hpp> 
   80 using namespace GpgME;
 
   81 using namespace boost;
 
   83 using namespace Kleo::Crypto;
 
   84 using namespace Kleo::Crypto::Gui;
 
   95 static void enable_disable( QAbstractButton & button, 
const QAbstractItemView * view ) {
 
   96     const QItemSelectionModel * ism = view ? view->selectionModel() : 0 ;
 
   97     button.setEnabled( ism && ism->hasSelection() );
 
  102     from.
view()->selectionModel()->clearSelection();
 
  112     const std::vector<Key> k
 
  113         = kdtools::copy_if< std::vector<Key> >( ktv.
keys(), boost::bind( &Key::protocol, _1 ) != proto );
 
  117 static QString 
join_max( 
const QStringList & sl, 
const int max, 
const QString & glue ) {
 
  118     return QStringList( sl.mid( 0, max ) ).join( glue );
 
  125     class ListDialog : 
public QDialog {
 
  128         explicit ListDialog( 
const QStringList & files, 
QWidget * parent=0 )
 
  131               buttonBox( QDialogButtonBox::Close, Qt::Vertical, this ),
 
  134             setWindowTitle( i18nc(
"@title:window",
"Selected Files") );
 
  140             listWidget.setSelectionMode( QListWidget::NoSelection );
 
  141             listWidget.addItems( files );
 
  143             hlay.addWidget( &listWidget );
 
  144             hlay.addWidget( &buttonBox );
 
  146             connect( &buttonBox, SIGNAL(rejected()), 
this, SLOT(reject()) );
 
  150         QListWidget listWidget;
 
  151         QDialogButtonBox buttonBox;
 
  159     class ObjectsLabel : 
public QLabel {
 
  161         Q_PROPERTY( QStringList files READ files WRITE setFiles )
 
  163         static const int MaxLinesShownInline = 5;
 
  165         explicit ObjectsLabel( 
QWidget * parent=0, Qt::WindowFlags f=0 )
 
  166             : QLabel( parent, f ), m_dialog(), m_files( dummyFiles() )
 
  168             connect( 
this, SIGNAL(linkActivated(QString)),
 
  169                      this, SLOT(slotLinkActivated()) );
 
  176         explicit ObjectsLabel( 
const QStringList & files, 
QWidget * parent=0, Qt::WindowFlags f=0 )
 
  177             : QLabel( parent, f ), m_dialog(), m_files( files )
 
  179             connect( 
this, SIGNAL(linkActivated(QString)),
 
  180                      this, SLOT(slotLinkActivated()) );
 
  184         QStringList files()
 const { 
return m_files; }
 
  185         void setFiles( 
const QStringList & files ) {
 
  186             if ( m_files == files )
 
  193         void slotLinkActivated() {
 
  195                 m_dialog = 
new ListDialog( m_files, 
this );
 
  196                 m_dialog->setAttribute( Qt::WA_DeleteOnClose );
 
  198             if ( m_dialog->isVisible() )
 
  205         static QStringList dummyFiles() {
 
  207             for ( 
int i = 0 ; i < MaxLinesShownInline+1 ; ++i )
 
  208                 dummy.push_back( QString::number( i ) );
 
  211         QString makeText()
 const {
 
  212             if ( m_files.empty() )
 
  213                 return QLatin1String(
"<p>") + i18n(
"No files selected.") + QLatin1String(
"</p>");
 
  214             QString html = QLatin1String(
"<p>") + i18np(
"Selected file:", 
"Selected files:", m_files.size() ) + QLatin1String(
"</p>")
 
  215                 + QLatin1String(
"<ul><li>") + 
join_max( m_files, MaxLinesShownInline, QLatin1String(
"</li><li>") ) + QLatin1String(
"</li></ul>") ;
 
  216             if ( m_files.size() > MaxLinesShownInline )
 
  217                 html += QLatin1String(
"<p><a href=\"link:/\">") + i18nc(
"@action",
"More...") + QLatin1String(
"</a></p>");
 
  220         void updateText() { setText( makeText() ); }
 
  223         QPointer<ListDialog> m_dialog;
 
  231     class ArchiveFileNameRequester : 
public Kleo::FileNameRequester {
 
  234         explicit ArchiveFileNameRequester( Protocol protocol, 
QWidget * parent=0 )
 
  235             : FileNameRequester( QDir::Files, parent ), m_protocol( protocol ), m_archiveDefinition()
 
  237             setExistingOnly( 
false );
 
  242             if ( ad == m_archiveDefinition )
 
  244             const QString oldExt = m_archiveDefinition ? m_archiveDefinition->extensions( m_protocol ).front() : QString() ;
 
  245             const QString newExt = ad                  ? ad->extensions( m_protocol ).front()                  : QString() ;
 
  246             QString fn = fileName();
 
  247             if ( fn.endsWith( oldExt ) )
 
  248                 fn.chop( oldExt.size() + 1 );
 
  249             m_archiveDefinition = ad;
 
  251                 fn += QLatin1Char(
'.') + newExt;
 
  252             FileNameRequester::setFileName( fn );
 
  254         void setFileName( 
const QString & fn ) {
 
  255             const QString ext = m_archiveDefinition ? m_archiveDefinition->extensions( m_protocol ).front() : QString() ;
 
  256             if ( m_archiveDefinition && !fn.endsWith( ext ) )
 
  257                 FileNameRequester::setFileName( fn + QLatin1Char(
'.') + ext );
 
  259                 FileNameRequester::setFileName( fn );
 
  262         const Protocol m_protocol;
 
  273               m_presetProtocol( UnknownProtocol )
 
  278         bool isArchiveRequested()
 const {
 
  279             return field(QLatin1String(
"archive")).toBool();
 
  282         QString archiveName( Protocol p )
 const {
 
  283             return field( p == 
OpenPGP ? QLatin1String(
"archive-name-pgp") : QLatin1String(
"archive-name-cms" )).toString();
 
  286         bool isRemoveUnencryptedFilesEnabled()
 const {
 
  287             return field(QLatin1String(
"remove")).toBool();
 
  290         bool isSignOnlySelected()
 const {
 
  291             return field(QLatin1String(
"sign")).toBool();
 
  294         bool isEncryptOnlySelected()
 const {
 
  295             return field(QLatin1String(
"encrypt")).toBool();
 
  298         bool isSignEncryptSelected()
 const {
 
  299             return field(QLatin1String(
"signencrypt")).toBool() ;
 
  302         bool isSigningSelected()
 const {
 
  303             return isSignOnlySelected() || isSignEncryptSelected() ;
 
  306         bool isEncryptionSelected()
 const {
 
  307             return isEncryptOnlySelected() || isSignEncryptSelected() ;
 
  310         Protocol protocol()
 const { 
return m_presetProtocol; }
 
  311         Protocol effectiveProtocol()
 const {
 
  312             if ( isSignEncryptSelected() ) {
 
  313                 assert( m_presetProtocol == 
OpenPGP || m_presetProtocol == UnknownProtocol );
 
  316                 return m_presetProtocol;
 
  320         void setPresetProtocol( Protocol proto ) {
 
  321             if ( proto == m_presetProtocol )
 
  323             m_presetProtocol = proto;
 
  324             doSetPresetProtocol();
 
  328         virtual void doSetPresetProtocol() {}
 
  331         Protocol m_presetProtocol;
 
  337         Q_PROPERTY( QStringList files READ files WRITE setFiles )
 
  338         Q_PROPERTY( 
bool signingPreset READ isSigningPreset WRITE setSigningPreset )
 
  339         Q_PROPERTY( 
bool signingUserMutable READ isSigningUserMutable WRITE setSigningUserMutable )
 
  340         Q_PROPERTY( 
bool encryptionPreset READ isEncryptionPreset WRITE setEncryptionPreset )
 
  341         Q_PROPERTY( 
bool encryptionUserMutable READ isEncryptionUserMutable WRITE setEncryptionUserMutable )
 
  342         Q_PROPERTY( 
bool archiveUserMutable READ isArchiveUserMutable WRITE setArchiveUserMutable )
 
  344         explicit OperationPage( 
QWidget * parent=0 )
 
  346               m_objectsLabel( this ),
 
  347               m_archiveCB( i18n(
"Archive files with:"), this ),
 
  349               m_archiveNamePgpLB( i18n(
"Archive name (OpenPGP):"), this ),
 
  350               m_archiveNamePgp( 
OpenPGP, this ),
 
  351               m_archiveNameCmsLB( i18n(
"Archive name (S/MIME):"), this ),
 
  352               m_archiveNameCms( 
CMS, this ),
 
  353               m_signencrypt( i18n(
"Sign and Encrypt (OpenPGP only)"), this ),
 
  354               m_encrypt( i18n(
"Encrypt"), this ),
 
  355               m_sign( i18n(
"Sign"), this ),
 
  356               m_armor( i18n(
"Text output (ASCII armor)"), this ),
 
  357               m_removeSource( i18n(
"Remove unencrypted original file when done"), this ),
 
  358               m_signingUserMutable( true ),
 
  359               m_encryptionUserMutable( true ),
 
  360               m_archiveUserMutable( true ),
 
  361               m_signingPreset( true ),
 
  362               m_encryptionPreset( true ),
 
  365             setTitle( i18nc(
"@title",
"What do you want to do?") );
 
  366             setSubTitle( i18nc(
"@title",
 
  367                                "Please select here whether you want to sign or encrypt files.") );
 
  381             QGridLayout * glay = 
new QGridLayout;
 
  382             glay->addWidget( &m_archiveCB,        0, 0 );
 
  383             glay->addWidget( &m_archive,          0, 1 );
 
  384             glay->addWidget( &m_archiveNamePgpLB, 1, 0 );
 
  385             glay->addWidget( &m_archiveNamePgp,   1, 1 );
 
  386             glay->addWidget( &m_archiveNameCmsLB, 2, 0 );
 
  387             glay->addWidget( &m_archiveNameCms,   2, 1 );
 
  389             QVBoxLayout * vlay = 
new QVBoxLayout( 
this );
 
  390             vlay->addWidget( &m_objectsLabel );
 
  391             vlay->addLayout( glay );
 
  392             vlay->addWidget( &m_signencrypt );
 
  393             vlay->addWidget( &m_encrypt );
 
  394             vlay->addWidget( &m_sign );
 
  395             vlay->addStretch( 1 );
 
  396             vlay->addWidget( &m_armor );
 
  397             vlay->addWidget( &m_removeSource );
 
  399             m_archiveNamePgpLB.setAlignment( Qt::AlignRight );
 
  400             m_archiveNamePgpLB.setBuddy( &m_archiveNamePgp );
 
  401             m_archiveNameCmsLB.setAlignment( Qt::AlignRight );
 
  402             m_archiveNameCmsLB.setBuddy( &m_archiveNameCms );
 
  404             m_armor.setChecked( 
false );
 
  405             m_archive.setEnabled( 
false );
 
  406             m_archiveNamePgpLB.setEnabled( 
false );
 
  407             m_archiveNamePgp.setEnabled( 
false );
 
  408             m_archiveNameCmsLB.setEnabled( 
false );
 
  409             m_archiveNameCms.setEnabled( 
false );
 
  412                 m_archive.addItem( ad->label(), qVariantFromValue( ad ) );
 
  414             registerField( QLatin1String("files"), this, "files" );
 
  416             registerField( QLatin1String("signing-preset"), this, "signingPreset" );
 
  417             registerField( QLatin1String("encryption-preset"), this, "encryptionPreset" );
 
  419             registerField( QLatin1String("signencrypt"), &m_signencrypt );
 
  420             registerField( QLatin1String("encrypt"), &m_encrypt );
 
  421             registerField( QLatin1String("sign"), &m_sign );
 
  423             registerField( QLatin1String("armor"), &m_armor );
 
  424             registerField( QLatin1String("remove"), &m_removeSource );
 
  426             registerField( QLatin1String("archive"), &m_archiveCB );
 
  427             registerField( QLatin1String("archive-
id"), &m_archive );
 
  428             registerField( QLatin1String("archive-
name-pgp"), &m_archiveNamePgp, "fileName" );
 
  429             registerField( QLatin1String("archive-
name-cms"), &m_archiveNameCms, "fileName" );
 
  431             registerField( QLatin1String("signing-user-mutable"), this, "signingUserMutable" );
 
  432             registerField( QLatin1String("encryption-user-mutable"), this, "encryptionUserMutable" );
 
  433             registerField( QLatin1String("archive-user-mutable"), this, "archiveUserMutable" );
 
  435             connect( &m_archive, SIGNAL(currentIndexChanged(
int)),
 
  436                      this, SLOT(slotArchiveDefinitionChanged()) );
 
  438             connect( &m_signencrypt, SIGNAL(clicked()), this, SIGNAL(completeChanged()) );
 
  439             connect( &m_encrypt,     SIGNAL(clicked()), this, SIGNAL(completeChanged()) );
 
  440             connect( &m_sign,        SIGNAL(clicked()), this, SIGNAL(completeChanged()) );
 
  441             connect( &m_archiveCB,   SIGNAL(clicked()), this, SIGNAL(completeChanged()) );
 
  442             connect( &m_archiveNamePgp, SIGNAL(fileNameChanged(QString)), this, SIGNAL(completeChanged()) );
 
  443             connect( &m_archiveNameCms, SIGNAL(fileNameChanged(QString)), this, SIGNAL(completeChanged()) );
 
  445             connect( &m_sign, SIGNAL(toggled(
bool)),
 
  446                      &m_removeSource, SLOT(setDisabled(
bool)) );
 
  447             connect( &m_archiveCB, SIGNAL(toggled(
bool)),
 
  448                      &m_archive, SLOT(setEnabled(
bool)) );
 
  449             connect( &m_archiveCB, SIGNAL(toggled(
bool)),
 
  450                      &m_archiveNamePgpLB, SLOT(setEnabled(
bool)) );
 
  451             connect( &m_archiveCB, SIGNAL(toggled(
bool)),
 
  452                      &m_archiveNamePgp, SLOT(setEnabled(
bool)) );
 
  453             connect( &m_archiveCB, SIGNAL(toggled(
bool)),
 
  454                      &m_archiveNameCmsLB, SLOT(setEnabled(
bool)) );
 
  455             connect( &m_archiveCB, SIGNAL(toggled(
bool)),
 
  456                      &m_archiveNameCms, SLOT(setEnabled(
bool)) );
 
  459             m_archiveNamePgp.setArchiveDefinition( ad );
 
  460             m_archiveNameCms.setArchiveDefinition( ad );
 
  463         QStringList files()
 const { 
return m_objectsLabel.files(); }
 
  464         void setFiles( 
const QStringList & files ) {
 
  465             m_objectsLabel.setFiles( files );
 
  466             const QString archiveName =
 
  467                 files.size() == 1 ? files.front() :
 
  469                                            .absoluteFilePath( i18nc(
"base name of an archive file, e.g. archive.zip or archive.tar.gz", 
"archive") );
 
  470             m_archiveNamePgp.setFileName( archiveName );
 
  471             m_archiveNameCms.setFileName( archiveName );
 
  474         bool isSigningPreset()
 const { 
return m_signingPreset; }
 
  475         void setSigningPreset( 
bool preset ) {
 
  476             if ( m_signingPreset == preset )
 
  478             m_signingPreset = preset;
 
  479             updateSignEncryptArchiveWidgetStates();
 
  482         bool isSigningUserMutable()
 const { 
return m_signingUserMutable; }
 
  483         void setSigningUserMutable( 
bool mut ) {
 
  484             if ( m_signingUserMutable == mut )
 
  486             m_signingUserMutable = mut;
 
  487             updateSignEncryptArchiveWidgetStates();
 
  490         bool isEncryptionPreset()
 const { 
return m_encryptionPreset; }
 
  491         void setEncryptionPreset( 
bool preset ) {
 
  492             if ( m_encryptionPreset == preset )
 
  494             m_encryptionPreset = preset;
 
  495             updateSignEncryptArchiveWidgetStates();
 
  498         bool isEncryptionUserMutable()
 const { 
return m_encryptionUserMutable; }
 
  499         void setEncryptionUserMutable( 
bool mut ) {
 
  500             if ( m_encryptionUserMutable == mut )
 
  502             m_encryptionUserMutable = mut;
 
  503             updateSignEncryptArchiveWidgetStates();
 
  506         bool isArchiveUserMutable()
 const { 
return m_archiveUserMutable; }
 
  507         void setArchiveUserMutable( 
bool mut ) {
 
  508             if ( m_archiveUserMutable == mut )
 
  510             m_archiveUserMutable = mut;
 
  511             updateSignEncryptArchiveWidgetStates();
 
  514          bool isComplete()
 const {
 
  515             return ( !isArchiveRequested() || !archiveName( 
OpenPGP ).isEmpty() && !archiveName( 
CMS ).isEmpty() ) 
 
  516                 && ( isSigningSelected() || isEncryptionSelected() ) ;
 
  519          bool validatePage() {
 
  520             if ( isSignOnlySelected() && isArchiveRequested() )
 
  521                 return KMessageBox::warningContinueCancel( 
this,
 
  523                                                                  "<para>Archiving in combination with sign-only currently requires what are known as opaque signatures - " 
  524                                                                  "unlike detached ones, these embed the content in the signature.</para>" 
  525                                                                  "<para>This format is rather unusual. You might want to archive the files separately, " 
  526                                                                  "and then sign the archive as one file with Kleopatra.</para>" 
  527                                                                  "<para>Future versions of Kleopatra are expected to also support detached signatures in this case.</para>" ),                                                    
 
  528                                                            i18nc(
"@title:window", 
"Unusual Signature Warning"),
 
  529                                                            KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
 
  530                                                            QLatin1String(
"signencryptfileswizard-archive+sign-only-warning") )
 
  531                     == KMessageBox::Continue ;
 
  539          void doSetPresetProtocol() {
 
  540             updateSignEncryptArchiveWidgetStates();
 
  548             m_archive.setCurrentIndex( m_archive.findData( qVariantFromValue( ad ) ) );
 
  551         void setArchiveDefinition( 
const QString & adName ) {
 
  552             const std::vector< shared_ptr<ArchiveDefinition> >::const_iterator
 
  553                 it = kdtools::find_if( m_archiveDefinitions, boost::bind( &ArchiveDefinition::id, _1 ) == adName );
 
  554             if ( it != m_archiveDefinitions.end() )
 
  555                 m_archive.setCurrentIndex( it - m_archiveDefinitions.begin() );
 
  559         void slotArchiveDefinitionChanged() {
 
  561             m_archiveNamePgp.setArchiveDefinition( ad );
 
  562             m_archiveNameCms.setArchiveDefinition( ad );
 
  566         void updateSignEncryptArchiveWidgetStates() {
 
  567             m_archiveCB.setEnabled( m_archiveUserMutable );
 
  569             const bool mustEncrypt = m_encryptionPreset && !m_encryptionUserMutable ;
 
  570             const bool mustSign    = m_signingPreset    && !m_signingUserMutable    ;
 
  572             const bool mayEncrypt  = m_encryptionPreset || m_encryptionUserMutable  ;
 
  573             const bool maySign     = m_signingPreset    || m_signingUserMutable     ;
 
  575             const bool canSignEncrypt = protocol() != 
CMS && mayEncrypt && maySign ;
 
  576             const bool canSignOnly    = maySign && !mustEncrypt ;
 
  577             const bool canEncryptOnly = mayEncrypt && !mustSign ;
 
  579             m_signencrypt.setEnabled( canSignEncrypt );
 
  580             m_encrypt.setEnabled( canEncryptOnly );
 
  581             m_sign.setEnabled( canSignOnly );
 
  583             really_check( m_signencrypt, canSignEncrypt &&  m_signingPreset &&  m_encryptionPreset );
 
  584             really_check( m_encrypt,     canEncryptOnly && !m_signingPreset &&  m_encryptionPreset );
 
  585             really_check( m_sign,        canSignOnly    &&  m_signingPreset && !m_encryptionPreset );
 
  587             m_signencrypt.setToolTip( protocol() == 
CMS 
  588                                       ? i18n(
"This operation is not available for S/MIME")
 
  592         ObjectsLabel m_objectsLabel;
 
  593         QCheckBox m_archiveCB;
 
  595         QLabel m_archiveNamePgpLB;
 
  596         ArchiveFileNameRequester m_archiveNamePgp;
 
  597         QLabel m_archiveNameCmsLB;
 
  598         ArchiveFileNameRequester m_archiveNameCms;
 
  599         QRadioButton m_signencrypt, m_encrypt, m_sign;
 
  600         QCheckBox m_armor, m_removeSource;
 
  601         bool m_signingUserMutable, m_encryptionUserMutable, m_archiveUserMutable;
 
  602         bool m_signingPreset, m_encryptionPreset;
 
  603         const std::vector< shared_ptr<ArchiveDefinition> > m_archiveDefinitions;
 
  610         explicit RecipientsPage( 
QWidget * parent=0 )
 
  612               m_lastEffectiveProtocol( static_cast<Protocol>(-1) ), 
 
  614               m_unselectedKTV( this ),
 
  615               m_selectPB( i18n(
"Add"), this ),
 
  616               m_unselectPB( i18n(
"Remove"), this ),
 
  617               m_selectedKTV( this )
 
  619             setTitle( i18nc(
"@title",
"For whom do you want to encrypt?") );
 
  620             setSubTitle( i18nc(
"@title",
 
  621                                "Please select for whom you want the files to be encrypted. " 
  622                                "Do not forget to pick one of your own certificates.") );
 
  632             m_selectPB.setIcon( KIcon( QLatin1String(
"arrow-down") ) );
 
  633             m_unselectPB.setIcon( KIcon( QLatin1String(
"arrow-up") ) );
 
  635             m_selectPB.setEnabled( 
false );
 
  636             m_unselectPB.setEnabled( 
false );
 
  638             m_unselectedKTV.setHierarchicalModel( AbstractKeyListModel::createHierarchicalKeyListModel( &m_unselectedKTV ) );
 
  639             m_unselectedKTV.setHierarchicalView( 
true );
 
  640             m_selectedKTV.setFlatModel( AbstractKeyListModel::createFlatKeyListModel( &m_selectedKTV ) );
 
  641             m_selectedKTV.setHierarchicalView( 
false );
 
  643             QVBoxLayout * vlay = 
new QVBoxLayout( 
this );
 
  644             vlay->addWidget( &m_searchbar );
 
  645             vlay->addWidget( &m_unselectedKTV, 1 );
 
  647             QHBoxLayout * hlay = 
new QHBoxLayout;
 
  648             hlay->addStretch( 1 );
 
  649             hlay->addWidget( &m_selectPB );
 
  650             hlay->addWidget( &m_unselectPB );
 
  651             hlay->addStretch( 1 );
 
  653             vlay->addLayout( hlay );
 
  654             vlay->addWidget( &m_selectedKTV, 1 );
 
  656             xconnect( &m_searchbar, SIGNAL(stringFilterChanged(QString)),
 
  657                       &m_unselectedKTV, SLOT(setStringFilter(QString)) );
 
  661             connect( m_unselectedKTV.view()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
 
  662                      this, SLOT(slotUnselectedSelectionChanged()) );
 
  663             connect( m_selectedKTV.view()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
 
  664                      this, SLOT(slotSelectedSelectionChanged()) );
 
  666             connect( &m_selectPB, SIGNAL(clicked()), 
this, SLOT(select()) );
 
  667             connect( &m_unselectPB, SIGNAL(clicked()), 
this, SLOT(unselect()) );
 
  670          bool isComplete()
 const {
 
  671             return !m_selectedKTV.keys().empty();
 
  675             if ( isSigningSelected() )
 
  681         static bool need_reload( Protocol now, Protocol then ) {
 
  682             if ( then == UnknownProtocol )
 
  684             if ( now == UnknownProtocol )
 
  689         static bool need_grep( Protocol now, Protocol then ) {
 
  690             return now != UnknownProtocol && then == UnknownProtocol ;
 
  693          void initializePage() {
 
  695             setCommitPage( !isSigningSelected() );
 
  697             const Protocol currentEffectiveProtocol = effectiveProtocol();
 
  699             if ( need_reload( currentEffectiveProtocol, m_lastEffectiveProtocol ) ) {
 
  700                 std::vector<Key> keys = KeyCache::instance()->keys();
 
  702                 if ( currentEffectiveProtocol != UnknownProtocol )
 
  704                 m_unselectedKTV.setKeys( keys );
 
  705             } 
else if ( need_grep( currentEffectiveProtocol, m_lastEffectiveProtocol ) ) {
 
  710             m_lastEffectiveProtocol = currentEffectiveProtocol;
 
  713          bool validatePage() {
 
  714             const std::vector<Key> & r = keys();
 
  716                 if ( KMessageBox::warningContinueCancel( 
this,
 
  718                                                                "<para>None of the recipients you are encrypting to seems to be your own.</para>" 
  719                                                                "<para>This means that you will not be able to decrypt the data anymore, once encrypted.</para>" 
  720                                                                "<para>Do you want to continue, or cancel to change the recipient selection?</para>"),
 
  721                                                          i18nc(
"@title:window",
"Encrypt-To-Self Warning"),
 
  722                                                          KStandardGuiItem::cont(),
 
  723                                                          KStandardGuiItem::cancel(),
 
  724                                                          QLatin1String(
"warn-encrypt-to-non-self"), KMessageBox::Notify|KMessageBox::Dangerous )
 
  725                      == KMessageBox::Cancel )
 
  727                 else if ( isRemoveUnencryptedFilesEnabled() )
 
  728                     if ( KMessageBox::warningContinueCancel( 
this,
 
  730                                                                    "<para>You have requested the unencrypted data to be removed after encryption.</para>" 
  731                                                                    "<para>Are you really sure you do not need to access the data anymore in decrypted form?</para>"),
 
  732                                                              i18nc(
"@title:window",
"Encrypt-To-Self Warning"),
 
  733                                                              KStandardGuiItem::cont(),
 
  734                                                              KStandardGuiItem::cancel(),
 
  735                                                              QLatin1String(
"warn-encrypt-to-non-self-destructive"), KMessageBox::Notify|KMessageBox::Dangerous )
 
  736                          == KMessageBox::Cancel )
 
  742         const std::vector<Key> & keys()
 const {
 
  743             return m_selectedKTV.keys();
 
  747         void slotUnselectedSelectionChanged() {
 
  750         void slotSelectedSelectionChanged() {
 
  755             emit completeChanged();
 
  759             emit completeChanged();
 
  763         Protocol m_lastEffectiveProtocol;
 
  767         QPushButton m_selectPB, m_unselectPB;
 
  775         explicit SignerPage( 
QWidget * parent=0 )
 
  778               pgpCB( i18n(
"Sign with OpenPGP"), this ),
 
  779               cmsCB( i18n(
"Sign with S/MIME"), this ),
 
  782             setTitle( i18nc(
"@title",
"Who do you want to sign as?") );
 
  783             setSubTitle( i18nc(
"@title",
 
  784                                "Please choose an identity with which to sign the data." ) );
 
  786             setCommitPage( 
true );
 
  788             QVBoxLayout * vlay = 
new QVBoxLayout( 
this );
 
  795             vlay->addWidget( &pgpCB );
 
  796             vlay->addWidget( &cmsCB );
 
  798             widget.layout()->setMargin( 0 );
 
  799             vlay->addWidget( &widget );
 
  804             connect( &pgpCB, SIGNAL(toggled(
bool)), 
this, SLOT(slotSignProtocolToggled()) );
 
  805             connect( &cmsCB, SIGNAL(toggled(
bool)), 
this, SLOT(slotSignProtocolToggled()) );
 
  808         std::vector<Key> keys()
 const {
 
  810             const bool pgp = pgpCB.isChecked();
 
  811             const bool cms = cmsCB.isChecked();
 
  813             std::vector<Key> result;
 
  814             result.reserve( pgp + cms );
 
  817                 result.push_back( keys[
OpenPGP] );
 
  819                 result.push_back( keys[
CMS] );
 
  822             result.erase( std::remove_if( result.begin(), result.end(), mem_fn( &Key::isNull ) ),
 
  827          bool isComplete()
 const {
 
  828             return !keys().empty();
 
  835          void initializePage() {
 
  837             if ( 
QWizard * wiz = wizard() ) {
 
  840                 disconnect( filesWizard, SIGNAL(operationPrepared()), 
this, SLOT(slotCommitSigningPreferences()) );
 
  841                 connect( filesWizard, SIGNAL(operationPrepared()), 
this, SLOT(slotCommitSigningPreferences()) );
 
  844             bool pgp = effectiveProtocol() == 
OpenPGP;
 
  845             bool cms = effectiveProtocol() == 
CMS;
 
  847             if ( effectiveProtocol() == UnknownProtocol )
 
  850             assert( pgp || cms );
 
  852             if ( isSignOnlySelected() ) {
 
  855                 pgpCB.setEnabled( pgp );
 
  856                 cmsCB.setEnabled( cms );
 
  857                 pgpCB.setChecked( pgp );
 
  858                 cmsCB.setChecked( cms );
 
  865                 const std::vector<Key> & recipients = resolvedRecipients();
 
  871                 pgpCB.setEnabled( 
false );
 
  872                 cmsCB.setEnabled( 
false );
 
  873                 pgpCB.setChecked( pgp );
 
  874                 cmsCB.setChecked( cms );
 
  881                 widget.setSelectedCertificates( signPref->preferredCertificate( OpenPGP ),
 
  882                                                 signPref->preferredCertificate( CMS ) );
 
  887         const std::vector<Key> & resolvedRecipients()
 const {
 
  889             assert( qobject_cast<NewSignEncryptFilesWizard*>( wizard() ) == static_cast<NewSignEncryptFilesWizard*>( wizard() ) );
 
  894         void slotSignProtocolToggled() {
 
  895             widget.setAllowedProtocols( pgpCB.isChecked(), cmsCB.isChecked() );
 
  896             emit completeChanged();
 
  899         void slotCommitSigningPreferences() {
 
  900             if ( widget.rememberAsDefault() )
 
  901                 Q_FOREACH( 
const GpgME::Key & key, keys() )
 
  903                         signPref->setPreferredCertificate( key.protocol(), key );
 
  908         QCheckBox pgpCB, cmsCB;
 
  919             setTitle( i18nc(
"@title",
"Results") );
 
  920             setSubTitle( i18nc(
"@title",
 
  921                                "Status and progress of the crypto operations is shown here." ) );
 
  928 class NewSignEncryptFilesWizard::Private {
 
  929     friend class ::Kleo::Crypto::Gui::NewSignEncryptFilesWizard;
 
  934           operationPage( new OperationPage( 
q ) ),
 
  935           recipientsPage( new RecipientsPage( 
q ) ),
 
  936           signerPage( new SignerPage( 
q ) ),
 
  938           createArchivePreset( false ),
 
  939           createArchiveUserMutable( true ),
 
  940           signingPreset( true ),
 
  941           signingUserMutable( true ),
 
  942           encryptionPreset( true ),
 
  943           encryptionUserMutable( true )
 
  955         connect( 
q, SIGNAL(currentIdChanged(
int)), 
q, SLOT(slotCurrentIdChanged(
int)) );
 
  959     void slotCurrentIdChanged( 
int id ) {
 
  961             emit 
q->operationPrepared();
 
  965     int startId()
 const {
 
  966         if ( !createArchivePreset && !createArchiveUserMutable ) {
 
  967             if ( signingPreset && !encryptionPreset && !encryptionUserMutable )
 
  969             if ( encryptionPreset && !signingPreset && !signingUserMutable ||
 
  970                  signingPreset && !signingUserMutable && encryptionPreset && !encryptionUserMutable )
 
  973         if ( signingUserMutable || encryptionUserMutable || createArchivePreset || createArchiveUserMutable )
 
  976             if ( encryptionPreset )
 
  981     void updateStartId() { 
q->setStartId( startId() ); }
 
  984     OperationPage  * operationPage;
 
  985     RecipientsPage * recipientsPage;
 
  986     SignerPage     * signerPage;
 
  989     bool createArchivePreset      : 1;
 
  990     bool createArchiveUserMutable : 1;
 
  991     bool signingPreset         : 1;
 
  992     bool signingUserMutable    : 1;
 
  993     bool encryptionPreset      : 1;
 
  994     bool encryptionUserMutable : 1;
 
  998 NewSignEncryptFilesWizard::NewSignEncryptFilesWizard( 
QWidget * parent, Qt::WindowFlags f )
 
  999     : 
QWizard( parent, f ), 
d( new Private( this ) )
 
 1007     d->operationPage->setPresetProtocol( proto );
 
 1008     d->recipientsPage->setPresetProtocol( proto );
 
 1009     d->signerPage->setPresetProtocol( proto );
 
 1015     d->createArchivePreset = preset;
 
 1016     setField( QLatin1String(
"archive"), preset );
 
 1021     if ( mut == d->createArchiveUserMutable )
 
 1023     d->createArchiveUserMutable = mut;
 
 1024     setField( QLatin1String(
"archive-user-mutable"), mut );
 
 1029     d->operationPage->setArchiveDefinition( 
id );
 
 1033     if ( preset == d->signingPreset )
 
 1035     d->signingPreset = preset;
 
 1036     setField( QLatin1String(
"signing-preset"), preset );
 
 1041     if ( mut == d->signingUserMutable )
 
 1043     d->signingUserMutable = mut;
 
 1044     setField( QLatin1String(
"signing-user-mutable"), mut );
 
 1049     if ( preset == d->encryptionPreset )
 
 1051     d->encryptionPreset = preset;
 
 1052     setField( QLatin1String(
"encryption-preset"), preset );
 
 1057     if ( mut == d->encryptionUserMutable )
 
 1059     d->encryptionUserMutable = mut;
 
 1060     setField( QLatin1String(
"encryption-user-mutable"), mut );
 
 1065     setField( QLatin1String(
"files"), files );
 
 1070     return field(QLatin1String(
"sign")).toBool() || 
field(QLatin1String(
"signencrypt")).toBool() ;
 
 1074     return field(QLatin1String(
"encrypt")).toBool() || 
field(QLatin1String(
"signencrypt")).toBool() ;
 
 1078     return field(QLatin1String(
"armor")).toBool();
 
 1086     return field(QLatin1String(
"archive")).toBool();
 
 1090     return d->operationPage->archiveDefinition();
 
 1094     return d->operationPage->archiveName( p );
 
 1098     return d->recipientsPage->keys();
 
 1102     return d->signerPage->keys();
 
 1107     d->resultPage->setTaskCollection( coll );
 
 1110 #include "moc_newsignencryptfileswizard.cpp" 
 1111 #include "newsignencryptfileswizard.moc" 
QString heuristicBaseDirectory(const QStringList &files)
static void copy_selected_from_to(KeyTreeView &from, KeyTreeView &to)
~NewSignEncryptFilesWizard()
void setCreateArchiveUserMutable(bool mut)
bool isSigningSelected() const 
void setSigningPreset(bool preset)
const std::vector< GpgME::Key > & keys() const 
bool isCreateArchiveSelected() const 
static void move_selected_from_to(KeyTreeView &from, KeyTreeView &to)
static void remove_all_keys_not_xyz(KeyTreeView &ktv, Protocol proto)
void setCreateArchivePreset(bool preset)
The QWizardPage class is the base class for wizard pages. 
void grep_can_encrypt(T &t)
QVariant field(const QString &name) const 
void setFiles(const QStringList &files)
void grep_protocol(T &t, GpgME::Protocol proto)
void addKeysSelected(const std::vector< GpgME::Key > &keys)
bool isAsciiArmorEnabled() const 
bool none_of_secret(const T &t)
void setArchiveDefinitionId(const QString &id)
bool none_of_protocol(const T &t, GpgME::Protocol proto)
QString archiveFileName(GpgME::Protocol proto) const 
std::vector< GpgME::Key > selectedKeys() const 
std::vector< GpgME::Key > resolvedSigners() const 
void setSigningUserMutable(bool mut)
void setField(const QString &name, const QVariant &value)
void setTaskCollection(const boost::shared_ptr< TaskCollection > &coll)
bool isEncryptionSelected() const 
void removeKeys(const std::vector< GpgME::Key > &keys)
bool isRemoveUnencryptedFilesEnabled() const 
const std::vector< GpgME::Key > & resolvedRecipients() const 
boost::shared_ptr< ArchiveDefinition > selectedArchiveDefinition() const 
void setEncryptionPreset(bool preset)
static void enable_disable(QAbstractButton &button, const QAbstractItemView *view)
void setEncryptionUserMutable(bool mut)
static QString join_max(const QStringList &sl, const int max, const QString &glue)
The QWizard class provides a framework for wizards. 
static void really_check(QAbstractButton &b, bool on)
void setPresetProtocol(GpgME::Protocol proto)