Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F26446189
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
102 KB
Subscribers
None
View Options
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4db5f463b..0defb8f03 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,218 +1,218 @@
project(kleopatra)
set( kleopatra_version 1.9.0 )
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.svn")
if ( NOT KdeSubversion_FOUND )
find_package( KdeSubversion )
endif ( NOT KdeSubversion_FOUND )
if ( KdeSubversion_FOUND )
KdeSubversion_WC_INFO( ${PROJECT_SOURCE_DIR} Kleopatra )
string( SUBSTRING "${Kleopatra_WC_LAST_CHANGED_DATE}" 0 10 Kleopatra_WC_LAST_CHANGED_DATE )
set( kleopatra_version "${kleopatra_version} (svn-${Kleopatra_WC_REVISION}, ${Kleopatra_WC_LAST_CHANGED_DATE})" )
endif ( KdeSubversion_FOUND )
endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.svn")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-kleopatra.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kleopatra.h )
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/libkleo ${Boost_INCLUDE_DIR} ${QGPGME_INCLUDES} ${GPGME_INCLUDES} )
if (USABLE_ASSUAN_FOUND)
include_directories(${ASSUAN_INCLUDES})
endif(USABLE_ASSUAN_FOUND)
add_definitions ( -DQT_STL -DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS -D_ASSUAN_ONLY_GPG_ERRORS -UQT_NO_STL )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
add_subdirectory( pics )
add_subdirectory( conf )
add_subdirectory( kgpgconf )
add_subdirectory( tests )
if ( WIN32 )
set( _kleopatra_extra_uiserver_SRCS
utils/gnupg-registry.c
uiserver/uiserver_win.cpp
)
else ( WIN32 )
set( _kleopatra_extra_uiserver_SRCS
uiserver/uiserver_unix.cpp
)
endif ( WIN32 )
if ( USABLE_ASSUAN_FOUND )
set(_kleopatra_uiserver_SRCS
uiserver/uiserver.cpp
${_kleopatra_extra_uiserver_SRCS}
uiserver/assuanserverconnection.cpp
uiserver/echocommand.cpp
uiserver/decryptverifycommand.cpp
uiserver/signemailcontroller.cpp
uiserver/signcommand.cpp
uiserver/signencryptfilescommand.cpp
uiserver/encryptemailcontroller.cpp
uiserver/prepencryptcommand.cpp
uiserver/encryptcommand.cpp
)
if ( WIN32 )
set( _kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES} )
else ( WIN32 )
set( _kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES} )
endif( WIN32 )
if ( HAVE_GPG_ERR_SOURCE_KLEO )
add_definitions( -DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO )
else( HAVE_GPG_ERR_SOURCE_KLEO )
add_definitions( -DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1 )
endif( HAVE_GPG_ERR_SOURCE_KLEO )
else ( USABLE_ASSUAN_FOUND )
set(_kleopatra_uiserver_SRCS)
endif ( USABLE_ASSUAN_FOUND )
kde4_add_ui_files( _kleopatra_uiserver_SRCS
crypto/gui/signingcertificateselectionwidget.ui)
set( _kleopatra_common_SRCS
utils/detail.cpp
utils/filesystemwatcher.cpp
utils/kdpipeiodevice.cpp
utils/kdlogtextwidget.cpp
utils/headerview.cpp
utils/hex.cpp
utils/input.cpp
utils/output.cpp
utils/exception.cpp
utils/formatting.cpp
utils/wsastarter.cpp
utils/classify.cpp
utils/iodevicelogger.cpp
utils/log.cpp
utils/action_data.cpp
models/keycache.cpp
models/keylistmodel.cpp
models/keylistsortfilterproxymodel.cpp
models/subkeylistmodel.cpp
models/useridlistmodel.cpp
view/keylistcontroller.cpp
view/searchbar.cpp
view/tabwidget.cpp
dialogs/certificateselectiondialog.cpp
dialogs/expirydialog.cpp
crypto/certificateresolver.cpp
crypto/task.cpp
+ crypto/decryptverifytask.cpp
crypto/encryptemailtask.cpp
crypto/signencryptfilestask.cpp
crypto/signemailtask.cpp
crypto/gui/wizard.cpp
crypto/gui/wizardpage.cpp
crypto/gui/scrollarea.cpp
crypto/gui/signingcertificateselectiondialog.cpp
crypto/gui/resultdisplaywidget.cpp
crypto/gui/decryptverifyoperationwidget.cpp
- crypto/gui/decryptverifyresultwidget.cpp
crypto/gui/decryptverifywizard.cpp
crypto/gui/objectspage.cpp
crypto/gui/resolverecipientspage.cpp
crypto/gui/wizardresultpage.cpp
crypto/gui/signerresolvepage.cpp
crypto/gui/signemailwizard.cpp
crypto/gui/signencryptfileswizard.cpp
crypto/gui/signencryptwizard.cpp
crypto/controller.cpp
crypto/signencryptfilescontroller.cpp
commands/command.cpp
commands/detailscommand.cpp
commands/exportcertificatecommand.cpp
commands/importcertificatefromfilecommand.cpp
commands/refreshkeyscommand.cpp
commands/deletecertificatescommand.cpp
commands/signencryptfilescommand.cpp
commands/clearcrlcachecommand.cpp
commands/dumpcrlcachecommand.cpp
commands/importcrlcommand.cpp
commands/changeexpirycommand.cpp
${_kleopatra_uiserver_files}
conf/configuredialog.cpp
certificatewizardimpl.cpp
aboutdata.cpp
systemtrayicon.cpp
exportcertificatesdialog.cpp
certificateinfowidgetimpl.cpp
main.cpp )
if ( KLEO_MODEL_TEST )
add_definitions( -DKLEO_MODEL_TEST )
set( _kleopatra_common_SRCS ${_kleopatra_common_SRCS} models/modeltest.cpp )
endif ( KLEO_MODEL_TEST )
kde4_add_ui_files( _kleopatra_common_SRCS certificateinfowidget.ui certificatewizard.ui dialogs/expirydialog.ui )
if (ONLY_KLEO)
add_definitions( -DONLY_KLEO )
endif(ONLY_KLEO)
set( _kleopatra_mainwindow_SRCS
mainwindow.cpp
)
if ( KLEO_BUILD_OLD_MAINWINDOW )
add_definitions( -DKLEO_BUILD_OLD_MAINWINDOW )
add_subdirectory( kwatchgnupg )
set( _kleopatra_mainwindow_SRCS
${libconf_SRCS}
customactions.cpp
certmanager.cpp
hierarchyanalyser.cpp
crlview.cpp
certlistview.cpp )
endif ( KLEO_BUILD_OLD_MAINWINDOW )
add_definitions ( -DKDE_DEFAULT_DEBUG_AREA=5151 )
kde4_add_app_icon(_kleopatra_mainwindow_SRCS "ox*-app-kleopatra.png")
kde4_add_executable(kleopatra_bin ${_kleopatra_common_SRCS} ${_kleopatra_mainwindow_SRCS} ${_kleopatra_uiserver_SRCS} )
set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
if ( KLEO_BUILD_OLD_MAINWINDOW )
if ( ONLY_KLEO )
set( _kleopatra_extra_libs ${KDE4_KDE3SUPPORT_LIBS} )
else ( ONLY_KLEO )
set( _kleopatra_extra_libs ${KDE4_KDE3SUPPORT_LIBS} ${KDE4_KABC_LIBS} )
endif ( ONLY_KLEO )
else ( KLEO_BUILD_OLD_MAINWINDOW )
set( _kleopatra_extra_libs ${QT_QT3SUPPORT_LIBRARY} )
endif ( KLEO_BUILD_OLD_MAINWINDOW )
if ( NOT KDE4_KCMUTILS_LIBS )
set( KDE4_KCMUTILS_LIBS ${KDE4_KUTILS_LIBS} )
endif ( NOT KDE4_KCMUTILS_LIBS )
target_link_libraries(kleopatra_bin ${_kleopatra_extra_libs} kleo ${QGPGME_LIBRARIES} ${KDE4_KMIME_LIBRARY} ${KDE4_KCMUTILS_LIBS} ${_kleopatra_uiserver_extra_libs} )
install(TARGETS kleopatra_bin DESTINATION ${BIN_INSTALL_DIR} )
########### install files ###############
install( FILES kleopatra_import.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install( FILES kleopatraui.rc kleopatra_newui.rc DESTINATION ${DATA_INSTALL_DIR}/kleopatra)
kde4_install_icons( ${ICON_INSTALL_DIR} )
diff --git a/crypto/decryptverifytask.cpp b/crypto/decryptverifytask.cpp
new file mode 100644
index 000000000..c26ed5196
--- /dev/null
+++ b/crypto/decryptverifytask.cpp
@@ -0,0 +1,694 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ decryptverifytask.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2008 Klarälvdalens Datakonsult AB
+
+ Kleopatra 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.
+
+ Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), 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
+ Qt. 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.
+*/
+
+#include <config-kleopatra.h>
+
+#include "decryptverifytask.h"
+
+#include <kleo/verifyopaquejob.h>
+#include <kleo/verifydetachedjob.h>
+#include <kleo/decryptjob.h>
+#include <kleo/decryptverifyjob.h>
+
+#include <models/keycache.h>
+#include <models/predicates.h>
+
+#include <utils/detail_p.h>
+#include <utils/input.h>
+#include <utils/output.h>
+#include <utils/classify.h>
+#include <utils/formatting.h>
+#include <utils/stl_util.h>
+#include <utils/kleo_assert.h>
+#include <utils/exception.h>
+
+#include <gpgme++/error.h>
+#include <gpgme++/key.h>
+#include <gpgme++/verificationresult.h>
+#include <gpgme++/decryptionresult.h>
+
+#include <gpg-error.h>
+
+#include <KIconLoader>
+#include <KLocalizedString>
+
+#include <QByteArray>
+#include <QColor>
+#include <QTextDocument> // Qt::escape
+
+#include <algorithm>
+
+using namespace Kleo;
+using namespace Kleo::Crypto;
+using namespace GpgME;
+using namespace boost;
+
+namespace {
+
+static const char * iconForSignature( const Signature & sig ) {
+ if ( sig.summary() & GpgME::Signature::Green )
+ return "dialog-ok";
+ if ( sig.summary() & GpgME::Signature::Red )
+ return "dialog-error";
+ return "dialog-warning";
+}
+
+
+static QString image( const char * img ) {
+ // ### escape?
+ return "<img src=\"" + KIconLoader::global()->iconPath( img, KIconLoader::Small ) + "\"/>";
+}
+
+static QColor color( const DecryptionResult & dr, const VerificationResult & vr ) {
+ if ( !dr.isNull() && dr.error() )
+ return Qt::red;
+ if ( !vr.isNull() && vr.error() )
+ return Qt::red;
+ return Qt::gray;
+}
+
+static QColor color( const Signature & sig ) {
+ if ( sig.summary() & GpgME::Signature::Red )
+ return Qt::red;
+ if ( sig.summary() & GpgME::Signature::Green )
+ return Qt::green;
+ return Qt::yellow;
+}
+
+static bool IsErrorOrCanceled( const GpgME::Error & err )
+{
+ return err || err.isCanceled();
+}
+
+static bool IsErrorOrCanceled( const Result & res )
+{
+ return IsErrorOrCanceled( res.error() );
+}
+
+QString renderKey( const Key & key ) {
+ if ( key.isNull() )
+ return i18n( "Unknown key" );
+ return QString::fromLatin1( "<a href=\"key:%1\">%2</a>" ).arg( key.primaryFingerprint(), Formatting::prettyName( key ) );
+}
+
+QString formatVerificationResultOverview( const VerificationResult & res ) {
+ if ( res.isNull() )
+ return QString();
+
+ const Error err = res.error();
+
+ QString overview;
+
+ // Icon:
+ overview += image( err ? "dialog-error" : "dialog-ok" );
+
+ // Summary:
+ overview += "<b>";
+ if ( err.isCanceled() )
+ overview += i18n("Verification canceled.");
+ else if ( err )
+ overview += i18n( "Verification failed: %1.", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
+ else
+ overview += i18n("Verification succeeded.");
+ overview += "</b>";
+
+ return overview;
+}
+
+static QString formatDecryptionResultOverview( const DecryptionResult & result )
+{
+ const Error err = result.error();
+ QString overview;
+
+ // Icon:
+ overview += image( err ? "dialog-error" : "dialog-ok" );
+
+ overview += "<b>";
+ if ( err.isCanceled() )
+ overview += i18n("Decryption canceled.");
+ else if ( err )
+ overview += i18n( "Decryption failed: %1.", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
+ else
+ overview += i18n("Decryption succeeded." );
+ overview += "</b>";
+ return overview;
+}
+
+
+QString formatSignature( const Signature & sig, const Key & key ) {
+ if ( sig.isNull() )
+ return QString();
+
+ const bool red = (sig.summary() & Signature::Red);
+ //const bool green = (sig.summary() & Signature::Green);
+ const bool valid = (sig.summary() & Signature::Valid);
+
+ if ( red )
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Bad signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Bad signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Bad signature by %1: %2", renderKey( key ), QString::fromLocal8Bit( sig.status().asString() ) );
+
+ else if ( valid )
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Good signature by unknown key %1.", QString::fromLatin1( fpr ) );
+ else
+ return i18n("Good signature by an unknown key.");
+ else
+ return i18n("Good signature by %1.", renderKey( key ) );
+
+ else
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Invalid signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Invalid signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Invalid signature by %1: %2", renderKey( key ), QString::fromLocal8Bit( sig.status().asString() ) );
+}
+
+static QString formatVerificationResultDetails( const VerificationResult & res )
+{
+ const std::vector<Signature> sigs = res.signatures();
+ const std::vector<Key> signers = KeyCache::instance()->findSigners( res );
+ QString details;
+ Q_FOREACH ( const Signature & sig, sigs )
+ details += formatSignature( sig, DecryptVerifyResult::keyForSignature( sig, signers ) ) + '\n';
+ details = details.trimmed();
+ details.replace( '\n', "<br/>" );
+ return details;
+}
+
+static QString formatDecryptionResultDetails( const DecryptionResult & res, const std::vector<Key> & recipients )
+{
+ if ( res.isNull() || !res.error() || res.error().isCanceled() )
+ return QString();
+
+ if ( recipients.empty() )
+ return QString( "<i>" + i18np( "One unknown recipient.", "%1 unknown recipients.", res.numRecipients() ) + "</i>" );
+
+ QString details;
+ details += i18np( "Recipients:", "Recipients:", res.numRecipients() );
+ if ( res.numRecipients() == 1 )
+ return details + renderKey( recipients.front() );
+
+ details += "<ul>";
+ Q_FOREACH( const Key & key, recipients )
+ details += "<li>" + renderKey( key ) + "</li>";
+ if ( recipients.size() < res.numRecipients() )
+ details += "<li><i>" + i18np( "One unknown recipient", "%1 unknown recipients",
+ res.numRecipients() - recipients.size() ) + "</i></li>";
+
+ return details + "</ul>";
+}
+
+static QString formatDecryptVerifyResultOverview( const DecryptionResult & dr, const VerificationResult & vr )
+{
+ const QString drOverview = formatDecryptionResultOverview( dr );
+ if ( IsErrorOrCanceled( dr ) )
+ return drOverview;
+ return drOverview + "<br/>" + formatVerificationResultOverview( vr );
+}
+
+
+static QString formatDecryptVerifyResultDetails( const DecryptionResult & dr,
+ const VerificationResult & vr,
+ const std::vector<Key> & recipients )
+{
+ const QString drDetails = formatDecryptionResultDetails( dr, recipients );
+ if ( IsErrorOrCanceled( dr ) )
+ return drDetails;
+ return drDetails + ( drDetails.isEmpty() ? "" : "<br/>" ) + formatVerificationResultDetails( vr );
+}
+
+}
+
+class DecryptVerifyResult::Private {
+public:
+ Private( DecryptVerifyTask::Type type,
+ const VerificationResult & vr,
+ const DecryptionResult & dr,
+ const QByteArray & stuff,
+ int errCode,
+ const QString& errString ) :
+ m_type( type ),
+ m_verificationResult( vr ),
+ m_decryptionResult( dr ),
+ m_stuff( stuff ),
+ m_error( errCode ),
+ m_errorString( errString )
+ {
+ }
+
+ bool isDecryptOnly() const { return m_type == DecryptVerifyTask::Decrypt; }
+ bool isVerifyOnly() const { return m_type == DecryptVerifyTask::VerifyOpaque || m_type == DecryptVerifyTask::VerifyOpaque; }
+ bool isDecryptVerify() const { return m_type == DecryptVerifyTask::DecryptVerify; }
+ DecryptVerifyTask::Type m_type;
+ VerificationResult m_verificationResult;
+ DecryptionResult m_decryptionResult;
+ QByteArray m_stuff;
+ int m_error;
+ QString m_errorString;
+};
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromDecryptResult( const DecryptionResult & dr, const QByteArray & plaintext ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::Decrypt,
+ VerificationResult(),
+ dr,
+ plaintext,
+ 0,
+ QString() ) );
+}
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromDecryptResult( const GpgME::Error & err, const QString& what ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::Decrypt,
+ VerificationResult(),
+ DecryptionResult( err ),
+ QByteArray(),
+ err.code(),
+ what ) );
+}
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromDecryptVerifyResult( const DecryptionResult & dr, const VerificationResult & vr, const QByteArray & plaintext ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::DecryptVerify,
+ vr,
+ dr,
+ plaintext,
+ 0,
+ QString() ) );
+}
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromDecryptVerifyResult( const GpgME::Error & err, const QString & details ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::DecryptVerify,
+ VerificationResult(),
+ DecryptionResult( err ),
+ QByteArray(),
+ err.code(),
+ details ) );
+}
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromVerifyOpaqueResult( const VerificationResult & vr, const QByteArray & plaintext ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::VerifyOpaque,
+ vr,
+ DecryptionResult(),
+ plaintext,
+ 0,
+ QString() ) );
+}
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromVerifyOpaqueResult( const GpgME::Error & err, const QString & details ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::VerifyOpaque,
+ VerificationResult( err ),
+ DecryptionResult(),
+ QByteArray(),
+ err.code(),
+ details ) );
+}
+
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromVerifyDetachedResult( const VerificationResult & vr ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::VerifyDetached,
+ vr,
+ DecryptionResult(),
+ QByteArray(),
+ 0,
+ QString() ) );
+}
+shared_ptr<DecryptVerifyResult> DecryptVerifyResult::fromVerifyDetachedResult( const GpgME::Error & err, const QString & details ) {
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ DecryptVerifyTask::VerifyDetached,
+ VerificationResult( err ),
+ DecryptionResult(),
+ QByteArray(),
+ err.code(),
+ details ) );
+}
+
+DecryptVerifyResult::DecryptVerifyResult( DecryptVerifyTask::Type type,
+ const VerificationResult& vr,
+ const DecryptionResult& dr,
+ const QByteArray& stuff,
+ int errCode,
+ const QString& errString )
+ : Task::Result(), d( new Private( type, vr, dr, stuff, errCode, errString ) )
+{
+}
+
+QString DecryptVerifyResult::overview() const
+{
+ if ( d->isDecryptOnly() )
+ return formatDecryptionResultOverview( d->m_decryptionResult );
+ if ( d->isVerifyOnly() )
+ return formatVerificationResultOverview( d->m_verificationResult );
+ return formatDecryptVerifyResultOverview( d->m_decryptionResult, d->m_verificationResult );
+}
+
+QString DecryptVerifyResult::details() const
+{
+ if ( d->isDecryptOnly() )
+ return formatDecryptionResultDetails( d->m_decryptionResult, KeyCache::instance()->findRecipients( d->m_decryptionResult ) );
+ if ( d->isVerifyOnly() )
+ return formatVerificationResultDetails( d->m_verificationResult );
+ return formatDecryptVerifyResultDetails( d->m_decryptionResult, d->m_verificationResult, KeyCache::instance()->findRecipients( d->m_decryptionResult ) );
+}
+
+bool DecryptVerifyResult::hasError() const
+{
+ return d->m_error != 0;
+}
+
+int DecryptVerifyResult::errorCode() const
+{
+ return d->m_error;
+}
+
+QString DecryptVerifyResult::errorString() const
+{
+ return d->m_errorString;
+}
+
+GpgME::VerificationResult DecryptVerifyResult::verificationResult() const
+{
+ return d->m_verificationResult;
+}
+
+
+const char * DecryptVerifyResult::summaryToString( const Signature::Summary summary )
+{
+ if ( summary & Signature::Red )
+ return "RED";
+ if ( summary & Signature::Green )
+ return "GREEN";
+ return "YELLOW";
+}
+
+QString DecryptVerifyResult::keyToString( const Key & key ) {
+
+ kleo_assert( !key.isNull() );
+
+ const QString email = Formatting::prettyEMail( key );
+ const QString name = Formatting::prettyName( key );
+
+ if ( name.isEmpty() )
+ return email;
+ else if ( email.isEmpty() )
+ return name;
+ else
+ return QString::fromLatin1( "%1 <%2>" ).arg( name, email );
+}
+
+
+const Key & DecryptVerifyResult::keyForSignature( const Signature & sig, const std::vector<Key> & keys ) {
+ if ( const char * const fpr = sig.fingerprint() ) {
+ const std::vector<Key>::const_iterator it
+ = std::lower_bound( keys.begin(), keys.end(), fpr, _detail::ByFingerprint<std::less>() );
+ if ( it != keys.end() && _detail::ByFingerprint<std::equal_to>()( *it, fpr ) )
+ return *it;
+ }
+ static const Key null;
+ return null;
+}
+
+QString DecryptVerifyResult::signatureToString( const Signature & sig, const Key & key )
+{
+ if ( sig.isNull() )
+ return QString();
+
+ const bool red = (sig.summary() & Signature::Red);
+ const bool valid = (sig.summary() & Signature::Valid);
+
+ if ( red )
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Bad signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Bad signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Bad signature by %1: %2", keyToString( key ), QString::fromLocal8Bit( sig.status().asString() ) );
+
+ else if ( valid )
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Good signature by unknown key %1.", QString::fromLatin1( fpr ) );
+ else
+ return i18n("Good signature by an unknown key.");
+ else
+ return i18n("Good signature by %1.", keyToString( key ) );
+
+ else
+ if ( key.isNull() )
+ if ( const char * fpr = sig.fingerprint() )
+ return i18n("Invalid signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Invalid signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
+ else
+ return i18n("Invalid signature by %1: %2", keyToString( key ), QString::fromLocal8Bit( sig.status().asString() ) );
+}
+
+class DecryptVerifyTask::Private {
+ DecryptVerifyTask* const q;
+public:
+ explicit Private( Type type, DecryptVerifyTask* qq ) : q( qq ), m_type( type ) {}
+
+ void slotResult( const DecryptionResult&, const QByteArray& );
+ void slotResult( const DecryptionResult&, const VerificationResult&, const QByteArray& );
+ void slotResult( const VerificationResult&, const QByteArray& );
+ void slotResult( const VerificationResult& );
+
+ void registerJob( VerifyDetachedJob* job ) {
+ q->connect( job, SIGNAL(result(GpgME::VerificationResult)),
+ q, SLOT(slotResult(GpgME::VerificationResult)) );
+ }
+
+ void registerJob( VerifyOpaqueJob* job ) {
+ q->connect( job, SIGNAL(result(GpgME::VerificationResult,QByteArray)),
+ q, SLOT(slotResult(GpgME::VerificationResult,QByteArray)) );
+ }
+
+ void registerJob( DecryptJob * job ) {
+ q->connect( job, SIGNAL(result(GpgME::DecryptionResult,QByteArray)),
+ q, SLOT(slotResult(GpgME::DecryptionResult,QByteArray)) );
+ }
+
+ void registerJob( DecryptVerifyJob * job ) {
+ q->connect( job, SIGNAL(result(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)),
+ q, SLOT(slotResult(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)) );
+ }
+
+ void emitResult( const shared_ptr<DecryptVerifyResult>& result );
+
+ Type m_type;
+ shared_ptr<Input> m_input, m_signedData;
+ shared_ptr<Output> m_output;
+ const CryptoBackend::Protocol* m_backend;
+};
+
+
+void DecryptVerifyTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
+{
+ emit q->result( result );
+ emit q->decryptVerifyResult( result );
+}
+
+void DecryptVerifyTask::Private::slotResult( const DecryptionResult& result, const QByteArray& plainText )
+{
+ if ( result.error().code() ) {
+ m_output->cancel();
+ } else {
+ try {
+ m_output->finalize();
+ } catch ( const GpgME::Exception & e ) {
+ emitResult( DecryptVerifyResult::fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ return;
+ }
+ }
+
+ emitResult( DecryptVerifyResult::fromDecryptResult( result, plainText ) );
+}
+
+void DecryptVerifyTask::Private::slotResult( const DecryptionResult& dr, const VerificationResult& vr, const QByteArray& plainText )
+{
+ if ( dr.error().code() || vr.error().code() ) {
+ m_output->cancel();
+ } else {
+ try {
+ m_output->finalize();
+ } catch ( const GpgME::Exception & e ) {
+ emitResult( DecryptVerifyResult::fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ return;
+ }
+ }
+
+ emitResult( DecryptVerifyResult::fromDecryptVerifyResult( dr, vr, plainText ) );
+}
+
+void DecryptVerifyTask::Private::slotResult( const VerificationResult& result, const QByteArray& plainText )
+{
+ if ( result.error().code() ) {
+ m_output->cancel();
+ } else {
+ try {
+ m_output->finalize();
+ } catch ( const GpgME::Exception & e ) {
+ emitResult( DecryptVerifyResult::fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ return;
+ }
+ }
+
+ emitResult( DecryptVerifyResult::fromVerifyOpaqueResult( result, plainText ) );
+}
+
+void DecryptVerifyTask::Private::slotResult( const VerificationResult& result )
+{
+ assert( !m_output );
+ emitResult( DecryptVerifyResult::fromVerifyDetachedResult( result ) );
+}
+
+DecryptVerifyTask::DecryptVerifyTask( Type type, QObject* parent ) : Task( parent ), d( new Private( type, this ) )
+{
+}
+
+DecryptVerifyTask::~DecryptVerifyTask()
+{
+}
+
+void DecryptVerifyTask::setInput( const shared_ptr<Input> & input )
+{
+ d->m_input = input;
+ kleo_assert( d->m_input->ioDevice() );
+}
+
+void DecryptVerifyTask::setSignedData( const shared_ptr<Input> & signedData )
+{
+ d->m_signedData = signedData;
+ kleo_assert( d->m_signedData->ioDevice() );
+}
+
+void DecryptVerifyTask::setOutput( const shared_ptr<Output> & output )
+{
+ d->m_output = output;
+ kleo_assert( d->m_output->ioDevice() );
+}
+
+void DecryptVerifyTask::setBackend( const CryptoBackend::Protocol* backend )
+{
+ d->m_backend = backend;
+}
+
+void DecryptVerifyTask::autodetectBackendFromInput()
+{
+ if ( d->m_input )
+ setBackend( CryptoBackendFactory::instance()->protocol( findProtocol( d->m_input->classification() ) ) );
+}
+
+QString DecryptVerifyTask::label() const
+{
+ switch ( d->m_type ) {
+ case Decrypt:
+ case DecryptVerify:
+ return i18n( "Decrypting: %1...", d->m_input->label() );
+ case VerifyOpaque:
+ return i18n( "Verifying: %1...", d->m_input->label() );
+ case VerifyDetached:
+ return i18n( "Verifying signature: %1...", d->m_input->label() );
+ }
+ return i18n( "not implemented" );
+}
+
+Protocol DecryptVerifyTask::protocol() const
+{
+
+}
+
+void DecryptVerifyTask::cancel()
+{
+
+}
+
+void DecryptVerifyTask::doStart()
+{
+ kleo_assert( d->m_backend );
+
+ switch ( d->m_type ) {
+ case Decrypt:
+ try {
+ DecryptJob * const job = d->m_backend->decryptJob();
+ kleo_assert( job );
+ d->registerJob( job );
+ job->start( d->m_input->ioDevice(), d->m_output->ioDevice() );
+ } catch ( const GpgME::Exception & e ) {
+ d->emitResult( DecryptVerifyResult::fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ }
+ break;
+ case DecryptVerify:
+ try {
+ DecryptVerifyJob * const job = d->m_backend->decryptVerifyJob();
+ kleo_assert( job );
+ d->registerJob( job );
+ job->start( d->m_input->ioDevice(), d->m_output->ioDevice() );
+ } catch ( const GpgME::Exception & e ) {
+ d->emitResult( DecryptVerifyResult::fromDecryptVerifyResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ }
+ break;
+ case VerifyOpaque:
+ try {
+ VerifyOpaqueJob * const job = d->m_backend->verifyOpaqueJob();
+ kleo_assert( job );
+ d->registerJob( job );
+ job->start( d->m_input->ioDevice(), d->m_output ? d->m_output->ioDevice() : shared_ptr<QIODevice>() );
+ } catch ( const GpgME::Exception & e ) {
+ d->emitResult( DecryptVerifyResult::fromVerifyOpaqueResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ }
+ break;
+ case VerifyDetached:
+ try {
+ VerifyDetachedJob * const job = d->m_backend->verifyDetachedJob();
+ kleo_assert( job );
+ d->registerJob( job );
+ job->start( d->m_input->ioDevice(), d->m_signedData->ioDevice() );
+ } catch ( const GpgME::Exception & e ) {
+ d->emitResult( DecryptVerifyResult::fromVerifyDetachedResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
+ }
+ break;
+ }
+}
+
+#include "decryptverifytask.moc"
diff --git a/crypto/decryptverifytask.h b/crypto/decryptverifytask.h
new file mode 100644
index 000000000..1da41d5e6
--- /dev/null
+++ b/crypto/decryptverifytask.h
@@ -0,0 +1,153 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ decryptverifytask.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2008 Klarälvdalens Datakonsult AB
+
+ Kleopatra 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.
+
+ Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), 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
+ Qt. 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.
+*/
+
+#ifndef __KLEOPATRA_CRYPTO_DECRYPTVERIFYTASK_H__
+#define __KLEOPATRA_CRYPTO_DECRYPTVERIFYTASK_H__
+
+#include "task.h"
+
+#include <kleo/cryptobackendfactory.h>
+
+#include <gpgme++/verificationresult.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Kleo {
+
+class Input;
+class Output;
+
+namespace Crypto {
+
+ class DecryptVerifyResult;
+
+ class DecryptVerifyTask : public Task {
+ Q_OBJECT
+ public:
+
+ enum Type {
+ Decrypt,
+ DecryptVerify,
+ VerifyOpaque,
+ VerifyDetached
+ };
+
+ explicit DecryptVerifyTask( Type type, QObject* parent = 0 );
+ ~DecryptVerifyTask();
+
+ void setInput( const boost::shared_ptr<Input> & input );
+ void setSignedData( const boost::shared_ptr<Input> & signedData );
+ void setOutput( const boost::shared_ptr<Output> & output );
+
+ void setBackend( const CryptoBackend::Protocol* backend );
+ void autodetectBackendFromInput();
+
+ /* reimp */ QString label() const;
+
+ /* reimp */ GpgME::Protocol protocol() const;
+
+ public Q_SLOTS:
+ /* reimp */ void cancel();
+
+ Q_SIGNALS:
+ void decryptVerifyResult( const boost::shared_ptr<const Kleo::Crypto::DecryptVerifyResult> & );
+
+ private:
+ /* reimp */ void doStart();
+
+ private:
+ class Private;
+ kdtools::pimpl_ptr<Private> d;
+ Q_PRIVATE_SLOT( d, void slotResult( GpgME::DecryptionResult, QByteArray ) );
+ Q_PRIVATE_SLOT( d, void slotResult( GpgME::DecryptionResult, GpgME::VerificationResult, QByteArray ) );
+ Q_PRIVATE_SLOT( d, void slotResult( GpgME::VerificationResult, QByteArray ) );
+ Q_PRIVATE_SLOT( d, void slotResult( GpgME::VerificationResult ) );
+ };
+
+}
+}
+
+namespace GpgME {
+ class DecryptionResult;
+ class VerificationResult;
+ class Key;
+ class Signature;
+}
+
+namespace Kleo {
+namespace Crypto {
+ class DecryptVerifyResult : public Task::Result {
+
+ public:
+
+ /* reimpl */ QString overview() const;
+ /* reimpl */ QString details() const;
+ /* reimpl */ bool hasError() const;
+ /* reimpl */ int errorCode() const;
+ /* reimpl */ QString errorString() const;
+
+ GpgME::VerificationResult verificationResult() const;
+
+ static boost::shared_ptr<DecryptVerifyResult> fromDecryptResult( const GpgME::DecryptionResult & dr, const QByteArray & plaintext );
+ static boost::shared_ptr<DecryptVerifyResult> fromDecryptResult( const GpgME::Error & err, const QString& details );
+ static boost::shared_ptr<DecryptVerifyResult> fromDecryptVerifyResult( const GpgME::DecryptionResult & dr, const GpgME::VerificationResult & vr, const QByteArray & plaintext );
+ static boost::shared_ptr<DecryptVerifyResult> fromDecryptVerifyResult( const GpgME::Error & err, const QString & what );
+ static boost::shared_ptr<DecryptVerifyResult> fromVerifyOpaqueResult( const GpgME::VerificationResult & vr, const QByteArray & plaintext );
+ static boost::shared_ptr<DecryptVerifyResult> fromVerifyOpaqueResult( const GpgME::Error & err, const QString & details );
+ static boost::shared_ptr<DecryptVerifyResult> fromVerifyDetachedResult( const GpgME::VerificationResult & vr );
+ static boost::shared_ptr<DecryptVerifyResult> fromVerifyDetachedResult( const GpgME::Error & err, const QString & details );
+
+ static QString keyToString( const GpgME::Key & key );
+ static QString signatureToString( const GpgME::Signature & sig, const GpgME::Key & key );
+ static const char * summaryToString( GpgME::Signature::Summary summary );
+ static const GpgME::Key & keyForSignature( const GpgME::Signature & sig, const std::vector<GpgME::Key> & keys );
+
+ private:
+ DecryptVerifyResult();
+ DecryptVerifyResult( const DecryptVerifyResult& );
+ DecryptVerifyResult& operator=( const DecryptVerifyResult& other );
+
+ DecryptVerifyResult( DecryptVerifyTask::Type type,
+ const GpgME::VerificationResult& vr,
+ const GpgME::DecryptionResult& dr,
+ const QByteArray& stuff,
+ int errCode,
+ const QString& errString );
+
+ private:
+ class Private;
+ kdtools::pimpl_ptr<Private> d;
+ };
+}
+}
+
+#endif //__KLEOPATRA_CRYPTO_DECRYPTVERIFYTASK_H__
diff --git a/crypto/gui/decryptverifyresultwidget.h b/crypto/gui/decryptverifyresultwidget.h
index fae7ccdd5..149dab59c 100644
--- a/crypto/gui/decryptverifyresultwidget.h
+++ b/crypto/gui/decryptverifyresultwidget.h
@@ -1,76 +1,76 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/decryptverifyresultwidget.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#ifndef __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYRESULTWIDGET_H__
#define __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYRESULTWIDGET_H__
#include <crypto/gui/resultdisplaywidget.h>
#include <vector>
namespace GpgME {
class DecryptionResult;
class VerificationResult;
class Signature;
class Key;
}
class QVBoxLayout;
class QLabel;
namespace Kleo {
namespace Crypto {
namespace Gui {
class DecryptVerifyResultWidget : public ResultDisplayWidget {
Q_OBJECT
public:
explicit DecryptVerifyResultWidget( QWidget * parent );
~DecryptVerifyResultWidget();
void setResult( const GpgME::DecryptionResult & decryptionResult, const GpgME::VerificationResult & verificationResult );
-
+
private:
QString formatDecryptionResult( const GpgME::DecryptionResult &, const std::vector<GpgME::Key> & );
QString formatVerificationResult( const GpgME::VerificationResult & ) const;
QString formatSignature( const GpgME::Signature &, const GpgME::Key & );
QLabel * formatSignatureWidget( QLabel *, const GpgME::Signature &, const GpgME::Key & );
private:
QVBoxLayout * m_box;
};
}
}
}
#endif /* __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYRESULTWIDGET_H__ */
diff --git a/crypto/gui/decryptverifywizard.cpp b/crypto/gui/decryptverifywizard.cpp
index cc02ced8d..9565b9482 100644
--- a/crypto/gui/decryptverifywizard.cpp
+++ b/crypto/gui/decryptverifywizard.cpp
@@ -1,336 +1,351 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/decryptverifywizard.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#include <config-kleopatra.h>
#include "decryptverifywizard.h"
#include "decryptverifyoperationwidget.h"
-#include "decryptverifyresultwidget.h"
#include <crypto/gui/scrollarea.h>
+#include <crypto/gui/resultdisplaywidget.h>
+#include <crypto/task.h>
+
+#include <utils/kleo_assert.h>
#include <utils/stl_util.h>
#include "libkleo/ui/filenamerequester.h"
#include <KLocale>
#include <QScrollArea>
#include <QWizardPage>
#include <QLayout>
#include <QLabel>
#include <QEventLoop>
#include <QPointer>
#include <QAbstractButton>
#include <QScrollBar>
#include <boost/bind.hpp>
#include <vector>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Crypto::Gui;
using namespace boost;
namespace {
class HLine : public QFrame {
Q_OBJECT
public:
explicit HLine( QWidget * p=0, Qt::WindowFlags f=0 )
: QFrame( p, f )
{
setFrameStyle( QFrame::HLine|QFrame::Sunken );
}
};
class OperationsPage : public QWizardPage {
Q_OBJECT
public:
explicit OperationsPage( QWidget * p=0 );
~OperationsPage();
void setOutputDirectory( const QString & dir ) {
m_ui.outputDirectoryFNR.setFileName( dir );
}
QString outputDirectory() const {
return m_ui.outputDirectoryFNR.fileName();
}
void ensureIndexAvailable( unsigned int idx );
DecryptVerifyOperationWidget * widget( unsigned int idx ) {
return m_widgets.at( idx );
}
private:
std::vector<DecryptVerifyOperationWidget*> m_widgets;
struct UI {
QLabel outputDirectoryLB;
FileNameRequester outputDirectoryFNR;
ScrollArea scrollArea; // ### replace with KDScrollArea when done
QVBoxLayout vlay;
QHBoxLayout hlay;
explicit UI( OperationsPage * q );
} m_ui;
};
class ResultPage : public QWizardPage {
Q_OBJECT
public:
explicit ResultPage( QWidget * p=0 );
~ResultPage();
void ensureIndexAvailable( unsigned int idx );
- DecryptVerifyResultWidget * widget( unsigned int idx ) {
+ ResultDisplayWidget * widget( unsigned int idx ) {
return m_widgets.at( idx );
}
private Q_SLOTS:
void slotMaybeNoMoreProgress() {
wizard()->button( QWizard::CancelButton )
->setEnabled( kdtools::any( m_widgets.begin(), m_widgets.end(),
- bind( &DecryptVerifyResultWidget::operationInProgress, _1 ) ) );
+ bind( &ResultDisplayWidget::operationInProgress, _1 ) ) );
}
private:
- std::vector<DecryptVerifyResultWidget*> m_widgets;
+ std::vector<ResultDisplayWidget*> m_widgets;
struct UI {
ScrollArea scrollArea; // ### replace with KDScrollArea when done
QVBoxLayout vlay;
explicit UI( ResultPage * q );
} m_ui;
};
}
class DecryptVerifyWizard::Private {
friend class ::Kleo::Crypto::Gui::DecryptVerifyWizard;
DecryptVerifyWizard * const q;
public:
Private( DecryptVerifyWizard * qq );
~Private();
void ensureIndexAvailable( unsigned int idx ) {
operationsPage.ensureIndexAvailable( idx );
resultPage.ensureIndexAvailable( idx );
}
private:
OperationsPage operationsPage;
ResultPage resultPage;
};
DecryptVerifyWizard::DecryptVerifyWizard( QWidget * p, Qt::WindowFlags f )
: QWizard( p, f ), d( new Private( this ) )
{
}
DecryptVerifyWizard::~DecryptVerifyWizard() {}
void DecryptVerifyWizard::setOutputDirectory( const QString & dir ) {
d->operationsPage.setOutputDirectory( dir );
}
QString DecryptVerifyWizard::outputDirectory() const {
return d->operationsPage.outputDirectory();
}
DecryptVerifyOperationWidget * DecryptVerifyWizard::operationWidget( unsigned int idx ) {
d->ensureIndexAvailable( idx );
return d->operationsPage.widget( idx );
}
-DecryptVerifyResultWidget * DecryptVerifyWizard::resultWidget( unsigned int idx ) {
+ResultDisplayWidget * DecryptVerifyWizard::resultWidget( unsigned int idx ) {
d->ensureIndexAvailable( idx );
return d->resultPage.widget( idx );
}
+
+void DecryptVerifyWizard::connectTask( const boost::shared_ptr<Task> & task, unsigned int idx )
+{
+ kleo_assert( task );
+ ResultDisplayWidget* const item = resultWidget( idx );
+ item->setLabel( task->label() );
+ connect( task.get(), SIGNAL( progress( QString, int, int ) ),
+ item, SLOT( setProgress( QString, int, int ) ) );
+ connect( task.get(), SIGNAL(result( boost::shared_ptr<const Kleo::Crypto::Task::Result> ) ),
+ item, SLOT( setResult( boost::shared_ptr<const Kleo::Crypto::Task::Result> ) ) );
+}
+
bool DecryptVerifyWizard::waitForOperationSelection() {
if ( !isVisible() )
return true;
assert( button( NextButton ) );
assert( button( CancelButton ) );
QEventLoop loop;
QPointer<QObject> that = this;
connect( this, SIGNAL(currentIdChanged(int)), &loop, SLOT(quit()) );
connect( this, SIGNAL(finished(int)), &loop, SLOT(quit()) );
loop.exec();
return that && currentPage() == &d->resultPage ;
}
DecryptVerifyWizard::Private::Private( DecryptVerifyWizard * qq )
: q( qq ),
operationsPage( q ),
resultPage( q )
{
q->setOptions( q->options() | NoBackButtonOnStartPage | NoBackButtonOnLastPage );
q->addPage( &operationsPage );
q->addPage( &resultPage );
}
DecryptVerifyWizard::Private::~Private() {}
OperationsPage::OperationsPage( QWidget * p )
: QWizardPage( p ), m_widgets(), m_ui( this )
{
setTitle( i18n("Choose operations to be performed") );
setSubTitle( i18n("Here you can check and, if needed, override "
"the operations Kleopatra detected for the input given.") );
setCommitPage( true );
setButtonText( QWizard::CommitButton, i18n("&Decrypt/Verify") );
}
OperationsPage::~OperationsPage() {}
OperationsPage::UI::UI( OperationsPage * q )
: outputDirectoryLB( i18n("&Output directory:"), q ),
outputDirectoryFNR( q ),
scrollArea( q ),
vlay( q ),
hlay()
{
KDAB_SET_OBJECT_NAME( outputDirectoryLB );
KDAB_SET_OBJECT_NAME( outputDirectoryFNR );
KDAB_SET_OBJECT_NAME( scrollArea );
KDAB_SET_OBJECT_NAME( vlay );
KDAB_SET_OBJECT_NAME( hlay );
assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );
outputDirectoryLB.setBuddy( &outputDirectoryFNR );
hlay.setMargin( 0 );
vlay.addWidget( &scrollArea, 1 );
vlay.addLayout( &hlay );
hlay.addWidget( &outputDirectoryLB );
hlay.addWidget( &outputDirectoryFNR );
}
void OperationsPage::ensureIndexAvailable( unsigned int idx ) {
if ( idx < m_widgets.size() )
return;
assert( m_ui.scrollArea.widget() );
assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );
for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
if ( i )
blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
DecryptVerifyOperationWidget * w = new DecryptVerifyOperationWidget( m_ui.scrollArea.widget() );
blay.insertWidget( blay.count()-1, w );
w->show();
m_widgets.push_back( w );
}
}
ResultPage::ResultPage( QWidget * p )
: QWizardPage( p ), m_widgets(), m_ui( this )
{
setTitle( i18n("Results") );
setSubTitle( i18n("Detailed operation results") );
setButtonText( QWizard::FinishButton, i18n("&OK") );
}
ResultPage::~ResultPage() {}
ResultPage::UI::UI( ResultPage * q )
: scrollArea( q ),
vlay( q )
{
KDAB_SET_OBJECT_NAME( scrollArea );
KDAB_SET_OBJECT_NAME( vlay );
assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );
vlay.addWidget( &scrollArea );
}
void ResultPage::ensureIndexAvailable( unsigned int idx ) {
if ( idx < m_widgets.size() )
return;
assert( m_ui.scrollArea.widget() );
assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );
for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
if ( i )
blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
- DecryptVerifyResultWidget * w = new DecryptVerifyResultWidget( m_ui.scrollArea.widget() );
+ ResultDisplayWidget * w = new ResultDisplayWidget( m_ui.scrollArea.widget() );
connect( w, SIGNAL(operationStateChanged()), this, SLOT(slotMaybeNoMoreProgress()) );
blay.insertWidget( blay.count()-1, w );
w->show();
m_widgets.push_back( w );
}
}
#include "decryptverifywizard.moc"
#include "moc_decryptverifywizard.cpp"
diff --git a/crypto/gui/decryptverifywizard.h b/crypto/gui/decryptverifywizard.h
index 8fa9f6a4d..b90ab021e 100644
--- a/crypto/gui/decryptverifywizard.h
+++ b/crypto/gui/decryptverifywizard.h
@@ -1,70 +1,75 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/decryptverifywizard.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#ifndef __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYWIZARD_H__
#define __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYWIZARD_H__
#include <QWizard>
#include <utils/pimpl_ptr.h>
+#include <boost/shared_ptr.hpp>
+
namespace Kleo {
namespace Crypto {
+ class Task;
namespace Gui {
class DecryptVerifyOperationWidget;
- class DecryptVerifyResultWidget;
+ class ResultDisplayWidget;
class DecryptVerifyWizard : public QWizard {
Q_OBJECT
public:
explicit DecryptVerifyWizard( QWidget * parent=0, Qt::WindowFlags f=0 );
~DecryptVerifyWizard();
void setOutputDirectory( const QString & dir );
QString outputDirectory() const;
+ void connectTask( const boost::shared_ptr<Task>& task, unsigned int idx );
+
DecryptVerifyOperationWidget * operationWidget( unsigned int idx );
- DecryptVerifyResultWidget * resultWidget( unsigned int idx );
+ ResultDisplayWidget * resultWidget( unsigned int idx );
bool waitForOperationSelection();
private:
class Private;
kdtools::pimpl_ptr<Private> d;
};
}
}
}
#endif /* __KLEOPATRA_CRYPTO_GUI_DECRYPTVERIFYWIZARD_H__ */
diff --git a/crypto/gui/resultdisplaywidget.cpp b/crypto/gui/resultdisplaywidget.cpp
index c69a444d9..eca14837a 100644
--- a/crypto/gui/resultdisplaywidget.cpp
+++ b/crypto/gui/resultdisplaywidget.cpp
@@ -1,259 +1,273 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resultdisplaywidget.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#include <config-kleopatra.h>
#include "resultdisplaywidget.h"
#include "certificateinfowidgetimpl.h"
#include <utils/formatting.h>
#include <models/predicates.h>
#include <QHash>
#include <QPointer>
#include <QLayout>
#include <QLabel>
#include <QProgressBar>
#include <QStackedWidget>
#include <QFrame>
#include <algorithm>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
using namespace GpgME;
+using namespace boost;
static const char ERROR_STYLE_SHEET[] =
"border:4px solid red; "
"border-radius:2px;";
class ProgressWidget : public QWidget {
Q_OBJECT
public:
explicit ProgressWidget( QWidget * p=0 )
: QWidget( p ), ui( this ) {}
public Q_SLOTS:
void setText( const QString & text ) {
ui.label.setText( text );
}
void setProgress( int current, int total ) {
ui.progress.setRange( 0, total );
ui.progress.setValue( current );
}
private:
struct UI {
QVBoxLayout vlay;
QLabel label;
QProgressBar progress;
explicit UI( ProgressWidget * q )
: vlay( q ),
label( q ),
progress( q )
{
KDAB_SET_OBJECT_NAME( vlay );
KDAB_SET_OBJECT_NAME( label );
KDAB_SET_OBJECT_NAME( progress );
progress.setRange( 0, 0 ); // knight rider mode
vlay.addWidget( &progress );
vlay.addWidget( &label );
}
} ui;
};
class ResultDisplayWidget::Private {
friend class ::Kleo::Crypto::Gui::ResultDisplayWidget;
ResultDisplayWidget * const q;
public:
explicit Private( ResultDisplayWidget * qq )
: q( qq ),
ui( q )
{
connect( ui.stack, SIGNAL(currentChanged(int)),
q, SIGNAL(operationStateChanged()) );
}
+ void keyLinkActivated( const QString & url );
+
std::vector<Key> keys;
static QHash<QString, QPointer<CertificateInfoWidgetImpl> > dialogMap;
struct UI {
QLabel * label;
ProgressWidget * progress;
QFrame * result;
QLabel * error;
QStackedWidget * stack;
explicit UI( ResultDisplayWidget * q )
: label( new QLabel( q ) ),
progress( new ProgressWidget( q ) ),
result( new QFrame( q ) ),
error( new QLabel( q ) ),
stack( new QStackedWidget( q ) )
{
KDAB_SET_OBJECT_NAME( label );
KDAB_SET_OBJECT_NAME( progress );
KDAB_SET_OBJECT_NAME( result );
KDAB_SET_OBJECT_NAME( error );
KDAB_SET_OBJECT_NAME( stack );
QVBoxLayout * layout = new QVBoxLayout( q );
layout->addWidget( label );
layout->addWidget( stack );
+ connect( label, SIGNAL(linkActivated(QString)), q, SLOT(keyLinkActivated(QString)));
+
error->setStyleSheet( ERROR_STYLE_SHEET );
stack->addWidget( progress );
stack->addWidget( result );
stack->addWidget( error );
stack->setCurrentWidget( progress );
}
} ui;
};
QHash<QString, QPointer<CertificateInfoWidgetImpl> > ResultDisplayWidget::Private::dialogMap;
ResultDisplayWidget::ResultDisplayWidget( QWidget * p )
: QWidget( p ), d( new Private( this ) )
{
setObjectName( "Kleo__ResultDisplayWidget" );
}
ResultDisplayWidget::~ResultDisplayWidget() {}
bool ResultDisplayWidget::operationInProgress() const {
return d->ui.stack->currentWidget() == d->ui.progress;
}
QString ResultDisplayWidget::renderKey( const Key & key ) {
if ( key.isNull() )
return i18n( "Unknown key" );
d->keys.push_back( key );
std::inplace_merge( d->keys.begin(), d->keys.end() - 1, d->keys.end(), _detail::ByFingerprint<std::less>() );
return QString::fromLatin1( "<a href=\"key:%1\">%2</a>" ).arg( key.primaryFingerprint(), Formatting::prettyName( key ) );
}
static QColor resaturate( const QColor & c, int sat ) {
int h, s, v;
c.getHsv( &h, &s, &v );
return QColor::fromHsv( h, sat, v );
}
// static
QString ResultDisplayWidget::styleSheet( const QColor & c ) {
return
"border:4px solid " + c.name() + "; border-radius:2px; "
"background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, "
"stop: 0.0 " + resaturate( c, 16 ).name() + ", "
"stop: 0.4 " + resaturate( c, 27 ).name() + ", "
"stop: 0.5 " + resaturate( c, 40 ).name() + ", "
"stop: 1.0 " + resaturate( c, 16 ).name() + ");"
;
}
void ResultDisplayWidget::setColor( const QColor & color ) {
setStyleSheet( '#' + objectName() + '{' + styleSheet( color ) + '}' );
}
-void ResultDisplayWidget::keyLinkActivated( const QString & link ) {
+void ResultDisplayWidget::Private::keyLinkActivated( const QString & link ) {
if ( !link.startsWith( "key:" ) )
return;
const QString fpr = link.mid( 4 );
const std::vector<Key>::const_iterator kit
- = qBinaryFind( d->keys.begin(), d->keys.end(), fpr.toStdString(), _detail::ByFingerprint<std::less>() );
- if ( kit == d->keys.end() )
+ = qBinaryFind( keys.begin(), keys.end(), fpr.toStdString(), _detail::ByFingerprint<std::less>() );
+ if ( kit == keys.end() )
return;
- QHash<QString, QPointer<CertificateInfoWidgetImpl> >::const_iterator dit = d->dialogMap.find( fpr );
- if ( dit == d->dialogMap.end() || !*dit ) {
+ QHash<QString, QPointer<CertificateInfoWidgetImpl> >::const_iterator dit = dialogMap.find( fpr );
+ if ( dit == dialogMap.end() || !*dit ) {
CertificateInfoWidgetImpl * const dlg = new CertificateInfoWidgetImpl( *kit, false, 0 );
dlg->setAttribute( Qt::WA_DeleteOnClose );
- dit = d->dialogMap.insert( fpr, dlg );
+ dit = dialogMap.insert( fpr, dlg );
}
- assert( dit != d->dialogMap.end() );
+ assert( dit != dialogMap.end() );
if ( (*dit)->isVisible() )
(*dit)->raise();
else
(*dit)->show();
}
void ResultDisplayWidget::setLabel( const QString & label ) {
d->ui.label->setText( label );
}
void ResultDisplayWidget::setProgress( const QString & what, int current, int total ) {
d->ui.progress->setText( what );
d->ui.progress->setProgress( current, total );
}
void ResultDisplayWidget::setError( int err, const QString & details ) {
Q_UNUSED( err );
setError( details );
}
-void ResultDisplayWidget::setResult( const boost::shared_ptr<const Task::Result> & result ) {
+void ResultDisplayWidget::setResult( const shared_ptr<const Task::Result> & result ) {
assert( result );
QVBoxLayout * const layout = new QVBoxLayout( d->ui.result );
QLabel * const overview = new QLabel;
overview->setTextFormat( Qt::RichText );
overview->setText( result->overview() );
+ connect( overview, SIGNAL(linkActivated(QString)), this, SLOT(keyLinkActivated(QString)));
layout->addWidget( overview );
+ const QString detailsStr = result->details();
+ if ( !detailsStr.isEmpty() ) {
+ QLabel * const details = new QLabel;
+ details->setTextFormat( Qt::RichText );
+ details->setText( detailsStr );
+ connect( details, SIGNAL(linkActivated(QString)), this, SLOT(keyLinkActivated(QString)));
+ layout->addWidget( details );
+ }
d->ui.stack->setCurrentWidget( d->ui.result );
}
void ResultDisplayWidget::showResultWidget() {
d->ui.stack->setCurrentWidget( d->ui.result );
}
void ResultDisplayWidget::setError( const QString & err ) {
d->ui.error->setText( err );
d->ui.stack->setCurrentWidget( d->ui.error );
}
QWidget * ResultDisplayWidget::resultWidget() {
return d->ui.result;
}
#include "resultdisplaywidget.moc"
#include "moc_resultdisplaywidget.cpp"
diff --git a/crypto/gui/resultdisplaywidget.h b/crypto/gui/resultdisplaywidget.h
index 292445211..bd2dbc3c7 100644
--- a/crypto/gui/resultdisplaywidget.h
+++ b/crypto/gui/resultdisplaywidget.h
@@ -1,93 +1,91 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resultdisplaywidget.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#ifndef __KLEOPATRA_CRYPTO_GUI_RESULTDISPLAYWIDGET_H__
#define __KLEOPATRA_CRYPTO_GUI_RESULTDISPLAYWIDGET_H__
#include <QWidget>
#include <crypto/task.h>
#include <utils/pimpl_ptr.h>
class QColor;
namespace GpgME {
class Key;
}
namespace Kleo {
namespace Crypto {
namespace Gui {
class ResultDisplayWidget : public QWidget {
Q_OBJECT
public:
explicit ResultDisplayWidget( QWidget * parent = 0 );
~ResultDisplayWidget();
bool operationInProgress() const;
bool operationFinished() const { return !operationInProgress(); }
void setLabel( const QString & str );
void showResultWidget();
void setError( const QString & err );
Q_SIGNALS:
void operationStateChanged();
public Q_SLOTS:
void setProgress( const QString & what, int current, int total );
void setError( int err, const QString & details );
void setResult( const boost::shared_ptr<const Kleo::Crypto::Task::Result> & result );
protected:
static QString styleSheet( const QColor & color );
protected:
QString renderKey( const GpgME::Key &key );
void setColor( const QColor &color );
QWidget * resultWidget();
-protected Q_SLOTS:
- void keyLinkActivated( const QString &link );
-
private:
class Private;
kdtools::pimpl_ptr<Private> d;
+ Q_PRIVATE_SLOT( d, void keyLinkActivated( QString ) )
};
}
}
}
#endif /* __KLEOPATRA_CRYPTO_GUI_RESULTDISPLAYWIDGET_H__ */
diff --git a/uiserver/decryptverifycommand.cpp b/uiserver/decryptverifycommand.cpp
index 34a838dea..df9c6e184 100644
--- a/uiserver/decryptverifycommand.cpp
+++ b/uiserver/decryptverifycommand.cpp
@@ -1,844 +1,587 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/decryptverifycommand.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007 Klarälvdalens Datakonsult AB
Kleopatra 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.
Kleopatra 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 Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), 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
Qt. 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.
*/
#include <config-kleopatra.h>
#include "decryptverifycommand.h"
+#include <crypto/decryptverifytask.h>
+
#include <crypto/gui/decryptverifywizard.h>
#include <crypto/gui/decryptverifyresultwidget.h>
#include <crypto/gui/decryptverifyoperationwidget.h>
#include <models/keycache.h>
#include <models/predicates.h>
#include <utils/input.h>
#include <utils/output.h>
#include <utils/detail_p.h>
#include <utils/hex.h>
#include <utils/classify.h>
#include <utils/formatting.h>
#include <utils/stl_util.h>
#include <utils/kleo_assert.h>
#include <utils/exception.h>
#include <kleo/verifyopaquejob.h>
#include <kleo/verifydetachedjob.h>
#include <kleo/decryptjob.h>
#include <kleo/decryptverifyjob.h>
#include <kleo/cryptobackendfactory.h>
#include <gpgme++/error.h>
#include <gpgme++/key.h>
#include <gpgme++/verificationresult.h>
#include <gpgme++/decryptionresult.h>
#include <gpg-error.h>
#include <KLocale>
#include <KIconLoader>
#include <KMessageBox>
#include <KWindowSystem>
#include <QFileDialog>
#include <QObject>
#include <QIODevice>
#include <QMap>
#include <QHash>
#include <QPointer>
-#include <QTemporaryFile>
+#include <QTimer>
#include <boost/bind.hpp>
#include <cassert>
#include <algorithm>
#include <functional>
#include <errno.h>
using namespace Kleo;
+using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
using namespace GpgME;
using namespace boost;
-// -- helpers ---
-static
-// dup of same function in decryptverifyresultwidget.cpp
-const GpgME::Key & keyForSignature( const Signature & sig, const std::vector<Key> & keys ) {
- if ( const char * const fpr = sig.fingerprint() ) {
- const std::vector<Key>::const_iterator it
- = std::lower_bound( keys.begin(), keys.end(), fpr, _detail::ByFingerprint<std::less>() );
- if ( it != keys.end() && _detail::ByFingerprint<std::equal_to>()( *it, fpr ) )
- return *it;
- }
- static const Key null;
- return null;
-}
-
-namespace {
-
- class TemporaryFile : public QTemporaryFile {
- public:
- explicit TemporaryFile() : QTemporaryFile() {}
- explicit TemporaryFile( const QString & templateName ) : QTemporaryFile( templateName ) {}
- explicit TemporaryFile( QObject * parent ) : QTemporaryFile( parent ) {}
- explicit TemporaryFile( const QString & templateName, QObject * parent ) : QTemporaryFile( templateName, parent ) {}
-
- /* reimp */ void close() {
- if ( isOpen() )
- m_oldFileName = fileName();
- QTemporaryFile::close();
- }
-
- QString oldFileName() const { return m_oldFileName; }
-
- private:
- QString m_oldFileName;
- };
-
- enum Type {
- Decrypt,
- DecryptVerify,
- VerifyOpaque,
- VerifyDetached
- } type;
-
- struct DVResult {
-
- Type type;
- VerificationResult verificationResult;
- DecryptionResult decryptionResult;
- QByteArray stuff;
- int error;
- QString errorString;
-
- static DVResult fromDecryptResult( const DecryptionResult & dr, const QByteArray & plaintext ) {
- const DVResult res = {
- Decrypt,
- VerificationResult(),
- dr,
- plaintext,
- 0,
- QString()
- };
- return res;
- }
- static DVResult fromDecryptResult( const Error & err ) {
- return fromDecryptResult( DecryptionResult( err ), QByteArray() );
- }
-
- static DVResult fromDecryptVerifyResult( const DecryptionResult & dr, const VerificationResult & vr, const QByteArray & plaintext ) {
- const DVResult res = {
- DecryptVerify,
- vr,
- dr,
- plaintext,
- 0,
- QString()
- };
- return res;
- }
- static DVResult fromDecryptVerifyResult( const Error & err ) {
- return fromDecryptVerifyResult( DecryptionResult( err ), VerificationResult(), QByteArray() );
- }
-
- static DVResult fromVerifyOpaqueResult( const VerificationResult & vr, const QByteArray & plaintext ) {
- const DVResult res = {
- VerifyOpaque,
- vr,
- DecryptionResult(),
- plaintext,
- 0,
- QString()
- };
- return res;
- }
- static DVResult fromVerifyOpaqueResult( const Error & err ) {
- return fromVerifyOpaqueResult( VerificationResult( err ), QByteArray() );
- }
-
- static DVResult fromVerifyDetachedResult( const VerificationResult & vr ) {
- const DVResult res = {
- VerifyDetached,
- vr,
- DecryptionResult(),
- QByteArray(),
- 0,
- QString()
- };
- return res;
- }
- static DVResult fromVerifyDetachedResult( const Error & err ) {
- return fromVerifyDetachedResult( VerificationResult( err ) );
- }
-
- };
-
- struct DVTask {
- private:
- DVTask( const DVTask & );
- DVTask & operator=( const DVTask & );
- public:
-
- DVTask() : type( VerifyDetached ), backend( 0 ) {}
-
- Type type;
-
- shared_ptr<Input> input, signedData;
-
- shared_ptr<Output> output;
-
- const CryptoBackend::Protocol* backend;
-
- shared_ptr<DVResult> result;
-
- };
-
-} // anon namespace
-
class DecryptVerifyCommand::Private : public QObject {
Q_OBJECT
friend class ::Kleo::DecryptVerifyCommand;
DecryptVerifyCommand * const q;
public:
explicit Private( DecryptVerifyCommand * qq )
: QObject(),
q( qq ),
wizard(),
- taskList(),
- m_errorString(),
- m_error( 0U )
+ m_runnableTasks(),
+ m_completedTasks(),
+ m_runningTask()
{
}
~Private() {
}
- std::vector< shared_ptr<DVTask> > buildTaskList();
- static shared_ptr<DVTask> taskFromOperationWidget( const DecryptVerifyOperationWidget * w, const shared_ptr<QFile> & file, const QDir & outDir );
+ std::vector< shared_ptr<DecryptVerifyTask> > buildTaskList();
+ static shared_ptr<DecryptVerifyTask> taskFromOperationWidget( const DecryptVerifyOperationWidget * w, const shared_ptr<QFile> & file, const QDir & outDir );
- void startTasks();
- static QString signatureToString( const Signature& sig, const Key & key );
+ void connectTask( const shared_ptr<DecryptVerifyTask> & t, unsigned int idx );
- void createWizard() {
+ void ensureWizardCreated() {
if ( wizard )
return;
wizard = new DecryptVerifyWizard;
q->applyWindowID( wizard );
wizard->setAttribute( Qt::WA_DeleteOnClose );
connect( wizard, SIGNAL(finished(int)), this, SLOT(slotDialogClosed()) );
- //if ( requestedWindowTitle().isEmpty() )
- wizard->setWindowTitle( i18n("Decrypt/Verify Wizard") );
- //else
- // wizard->setWindowTitle( i18n("Decrypt/Verify Wizard: %1", requestedWindowTitle() ) );
+ wizard->setWindowTitle( i18n( "Decrypt/Verify" ) );
}
void showWizard() {
if ( !wizard ) {
- createWizard();
+ ensureWizardCreated();
wizard->next();
}
if ( !wizard->isVisible() )
wizard->show();
wizard->raise();
#ifdef Q_WS_WIN
KWindowSystem::forceActiveWindow( wizard->winId() );
#endif
}
public Q_SLOTS:
void slotProgress( const QString & what, int current, int total );
public:
- void registerJob( int id, VerifyDetachedJob* job ) {
- connect( job, SIGNAL(result(GpgME::VerificationResult)),
- this, SLOT(slotVerifyDetachedResult(GpgME::VerificationResult)) );
- m_senderToId[job] = id;
- }
- void registerJob( int id, VerifyOpaqueJob* job ) {
- connect( job, SIGNAL(result(GpgME::VerificationResult,QByteArray)),
- this, SLOT(slotVerifyOpaqueResult(GpgME::VerificationResult,QByteArray)) );
- m_senderToId[job] = id;
- }
- void registerJob( int id, DecryptJob * job ) {
- connect( job, SIGNAL(result(GpgME::DecryptionResult,QByteArray)),
- this, SLOT(slotDecryptResult(GpgME::DecryptionResult,QByteArray)) );
- m_senderToId[job] = id;
- }
- void registerJob( int id, DecryptVerifyJob * job ) {
- connect( job, SIGNAL(result(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)),
- this, SLOT(slotDecryptVerifyResult(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)) );
- m_senderToId[job] = id;
- }
- bool hasError() const { return m_error; }
- unsigned int error() const { return m_error; }
- const QString & errorString() const { return m_errorString; }
-
- void addResult( unsigned int id, const DVResult & res );
+ std::vector<shared_ptr<const DecryptVerifyResult> >::const_iterator firstErrorResult() const;
+ bool hasError() const;
+ unsigned int error() const;
+ QString errorString() const;
+
+ void addStartErrorResult( unsigned int id, const shared_ptr<DecryptVerifyResult> & res );
void sendSigStatii() const;
void finishCommand() const {
if ( hasError() )
q->done( error(), errorString() );
else
q->done();
}
private Q_SLOTS:
void slotDialogClosed() {
finishCommand();
}
- void slotVerifyOpaqueResult( const GpgME::VerificationResult & result, const QByteArray & plainText ) {
- assert( m_senderToId.contains( sender() ) );
- const unsigned int id = m_senderToId[sender()];
- addResult( id, DVResult::fromVerifyOpaqueResult( result, plainText ) );
- }
-
- void slotVerifyDetachedResult( const GpgME::VerificationResult & result ) {
- assert( m_senderToId.contains( sender() ) );
- const unsigned int id = m_senderToId[sender()];
- addResult( id, DVResult::fromVerifyDetachedResult( result ) );
- }
-
- void slotDecryptResult( const GpgME::DecryptionResult & result, const QByteArray & plainText ) {
- assert( m_senderToId.contains( sender() ) );
- const unsigned int id = m_senderToId[sender()];
- addResult( id, DVResult::fromDecryptResult( result, plainText ) );
- }
- void slotDecryptVerifyResult( const GpgME::DecryptionResult & dr, const GpgME::VerificationResult & vr, const QByteArray & plainText ) {
- assert( m_senderToId.contains( sender() ) );
- const unsigned int id = m_senderToId[sender()];
- addResult( id, DVResult::fromDecryptVerifyResult( dr, vr, plainText ) );
- }
+ void schedule();
+ void slotTaskDone( const boost::shared_ptr<const Kleo::Crypto::DecryptVerifyResult>& result );
private:
QPointer<DecryptVerifyWizard> wizard;
- std::vector< shared_ptr<DVTask> > taskList;
- QHash<QObject*, unsigned int> m_senderToId;
- QString m_errorString;
- unsigned int m_error;
+ std::vector< shared_ptr<DecryptVerifyTask> > m_runnableTasks, m_completedTasks;
+ shared_ptr<DecryptVerifyTask> m_runningTask;
+ std::vector<shared_ptr<const DecryptVerifyResult> > m_results;
};
DecryptVerifyCommand::DecryptVerifyCommand()
: AssuanCommandMixin<DecryptVerifyCommand>(), d( new Private( this ) )
{
}
+void DecryptVerifyCommand::Private::schedule()
+{
+ if ( !m_runningTask && !m_runnableTasks.empty() ) {
+ const shared_ptr<DecryptVerifyTask> t = m_runnableTasks.back();
+ m_runnableTasks.pop_back();
+ t->start(); // ### FIXME: this might throw
+ m_runningTask = t;
+ }
+ if ( !m_runningTask ) {
+ kleo_assert( m_runnableTasks.empty() );
+#if KDAB_PENDING // remove encrypted inputs here if wanted?
+ if ( wizard->removeUnencryptedFile() && wizard->encryptionSelected() && !errorDetected )
+ removeInputFiles();
+#endif
+ sendSigStatii();
+ }
+}
+
+void DecryptVerifyCommand::Private::slotTaskDone( const shared_ptr<const DecryptVerifyResult>& result )
+{
+ assert( sender() );
+
+ // We could just delete the tasks here, but we can't use
+ // Qt::QueuedConnection here (we need sender()) and other slots
+ // might not yet have executed. Therefore, we push completed tasks
+ // into a burial container
+
+ if ( sender() == m_runningTask.get() ) {
+ m_completedTasks.push_back( m_runningTask );
+ m_results.push_back( result );
+ m_runningTask.reset();
+ }
+
+ QTimer::singleShot( 0, this, SLOT(schedule()) );
+}
+
+std::vector<shared_ptr<const DecryptVerifyResult> >::const_iterator DecryptVerifyCommand::Private::firstErrorResult() const
+{
+ return std::find_if( m_results.begin(), m_results.end(), bind( &DecryptVerifyResult::hasError, _1 ) );
+}
+
+bool DecryptVerifyCommand::Private::hasError() const
+{
+ return firstErrorResult() != m_results.end();
+}
+
+QString DecryptVerifyCommand::Private::errorString() const
+{
+ const std::vector<shared_ptr<const DecryptVerifyResult> >::const_iterator it = firstErrorResult();
+ return it != m_results.end() ? (*it)->errorString() : QString();
+}
+
+unsigned int DecryptVerifyCommand::Private::error() const
+{
+ const std::vector<shared_ptr<const DecryptVerifyResult> >::const_iterator it = firstErrorResult();
+ return it != m_results.end() ? (*it)->errorCode() : 0;
+}
+
DecryptVerifyCommand::~DecryptVerifyCommand() {}
+void DecryptVerifyCommand::Private::connectTask( const shared_ptr<DecryptVerifyTask> & t, unsigned int idx ) {
+ connect( t.get(), SIGNAL(decryptVerifyResult(boost::shared_ptr<const Kleo::Crypto::DecryptVerifyResult>)),
+ this, SLOT(slotTaskDone(boost::shared_ptr<const Kleo::Crypto::DecryptVerifyResult>)) );
+ ensureWizardCreated();
+ wizard->connectTask( t, idx );
+}
+
int DecryptVerifyCommand::doStart() {
- d->taskList = d->buildTaskList();
+ d->m_runnableTasks = d->buildTaskList();
- if ( d->taskList.empty() )
+ if ( d->m_runnableTasks.empty() )
throw Kleo::Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
i18n("No usable inputs found") );
+
+ d->ensureWizardCreated();
+ uint i = d->m_results.size();
+ Q_FOREACH( const shared_ptr<DecryptVerifyTask> & task, d->m_runnableTasks )
+ d->connectTask( task, i++ );
+
try {
- d->startTasks();
+ d->schedule();
return 0;
} catch ( ... ) {
//d->showWizard();
throw;
}
}
void DecryptVerifyCommand::doCanceled() {
// ### cancel all jobs?
if ( d->wizard )
d->wizard->close();
}
-std::vector< shared_ptr<DVTask> > DecryptVerifyCommand::Private::buildTaskList()
+std::vector< shared_ptr<DecryptVerifyTask> > DecryptVerifyCommand::Private::buildTaskList()
{
if ( !q->senders().empty() )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
i18n("Can't use SENDER") );
if ( !q->recipients().empty() )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
i18n("Can't use RECIPIENT") );
const unsigned int numInputs = q->inputs().size();
const unsigned int numMessages = q->messages().size();
const unsigned int numOutputs = q->outputs().size();
const unsigned int op = q->operation();
const Mode mode = q->mode();
const GpgME::Protocol proto = q->checkProtocol( mode );
const unsigned int numFiles = q->numFiles();
kleo_assert( op != 0 );
- std::vector< shared_ptr<DVTask> > tasks;
+ std::vector< shared_ptr<DecryptVerifyTask> > tasks;
if ( mode == EMail ) {
if ( numFiles )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ), i18n("FILES present") );
if ( !numInputs )
throw Kleo::Exception( q->makeError( GPG_ERR_ASS_NO_INPUT ),
i18n("At least one INPUT needs to be provided") );
if ( numMessages )
if ( numMessages != numInputs )
throw Kleo::Exception( q->makeError( GPG_ERR_ASS_NO_INPUT ), //TODO use better error code if possible
i18n("INPUT/MESSAGE count mismatch") );
else if ( op != VerifyImplied )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
i18n("MESSAGE can only be given for detached signature verification") );
if ( numOutputs )
if ( numOutputs != numInputs )
throw Kleo::Exception( q->makeError( GPG_ERR_ASS_NO_OUTPUT ), //TODO use better error code if possible
i18n("INPUT/OUTPUT count mismatch") );
else if ( numMessages )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
i18n("Can't use OUTPUT and MESSAGE simultaneously") );
kleo_assert( proto != UnknownProtocol );
const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( proto );
if ( !backend )
throw Kleo::Exception( q->makeError( GPG_ERR_UNSUPPORTED_PROTOCOL ),
proto == OpenPGP ? i18n("No backend support for OpenPGP") :
proto == CMS ? i18n("No backend support for S/MIME") : QString() );
- Type type;
+ DecryptVerifyTask::Type type;
if ( numMessages )
- type = VerifyDetached;
+ type = DecryptVerifyTask::VerifyDetached;
else if ( (op&DecryptMask) == DecryptOff )
- type = VerifyOpaque;
+ type = DecryptVerifyTask::VerifyOpaque;
else if ( (op&VerifyMask) == VerifyOff )
- type = Decrypt;
+ type = DecryptVerifyTask::Decrypt;
else
- type = DecryptVerify;
+ type = DecryptVerifyTask::DecryptVerify;
- if ( type != Decrypt && !q->hasOption("silent") ) {
+ if ( type != DecryptVerifyTask::Decrypt && !q->hasOption("silent") ) {
showWizard();
wizard->next();
}
for ( unsigned int i = 0 ; i < numInputs ; ++i ) {
- shared_ptr<DVTask> task( new DVTask );
- task->type = type;
+ shared_ptr<DecryptVerifyTask> task( new DecryptVerifyTask( type ) );
- task->input = q->inputs().at( i );
- kleo_assert( task->input->ioDevice() );
+ task->setInput( q->inputs().at( i ) );
- if ( type == VerifyDetached ) {
- task->signedData = q->messages().at( i );
- kleo_assert( task->signedData->ioDevice() );
- }
+ if ( type == DecryptVerifyTask::VerifyDetached )
+ task->setSignedData( q->messages().at( i ) );
- if ( numOutputs ) {
- task->output = q->outputs().at( i );
- kleo_assert( task->output->ioDevice() );
- }
+ if ( numOutputs )
+ task->setOutput( q->outputs().at( i ) );
- task->backend = backend;
+ task->setBackend( backend );
tasks.push_back( task );
}
} else {
if ( numInputs )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ), i18n("INPUT present") );
if ( numMessages )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ), i18n("MESSAGE present") );
if ( numOutputs )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ), i18n("OUTPUT present") );
- createWizard();
+ ensureWizardCreated();
std::vector< shared_ptr<QFile> > files;
unsigned int counter = 0;
Q_FOREACH( const shared_ptr<QFile> & file, q->files() ) {
kleo_assert( file );
const QString fname = file->fileName();
kleo_assert( !fname.isEmpty() );
const unsigned int classification = classify( fname );
if ( mayBeOpaqueSignature( classification ) || mayBeCipherText( classification ) || mayBeDetachedSignature( classification ) ) {
DecryptVerifyOperationWidget * const op = wizard->operationWidget( counter++ );
kleo_assert( op != 0 );
if ( mayBeOpaqueSignature( classification ) || mayBeCipherText( classification ) )
op->setMode( DecryptVerifyOperationWidget::DecryptVerifyOpaque );
else
op->setMode( DecryptVerifyOperationWidget::VerifyDetachedWithSignature );
op->setInputFileName( fname );
op->setSignedDataFileName( findSignedData( fname ) );
files.push_back( file );
} else {
// probably the signed data file was selected:
QStringList signatures = findSignatures( fname );
if ( signatures.empty() )
signatures.push_back( QString() );
Q_FOREACH( const QString s, signatures ) {
DecryptVerifyOperationWidget * op = wizard->operationWidget( counter++ );
kleo_assert( op != 0 );
op->setMode( DecryptVerifyOperationWidget::VerifyDetachedWithSignedData );
op->setInputFileName( s );
op->setSignedDataFileName( fname );
files.push_back( file );
}
}
}
kleo_assert( counter == files.size() );
if ( !counter )
throw Kleo::Exception( q->makeError( GPG_ERR_ASS_NO_INPUT ), i18n("No usable inputs found") );
wizard->setOutputDirectory( q->heuristicBaseDirectory() );
showWizard();
if ( !wizard->waitForOperationSelection() )
throw Kleo::Exception( q->makeError( GPG_ERR_CANCELED ), i18n("Confirmation dialog canceled") );
const QFileInfo outDirInfo( wizard->outputDirectory() );
kleo_assert( outDirInfo.isDir() );
const QDir outDir( outDirInfo.absoluteFilePath() );
kleo_assert( outDir.exists() );
+ int failed = 0;
for ( unsigned int i = 0 ; i < counter ; ++i )
try {
tasks.push_back( taskFromOperationWidget( wizard->operationWidget( i ), files[i], outDir ) );
} catch ( const GpgME::Exception & e ) {
- addResult( i, DVResult::fromDecryptVerifyResult( e.error() ) );
+ addStartErrorResult( failed++, DecryptVerifyResult::fromDecryptVerifyResult( e.error(), QString::fromLocal8Bit( e.what() ) ) );
}
-
}
return tasks;
}
-static const CryptoBackend::Protocol * backendFor( const shared_ptr<Input> & input ) {
- return CryptoBackendFactory::instance()->protocol( findProtocol( input->classification() ) );
-}
-
// static
-shared_ptr<DVTask> DecryptVerifyCommand::Private::taskFromOperationWidget( const DecryptVerifyOperationWidget * w, const shared_ptr<QFile> & file, const QDir & outDir) {
+shared_ptr<DecryptVerifyTask> DecryptVerifyCommand::Private::taskFromOperationWidget( const DecryptVerifyOperationWidget * w, const shared_ptr<QFile> & file, const QDir & outDir) {
kleo_assert( w );
- shared_ptr<DVTask> task( new DVTask );
+ shared_ptr<DecryptVerifyTask> task;
switch ( w->mode() ) {
case DecryptVerifyOperationWidget::VerifyDetachedWithSignature:
- task->type = VerifyDetached;
- task->input = Input::createFromFile( file );
- task->signedData = Input::createFromFile( w->signedDataFileName() );
+ task.reset( new DecryptVerifyTask( DecryptVerifyTask::VerifyDetached ) );
+ task->setInput( Input::createFromFile( file ) );
+ task->setSignedData( Input::createFromFile( w->signedDataFileName() ) );
kleo_assert( file->fileName() == w->inputFileName() );
break;
case DecryptVerifyOperationWidget::VerifyDetachedWithSignedData:
-
- task->type = VerifyDetached;
- task->input = Input::createFromFile( w->inputFileName() );
- task->signedData = Input::createFromFile( file );
+ task.reset( new DecryptVerifyTask( DecryptVerifyTask::VerifyDetached ) );
+ task->setInput( Input::createFromFile( w->inputFileName() ) );
+ task->setSignedData( Input::createFromFile( file ) );
kleo_assert( file->fileName() == w->signedDataFileName() );
break;
case DecryptVerifyOperationWidget::DecryptVerifyOpaque:
- task->type = DecryptVerify;
- task->input = Input::createFromFile( file );
- task->output = Output::createFromFile( outDir.absoluteFilePath( outputFileName( QFileInfo( file->fileName() ).fileName() ) ), false );
+ task.reset( new DecryptVerifyTask( DecryptVerifyTask::DecryptVerify ) );
+ task->setInput( Input::createFromFile( file ) );
+ task->setOutput( Output::createFromFile( outDir.absoluteFilePath( outputFileName( QFileInfo( file->fileName() ).fileName() ) ), false ) );
kleo_assert( file->fileName() == w->inputFileName() );
break;
}
- task->backend = backendFor( task->input );
-
+ task->autodetectBackendFromInput();
return task;
}
-
-
-void DecryptVerifyCommand::Private::startTasks()
-{
- kleo_assert( !taskList.empty() );
-
- unsigned int i = 0;
- Q_FOREACH ( shared_ptr<DVTask> task, taskList ) {
-
- kleo_assert( task->backend );
-
- QPointer<QObject> that = this;
- switch ( task->type ) {
- case Decrypt:
- try {
- DecryptJob * const job = task->backend->decryptJob();
- kleo_assert( job );
- registerJob( i, job );
- job->start( task->input->ioDevice(), task->output->ioDevice() );
- } catch ( const GpgME::Exception & e ) {
- addResult( i, DVResult::fromDecryptResult( e.error() ) );
- }
- break;
- case DecryptVerify:
- try {
- DecryptVerifyJob * const job = task->backend->decryptVerifyJob();
- kleo_assert( job );
- registerJob( i, job );
- job->start( task->input->ioDevice(), task->output->ioDevice() );
- } catch ( const GpgME::Exception & e ) {
- addResult( i, DVResult::fromDecryptVerifyResult( e.error() ) );
- }
- break;
- case VerifyOpaque:
- try {
- VerifyOpaqueJob * const job = task->backend->verifyOpaqueJob();
- kleo_assert( job );
- registerJob( i, job );
- job->start( task->input->ioDevice(), task->output ? task->output->ioDevice() : shared_ptr<QIODevice>() );
- } catch ( const GpgME::Exception & e ) {
- addResult( i, DVResult::fromVerifyOpaqueResult( e.error() ) );
- }
- break;
- case VerifyDetached:
- try {
- VerifyDetachedJob * const job = task->backend->verifyDetachedJob();
- kleo_assert( job );
- registerJob( i, job );
- job->start( task->input->ioDevice(), task->signedData->ioDevice() );
- } catch ( const GpgME::Exception & e ) {
- addResult( i, DVResult::fromVerifyDetachedResult( e.error() ) );
- }
- break;
- }
- if ( !that )
- return;
- ++i;
- }
-
-}
-
-static const char * summaryToString( const Signature::Summary summary )
-{
- if ( summary & Signature::Red )
- return "RED";
- if ( summary & Signature::Green )
- return "GREEN";
- return "YELLOW";
-}
-
-static QString keyToString( const Key & key ) {
-
- kleo_assert( !key.isNull() );
-
- const QString email = Formatting::prettyEMail( key );
- const QString name = Formatting::prettyName( key );
-
- if ( name.isEmpty() )
- return email;
- else if ( email.isEmpty() )
- return name;
- else
- return QString::fromLatin1( "%1 <%2>" ).arg( name, email );
-}
-
-QString DecryptVerifyCommand::Private::signatureToString( const Signature & sig, const Key & key )
-{
- if ( sig.isNull() )
- return QString();
-
- const bool red = (sig.summary() & Signature::Red);
- const bool valid = (sig.summary() & Signature::Valid);
-
- if ( red )
- if ( key.isNull() )
- if ( const char * fpr = sig.fingerprint() )
- return i18n("Bad signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
- else
- return i18n("Bad signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
- else
- return i18n("Bad signature by %1: %2", keyToString( key ), QString::fromLocal8Bit( sig.status().asString() ) );
-
- else if ( valid )
- if ( key.isNull() )
- if ( const char * fpr = sig.fingerprint() )
- return i18n("Good signature by unknown key %1.", QString::fromLatin1( fpr ) );
- else
- return i18n("Good signature by an unknown key.");
- else
- return i18n("Good signature by %1.", keyToString( key ) );
-
- else
- if ( key.isNull() )
- if ( const char * fpr = sig.fingerprint() )
- return i18n("Invalid signature by unknown key %1: %2", QString::fromLatin1( fpr ), QString::fromLocal8Bit( sig.status().asString() ) );
- else
- return i18n("Invalid signature by an unknown key: %1", QString::fromLocal8Bit( sig.status().asString() ) );
- else
- return i18n("Invalid signature by %1: %2", keyToString( key ), QString::fromLocal8Bit( sig.status().asString() ) );
-}
-
-static QStringList labels( const std::vector< shared_ptr<DVTask> > & taskList )
-{
- QStringList labels;
- for ( unsigned int i = 0, end = taskList.size() ; i < end ; ++i ) {
- const shared_ptr<DVTask> & task = taskList[i];
- switch ( task->type ) {
- case Decrypt:
- case DecryptVerify:
- labels.push_back( i18n( "Decrypting: %1...", task->input->label() ) );
- break;
- case VerifyOpaque:
- labels.push_back( i18n( "Verifying: %1...", task->input->label() ) );
- break;
- case VerifyDetached:
- labels.push_back( i18n( "Verifying signature: %1...", task->input->label() ) );
- break;
- }
- }
- return labels;
-}
-
void DecryptVerifyCommand::Private::slotProgress( const QString& what, int current, int total )
{
- // FIXME report progress, via sendStatus()
+ // ### FIXME report progress, via sendStatus()
}
+#if KDAB_PENDING
+
struct ResultPresentAndOutputFinalized {
typedef bool result_type;
- bool operator()( const shared_ptr<DVTask> & task ) const {
+ bool operator()( const shared_ptr<DecryptVerifyTask> & task ) const {
return task->result && ( !task->output || task->output->isFinalized() );
}
};
-void DecryptVerifyCommand::Private::addResult( unsigned int id, const DVResult & res )
+void DecryptVerifyCommand::Private::addResult( unsigned int id, const shared_ptr<DecryptVerifyResult> & res )
{
const bool taskExists = id < taskList.size();
assert( !taskExists || !taskList[id]->result );
const shared_ptr<DVResult> result( new DVResult( res ) );
if ( taskExists )
taskList[id]->result = result;
qDebug( "addResult: %d (%p)", id, result.get() );
const VerificationResult & vResult = result->verificationResult;
const DecryptionResult & dResult = result->decryptionResult;
if ( dResult.error().code() )
result->error = dResult.error().encodedError();
else if ( vResult.error().code() )
result->error = vResult.error().encodedError();
if ( !result->error && taskExists && taskList[id]->output )
try {
QPointer<QObject> that = this;
taskList[id]->output->finalize( /*wizard*/ );
if ( !that )
return;
} catch ( const Kleo::Exception & e ) {
result->error = e.error_code();
result->errorString = e.message();
// FIXME ask to continue or cancel?
}
if ( wizard )
wizard->resultWidget( id )->setResult( result->decryptionResult, result->verificationResult );
if ( result->error && !m_error ) {
m_error = result->error;
m_errorString = result->errorString;
}
if ( kdtools::all( taskList.begin(), taskList.end(), ResultPresentAndOutputFinalized() ) )
sendSigStatii();
}
+#endif // KDAB_PENDING
-void DecryptVerifyCommand::Private::sendSigStatii() const {
-
- Q_FOREACH( const shared_ptr<DVTask> & task, taskList ) {
-
- const shared_ptr<DVResult> result = task->result;
- if ( !result )
- continue;
+void DecryptVerifyCommand::Private::addStartErrorResult( unsigned int id, const shared_ptr<DecryptVerifyResult> & res )
+{
+ ensureWizardCreated();
+ wizard->resultWidget( id )->setResult( res );
+ m_results.push_back( res );
+}
- const VerificationResult & vResult = result->verificationResult;
+void DecryptVerifyCommand::Private::sendSigStatii() const {
+ Q_FOREACH( const shared_ptr<const DecryptVerifyResult> & result, m_results ) {
+ const VerificationResult vResult = result->verificationResult();
try {
const std::vector<Signature> sigs = vResult.signatures();
const std::vector<Key> signers = KeyCache::instance()->findSigners( vResult );
Q_FOREACH ( const Signature & sig, sigs ) {
- const QString s = signatureToString( sig, keyForSignature( sig, signers ) );
- const char * color = summaryToString( sig.summary() );
+ const QString s = DecryptVerifyResult::signatureToString( sig, DecryptVerifyResult::keyForSignature( sig, signers ) );
+ const char * color = DecryptVerifyResult::summaryToString( sig.summary() );
q->sendStatusEncoded( "SIGSTATUS",
color + ( ' ' + hexencode( s.toUtf8().constData() ) ) );
}
} catch ( ... ) {}
-
}
-
finishCommand();
}
#include "decryptverifycommand.moc"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jul 17, 12:40 AM (1 d, 10 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
7f/af/7ae79095f1031dad123e8d30c27a
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment