33 #include <config-kleopatra.h> 
   44 #include <kleo/stl_util.h> 
   45 #include <kleo/cryptobackend.h> 
   46 #include <kleo/cryptobackendfactory.h> 
   47 #include <kleo/multideletejob.h> 
   48 #include <kleo/deletejob.h> 
   50 #include <gpgme++/key.h> 
   52 #include <KLocalizedString> 
   55 #include <QAbstractItemView> 
   58 #include <boost/bind.hpp> 
   65 using namespace boost;
 
   66 using namespace GpgME;
 
   68 using namespace Kleo::Dialogs;
 
   71     friend class ::Kleo::DeleteCertificatesCommand;
 
   77     void startDeleteJob( GpgME::Protocol protocol );
 
   80     void pgpDeleteResult( 
const GpgME::Error & );
 
   81     void cmsDeleteResult( 
const GpgME::Error & );
 
   82     void showErrorsAndFinish();
 
   84     bool canDelete( GpgME::Protocol proto )
 const {
 
   85         if ( 
const CryptoBackend::Protocol * 
const cbp = CryptoBackendFactory::instance()->protocol( proto ) )
 
   86             if ( DeleteJob * 
const job = cbp->deleteJob() ) {
 
   93     void ensureDialogCreated() {
 
   97         applyWindowID( dialog );
 
   98         dialog->setAttribute( Qt::WA_DeleteOnClose );
 
   99         dialog->setWindowTitle( i18nc(
"@title:window", 
"Delete Certificates") );
 
  100         connect( dialog, SIGNAL(accepted()), q_func(), SLOT(slotDialogAccepted()) );
 
  101         connect( dialog, SIGNAL(rejected()), q_func(), SLOT(slotDialogRejected()) );
 
  103     void ensureDialogShown() {
 
  108     void slotDialogAccepted();
 
  109     void slotDialogRejected() {
 
  116     GpgME::Error cmsError, pgpError;
 
  117     std::vector<Key> cmsKeys, pgpKeys;
 
  120 DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func() { 
return static_cast<Private*
>(
d.get()); }
 
  121 const DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func()
 const { 
return static_cast<const Private*
>(
d.get()); }
 
  132 DeleteCertificatesCommand::Private::~Private() {}
 
  136     : 
Command( new Private( this, p ) )
 
  142     : 
Command( v, new Private( this, p ) )
 
  151     enum Action { Nothing = 0, Failure = 1, ClearCMS = 2, ClearPGP = 4 };
 
  157     static const struct {
 
  160     } deletionErrorCases[16] = {
 
  164         { I18N_NOOP( 
"Neither the OpenPGP nor the CMS " 
  165                      "backends support certificate deletion.\n" 
  166                      "Check your installation." ),
 
  168         { I18N_NOOP( 
"The OpenPGP backend does not support " 
  169                      "certificate deletion.\n" 
  170                      "Check your installation.\n" 
  171                      "Only the selected CMS certificates " 
  172                      "will be deleted." ),
 
  175         { I18N_NOOP( 
"The OpenPGP backend does not support " 
  176                      "certificate deletion.\n" 
  177                      "Check your installation." ),
 
  179         { I18N_NOOP( 
"The OpenPGP backend does not support " 
  180                      "certificate deletion.\n" 
  181                      "Check your installation." ),
 
  185         { I18N_NOOP( 
"The CMS backend does not support " 
  186                      "certificate deletion.\n" 
  187                      "Check your installation.\n" 
  188                      "Only the selected OpenPGP certificates " 
  189                      "will be deleted." ),
 
  201         { I18N_NOOP( 
"The CMS backend does not support " 
  202                      "certificate deletion.\n" 
  203                      "Check your installation." ),
 
  214         { I18N_NOOP( 
"The CMS backend does not support " 
  215                      "certificate deletion.\n" 
  216                      "Check your installation." ),
 
  228 void DeleteCertificatesCommand::doStart() {
 
  230     std::vector<Key> selected = 
d->keys();
 
  231     if ( selected.empty() ) {
 
  236     kdtools::sort( selected, _detail::ByFingerprint<std::less>() );
 
  242     kdtools::sort( toBeDeleted, _detail::ByFingerprint<std::less>() );
 
  244     std::vector<Key> unselected;
 
  245     unselected.reserve( toBeDeleted.size() );
 
  246     std::set_difference( toBeDeleted.begin(), toBeDeleted.end(),
 
  247                          selected.begin(), selected.end(),
 
  248                          std::back_inserter( unselected ),
 
  249                          _detail::ByFingerprint<std::less>() );
 
  251     d->ensureDialogCreated();
 
  253     d->dialog->setSelectedKeys( selected );
 
  254     d->dialog->setUnselectedKeys( unselected );
 
  256     d->ensureDialogShown();
 
  260 void DeleteCertificatesCommand::Private::slotDialogAccepted() {
 
  261     std::vector<Key> keys = dialog->keys();
 
  262     assert( !keys.empty() );
 
  264     std::vector<Key>::iterator
 
  265         pgpBegin = keys.begin(),
 
  266         pgpEnd = std::stable_partition( pgpBegin, keys.end(),
 
  267                                         boost::bind( &GpgME::Key::protocol, _1 ) != 
CMS ),
 
  269         cmsEnd = keys.end() ;
 
  271     std::vector<Key> openpgp( pgpBegin, pgpEnd );
 
  272     std::vector<Key>     cms( cmsBegin, cmsEnd );
 
  274     const unsigned int errorCase =
 
  275         openpgp.empty() << 3U | canDelete( 
OpenPGP ) << 2U |
 
  276             cms.empty() << 1U |     canDelete( 
CMS ) << 0U ;
 
  278     if ( 
const unsigned int actions = deletionErrorCases[errorCase].actions ) {
 
  279         information( i18n( deletionErrorCases[errorCase].text ),
 
  281                      ? i18n( 
"Certificate Deletion Failed" )
 
  282                      : i18n( 
"Certificate Deletion Problem" ) );
 
  283         if ( actions & ClearCMS )
 
  285         if ( actions & ClearPGP )
 
  287         if ( actions & Failure ) {
 
  293     assert( !openpgp.empty() || !cms.empty() );
 
  295     pgpKeys.swap( openpgp );
 
  298     if ( !pgpKeys.empty() )
 
  300     if ( !cmsKeys.empty() )
 
  303     if ( ( pgpKeys.empty() || pgpError.code() ) &&
 
  304          ( cmsKeys.empty() || cmsError.code() ) )
 
  305         showErrorsAndFinish();
 
  308 void DeleteCertificatesCommand::Private::startDeleteJob( GpgME::Protocol protocol ) {
 
  309     assert( protocol != GpgME::UnknownProtocol );
 
  311     const std::vector<Key> & keys = protocol == 
CMS ? cmsKeys : pgpKeys ;
 
  313     const CryptoBackend::Protocol * 
const backend = CryptoBackendFactory::instance()->protocol( protocol );
 
  316     std::auto_ptr<MultiDeleteJob> job( 
new MultiDeleteJob( backend ) );
 
  318     if ( protocol == 
CMS )
 
  319         connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
 
  320                  q_func(), SLOT(cmsDeleteResult(GpgME::Error)) );
 
  322         connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
 
  323                  q_func(), SLOT(pgpDeleteResult(GpgME::Error)) );
 
  325     connect( job.get(), SIGNAL(progress(
QString,
int,
int)),
 
  326              q, SIGNAL(progress(
QString,
int,
int)) );
 
  328     if ( 
const Error err = job->start( keys, 
true  ) )
 
  329         ( protocol == 
CMS ? cmsError : pgpError ) = err;
 
  331         ( protocol == 
CMS ? cmsJob : pgpJob ) = job.release();
 
  334 void DeleteCertificatesCommand::Private::showErrorsAndFinish() {
 
  336     assert( !pgpJob ); assert( !cmsJob );
 
  338     if ( pgpError || cmsError ) {
 
  346         const QString msg = i18n(
"<qt><p>An error occurred while trying to delete " 
  347                                  "the certificate:</p>" 
  348                                  "<p><b>%1</b></p></qt>",
 
  349                                  pgpError ? cmsError ? pgpErrorString + 
QLatin1String(
"</br>") + cmsErrorString : pgpErrorString : cmsErrorString );
 
  350         error( msg, i18n(
"Certificate Deletion Failed") );
 
  352         std::vector<Key> keys = pgpKeys;
 
  353         keys.insert( keys.end(), cmsKeys.begin(), cmsKeys.end() );
 
  360 void DeleteCertificatesCommand::doCancel() {
 
  364 void DeleteCertificatesCommand::Private::pgpDeleteResult( 
const Error & err ) {
 
  368         showErrorsAndFinish();
 
  371 void DeleteCertificatesCommand::Private::cmsDeleteResult( 
const Error & err ) {
 
  375         showErrorsAndFinish();
 
  378 void DeleteCertificatesCommand::Private::cancelJobs()
 
  381         cmsJob->slotCancel();
 
  383         pgpJob->slotCancel();
 
  389 #include "moc_deletecertificatescommand.cpp" 
DeleteCertificatesCommand(QAbstractItemView *view, KeyListController *parent)
kdtools::pimpl_ptr< Private > d
QString fromLocal8Bit(const char *str, int size)
static boost::shared_ptr< const KeyCache > instance()
~DeleteCertificatesCommand()
static boost::shared_ptr< KeyCache > mutableInstance()