Page MenuHome GnuPG

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7869179b7..a1fdcca57 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,282 +1,262 @@
project(kleopatra)
include(MacroOptionalAddSubdirectory)
-set( kleopatra_version 1.9.3-beta )
+set( kleopatra_version 1.9.1 )
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 )
if ( USABLE_ASSUAN_FOUND AND BUILD_libkleopatraclient )
# can't use macro_optional_add_subdirectory here, since it's split
# off into ConfigureChecks.cmake..
add_subdirectory( libkleopatraclient )
endif ( USABLE_ASSUAN_FOUND AND BUILD_libkleopatraclient )
add_subdirectory( kgpgconf )
add_subdirectory( kwatchgnupg )
add_subdirectory( tests )
if ( WIN32 )
set( _kleopatra_extra_uiserver_SRCS
uiserver/uiserver_win.cpp
)
set( _kleopatra_extra_SRCS
utils/gnupg-registry.c
selftest/registrycheck.cpp
)
else ( WIN32 )
set( _kleopatra_extra_uiserver_SRCS
uiserver/uiserver_unix.cpp
)
set( _kleopatra_extra_SRCS
)
endif ( WIN32 )
if ( USABLE_ASSUAN_FOUND )
add_definitions ( -DKLEOPATRACLIENT_NAMESPACE=KleopatraClientCopy -DKLEOPATRACLIENTCORE_EXPORT= )
set(_kleopatra_uiserver_SRCS
uiserver/uiserver.cpp
${_kleopatra_extra_uiserver_SRCS}
uiserver/assuanserverconnection.cpp
uiserver/echocommand.cpp
uiserver/decryptverifycommandemailbase.cpp
uiserver/decryptverifycommandfilesbase.cpp
uiserver/signcommand.cpp
uiserver/signencryptfilescommand.cpp
uiserver/prepencryptcommand.cpp
uiserver/encryptcommand.cpp
uiserver/selectcertificatecommand.cpp
libkleopatraclient/core/command.cpp
selftest/uiservercheck.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_SRCS
utils/gnupg-helper.cpp
utils/filesystemwatcher.cpp
utils/kdpipeiodevice.cpp
utils/kdlogtextwidget.cpp
utils/headerview.cpp
utils/scrollarea.cpp
- utils/dragqueen.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
selftest/selftest.cpp
selftest/enginecheck.cpp
selftest/gpgconfcheck.cpp
${_kleopatra_extra_SRCS}
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
dialogs/lookupcertificatesdialog.cpp
dialogs/ownertrustdialog.cpp
dialogs/selftestdialog.cpp
- dialogs/certifycertificatedialog.cpp
- dialogs/exportsecretkeydialog.cpp
- dialogs/adduseriddialog.cpp
- dialogs/certificatedetailsdialog.cpp
- dialogs/exportcertificatesdialog.cpp
+ dialogs/signcertificatedialog.cpp
crypto/certificateresolver.cpp
crypto/task.cpp
crypto/taskcollection.cpp
crypto/decryptverifytask.cpp
crypto/decryptverifyemailcontroller.cpp
crypto/decryptverifyfilescontroller.cpp
crypto/encryptemailtask.cpp
crypto/encryptemailcontroller.cpp
crypto/signencryptfilestask.cpp
crypto/signemailtask.cpp
crypto/signemailcontroller.cpp
crypto/gui/wizard.cpp
crypto/gui/wizardpage.cpp
crypto/gui/signingcertificateselectiondialog.cpp
crypto/gui/resultitemwidget.cpp
crypto/gui/resultlistwidget.cpp
crypto/gui/resultpage.cpp
crypto/gui/decryptverifyoperationwidget.cpp
crypto/gui/decryptverifyfileswizard.cpp
crypto/gui/objectspage.cpp
crypto/gui/resolverecipientspage.cpp
crypto/gui/signerresolvepage.cpp
crypto/gui/encryptemailwizard.cpp
crypto/gui/signemailwizard.cpp
crypto/gui/signencryptfileswizard.cpp
crypto/gui/signencryptwizard.cpp
crypto/controller.cpp
crypto/signencryptfilescontroller.cpp
commands/command.cpp
commands/gnupgprocesscommand.cpp
commands/detailscommand.cpp
commands/exportcertificatecommand.cpp
commands/importcertificatescommand.cpp
commands/importcertificatefromfilecommand.cpp
commands/lookupcertificatescommand.cpp
commands/reloadkeyscommand.cpp
commands/refreshx509certscommand.cpp
commands/refreshopenpgpcertscommand.cpp
commands/deletecertificatescommand.cpp
commands/decryptverifyfilescommand.cpp
commands/signencryptfilescommand.cpp
commands/encryptclipboardcommand.cpp
commands/signclipboardcommand.cpp
commands/decryptverifyclipboardcommand.cpp
commands/clearcrlcachecommand.cpp
commands/dumpcrlcachecommand.cpp
- commands/dumpcertificatecommand.cpp
commands/importcrlcommand.cpp
commands/changeexpirycommand.cpp
commands/changeownertrustcommand.cpp
- commands/changepassphrasecommand.cpp
- commands/certifycertificatecommand.cpp
+ commands/signcertificatecommand.cpp
commands/selftestcommand.cpp
- commands/exportsecretkeycommand.cpp
- commands/exportopenpgpcertstoservercommand.cpp
- commands/adduseridcommand.cpp
${_kleopatra_uiserver_files}
conf/configuredialog.cpp
- newcertificatewizard/listwidget.cpp
- newcertificatewizard/newcertificatewizard.cpp
-
+ certificatewizardimpl.cpp
aboutdata.cpp
systemtrayicon.cpp
- kleopatraapplication.cpp
+ exportcertificatesdialog.cpp
+ certificateinfowidgetimpl.cpp
main.cpp )
if ( KLEO_MODEL_TEST )
add_definitions( -DKLEO_MODEL_TEST )
set( _kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp )
endif ( KLEO_MODEL_TEST )
kde4_add_ui_files( _kleopatra_SRCS
- dialogs/certificationoptionswidget.ui
+ certificateinfowidget.ui
+ certificatewizard.ui
dialogs/expirydialog.ui
dialogs/lookupcertificatesdialog.ui
dialogs/ownertrustdialog.ui
- dialogs/selectchecklevelwidget.ui
dialogs/selftestdialog.ui
- dialogs/exportsecretkeydialog.ui
- dialogs/adduseriddialog.ui
- dialogs/certificatedetailsdialog.ui
- newcertificatewizard/listwidget.ui
- newcertificatewizard/chooseprotocolpage.ui
- newcertificatewizard/enterdetailspage.ui
- newcertificatewizard/overviewpage.ui
- newcertificatewizard/keycreationpage.ui
- newcertificatewizard/resultpage.ui
- newcertificatewizard/advancedsettingsdialog.ui
+ dialogs/signcertificatedialog.ui
)
kde4_add_kcfg_files( _kleopatra_SRCS
kcfg/tooltippreferences.kcfgc
kcfg/emailoperationspreferences.kcfgc
kcfg/smimevalidationpreferences.kcfgc
)
if (ONLY_KLEO)
add_definitions( -DONLY_KLEO )
endif(ONLY_KLEO)
set( _kleopatra_mainwindow_SRCS
mainwindow.cpp
)
add_definitions ( -DKDE_DEFAULT_DEBUG_AREA=5151 )
kde4_add_app_icon(_kleopatra_mainwindow_SRCS "ox*-app-kleopatra.png")
kde4_add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_mainwindow_SRCS} ${_kleopatra_uiserver_SRCS} )
set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
set( _kleopatra_extra_libs ${QT_QT3SUPPORT_LIBRARY} )
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 kleopatra.rc DESTINATION ${DATA_INSTALL_DIR}/kleopatra)
kde4_install_icons( ${ICON_INSTALL_DIR} )
diff --git a/aboutdata.cpp b/aboutdata.cpp
index 06828c35f..74847b75f 100644
--- a/aboutdata.cpp
+++ b/aboutdata.cpp
@@ -1,103 +1,103 @@
/*
aboutdata.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2001,2002,2004 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 "aboutdata.h"
#include <klocale.h>
static const char kleopatra_version[] = KLEOPATRA_VERSION_STRING;
static const char description[] = I18N_NOOP("KDE Certificate Manager");
struct about_data {
const char * name;
const char * desc;
const char * email;
const char * web;
};
static const about_data authors[] = {
{ "Marc Mutz", I18N_NOOP("Current Maintainer"), "mutz@kde.org", 0 },
{ "Steffen Hansen", I18N_NOOP("Former Maintainer"), "hansen@kde.org", 0 },
{ "Kalle Dalheimer", I18N_NOOP("Original Author"), "kalle@kde.org", 0 },
{ "Jesper Petersen", I18N_NOOP("Original Author"), "blackie@kde.org", 0 },
};
static const about_data credits[] = {
{ I18N_NOOP("Till Adam"),
I18N_NOOP("UI Server commands and dialogs"),
"adam@kde.org", 0 },
{ I18N_NOOP("David Faure"),
I18N_NOOP("Backend configuration framework, KIO integration"),
"faure@kde.org", 0 },
{ I18N_NOOP("Michel Boyer de la Giroday"),
I18N_NOOP("Key-state dependant colors and fonts in the key list"),
"michel@klaralvdalens-datakonsult.se", 0 },
{ I18N_NOOP("Volker Krause"),
I18N_NOOP("UI Server dialogs"),
"vkrause@kde.org", 0 },
{ I18N_NOOP("Thomas Moenicke"),
I18N_NOOP("Artwork"),
"tm@php-qt.org", 0 },
{ I18N_NOOP("Daniel Molkentin"),
I18N_NOOP("Certificate Wizard KIOSK integration, infrastructure"),
"molkentin@kde.org", 0 },
{ I18N_NOOP("Ralf Nolden"),
I18N_NOOP("Support for obsolete EMAIL RDN in Certificate Wizard"),
"nolden@kde.org", 0 },
{ I18N_NOOP("Frank Osterfeld"),
I18N_NOOP("Resident gpgme/win wrangler, UI Server commands and dialogs"),
"osterfeld@kde.org", 0 },
{ I18N_NOOP("Karl-Heinz Zimmer"),
I18N_NOOP("DN display ordering support, infrastructure"),
"khz@kde.org", 0 },
};
AboutData::AboutData()
: KAboutData( "kleopatra", 0, ki18n("Kleopatra"),
kleopatra_version, ki18n(description), License_GPL,
ki18n("(c) 2002 Steffen Hansen, Jesper Pedersen,\n"
"Kalle Dalheimer, Klar\xC3\xA4lvdalens Datakonsult AB\n\n"
- "(c) 2004, 2007, 2008 Marc Mutz, Klar\xC3\xA4lvdalens Datakonsult AB") )
+ "(c) 2004, 2007 Marc Mutz, Klar\xC3\xA4lvdalens Datakonsult AB") )
{
using ::authors;
using ::credits;
for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i )
addAuthor( ki18n(authors[i].name), ki18n(authors[i].desc),
authors[i].email, authors[i].web );
for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i )
addCredit( ki18n(credits[i].name), ki18n(credits[i].desc),
credits[i].email, credits[i].web );
}
diff --git a/commands/adduseridcommand.cpp b/commands/adduseridcommand.cpp
index b5bebb707..e69de29bb 100644
--- a/commands/adduseridcommand.cpp
+++ b/commands/adduseridcommand.cpp
@@ -1,227 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/adduseridcommand.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 "adduseridcommand.h"
-
-#include "command_p.h"
-
-#include <dialogs/adduseriddialog.h>
-
-#include <utils/formatting.h>
-
-#include <kleo/cryptobackendfactory.h>
-#include <kleo/cryptobackend.h>
-#include <kleo/adduseridjob.h>
-
-#include <gpgme++/key.h>
-
-#include <KLocale>
-#include <KMessageBox>
-#include <kdebug.h>
-
-#include <cassert>
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace Kleo::Dialogs;
-using namespace GpgME;
-
-class AddUserIDCommand::Private : public Command::Private {
- friend class ::Kleo::Commands::AddUserIDCommand;
- AddUserIDCommand * q_func() const { return static_cast<AddUserIDCommand*>( q ); }
-public:
- explicit Private( AddUserIDCommand * qq, KeyListController * c );
- ~Private();
-
- void init();
-
-private:
- void slotDialogAccepted();
- void slotDialogRejected();
- void slotResult( const Error & err );
-
-private:
- void ensureDialogCreated();
- void createJob();
- void showErrorDialog( const Error & error );
- void showSuccessDialog();
-
-private:
- GpgME::Key key;
- QPointer<AddUserIDDialog> dialog;
- QPointer<AddUserIDJob> job;
-};
-
-
-AddUserIDCommand::Private * AddUserIDCommand::d_func() { return static_cast<Private*>( d.get() ); }
-const AddUserIDCommand::Private * AddUserIDCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
-
-#define d d_func()
-#define q q_func()
-
-AddUserIDCommand::Private::Private( AddUserIDCommand * qq, KeyListController * c )
- : Command::Private( qq, c ),
- key(),
- dialog(),
- job()
-{
-
-}
-
-AddUserIDCommand::Private::~Private() { kDebug(); }
-
-AddUserIDCommand::AddUserIDCommand( KeyListController * c )
- : Command( new Private( this, c ) )
-{
- d->init();
-}
-
-AddUserIDCommand::AddUserIDCommand( QAbstractItemView * v, KeyListController * c )
- : Command( v, new Private( this, c ) )
-{
- d->init();
-}
-
-AddUserIDCommand::AddUserIDCommand( const GpgME::Key & key )
- : Command( key, new Private( this, 0 ) )
-{
- d->init();
-}
-
-void AddUserIDCommand::Private::init() {
-
-}
-
-AddUserIDCommand::~AddUserIDCommand() { kDebug(); }
-
-void AddUserIDCommand::doStart() {
-
- const std::vector<Key> keys = d->keys();
- if ( keys.size() != 1 ||
- keys.front().protocol() != GpgME::OpenPGP ||
- !keys.front().hasSecret() ) {
- d->finished();
- return;
- }
-
- d->key = keys.front();
-
- d->ensureDialogCreated();
- assert( d->dialog );
- d->dialog->show();
-}
-
-void AddUserIDCommand::Private::slotDialogAccepted() {
- assert( dialog );
-
- createJob();
- if ( !job )
- finished();
-
- else if ( const Error err = job->start( key, dialog->name(), dialog->email(), dialog->comment() ) ) {
- showErrorDialog( err );
- finished();
- }
-}
-
-void AddUserIDCommand::Private::slotDialogRejected() {
- emit q->canceled();
- finished();
-}
-
-void AddUserIDCommand::Private::slotResult( const Error & err ) {
- if ( err.isCanceled() )
- ;
- else if ( err )
- showErrorDialog( err );
- else
- showSuccessDialog();
- finished();
-}
-
-void AddUserIDCommand::doCancel() {
- kDebug();
- if ( d->job )
- d->job->slotCancel();
-}
-
-void AddUserIDCommand::Private::ensureDialogCreated() {
- if ( dialog )
- return;
-
- dialog = new AddUserIDDialog( view() );
- dialog->setAttribute( Qt::WA_DeleteOnClose );
-
- connect( dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted()) );
- connect( dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()) );
-}
-
-void AddUserIDCommand::Private::createJob() {
- assert( !job );
-
- const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( key.protocol() );
- if ( !backend )
- return;
-
- AddUserIDJob * const j = backend->addUserIDJob();
- if ( !j )
- return;
-
- connect( j, SIGNAL(progress(QString,int,int)),
- q, SIGNAL(progress(QString,int,int)) );
- connect( j, SIGNAL(result(GpgME::Error)),
- q, SLOT(slotResult(GpgME::Error)) );
-
- job = j;
-}
-
-void AddUserIDCommand::Private::showErrorDialog( const Error & err ) {
- KMessageBox::error( view(),
- i18nc("@info",
- "<para>An error occurred while trying to add the user-id: "
- "<message>%1</message></para>",
- QString::fromLocal8Bit( err.asString() ) ),
- i18n("Add User-ID Error") );
-}
-
-void AddUserIDCommand::Private::showSuccessDialog() {
- KMessageBox::information( view(),
- i18n("User-ID successfully added."),
- i18n("Add User-ID Succeeded") );
-}
-
-#undef d
-#undef q
-
-#include "moc_adduseridcommand.cpp"
diff --git a/commands/adduseridcommand.h b/commands/adduseridcommand.h
index ebdab6d56..e69de29bb 100644
--- a/commands/adduseridcommand.h
+++ b/commands/adduseridcommand.h
@@ -1,76 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/adduseridcommand.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_COMMANDS_ADDUSERIDCOMMAND_H__
-#define __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__
-
-#include <commands/command.h>
-
-namespace Kleo {
-namespace Commands {
-
- class AddUserIDCommand : public Command {
- Q_OBJECT
- public:
- explicit AddUserIDCommand( QAbstractItemView * view, KeyListController * parent );
- explicit AddUserIDCommand( KeyListController * parent );
- explicit AddUserIDCommand( const GpgME::Key & key );
- ~AddUserIDCommand();
-
- /* reimp */ static Restrictions restrictions() { return OnlyOneKey|MustBeOpenPGP; }
-
- void setName( const QString & name );
- const QString & name() const;
-
- void setEmail( const QString & email );
- const QString & email() const;
-
- void setComment( const QString & comment );
- const QString & comment() const;
-
- private:
- /* reimp */ void doStart();
- /* reimp */ void doCancel();
-
- private:
- class Private;
- inline Private * d_func();
- inline const Private * d_func() const;
- Q_PRIVATE_SLOT( d_func(), void slotResult(GpgME::Error) )
- Q_PRIVATE_SLOT( d_func(), void slotDialogAccepted() )
- Q_PRIVATE_SLOT( d_func(), void slotDialogRejected() )
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMANDS_ADDUSERIDCOMMAND_H__
diff --git a/commands/certifycertificatecommand.cpp b/commands/certifycertificatecommand.cpp
index ceb8be9b0..e69de29bb 100644
--- a/commands/certifycertificatecommand.cpp
+++ b/commands/certifycertificatecommand.cpp
@@ -1,281 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/signcertificatecommand.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 Softwarls 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 "certifycertificatecommand.h"
-
-#include "command_p.h"
-
-#include "exportopenpgpcertstoservercommand.h"
-
-#include <dialogs/certifycertificatedialog.h>
-
-#include <models/keycache.h>
-
-#include <utils/formatting.h>
-
-#include <kleo/cryptobackendfactory.h>
-#include <kleo/cryptobackend.h>
-#include <kleo/signkeyjob.h>
-
-#include <gpgme++/key.h>
-
-#include <KLocale>
-#include <KMessageBox>
-#include <kdebug.h>
-
-#include <boost/bind.hpp>
-
-#include <cassert>
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace Kleo::Dialogs;
-using namespace GpgME;
-
-class CertifyCertificateCommand::Private : public Command::Private {
- friend class ::Kleo::Commands::CertifyCertificateCommand;
- CertifyCertificateCommand * q_func() const { return static_cast<CertifyCertificateCommand*>( q ); }
-public:
- explicit Private( CertifyCertificateCommand * qq, KeyListController * c );
- ~Private();
-
- void init();
-
-private:
- void slotDialogRejected();
- void slotResult( const Error & err );
- void slotCertificationPrepared();
-
-private:
- void ensureDialogCreated();
- void createJob();
-
-private:
- std::vector<UserID> uids;
- QPointer<CertifyCertificateDialog> dialog;
- QPointer<SignKeyJob> job;
-};
-
-
-CertifyCertificateCommand::Private * CertifyCertificateCommand::d_func() { return static_cast<Private*>( d.get() ); }
-const CertifyCertificateCommand::Private * CertifyCertificateCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
-
-#define d d_func()
-#define q q_func()
-
-CertifyCertificateCommand::Private::Private( CertifyCertificateCommand * qq, KeyListController * c )
- : Command::Private( qq, c ),
- uids(),
- dialog(),
- job()
-{
-
-}
-
-CertifyCertificateCommand::Private::~Private() { kDebug(); }
-
-CertifyCertificateCommand::CertifyCertificateCommand( KeyListController * c )
- : Command( new Private( this, c ) )
-{
- d->init();
-}
-
-CertifyCertificateCommand::CertifyCertificateCommand( QAbstractItemView * v, KeyListController * c )
- : Command( v, new Private( this, c ) )
-{
- d->init();
-}
-
-CertifyCertificateCommand::CertifyCertificateCommand( const Key & key )
- : Command( key, new Private( this, 0 ) )
-{
- d->init();
-}
-
-CertifyCertificateCommand::CertifyCertificateCommand( const UserID & uid )
- : Command( uid.parent(), new Private( this, 0 ) )
-{
- std::vector<UserID>( 1, uid ).swap( d->uids );
- d->init();
-}
-
-CertifyCertificateCommand::CertifyCertificateCommand( const std::vector<UserID> & uids )
- : Command( uids.empty() ? Key() : uids.front().parent(), new Private( this, 0 ) )
-{
- d->uids = uids;
- d->init();
-}
-
-void CertifyCertificateCommand::Private::init() {
-
-}
-
-CertifyCertificateCommand::~CertifyCertificateCommand() { kDebug(); }
-
-void CertifyCertificateCommand::setCertificationExportable( bool on ) {
-
-}
-
-void CertifyCertificateCommand::setCertificationRevocable( bool on ) {
-
-}
-
-void CertifyCertificateCommand::setCertifyingKey( const Key & signer ) {
-
-}
-
-void CertifyCertificateCommand::setUserIDs( const std::vector<UserID> & uids ) {
- d->uids = uids;
- if ( !uids.empty() && d->key().isNull() )
- setKey( uids.front().parent() );
-}
-
-void CertifyCertificateCommand::setUserID( const UserID & uid ) {
- setUserIDs( std::vector<UserID>( 1, uid ) );
-}
-
-void CertifyCertificateCommand::doStart() {
-
- const std::vector<Key> keys = d->keys();
- if ( keys.size() != 1 ||
- keys.front().protocol() != GpgME::OpenPGP ) {
- d->finished();
- return;
- }
-
- std::vector<Key> secKeys = KeyCache::instance()->secretKeys();
- std::vector<Key>::iterator it = std::remove_if( secKeys.begin(), secKeys.end(), !bind( &Key::canCertify, _1 ) );
- it = std::remove_if( it, secKeys.end(), bind( &Key::protocol, _1 ) != OpenPGP );
- secKeys.erase( it, secKeys.end() );
-
- if ( secKeys.empty() ) {
- KMessageBox::error( d->view(),
- i18n( "To certify other certificates, you first need to create an OpenPGP certificate for yourself. Choose <interface>File->New Certificate...</interface> to create one." ),
- i18n( "Certification Not Possible" ) );
- d->finished();
- return;
- }
- const Key & key = keys.front();
-
- Q_FOREACH( const UserID & uid, d->uids )
- if ( qstricmp( uid.parent().primaryFingerprint(), key.primaryFingerprint() ) != 0 ) {
- kWarning() << "User-ID <-> Key mismatch!";
- d->finished();
- return;
- }
-
- d->ensureDialogCreated();
- assert( d->dialog );
- d->dialog->setCertificateToCertify( d->key() );
- d->dialog->setCertificatesWithSecretKeys( secKeys );
- d->dialog->show();
-}
-
-void CertifyCertificateCommand::Private::slotDialogRejected() {
- emit q->canceled();
- finished();
-}
-
-void CertifyCertificateCommand::Private::slotResult( const Error & err ) {
- if ( !err && !err.isCanceled() && dialog && dialog->exportableCertificationSelected() && dialog->sendToServer() ) {
- ExportOpenPGPCertsToServerCommand * const cmd = new ExportOpenPGPCertsToServerCommand( key() );
- cmd->start();
- }
-
- finished();
-}
-
-void CertifyCertificateCommand::Private::slotCertificationPrepared() {
- assert( dialog );
-
- createJob();
- assert( job );
- job->setExportable( dialog->exportableCertificationSelected() );
- job->setNonRevocable( dialog->nonRevocableCertificationSelected() );
- job->setUserIDsToSign( dialog->selectedUserIDs() );
- job->setSigningKey( dialog->selectedSecretKey() );
- job->setCheckLevel( dialog->selectedCheckLevel() );
-
- dialog->connectJob( job );
-
- if ( const Error err = job->start( key() ) ) {
- dialog->setError( err );
- finished();
- }
-}
-
-void CertifyCertificateCommand::doCancel() {
- kDebug();
- if ( d->job )
- d->job->slotCancel();
-}
-
-void CertifyCertificateCommand::Private::ensureDialogCreated() {
- if ( dialog )
- return;
-
- dialog = new CertifyCertificateDialog( view() );
- dialog->setAttribute( Qt::WA_DeleteOnClose );
-
- connect( dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()) );
- connect( dialog, SIGNAL(certificationPrepared()), q, SLOT(slotCertificationPrepared()) );
-}
-
-void CertifyCertificateCommand::Private::createJob() {
- if ( dialog )
- disconnect( dialog, SIGNAL(certificationPrepared()), q, SLOT(slotCertificationPrepared()) );
-
- assert( !job );
-
- assert( key().protocol() == OpenPGP );
- const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( key().protocol() );
- if ( !backend )
- return;
-
- SignKeyJob * const j = backend->signKeyJob();
- if ( !j )
- return;
-
- connect( j, SIGNAL(progress(QString,int,int)),
- q, SIGNAL(progress(QString,int,int)) );
- connect( j, SIGNAL(result(GpgME::Error)),
- q, SLOT(slotResult(GpgME::Error)) );
-
- job = j;
-}
-
-
-#undef d
-#undef q
-
-#include "moc_certifycertificatecommand.cpp"
diff --git a/commands/certifycertificatecommand.h b/commands/certifycertificatecommand.h
index 0fc1eabff..e69de29bb 100644
--- a/commands/certifycertificatecommand.h
+++ b/commands/certifycertificatecommand.h
@@ -1,81 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/signcertificatecommand.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_COMMANDS_SIGNCERTIFICATECOMMAND_H__
-#define __KLEOPATRA_COMMANDS_SIGNCERTIFICATECOMMAND_H__
-
-#include <commands/command.h>
-
-namespace GpgME {
- class UserID;
-}
-
-namespace Kleo {
-namespace Commands {
-
- class CertifyCertificateCommand : public Command {
- Q_OBJECT
- public:
- explicit CertifyCertificateCommand( QAbstractItemView * view, KeyListController * parent );
- explicit CertifyCertificateCommand( KeyListController * parent );
- explicit CertifyCertificateCommand( const GpgME::Key & key );
- explicit CertifyCertificateCommand( const GpgME::UserID & uid );
- explicit CertifyCertificateCommand( const std::vector<GpgME::UserID> & uids );
- ~CertifyCertificateCommand();
-
- /* reimp */ static Restrictions restrictions() { return OnlyOneKey|MustBeOpenPGP; }
-
- void setCertificationExportable( bool on );
- void setCertificationRevocable( bool on );
-
- void setCertifyingKey( const GpgME::Key & key );
-
- void setUserID( const GpgME::UserID & uid );
- void setUserIDs( const std::vector<GpgME::UserID> & uids );
-
- private:
- /* reimp */ void doStart();
- /* reimp */ void doCancel();
-
- private:
- class Private;
- inline Private * d_func();
- inline const Private * d_func() const;
- Q_PRIVATE_SLOT( d_func(), void slotResult(GpgME::Error) )
- Q_PRIVATE_SLOT( d_func(), void slotDialogRejected() )
- Q_PRIVATE_SLOT( d_func(), void slotCertificationPrepared() )
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMANDS_SIGNCERTIFICATECOMMAND_H__
diff --git a/commands/changeexpirycommand.cpp b/commands/changeexpirycommand.cpp
index 82846796a..14e67c5cc 100644
--- a/commands/changeexpirycommand.cpp
+++ b/commands/changeexpirycommand.cpp
@@ -1,238 +1,231 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeexpirycommand.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 "changeexpirycommand.h"
#include "command_p.h"
#include <dialogs/expirydialog.h>
#include <utils/formatting.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/cryptobackend.h>
#include <kleo/changeexpiryjob.h>
#include <gpgme++/key.h>
#include <KLocale>
#include <KMessageBox>
#include <kdebug.h>
#include <QDateTime>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
class ChangeExpiryCommand::Private : public Command::Private {
friend class ::Kleo::Commands::ChangeExpiryCommand;
ChangeExpiryCommand * q_func() const { return static_cast<ChangeExpiryCommand*>( q ); }
public:
explicit Private( ChangeExpiryCommand * qq, KeyListController * c );
~Private();
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult( const Error & err );
private:
void ensureDialogCreated();
void createJob();
void showErrorDialog( const Error & error );
void showSuccessDialog();
private:
GpgME::Key key;
QPointer<ExpiryDialog> dialog;
QPointer<ChangeExpiryJob> job;
};
ChangeExpiryCommand::Private * ChangeExpiryCommand::d_func() { return static_cast<Private*>( d.get() ); }
const ChangeExpiryCommand::Private * ChangeExpiryCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
ChangeExpiryCommand::Private::Private( ChangeExpiryCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
key(),
dialog(),
job()
{
}
ChangeExpiryCommand::Private::~Private() { kDebug(); }
ChangeExpiryCommand::ChangeExpiryCommand( KeyListController * c )
: Command( new Private( this, c ) )
{
d->init();
}
ChangeExpiryCommand::ChangeExpiryCommand( QAbstractItemView * v, KeyListController * c )
: Command( v, new Private( this, c ) )
{
d->init();
}
-ChangeExpiryCommand::ChangeExpiryCommand( const GpgME::Key & key )
- : Command( key, new Private( this, 0 ) )
-{
- d->init();
-}
-
void ChangeExpiryCommand::Private::init() {
}
ChangeExpiryCommand::~ChangeExpiryCommand() { kDebug(); }
void ChangeExpiryCommand::doStart() {
const std::vector<Key> keys = d->keys();
if ( keys.size() != 1 ||
keys.front().protocol() != GpgME::OpenPGP ||
!keys.front().hasSecret() ||
keys.front().subkey(0).isNull() ) {
d->finished();
return;
}
d->key = keys.front();
d->ensureDialogCreated();
assert( d->dialog );
const Subkey subkey = d->key.subkey(0);
d->dialog->setDateOfExpiry( subkey.neverExpires() ? QDate() : QDateTime::fromTime_t( d->key.subkey(0).expirationTime() ).date() );
d->dialog->show();
}
void ChangeExpiryCommand::Private::slotDialogAccepted() {
assert( dialog );
static const QTime END_OF_DAY( 23, 59, 59 ); // not used, so as good as any
const QDateTime expiry( dialog->dateOfExpiry(), END_OF_DAY );
kDebug() << "expiry" << expiry;
createJob();
assert( job );
if ( const Error err = job->start( key, expiry ) ) {
showErrorDialog( err );
finished();
}
}
void ChangeExpiryCommand::Private::slotDialogRejected() {
emit q->canceled();
finished();
}
void ChangeExpiryCommand::Private::slotResult( const Error & err ) {
if ( err.isCanceled() )
- ;
+ finished();
else if ( err )
showErrorDialog( err );
else
showSuccessDialog();
- finished();
}
void ChangeExpiryCommand::doCancel() {
kDebug();
if ( d->job )
d->job->slotCancel();
}
void ChangeExpiryCommand::Private::ensureDialogCreated() {
if ( dialog )
return;
dialog = new ExpiryDialog( view() );
dialog->setAttribute( Qt::WA_DeleteOnClose );
connect( dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted()) );
connect( dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()) );
}
void ChangeExpiryCommand::Private::createJob() {
assert( !job );
const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( key.protocol() );
if ( !backend )
return;
ChangeExpiryJob * const j = backend->changeExpiryJob();
if ( !j )
return;
connect( j, SIGNAL(progress(QString,int,int)),
q, SIGNAL(progress(QString,int,int)) );
connect( j, SIGNAL(result(GpgME::Error)),
q, SLOT(slotResult(GpgME::Error)) );
job = j;
}
void ChangeExpiryCommand::Private::showErrorDialog( const Error & err ) {
KMessageBox::error( view(),
i18n("<p>An error occurred while trying to change "
"the expiry date for <b>%1</b>:</p><p>%2</p>",
Formatting::formatForComboBox( key ),
QString::fromLocal8Bit( err.asString() ) ),
i18n("Expiry Date Change Error") );
}
void ChangeExpiryCommand::Private::showSuccessDialog() {
KMessageBox::information( view(),
i18n("Expiry date changed successfully."),
i18n("Expiry Date Change Succeeded") );
}
#undef d
#undef q
#include "moc_changeexpirycommand.cpp"
diff --git a/commands/changeexpirycommand.h b/commands/changeexpirycommand.h
index e5ad7e8e5..775d1ac27 100644
--- a/commands/changeexpirycommand.h
+++ b/commands/changeexpirycommand.h
@@ -1,67 +1,66 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeexpirycommand.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_COMMMANDS_CHANGEEXPIRYCOMMAND_H__
#define __KLEOPATRA_COMMMANDS_CHANGEEXPIRYCOMMAND_H__
#include <commands/command.h>
namespace Kleo {
namespace Commands {
class ChangeExpiryCommand : public Command {
Q_OBJECT
public:
explicit ChangeExpiryCommand( QAbstractItemView * view, KeyListController * parent );
explicit ChangeExpiryCommand( KeyListController * parent );
- explicit ChangeExpiryCommand( const GpgME::Key & key );
~ChangeExpiryCommand();
/* reimp */ static Restrictions restrictions() { return OnlyOneKey|MustBeOpenPGP|NeedSecretKey; }
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
Q_PRIVATE_SLOT( d_func(), void slotResult(GpgME::Error) )
Q_PRIVATE_SLOT( d_func(), void slotDialogAccepted() )
Q_PRIVATE_SLOT( d_func(), void slotDialogRejected() )
};
}
}
#endif // __KLEOPATRA_COMMMANDS_CHANGEEXPIRYCOMMAND_H__
diff --git a/commands/changeownertrustcommand.cpp b/commands/changeownertrustcommand.cpp
index c724a9198..f3dc4a8ee 100644
--- a/commands/changeownertrustcommand.cpp
+++ b/commands/changeownertrustcommand.cpp
@@ -1,237 +1,227 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeexpirycommand.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 "changeownertrustcommand.h"
#include "command_p.h"
#include <dialogs/ownertrustdialog.h>
#include <utils/formatting.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/cryptobackend.h>
#include <kleo/changeownertrustjob.h>
#include <gpgme++/key.h>
#include <KLocale>
#include <KMessageBox>
#include <kdebug.h>
#include <QDateTime>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
class ChangeOwnerTrustCommand::Private : public Command::Private {
friend class ::Kleo::Commands::ChangeOwnerTrustCommand;
ChangeOwnerTrustCommand * q_func() const { return static_cast<ChangeOwnerTrustCommand*>( q ); }
public:
explicit Private( ChangeOwnerTrustCommand * qq, KeyListController * c );
~Private();
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult( const Error & err );
private:
void ensureDialogCreated();
void createJob();
void showErrorDialog( const Error & error );
void showSuccessDialog();
private:
+ GpgME::Key key;
QPointer<OwnerTrustDialog> dialog;
QPointer<ChangeOwnerTrustJob> job;
};
ChangeOwnerTrustCommand::Private * ChangeOwnerTrustCommand::d_func() { return static_cast<Private*>( d.get() ); }
const ChangeOwnerTrustCommand::Private * ChangeOwnerTrustCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
ChangeOwnerTrustCommand::Private::Private( ChangeOwnerTrustCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
+ key(),
dialog(),
job()
{
}
ChangeOwnerTrustCommand::Private::~Private() { kDebug(); }
ChangeOwnerTrustCommand::ChangeOwnerTrustCommand( KeyListController * c )
: Command( new Private( this, c ) )
{
d->init();
}
ChangeOwnerTrustCommand::ChangeOwnerTrustCommand( QAbstractItemView * v, KeyListController * c )
: Command( v, new Private( this, c ) )
{
d->init();
}
-ChangeOwnerTrustCommand::ChangeOwnerTrustCommand( const Key & key )
- : Command( key, new Private( this, 0 ) )
-{
- d->init();
-}
-
void ChangeOwnerTrustCommand::Private::init() {
}
ChangeOwnerTrustCommand::~ChangeOwnerTrustCommand() { kDebug(); }
void ChangeOwnerTrustCommand::doStart() {
- if ( d->keys().size() != 1 ) {
+ const std::vector<Key> keys = d->keys();
+ if ( keys.size() != 1 ||
+ keys.front().protocol() != GpgME::OpenPGP ||
+ keys.front().hasSecret() ) {
d->finished();
return;
}
- const Key key = d->key();
- if ( key.protocol() != GpgME::OpenPGP || key.hasSecret() && key.ownerTrust() == Key::Ultimate ) {
- d->finished();
- return;
- }
+ d->key = keys.front();
d->ensureDialogCreated();
assert( d->dialog );
-
- d->dialog->setHasSecretKey( key.hasSecret() );
- d->dialog->setFormattedCertificateName( Formatting::formatForComboBox( key ) );
- d->dialog->setOwnerTrust( key.ownerTrust() );
-
+ d->dialog->setOwnerTrust( d->key.ownerTrust() );
d->dialog->show();
}
void ChangeOwnerTrustCommand::Private::slotDialogAccepted() {
assert( dialog );
const Key::OwnerTrust trust = dialog->ownerTrust();
kDebug() << "trust " << trust;
createJob();
assert( job );
- if ( const Error err = job->start( key(), trust ) ) {
+ if ( const Error err = job->start( key, trust ) ) {
showErrorDialog( err );
finished();
}
}
void ChangeOwnerTrustCommand::Private::slotDialogRejected() {
emit q->canceled();
finished();
}
void ChangeOwnerTrustCommand::Private::slotResult( const Error & err ) {
if ( err.isCanceled() )
- ;
+ finished();
else if ( err )
showErrorDialog( err );
else
showSuccessDialog();
- finished();
}
void ChangeOwnerTrustCommand::doCancel() {
kDebug();
if ( d->job )
d->job->slotCancel();
}
void ChangeOwnerTrustCommand::Private::ensureDialogCreated() {
if ( dialog )
return;
dialog = new OwnerTrustDialog( view() );
dialog->setAttribute( Qt::WA_DeleteOnClose );
connect( dialog, SIGNAL(accepted()), q, SLOT(slotDialogAccepted()) );
connect( dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()) );
}
void ChangeOwnerTrustCommand::Private::createJob() {
assert( !job );
- const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( key().protocol() );
+ const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( key.protocol() );
if ( !backend )
return;
ChangeOwnerTrustJob * const j = backend->changeOwnerTrustJob();
if ( !j )
return;
connect( j, SIGNAL(progress(QString,int,int)),
q, SIGNAL(progress(QString,int,int)) );
connect( j, SIGNAL(result(GpgME::Error)),
q, SLOT(slotResult(GpgME::Error)) );
job = j;
}
void ChangeOwnerTrustCommand::Private::showErrorDialog( const Error & err ) {
KMessageBox::error( view(),
i18n("<p>An error occurred while trying to change "
"the owner trust for <b>%1</b>:</p><p>%2</p>",
- Formatting::formatForComboBox( key() ),
+ Formatting::formatForComboBox( key ),
QString::fromLocal8Bit( err.asString() ) ),
i18n("Owner Trust Change Error") );
}
void ChangeOwnerTrustCommand::Private::showSuccessDialog() {
KMessageBox::information( view(),
i18n("Owner trust changed successfully."),
i18n("Owner Trust Change Succeeded") );
}
#undef d
#undef q
#include "moc_changeownertrustcommand.cpp"
diff --git a/commands/changeownertrustcommand.h b/commands/changeownertrustcommand.h
index b4ad21f8c..3961fd68c 100644
--- a/commands/changeownertrustcommand.h
+++ b/commands/changeownertrustcommand.h
@@ -1,67 +1,66 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeownertrustcommand.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_COMMMANDS_CHANGEOWNERTRUSTCOMMAND_H__
#define __KLEOPATRA_COMMMANDS_CHANGEOWNERTRUSTCOMMAND_H__
#include <commands/command.h>
namespace Kleo {
namespace Commands {
class ChangeOwnerTrustCommand : public Command {
Q_OBJECT
public:
explicit ChangeOwnerTrustCommand( QAbstractItemView * view, KeyListController * parent );
explicit ChangeOwnerTrustCommand( KeyListController * parent );
- explicit ChangeOwnerTrustCommand( const GpgME::Key & key );
~ChangeOwnerTrustCommand();
- /* reimp */ static Restrictions restrictions() { return OnlyOneKey|MustBeOpenPGP|MayOnlyBeSecretKeyIfOwnerTrustIsNotYetUltimate; }
+ /* reimp */ static Restrictions restrictions() { return OnlyOneKey|MustBeOpenPGP; }
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
Q_PRIVATE_SLOT( d_func(), void slotResult(GpgME::Error) )
Q_PRIVATE_SLOT( d_func(), void slotDialogAccepted() )
Q_PRIVATE_SLOT( d_func(), void slotDialogRejected() )
};
}
}
#endif // __KLEOPATRA_COMMMANDS_CHANGEOWNERTRUSTCOMMAND_H__
diff --git a/commands/changepassphrasecommand.cpp b/commands/changepassphrasecommand.cpp
index f30aa0b75..e69de29bb 100644
--- a/commands/changepassphrasecommand.cpp
+++ b/commands/changepassphrasecommand.cpp
@@ -1,104 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/changepassphrasecommand.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 "changepassphrasecommand.h"
-
-#include "command_p.h"
-
-#include <utils/gnupg-helper.h>
-
-#include <gpgme++/key.h>
-
-#include <KLocale>
-#include <KMessageBox>
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace GpgME;
-
-ChangePassphraseCommand::ChangePassphraseCommand( KeyListController * c )
- : GnuPGProcessCommand( c )
-{
-
-}
-
-ChangePassphraseCommand::ChangePassphraseCommand( QAbstractItemView * v, KeyListController * c )
- : GnuPGProcessCommand( v, c )
-{
-
-}
-
-ChangePassphraseCommand::ChangePassphraseCommand( const Key & key )
- : GnuPGProcessCommand( key )
-{
-
-}
-
-ChangePassphraseCommand::~ChangePassphraseCommand() {}
-
-QStringList ChangePassphraseCommand::arguments() const {
- const Key key = d->key();
- if ( key.protocol() == OpenPGP )
- return QStringList() << gpgPath() << "--edit-key" << key.primaryFingerprint() << "passwd";
- else
- return QStringList() << gpgSmPath() << "--passwd" << key.primaryFingerprint();
-}
-
-QString ChangePassphraseCommand::errorCaption() const {
- return i18n( "Passphrase Change Error" );
-}
-
-QString ChangePassphraseCommand::successCaption() const {
- return i18n( "Passphrase Change Finished" );
-}
-
-QString ChangePassphraseCommand::crashExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>The GPG or GpgSM process that tried to change the passphrase "
- "ended prematurely because of an unexpected error.</para>"
- "<para>Please check the output of <icode>%1</icode> for details.</para>", args.join( " " ) ) ;
-}
-
-QString ChangePassphraseCommand::errorExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>An error occurred while trying to change the passphrase.</para> "
- "<para>The output from <command>%1</command> was: <message>%2</message></para>",
- args[0], errorString() );
-}
-
-QString ChangePassphraseCommand::successMessage( const QStringList & ) const {
- return i18n( "Passphrase changed successfully." );
-}
-
-#include "moc_changepassphrasecommand.cpp"
diff --git a/commands/changepassphrasecommand.h b/commands/changepassphrasecommand.h
index 15f55e80b..e69de29bb 100644
--- a/commands/changepassphrasecommand.h
+++ b/commands/changepassphrasecommand.h
@@ -1,67 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/changepassphrasecommand.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_COMMMANDS_CHANGEPASSPHRASECOMMAND_H__
-#define __KLEOPATRA_COMMMANDS_CHANGEPASSPHRASECOMMAND_H__
-
-#include <commands/gnupgprocesscommand.h>
-
-namespace Kleo {
-namespace Commands {
-
- class ChangePassphraseCommand : public GnuPGProcessCommand {
- Q_OBJECT
- public:
- explicit ChangePassphraseCommand( QAbstractItemView * view, KeyListController * parent );
- explicit ChangePassphraseCommand( KeyListController * parent );
- explicit ChangePassphraseCommand( const GpgME::Key & key );
- ~ChangePassphraseCommand();
-
- /* reimp */ static Restrictions restrictions() { return OnlyOneKey; }
-
- private:
- //* reimp */ bool preStartHook( QWidget * ) const;
-
- /* reimp */ QStringList arguments() const;
-
- /* reimp */ QString errorCaption() const;
- /* reimp */ QString successCaption() const;
-
- /* reimp */ QString crashExitMessage( const QStringList & ) const;
- /* reimp */ QString errorExitMessage( const QStringList & ) const;
- /* reimp */ QString successMessage( const QStringList & ) const;
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMMANDS_CHANGEPASSPHRASECOMMAND_H__
diff --git a/commands/command.cpp b/commands/command.cpp
index 59ef30721..af925ff5e 100644
--- a/commands/command.cpp
+++ b/commands/command.cpp
@@ -1,190 +1,146 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/command.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 "command.h"
#include "command_p.h"
#include <view/tabwidget.h>
#include <kdebug.h>
#include <QAbstractItemView>
using namespace Kleo;
-using namespace GpgME;
Command::Private::Private( Command * qq, KeyListController * controller )
: q( qq ),
autoDelete( true ),
- warnWhenRunningAtShutdown( true ),
indexes_(),
view_(),
controller_( controller )
{
}
Command::Private::~Private() { kDebug(); }
Command::Command( KeyListController * p )
: QObject( p ), d( new Private( this, p ) )
{
if ( p )
p->registerCommand( this );
}
Command::Command( QAbstractItemView * v, KeyListController * p )
: QObject( p ), d( new Private( this, p ) )
{
if ( p )
p->registerCommand( this );
if ( v )
setView( v );
}
Command::Command( Private * pp )
: QObject( pp->controller_ ), d( pp )
{
if ( pp->controller_ )
pp->controller_->registerCommand( this );
}
Command::Command( QAbstractItemView * v, Private * pp )
: QObject( pp->controller_ ), d( pp )
{
if ( pp->controller_ )
pp->controller_->registerCommand( this );
if ( v )
setView( v );
}
-Command::Command( const Key & key )
- : QObject( 0 ), d( new Private( this, 0 ) )
-{
- d->keys_ = std::vector<Key>( 1, key );
-}
-
-Command::Command( const std::vector<Key> & keys )
- : QObject( 0 ), d( new Private( this, 0 ) )
-{
- d->keys_ = keys;
-}
-
-Command::Command( const Key & key, Private * pp )
- : QObject( 0 ), d( pp )
-{
- d->keys_ = std::vector<Key>( 1, key );
-}
-
-Command::Command( const std::vector<Key> & keys, Private * pp )
- : QObject( 0 ), d( pp )
-{
- d->keys_ = keys;
-}
-
Command::~Command() { kDebug(); }
void Command::setAutoDelete( bool on ) {
d->autoDelete = on;
}
bool Command::autoDelete() const {
return d->autoDelete;
}
-void Command::setWarnWhenRunningAtShutdown( bool on ) {
- d->warnWhenRunningAtShutdown = on;
-}
-
-bool Command::warnWhenRunningAtShutdown() const {
- return d->warnWhenRunningAtShutdown;
-}
-
void Command::setView( QAbstractItemView * view ) {
if ( view == d->view_ )
return;
d->view_ = view;
if ( !view || !d->indexes_.empty() )
return;
const QItemSelectionModel * const sm = view->selectionModel();
if ( !sm ) {
qWarning( "Command::setView: view %p has no selectionModel!", view );
return;
}
const QList<QModelIndex> selected = sm->selectedRows();
if ( !selected.empty() ) {
std::copy( selected.begin(), selected.end(), std::back_inserter( d->indexes_ ) );
return;
}
}
void Command::setIndex( const QModelIndex & idx ) {
d->indexes_.clear();
d->indexes_.push_back( idx );
}
void Command::setIndexes( const QList<QModelIndex> & idx ) {
d->indexes_.clear();
std::copy( idx.begin(), idx.end(), std::back_inserter( d->indexes_ ) );
}
-void Command::setKey( const Key & key ) {
- d->keys_.clear();
- if ( !key.isNull() )
- d->keys_.push_back( key );
-}
-
-void Command::setKeys( const std::vector<Key> & keys ) {
- d->keys_ = keys;
-}
-
void Command::start() {
doStart();
}
void Command::cancel() {
kDebug();
doCancel();
emit canceled();
}
void Command::addTemporaryView( const QString & title ) {
if ( TabWidget * const tw = d->controller_ ? d->controller_->tabWidget() : 0 )
if ( QAbstractItemView * const v = tw->addTemporaryView( title ) )
setView( v );
}
//#include "moc_command.cpp"
#include "command.moc" // the above clashes with libkleopatra/core/command.cpp, since CMake/Automoc4 is too stupid to handle that situation
diff --git a/commands/command.h b/commands/command.h
index 1a63764c9..1c8b7e443 100644
--- a/commands/command.h
+++ b/commands/command.h
@@ -1,126 +1,106 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/command.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_COMMANDS_COMMAND_H__
#define __KLEOPATRA_COMMANDS_COMMAND_H__
#include <QObject>
#include <utils/pimpl_ptr.h>
-#include <vector>
-
class QModelIndex;
template <typename T> class QList;
class QAbstractItemView;
-namespace GpgME {
- class Key;
-}
-
namespace Kleo {
class KeyListController;
class Command : public QObject {
Q_OBJECT
public:
explicit Command( KeyListController * parent );
explicit Command( QAbstractItemView * view, KeyListController * parent );
- explicit Command( const GpgME::Key & key );
- explicit Command( const std::vector<GpgME::Key> & keys );
~Command();
enum Restriction {
NoRestriction = 0,
NeedSelection = 1,
OnlyOneKey = 2,
NeedSecretKey = 4,
MustNotBeSecretKey = 8,
MustBeOpenPGP = 16,
MustBeCMS = 32,
- // esoteric:
- MayOnlyBeSecretKeyIfOwnerTrustIsNotYetUltimate = 64, // for set-owner-trust
-
- _AllRestrictions_Helper,
- AllRestrictions = 2*(_AllRestrictions_Helper-1) - 1
+ AllRestrictions
};
-
Q_DECLARE_FLAGS( Restrictions, Restriction )
static Restrictions restrictions() { return NoRestriction; }
void setView( QAbstractItemView * view );
void setIndex( const QModelIndex & idx );
void setIndexes( const QList<QModelIndex> & idx );
- void setKey( const GpgME::Key & key );
- void setKeys( const std::vector<GpgME::Key> & keys );
void setAutoDelete( bool on );
bool autoDelete() const;
- void setWarnWhenRunningAtShutdown( bool warn );
- bool warnWhenRunningAtShutdown() const;
-
public Q_SLOTS:
void start();
void cancel();
Q_SIGNALS:
void info( const QString & message, int timeout = 0 );
void progress( const QString & message, int current, int total );
void finished();
void canceled();
private:
virtual void doStart() = 0;
virtual void doCancel() = 0;
protected:
void addTemporaryView( const QString & title );
protected:
class Private;
kdtools::pimpl_ptr<Private> d;
protected:
explicit Command( Private * pp );
explicit Command( QAbstractItemView * view, Private * pp );
- explicit Command( const std::vector<GpgME::Key> & keys, Private * pp );
- explicit Command( const GpgME::Key & key, Private * pp );
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS( Kleo::Command::Restrictions )
#endif /* __KLEOPATRA_COMMANDS_COMMAND_H__ */
diff --git a/commands/command_p.h b/commands/command_p.h
index 142ac9150..075cd34dd 100644
--- a/commands/command_p.h
+++ b/commands/command_p.h
@@ -1,89 +1,87 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/command_p.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_COMMANDS_COMMAND_P_H__
#define __KLEOPATRA_COMMANDS_COMMAND_P_H__
#include "command.h"
#include "view/keylistcontroller.h"
#include "models/keylistmodel.h"
#include <QAbstractItemView>
#include <QPointer>
#include <QList>
#include <QModelIndex>
#include <gpgme++/key.h>
#include <algorithm>
#include <iterator>
class Kleo::Command::Private {
friend class ::Kleo::Command;
protected:
Command * const q;
public:
explicit Private( Command * qq, KeyListController * controller );
virtual ~Private();
QAbstractItemView * view() const { return view_; }
KeyListModelInterface * model() const { return view_ ? dynamic_cast<KeyListModelInterface*>( view_->model() ) : 0 ; }
KeyListController * controller() const { return controller_; }
QList<QModelIndex> indexes() const {
QList<QModelIndex> result;
std::copy( indexes_.begin(), indexes_.end(), std::back_inserter( result ) );
return result;
}
- GpgME::Key key() const { return keys_.empty() ? model() && !indexes_.empty() ? model()->key( indexes_.front() ) : GpgME::Key::null : keys_.front() ; }
- std::vector<GpgME::Key> keys() const { return keys_.empty() ? model() ? model()->keys( indexes() ) : std::vector<GpgME::Key>() : keys_ ; }
+ GpgME::Key key() const { return model() && !indexes_.empty() ? model()->key( indexes_.front() ) : GpgME::Key::null ; }
+ std::vector<GpgME::Key> keys() const { return model() ? model()->keys( indexes() ) : std::vector<GpgME::Key>() ; }
void finished() {
emit q->finished();
if ( autoDelete )
q->deleteLater();
}
void canceled() {
emit q->canceled();
finished();
}
private:
bool autoDelete : 1;
- bool warnWhenRunningAtShutdown : 1;
- std::vector<GpgME::Key> keys_;
QList<QPersistentModelIndex> indexes_;
QPointer<QAbstractItemView> view_;
QPointer<KeyListController> controller_;
};
#endif /* __KLEOPATRA_COMMANDS_COMMAND_P_H__ */
diff --git a/commands/detailscommand.cpp b/commands/detailscommand.cpp
index cda26864d..ee474920a 100644
--- a/commands/detailscommand.cpp
+++ b/commands/detailscommand.cpp
@@ -1,164 +1,131 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/detailscommand.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 "detailscommand.h"
#include "command_p.h"
-#include <dialogs/certificatedetailsdialog.h>
+#include "../certificateinfowidgetimpl.h"
+
+#include <KDialog>
+
+#include <QAbstractItemView>
#include <cassert>
using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace Kleo::Dialogs;
+//using namespace Kleo::Commands;
using namespace GpgME;
class DetailsCommand::Private : public Command::Private {
- friend class ::Kleo::Commands::DetailsCommand;
+ friend class ::DetailsCommand;
DetailsCommand * q_func() const { return static_cast<DetailsCommand*>( q ); }
public:
explicit Private( DetailsCommand * qq, KeyListController * c );
~Private();
-private:
- void ensureDialogCreated() {
- if ( dialog )
- return;
-
- CertificateDetailsDialog * dlg = new CertificateDetailsDialog( view() );
- dlg->setAttribute( Qt::WA_DeleteOnClose );
- connect( dlg, SIGNAL(rejected()), q, SLOT(slotDialogClosed()) );
-
- dialog = dlg;
- }
-
- void ensureDialogVisible() {
- ensureDialogCreated();
- if ( dialog->isVisible() )
- dialog->raise();
- else
- dialog->show();
- }
-
- void init() {
- q->setWarnWhenRunningAtShutdown( false );
- }
+ void init();
private:
- void slotDialogClosed();
-
-private:
- QPointer<CertificateDetailsDialog> dialog;
+ Key key;
};
DetailsCommand::Private * DetailsCommand::d_func() { return static_cast<Private*>( d.get() ); }
const DetailsCommand::Private * DetailsCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define q q_func()
#define d d_func()
DetailsCommand::Private::Private( DetailsCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
- dialog()
+ key()
{
}
DetailsCommand::Private::~Private() {}
DetailsCommand::DetailsCommand( KeyListController * p )
: Command( new Private( this, p ) )
{
- d->init();
+
}
DetailsCommand::DetailsCommand( QAbstractItemView * v, KeyListController * p )
: Command( v, new Private( this, p ) )
{
- d->init();
+
}
DetailsCommand::DetailsCommand( const Key & key, KeyListController * p )
: Command( new Private( this, p ) )
{
assert( !key.isNull() );
- d->init();
- setKey( key );
+ d->key = key;
}
DetailsCommand::DetailsCommand( const Key & key, QAbstractItemView * v, KeyListController * p )
: Command( v, new Private( this, p ) )
{
assert( !key.isNull() );
- d->init();
- setKey( key );
+ d->key = key;
}
DetailsCommand::~DetailsCommand() {}
void DetailsCommand::doStart() {
- const std::vector<Key> keys = d->keys();
Key key;
- if ( keys.size() == 1 )
- key = keys.front();
+ if ( !d->key.isNull() )
+ key = d->key;
+ else if ( d->indexes().size() == 1 )
+ key = d->Command::Private::key();
else
qWarning( "DetailsCommand::doStart: can only work with one certificate at a time" );
- if ( key.isNull() ) {
- d->finished();
- return;
+ if ( !key.isNull() ) {
+ KDialog * const dlg = CertificateInfoWidgetImpl::createDialog( key, d->view() );
+ assert( dlg );
+ dlg->setAttribute( Qt::WA_DeleteOnClose );
+ dlg->show();
}
- d->ensureDialogCreated();
-
- d->dialog->setKey( key );
-
- d->ensureDialogVisible();
+ d->finished();
}
-void DetailsCommand::doCancel() {
- if ( d->dialog )
- d->dialog->close();
-}
-
-void DetailsCommand::Private::slotDialogClosed() {
- finished();
-}
-
+void DetailsCommand::doCancel() {}
#undef q_func
#undef d_func
#include "moc_detailscommand.cpp"
diff --git a/commands/detailscommand.h b/commands/detailscommand.h
index 299748aee..2fadf61e2 100644
--- a/commands/detailscommand.h
+++ b/commands/detailscommand.h
@@ -1,70 +1,67 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/detailscommand.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_COMMANDS_DETAILSCOMMAND_H__
#define __KLEOPATRA_COMMANDS_DETAILSCOMMAND_H__
#include <commands/command.h>
namespace GpgME {
class Key;
}
namespace Kleo {
-namespace Commands {
class DetailsCommand : public Command {
Q_OBJECT
public:
explicit DetailsCommand( KeyListController * parent );
explicit DetailsCommand( QAbstractItemView * view, KeyListController * parent );
explicit DetailsCommand( const GpgME::Key & key, KeyListController * parent );
explicit DetailsCommand( const GpgME::Key & key, QAbstractItemView * view, KeyListController * parent );
~DetailsCommand();
/* reimp */ static Restrictions restrictions() { return OnlyOneKey; }
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
- Q_PRIVATE_SLOT( d_func(), void slotDialogClosed() )
};
}
-}
#endif /* __KLEOPATRA_COMMANDS_DETAILSCOMMAND_H__ */
diff --git a/commands/dumpcertificatecommand.cpp b/commands/dumpcertificatecommand.cpp
index b2a31eb73..e69de29bb 100644
--- a/commands/dumpcertificatecommand.cpp
+++ b/commands/dumpcertificatecommand.cpp
@@ -1,325 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/dumpcertificatecommand.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 "dumpcertificatecommand.h"
-
-#include "command_p.h"
-
-#include <utils/kdlogtextwidget.h>
-#include <utils/gnupg-helper.h>
-
-#include <gpgme++/key.h>
-
-#include <KProcess>
-#include <KMessageBox>
-#include <KLocale>
-#include <KPushButton>
-#include <KStandardGuiItem>
-#include <KGlobalSettings>
-
-#include <QString>
-#include <QByteArray>
-#include <QTimer>
-#include <QLayout>
-#include <QPointer>
-
-
-static const int PROCESS_TERMINATE_TIMEOUT = 5000; // milliseconds
-
-namespace {
- class DumpCertificateDialog : public QDialog {
- Q_OBJECT
- public:
- explicit DumpCertificateDialog( QWidget * parent=0 )
- : QDialog( parent ), ui( this )
- {
-
- }
-
- Q_SIGNALS:
- void updateRequested();
-
- public Q_SLOTS:
- void append( const QString & line ) {
- ui.logTextWidget.message( line );
- }
- void clear() {
- ui.logTextWidget.clear();
- }
-
- private:
- struct Ui {
- KDLogTextWidget logTextWidget;
- KPushButton updateButton, closeButton;
- QVBoxLayout vlay;
- QHBoxLayout hlay;
-
- explicit Ui( DumpCertificateDialog * q )
- : logTextWidget( q ),
- updateButton( i18n("&Update"), q ),
- closeButton( KStandardGuiItem::close(), q ),
- vlay( q ),
- hlay()
- {
- KDAB_SET_OBJECT_NAME( logTextWidget );
- KDAB_SET_OBJECT_NAME( updateButton );
- KDAB_SET_OBJECT_NAME( closeButton );
- KDAB_SET_OBJECT_NAME( vlay );
- KDAB_SET_OBJECT_NAME( hlay );
-
- logTextWidget.setFont( KGlobalSettings::fixedFont() );
- logTextWidget.setMinimumVisibleLines( 25 );
- logTextWidget.setMinimumVisibleColumns( 80 );
-
- vlay.addWidget( &logTextWidget, 1 );
- vlay.addLayout( &hlay );
-
- hlay.addWidget( &updateButton );
- hlay.addStretch( 1 );
- hlay.addWidget( &closeButton );
-
- connect( &updateButton, SIGNAL(clicked()),
- q, SIGNAL(updateRequested()) );
- connect( &closeButton, SIGNAL(clicked()),
- q, SLOT(close()) );
- }
- } ui;
- };
-}
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-
-static QByteArray chomped( QByteArray ba ) {
- while ( ba.endsWith( '\n' ) || ba.endsWith( '\r' ) )
- ba.chop( 1 );
- return ba;
-}
-
-class DumpCertificateCommand::Private : Command::Private {
- friend class ::Kleo::Commands::DumpCertificateCommand;
- DumpCertificateCommand * q_func() const { return static_cast<DumpCertificateCommand*>( q ); }
-public:
- explicit Private( DumpCertificateCommand * qq, KeyListController * c );
- ~Private();
-
- QString errorString() const {
- return QString::fromLocal8Bit( errorBuffer );
- }
-
-private:
- void init();
- void refreshView();
-
-private:
- void slotProcessFinished( int, QProcess::ExitStatus );
-
- void slotProcessReadyReadStandardOutput() {
- while ( process.canReadLine() ) {
- const QString line = QString::fromUtf8( chomped( process.readLine() ) );
- if ( dialog )
- dialog->append( line );
- outputBuffer.push_back( line );
- }
- }
-
- void slotProcessReadyReadStandardError() {
- errorBuffer += process.readAllStandardError();
- }
-
- void slotUpdateRequested() {
- if ( process.state() == QProcess::NotRunning )
- refreshView();
- }
-
- void slotDialogDestroyed() {
- dialog = 0;
- if ( process.state() != QProcess::NotRunning )
- q->cancel();
- else
- finished();
- }
-
-private:
- QPointer<DumpCertificateDialog> dialog;
- KProcess process;
- QByteArray errorBuffer;
- QStringList outputBuffer;
- bool useDialog;
- bool canceled;
-};
-
-DumpCertificateCommand::Private * DumpCertificateCommand::d_func() { return static_cast<Private*>( d.get() ); }
-const DumpCertificateCommand::Private * DumpCertificateCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
-
-#define d d_func()
-#define q q_func()
-
-DumpCertificateCommand::Private::Private( DumpCertificateCommand * qq, KeyListController * c )
- : Command::Private( qq, c ),
- process(),
- errorBuffer(),
- outputBuffer(),
- useDialog( true ),
- canceled( false )
-{
- process.setOutputChannelMode( KProcess::SeparateChannels );
- process.setReadChannel( KProcess::StandardOutput );
-}
-
-DumpCertificateCommand::Private::~Private() {
- if ( dialog && !dialog->isVisible() )
- delete dialog;
-}
-
-DumpCertificateCommand::DumpCertificateCommand( KeyListController * c )
- : Command( new Private( this, c ) )
-{
- d->init();
-}
-
-DumpCertificateCommand::DumpCertificateCommand( QAbstractItemView * v, KeyListController * c )
- : Command( v, new Private( this, c ) )
-{
- d->init();
-}
-
-DumpCertificateCommand::DumpCertificateCommand( const GpgME::Key & k )
- : Command( k, new Private( this, 0 ) )
-{
- d->init();
-}
-
-void DumpCertificateCommand::Private::init() {
- connect( &process, SIGNAL(finished(int,QProcess::ExitStatus)),
- q, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
- connect( &process, SIGNAL(readyReadStandardError()),
- q, SLOT(slotProcessReadyReadStandardError()) );
- connect( &process, SIGNAL(readyReadStandardOutput()),
- q, SLOT(slotProcessReadyReadStandardOutput()) );
- if ( !key().isNull() )
- process << gpgSmPath() << "--dump-cert" << key().primaryFingerprint();
-}
-
-DumpCertificateCommand::~DumpCertificateCommand() {}
-
-void DumpCertificateCommand::setUseDialog( bool use ) {
- d->useDialog = use;
-}
-
-bool DumpCertificateCommand::useDialog() const {
- return d->useDialog;
-}
-
-QStringList DumpCertificateCommand::output() const {
- return d->outputBuffer;
-}
-
-void DumpCertificateCommand::doStart() {
-
- const std::vector<GpgME::Key> keys = d->keys();
- if ( keys.size() != 1 || keys.front().protocol() != GpgME::CMS ) {
- d->finished();
- return;
- }
-
- if ( d->useDialog ) {
- d->dialog = new DumpCertificateDialog;
- d->dialog->setAttribute( Qt::WA_DeleteOnClose );
- d->dialog->setWindowTitle( i18n("Certificate Dump") );
-
- connect( d->dialog, SIGNAL(updateRequested()),
- this, SLOT(slotUpdateRequested()) );
- connect( d->dialog, SIGNAL(destroyed()),
- this, SLOT(slotDialogDestroyed()) );
- }
-
- d->refreshView();
-}
-
-void DumpCertificateCommand::Private::refreshView() {
-
- if ( dialog )
- dialog->clear();
- errorBuffer.clear();
- outputBuffer.clear();
-
- process.start();
-
- if ( process.waitForStarted() ) {
- if ( dialog )
- dialog->show();
- } else {
- KMessageBox::error( dialog ? static_cast<QWidget*>( dialog ) : view(),
- i18n( "Unable to start process gpgsm. "
- "Please check your installation." ),
- i18n( "Dump Certificate Error" ) );
- finished();
- }
-}
-
-void DumpCertificateCommand::doCancel() {
- d->canceled = true;
- if ( d->process.state() != QProcess::NotRunning ) {
- d->process.terminate();
- QTimer::singleShot( PROCESS_TERMINATE_TIMEOUT, &d->process, SLOT(kill()) );
- }
- if ( d->dialog )
- d->dialog->close();
- d->dialog = 0;
-}
-
-void DumpCertificateCommand::Private::slotProcessFinished( int code, QProcess::ExitStatus status ) {
- if ( !canceled )
- if ( status == QProcess::CrashExit )
- KMessageBox::error( dialog,
- i18n( "The GpgSM process that tried to dump the certificate "
- "ended prematurely because of an unexpected error. "
- "Please check the output of gpgsm --dump-cert %1 for details.",
- key().primaryFingerprint() ),
- i18n( "Dump Certificate Error" ) );
- else if ( code )
- KMessageBox::error( dialog,
- i18n( "An error occurred while trying to dump the certificate. "
- "The output from GpgSM was:\n%1", errorString() ),
- i18n( "Dump Certificate Error" ) );
- if ( !useDialog )
- slotDialogDestroyed();
-}
-
-#undef d
-#undef q
-
-#include "moc_dumpcertificatecommand.cpp"
-#include "dumpcertificatecommand.moc"
diff --git a/commands/dumpcertificatecommand.h b/commands/dumpcertificatecommand.h
index 42dbf90b3..e69de29bb 100644
--- a/commands/dumpcertificatecommand.h
+++ b/commands/dumpcertificatecommand.h
@@ -1,74 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/dumpcertificatecommand.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_COMMMANDS_DUMPCERTIFICATECOMMAND_H__
-#define __KLEOPATRA_COMMMANDS_DUMPCERTIFICATECOMMAND_H__
-
-#include <commands/command.h>
-
-namespace Kleo {
-namespace Commands {
-
- class DumpCertificateCommand : public Command {
- Q_OBJECT
- public:
- explicit DumpCertificateCommand( QAbstractItemView * view, KeyListController * parent );
- explicit DumpCertificateCommand( KeyListController * parent );
- explicit DumpCertificateCommand( const GpgME::Key & key );
- ~DumpCertificateCommand();
-
- static Restrictions restrictions() { return OnlyOneKey|MustBeCMS; }
-
- void setUseDialog( bool on );
- bool useDialog() const;
-
- QStringList output() const;
-
- private:
- /* reimp */ void doStart();
- /* reimp */ void doCancel();
-
- private:
- class Private;
- inline Private * d_func();
- inline const Private * d_func() const;
- Q_PRIVATE_SLOT( d_func(), void slotProcessFinished( int, QProcess::ExitStatus ) )
- Q_PRIVATE_SLOT( d_func(), void slotProcessReadyReadStandardOutput() )
- Q_PRIVATE_SLOT( d_func(), void slotProcessReadyReadStandardError() )
- Q_PRIVATE_SLOT( d_func(), void slotUpdateRequested() )
- Q_PRIVATE_SLOT( d_func(), void slotDialogDestroyed() )
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMMANDS_DUMPCERTIFICATECOMMAND_H__
diff --git a/commands/dumpcrlcachecommand.cpp b/commands/dumpcrlcachecommand.cpp
index a798904bf..6b0b87c53 100644
--- a/commands/dumpcrlcachecommand.cpp
+++ b/commands/dumpcrlcachecommand.cpp
@@ -1,283 +1,282 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/dumpcrlcachecommand.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 "dumpcrlcachecommand.h"
#include "command_p.h"
#include <utils/kdlogtextwidget.h>
-#include <utils/gnupg-helper.h>
#include <KProcess>
#include <KMessageBox>
#include <KLocale>
#include <KPushButton>
#include <KStandardGuiItem>
#include <KGlobalSettings>
#include <QString>
#include <QByteArray>
#include <QTimer>
#include <QLayout>
static const int PROCESS_TERMINATE_TIMEOUT = 5000; // milliseconds
namespace {
class DumpCrlCacheDialog : public QDialog {
Q_OBJECT
public:
explicit DumpCrlCacheDialog( QWidget * parent=0 )
: QDialog( parent ), ui( this )
{
}
Q_SIGNALS:
void updateRequested();
public Q_SLOTS:
void append( const QString & line ) {
ui.logTextWidget.message( line );
}
void clear() {
ui.logTextWidget.clear();
}
private:
struct Ui {
KDLogTextWidget logTextWidget;
KPushButton updateButton, closeButton;
QVBoxLayout vlay;
QHBoxLayout hlay;
explicit Ui( DumpCrlCacheDialog * q )
: logTextWidget( q ),
updateButton( i18n("&Update"), q ),
closeButton( KStandardGuiItem::close(), q ),
vlay( q ),
hlay()
{
KDAB_SET_OBJECT_NAME( logTextWidget );
KDAB_SET_OBJECT_NAME( updateButton );
KDAB_SET_OBJECT_NAME( closeButton );
KDAB_SET_OBJECT_NAME( vlay );
KDAB_SET_OBJECT_NAME( hlay );
logTextWidget.setFont( KGlobalSettings::fixedFont() );
logTextWidget.setMinimumVisibleLines( 25 );
logTextWidget.setMinimumVisibleColumns( 80 );
vlay.addWidget( &logTextWidget, 1 );
vlay.addLayout( &hlay );
hlay.addWidget( &updateButton );
hlay.addStretch( 1 );
hlay.addWidget( &closeButton );
connect( &updateButton, SIGNAL(clicked()),
q, SIGNAL(updateRequested()) );
connect( &closeButton, SIGNAL(clicked()),
q, SLOT(close()) );
}
} ui;
};
}
using namespace Kleo;
using namespace Kleo::Commands;
static QByteArray chomped( QByteArray ba ) {
while ( ba.endsWith( '\n' ) || ba.endsWith( '\r' ) )
ba.chop( 1 );
return ba;
}
class DumpCrlCacheCommand::Private : Command::Private {
friend class ::Kleo::Commands::DumpCrlCacheCommand;
DumpCrlCacheCommand * q_func() const { return static_cast<DumpCrlCacheCommand*>( q ); }
public:
explicit Private( DumpCrlCacheCommand * qq, KeyListController * c );
~Private();
QString errorString() const {
return QString::fromLocal8Bit( errorBuffer );
}
private:
void init();
void refreshView();
private:
void slotProcessFinished( int, QProcess::ExitStatus );
void slotProcessReadyReadStandardOutput() {
while ( process.canReadLine() ) {
const QByteArray line = chomped( process.readLine() );
if ( dialog )
dialog->append( QString::fromLocal8Bit( line ) );
}
}
void slotProcessReadyReadStandardError() {
errorBuffer += process.readAllStandardError();
}
void slotUpdateRequested() {
if ( process.state() == QProcess::NotRunning )
refreshView();
}
void slotDialogDestroyed() {
dialog = 0;
if ( process.state() != QProcess::NotRunning )
q->cancel();
else
finished();
}
private:
DumpCrlCacheDialog * dialog;
KProcess process;
QByteArray errorBuffer;
bool canceled;
};
DumpCrlCacheCommand::Private * DumpCrlCacheCommand::d_func() { return static_cast<Private*>( d.get() ); }
const DumpCrlCacheCommand::Private * DumpCrlCacheCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
DumpCrlCacheCommand::Private::Private( DumpCrlCacheCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
process(),
errorBuffer(),
canceled( false )
{
process.setOutputChannelMode( KProcess::SeparateChannels );
process.setReadChannel( KProcess::StandardOutput );
- process << gpgSmPath() << "--call-dirmngr" << "listcrls";
+ process << "gpgsm" << "--call-dirmngr" << "listcrls";
}
DumpCrlCacheCommand::Private::~Private() {
if ( dialog && !dialog->isVisible() )
delete dialog;
}
DumpCrlCacheCommand::DumpCrlCacheCommand( KeyListController * c )
: Command( new Private( this, c ) )
{
d->init();
}
DumpCrlCacheCommand::DumpCrlCacheCommand( QAbstractItemView * v, KeyListController * c )
: Command( v, new Private( this, c ) )
{
d->init();
}
void DumpCrlCacheCommand::Private::init() {
connect( &process, SIGNAL(finished(int,QProcess::ExitStatus)),
q, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
connect( &process, SIGNAL(readyReadStandardError()),
q, SLOT(slotProcessReadyReadStandardError()) );
connect( &process, SIGNAL(readyReadStandardOutput()),
q, SLOT(slotProcessReadyReadStandardOutput()) );
}
DumpCrlCacheCommand::~DumpCrlCacheCommand() {}
void DumpCrlCacheCommand::doStart() {
d->dialog = new DumpCrlCacheDialog;
d->dialog->setAttribute( Qt::WA_DeleteOnClose );
d->dialog->setWindowTitle( i18n("CRL Cache Dump") );
connect( d->dialog, SIGNAL(updateRequested()),
this, SLOT(slotUpdateRequested()) );
connect( d->dialog, SIGNAL(destroyed()),
this, SLOT(slotDialogDestroyed()) );
d->refreshView();
}
void DumpCrlCacheCommand::Private::refreshView() {
dialog->clear();
process.start();
if ( process.waitForStarted() ) {
dialog->show();
} else {
KMessageBox::error( dialog ? static_cast<QWidget*>( dialog ) : view(),
i18n( "Unable to start process gpgsm. "
"Please check your installation." ),
i18n( "Dump CRL Cache Error" ) );
finished();
}
}
void DumpCrlCacheCommand::doCancel() {
d->canceled = true;
if ( d->process.state() != QProcess::NotRunning ) {
d->process.terminate();
QTimer::singleShot( PROCESS_TERMINATE_TIMEOUT, &d->process, SLOT(kill()) );
}
if ( d->dialog )
d->dialog->close();
d->dialog = 0;
}
void DumpCrlCacheCommand::Private::slotProcessFinished( int code, QProcess::ExitStatus status ) {
if ( !canceled )
if ( status == QProcess::CrashExit )
KMessageBox::error( dialog,
i18n( "The GpgSM process that tried to dump the CRL cache "
"ended prematurely because of an unexpected error. "
"Please check the output of gpgsm --call-dirmngr listcrls for details." ),
i18n( "Dump CRL Cache Error" ) );
else if ( code )
KMessageBox::error( dialog,
i18n( "An error occurred while trying to dump the CRL cache. "
"The output from GpgSM was:\n%1", errorString() ),
i18n( "Dump CRL Cache Error" ) );
}
#undef d
#undef q
#include "moc_dumpcrlcachecommand.cpp"
#include "dumpcrlcachecommand.moc"
diff --git a/commands/exportcertificatecommand.cpp b/commands/exportcertificatecommand.cpp
index e5c9fff67..a4d77cb62 100644
--- a/commands/exportcertificatecommand.cpp
+++ b/commands/exportcertificatecommand.cpp
@@ -1,309 +1,269 @@
/* -*- mode: c++; c-basic-offset:4 -*-
exportcertificatecommand.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 "exportcertificatecommand.h"
+#include "exportcertificatesdialog.h"
#include "command_p.h"
-#include <dialogs/exportcertificatesdialog.h>
-
#include <kleo/cryptobackend.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/exportjob.h>
#include <gpgme++/key.h>
#include <KLocale>
#include <KMessageBox>
#include <KSaveFile>
#include <QDataStream>
#include <QFileDialog>
#include <QMap>
#include <QPointer>
#include <QTextStream>
#include <boost/bind.hpp>
#include <algorithm>
#include <vector>
#include <cassert>
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-using namespace GpgME;
using namespace boost;
+using namespace GpgME;
+using namespace Kleo;
class ExportCertificateCommand::Private : public Command::Private {
friend class ::ExportCertificateCommand;
ExportCertificateCommand * q_func() const { return static_cast<ExportCertificateCommand*>(q); }
public:
explicit Private( ExportCertificateCommand * qq, KeyListController * c );
~Private();
void startExportJob( GpgME::Protocol protocol, const std::vector<Key>& keys );
void cancelJobs();
void exportResult( const GpgME::Error&, const QByteArray& );
void showError( const GpgME::Error& error );
bool requestFileNames( Protocol prot );
void finishedIfLastJob();
private:
bool textArmor;
QMap<GpgME::Protocol, QString> fileNames;
uint jobsPending;
QMap<QObject*, QString> outFileForSender;
QPointer<ExportJob> cmsJob;
QPointer<ExportJob> pgpJob;
};
ExportCertificateCommand::Private * ExportCertificateCommand::d_func() { return static_cast<Private*>(d.get()); }
const ExportCertificateCommand::Private * ExportCertificateCommand::d_func() const { return static_cast<const Private*>(d.get()); }
#define d d_func()
#define q q_func()
ExportCertificateCommand::Private::Private( ExportCertificateCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
textArmor( true ),
jobsPending( 0 )
{
}
ExportCertificateCommand::Private::~Private() {}
ExportCertificateCommand::ExportCertificateCommand( KeyListController * p )
: Command( new Private( this, p ) )
{
}
ExportCertificateCommand::ExportCertificateCommand( QAbstractItemView * v, KeyListController * p )
: Command( v, new Private( this, p ) )
{
}
-ExportCertificateCommand::ExportCertificateCommand( const Key & key )
- : Command( key, new Private( this, 0 ) )
-{
-
-}
-
ExportCertificateCommand::~ExportCertificateCommand() {}
-void ExportCertificateCommand::setOpenPGPFileName( const QString & fileName )
-{
- if ( !d->jobsPending )
- d->fileNames[OpenPGP] = fileName;
-}
-
-QString ExportCertificateCommand::openPGPFileName() const
-{
- return d->fileNames[OpenPGP];
-}
-
-void ExportCertificateCommand::setX509FileName( const QString & fileName )
-{
- if ( !d->jobsPending )
- d->fileNames[CMS] = fileName;
-}
-
-QString ExportCertificateCommand::x509FileName() const
-{
- return d->fileNames[CMS];
-}
-
void ExportCertificateCommand::doStart()
{
std::vector<Key> keys = d->keys();
if ( keys.empty() )
return;
const std::vector<Key>::iterator firstCms = std::partition( keys.begin(), keys.end(), bind( &GpgME::Key::protocol, _1 ) != CMS );
std::vector<Key> openpgp, cms;
std::copy( keys.begin(), firstCms, std::back_inserter( openpgp ) );
std::copy( firstCms, keys.end(), std::back_inserter( cms ) );
assert( !openpgp.empty() || !cms.empty() );
const bool haveBoth = !cms.empty() && !openpgp.empty();
const GpgME::Protocol prot = haveBoth ? UnknownProtocol : ( !cms.empty() ? CMS : OpenPGP );
if ( !d->requestFileNames( prot ) ) {
emit canceled();
d->finished();
} else {
if ( !openpgp.empty() )
d->startExportJob( GpgME::OpenPGP, openpgp );
if ( !cms.empty() )
d->startExportJob( GpgME::CMS, cms );
}
}
bool ExportCertificateCommand::Private::requestFileNames( GpgME::Protocol protocol )
{
+ fileNames.clear();
if ( protocol == UnknownProtocol )
{
- if ( !fileNames[OpenPGP].isEmpty() && !fileNames[CMS].isEmpty() )
- return true;
const QPointer<ExportCertificatesDialog> dlg( new ExportCertificatesDialog( view() ) );
- dlg->setOpenPgpExportFileName( fileNames[OpenPGP] );
- dlg->setCmsExportFileName( fileNames[CMS] );
const bool accepted = dlg->exec() == QDialog::Accepted && dlg ;
if ( accepted )
{
fileNames[OpenPGP] = dlg->openPgpExportFileName();
fileNames[CMS] = dlg->cmsExportFileName();
}
- else
- {
- fileNames.clear();
- }
delete dlg;
return accepted;
}
- if ( !fileNames[protocol].isEmpty() )
- return true;
-
const QString fname = QFileDialog::getSaveFileName( view(), i18n( "Export Certificates" ), QString(), protocol == GpgME::OpenPGP ? i18n( "OpenPGP Certificates (.asc)" ) : i18n( "S/MIME Certificates (.pem)" ) );
fileNames[protocol] = fname;
return !fname.isNull();
}
void ExportCertificateCommand::Private::startExportJob( GpgME::Protocol protocol, const std::vector<Key>& keys )
{
assert( protocol != GpgME::UnknownProtocol );
const CryptoBackend::Protocol* const backend = CryptoBackendFactory::instance()->protocol( protocol );
assert( backend );
std::auto_ptr<ExportJob> job( backend->publicKeyExportJob( /*armor=*/true ) );
assert( job.get() );
connect( job.get(), SIGNAL(result(GpgME::Error,QByteArray)),
q, SLOT(exportResult(GpgME::Error,QByteArray)) );
connect( job.get(), SIGNAL(progress(QString,int,int)),
q, SIGNAL(progress(QString,int,int)) );
QStringList fingerprints;
Q_FOREACH ( const Key& i, keys )
fingerprints << i.primaryFingerprint();
const GpgME::Error err = job->start( fingerprints );
if ( err ) {
showError( err );
finished();
return;
}
emit q->info( i18n( "Exporting certificates..." ) );
++jobsPending;
const QPointer<ExportJob> exportJob( job.release() );
outFileForSender[exportJob] = fileNames[protocol];
( protocol == CMS ? cmsJob : pgpJob ) = exportJob;
}
void ExportCertificateCommand::Private::showError( const GpgME::Error& err )
{
assert( err );
const QString msg = i18n("<qt><p>An error occurred while trying to export "
"the certificate:</p>"
"<p><b>%1</b></p></qt>",
QString::fromLocal8Bit( err.asString() ) );
KMessageBox::error( view(), msg, i18n("Certificate Export Failed") );
}
void ExportCertificateCommand::doCancel()
{
d->cancelJobs();
}
void ExportCertificateCommand::Private::finishedIfLastJob()
{
if ( jobsPending <= 0 )
finished();
}
void ExportCertificateCommand::Private::exportResult( const GpgME::Error& err, const QByteArray& data )
{
assert( jobsPending > 0 );
--jobsPending;
assert( outFileForSender.contains( q->sender() ) );
const QString outFile = outFileForSender[q->sender()];
if ( err ) {
showError( err );
finishedIfLastJob();
return;
}
KSaveFile savefile( outFile );
//TODO: use KIO
const QString writeErrorMsg = i18n( "Could not write to file %1.", outFile );
const QString errorCaption = i18n( "Certificate Export Failed" );
if ( !savefile.open() )
{
KMessageBox::error( view(), writeErrorMsg, errorCaption );
finishedIfLastJob();
return;
}
if ( textArmor )
{
QTextStream out( &savefile );
out << data;
}
else
{
QDataStream out( &savefile );
out << data;
}
if ( !savefile.finalize() )
KMessageBox::error( view(), writeErrorMsg, errorCaption );
finishedIfLastJob();
}
void ExportCertificateCommand::Private::cancelJobs()
{
if ( cmsJob )
cmsJob->slotCancel();
if ( pgpJob )
pgpJob->slotCancel();
}
#undef d
#undef q
#include "moc_exportcertificatecommand.cpp"
diff --git a/commands/exportcertificatecommand.h b/commands/exportcertificatecommand.h
index acffd861d..c18e5b400 100644
--- a/commands/exportcertificatecommand.h
+++ b/commands/exportcertificatecommand.h
@@ -1,68 +1,61 @@
/* -*- mode: c++; c-basic-offset:4 -*-
exportcertificatecommand.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_EXPORTCERTIFICATECOMMAND_H__
#define __KLEOPATRA_EXPORTCERTIFICATECOMMAND_H__
#include "command.h"
namespace Kleo {
class ExportCertificateCommand : public Command {
Q_OBJECT
public:
explicit ExportCertificateCommand( QAbstractItemView * view, KeyListController * parent );
explicit ExportCertificateCommand( KeyListController * parent );
- explicit ExportCertificateCommand( const GpgME::Key & key );
~ExportCertificateCommand();
/* reimp */ static Restrictions restrictions() { return NeedSelection; }
- void setOpenPGPFileName( const QString & fileName );
- QString openPGPFileName() const;
-
- void setX509FileName( const QString & fileName );
- QString x509FileName() const;
-
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
Q_PRIVATE_SLOT( d_func(), void exportResult( GpgME::Error, QByteArray ) )
};
}
#endif // __KLEOPATRA_EXPORTCERTIFICATECOMMAND_H__
diff --git a/commands/exportopenpgpcertstoservercommand.cpp b/commands/exportopenpgpcertstoservercommand.cpp
index 7e05970b0..e69de29bb 100644
--- a/commands/exportopenpgpcertstoservercommand.cpp
+++ b/commands/exportopenpgpcertstoservercommand.cpp
@@ -1,148 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/exportopenpgpcertstoservercommand.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 "exportopenpgpcertstoservercommand.h"
-
-#include "command_p.h"
-
-#include <utils/gnupg-helper.h>
-
-#include <kleo/cryptobackendfactory.h>
-#include <kleo/cryptoconfig.h>
-
-#include <gpgme++/key.h>
-
-#include <KLocale>
-#include <KMessageBox>
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace GpgME;
-
-static bool haveKeyserverConfigured() {
- const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
- if ( !config )
- return false;
- const Kleo::CryptoConfigEntry * const entry = config->entry( "gpg", "Keyserver", "keyserver" );
- return entry && !entry->stringValue().isEmpty();
-}
-
-ExportOpenPGPCertsToServerCommand::ExportOpenPGPCertsToServerCommand( KeyListController * c )
- : GnuPGProcessCommand( c )
-{
-
-}
-
-ExportOpenPGPCertsToServerCommand::ExportOpenPGPCertsToServerCommand( QAbstractItemView * v, KeyListController * c )
- : GnuPGProcessCommand( v, c )
-{
-
-}
-
-
-ExportOpenPGPCertsToServerCommand::ExportOpenPGPCertsToServerCommand( const Key & key )
- : GnuPGProcessCommand( key )
-{
-
-}
-
-ExportOpenPGPCertsToServerCommand::~ExportOpenPGPCertsToServerCommand() {}
-
-bool ExportOpenPGPCertsToServerCommand::preStartHook( QWidget * parent ) const {
- if ( !haveKeyserverConfigured() )
- if ( KMessageBox::warningContinueCancel( parent,
- i18nc("@info",
- "<para>No OpenPGP directory services have been configured.</para>"
- "<para>Since none is configured, <application>Kleopatra</application> will use "
- "<resource>keys.gnupg.net</resource> as the server to export to.</para>"
- "<para>You can configure OpenPGP directory servers in <application>Kleopatra</application>'s "
- "configuration dialog.</para>"
- "<para>Do you want to continue with <resource>keys.gnupg.net</resource> "
- "as the server to export to?</para>" ),
- i18n("OpenPGP Certificate Export"),
- KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- QLatin1String( "warn-export-openpgp-missing-keyserver" ) )
- != KMessageBox::Continue )
- return false;
- return KMessageBox::warningContinueCancel( parent,
- i18nc("@info",
- "<para>When OpenPGP certificates have been exported to a public directory server, "
- "it is nearly impossible to remove them again.</para>"
- "<para>Before exporting your certificate to a public directory server, make sure that you "
- "have created a revocation certificate so you can revoke the certificate if needed later.</para>"
- "<para>Are you sure you want to continue?</para>"),
- i18n("OpenPGP Certificate Export"),
- KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
- QLatin1String( "warn-export-openpgp-nonrevocable" ) )
- == KMessageBox::Continue;
-}
-
-QStringList ExportOpenPGPCertsToServerCommand::arguments() const {
- QStringList result;
- result << gpgPath();
- if ( !haveKeyserverConfigured() )
- result << "--keyserver" << "keys.gnupg.net";
- result << "--send-keys";
- Q_FOREACH( const Key & key, d->keys() )
- result << key.primaryFingerprint();
- return result;
-}
-
-QString ExportOpenPGPCertsToServerCommand::errorCaption() const {
- return i18n( "OpenPGP Certificate Export Error" );
-}
-
-QString ExportOpenPGPCertsToServerCommand::successCaption() const {
- return i18n( "OpenPGP Certificate Export Finished" );
-}
-
-QString ExportOpenPGPCertsToServerCommand::crashExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>The GPG process that tried to export OpenPGP certificates "
- "ended prematurely because of an unexpected error.</para>"
- "<para>Please check the output of <icode>%1</icode> for details.</para>", args.join( " " ) ) ;
-}
-
-QString ExportOpenPGPCertsToServerCommand::errorExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>An error occurred while trying to export OpenPGP certificates.</para> "
- "<para>The output from <command>%1</command> was: <message>%2</message></para>",
- args[0], errorString() );
-}
-
-QString ExportOpenPGPCertsToServerCommand::successMessage( const QStringList & ) const {
- return i18n( "OpenPGP certificates exported successfully." );
-}
-
-#include "moc_exportopenpgpcertstoservercommand.cpp"
diff --git a/commands/exportopenpgpcertstoservercommand.h b/commands/exportopenpgpcertstoservercommand.h
index ce3cfb5d1..e69de29bb 100644
--- a/commands/exportopenpgpcertstoservercommand.h
+++ b/commands/exportopenpgpcertstoservercommand.h
@@ -1,68 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/exportopenpgpcertstoservercommand.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_COMMMANDS_EXPORTOPENPGPCERTSTOSERVERCOMMAND_H__
-#define __KLEOPATRA_COMMMANDS_EXPORTOPENPGPCERTSTOSERVERCOMMAND_H__
-
-#include <commands/gnupgprocesscommand.h>
-
-namespace Kleo {
-namespace Commands {
-
- class ExportOpenPGPCertsToServerCommand : public GnuPGProcessCommand {
- Q_OBJECT
- public:
- explicit ExportOpenPGPCertsToServerCommand( QAbstractItemView * view, KeyListController * parent );
- explicit ExportOpenPGPCertsToServerCommand( KeyListController * parent );
- explicit ExportOpenPGPCertsToServerCommand( const GpgME::Key & key );
-
- ~ExportOpenPGPCertsToServerCommand();
-
- static Restrictions restrictions() { return MustBeOpenPGP; }
-
- private:
- /* reimp */ bool preStartHook( QWidget * ) const;
-
- /* reimp */ QStringList arguments() const;
-
- /* reimp */ QString errorCaption() const;
- /* reimp */ QString successCaption() const;
-
- /* reimp */ QString crashExitMessage( const QStringList & ) const;
- /* reimp */ QString errorExitMessage( const QStringList & ) const;
- /* reimp */ QString successMessage( const QStringList & ) const;
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMMANDS_EXPORTOPENPGPCERTSTOSERVERCOMMAND_H__
diff --git a/commands/exportsecretkeycommand.cpp b/commands/exportsecretkeycommand.cpp
index d1600d125..e69de29bb 100644
--- a/commands/exportsecretkeycommand.cpp
+++ b/commands/exportsecretkeycommand.cpp
@@ -1,154 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/exportsecretkeycommand.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 "exportsecretkeycommand.h"
-
-#include "command_p.h"
-
-#include <dialogs/exportsecretkeydialog.h>
-
-#include <utils/gnupg-helper.h>
-
-#include <gpgme++/key.h>
-
-#include <KLocale>
-#include <KMessageBox>
-
-using namespace Kleo;
-using namespace Kleo::Commands;
-using namespace Kleo::Dialogs;
-using namespace GpgME;
-
-ExportSecretKeyCommand::ExportSecretKeyCommand( KeyListController * c )
- : GnuPGProcessCommand( c )
-{
-
-}
-
-ExportSecretKeyCommand::ExportSecretKeyCommand( QAbstractItemView * v, KeyListController * c )
- : GnuPGProcessCommand( v, c )
-{
-
-}
-
-ExportSecretKeyCommand::ExportSecretKeyCommand( const Key & key )
- : GnuPGProcessCommand( key )
-{
-
-}
-
-ExportSecretKeyCommand::~ExportSecretKeyCommand() {}
-
-void ExportSecretKeyCommand::setFileName( const QString & fileName ) {
- m_filename = fileName;
-}
-
-void ExportSecretKeyCommand::setPassphraseCharset( const QByteArray & charset ) {
- m_charset = charset;
-}
-
-void ExportSecretKeyCommand::setUseArmor( bool armor ) {
- m_armor = armor;
-}
-
-bool ExportSecretKeyCommand::preStartHook( QWidget * parent ) const {
- if ( !m_filename.isEmpty() )
- return true;
-
- ExportSecretKeyDialog dlg( parent );
- dlg.setKey( d->key() );
- if ( !dlg.exec() )
- return false;
-
- m_filename = dlg.fileName();
- m_armor = dlg.useArmor();
- m_charset = dlg.charset();
-
- return true;
-}
-
-QStringList ExportSecretKeyCommand::arguments() const {
- const Key key = d->key();
- QStringList result;
-
- if ( key.protocol() == OpenPGP )
- result << gpgPath();
- else
- result << gpgSmPath();
-
- result << "--output" << m_filename;
-
- if ( m_armor )
- result << "--armor";
-
- if ( key.protocol() == CMS && !m_charset.isEmpty() )
- result << "--p12-charset" << m_charset;
-
- if ( key.protocol() == OpenPGP )
- result << "--export-secret-key";
- else
- result << "--export-secret-key-p12";
-
- result << key.primaryFingerprint();
-
- return result;
-}
-
-QString ExportSecretKeyCommand::errorCaption() const {
- return i18n( "Secret Key Export Error" );
-}
-
-QString ExportSecretKeyCommand::successCaption() const {
- return i18n( "Secret Key Export Finished" );
-}
-
-QString ExportSecretKeyCommand::crashExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>The GPG or GpgSM process that tried to export the secret key "
- "ended prematurely because of an unexpected error.</para>"
- "<para>Please check the output of <icode>%1</icode> for details.</para>", args.join( " " ) ) ;
-}
-
-QString ExportSecretKeyCommand::errorExitMessage( const QStringList & args ) const {
- return i18nc("@info",
- "<para>An error occurred while trying to export the secret key.</para> "
- "<para>The output from <command>%1</command> was: <message>%2</message></para>",
- args[0], errorString() );
-}
-
-QString ExportSecretKeyCommand::successMessage( const QStringList & ) const {
- return i18n( "Secret key successfully exported." );
-}
-
-#include "moc_exportsecretkeycommand.cpp"
diff --git a/commands/exportsecretkeycommand.h b/commands/exportsecretkeycommand.h
index 7843881ca..e69de29bb 100644
--- a/commands/exportsecretkeycommand.h
+++ b/commands/exportsecretkeycommand.h
@@ -1,84 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/exportsecretkeycommand.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_COMMMANDS_EXPORTSECRETKEYCOMMAND_H__
-#define __KLEOPATRA_COMMMANDS_EXPORTSECRETKEYCOMMAND_H__
-
-#include <commands/gnupgprocesscommand.h>
-
-#include <QString>
-#include <QByteArray>
-
-namespace Kleo {
-namespace Commands {
-
- class ExportSecretKeyCommand : public GnuPGProcessCommand {
- Q_OBJECT
- public:
- explicit ExportSecretKeyCommand( QAbstractItemView * view, KeyListController * parent );
- explicit ExportSecretKeyCommand( KeyListController * parent );
- explicit ExportSecretKeyCommand( const GpgME::Key & key );
- ~ExportSecretKeyCommand();
-
- void setFileName( const QString & fileName );
- QString fileName() const { return m_filename; }
-
- void setPassphraseCharset( const QByteArray & charset );
- QByteArray passphraseCharset() const { return m_charset; }
-
- void setUseArmor( bool armor );
- bool useArmor() const { return m_armor; }
-
- /* reimp */ static Restrictions restrictions() { return OnlyOneKey|NeedSecretKey; }
-
- private:
- /* reimp */ bool preStartHook( QWidget * ) const;
-
- /* reimp */ QStringList arguments() const;
-
- /* reimp */ QString errorCaption() const;
- /* reimp */ QString successCaption() const;
-
- /* reimp */ QString crashExitMessage( const QStringList & ) const;
- /* reimp */ QString errorExitMessage( const QStringList & ) const;
- /* reimp */ QString successMessage( const QStringList & ) const;
-
- private:
- mutable QString m_filename;
- mutable QByteArray m_charset;
- mutable bool m_armor;
- };
-
-}
-}
-
-#endif // __KLEOPATRA_COMMMANDS_EXPORTSECRETKEYCOMMAND_H__
diff --git a/commands/gnupgprocesscommand.cpp b/commands/gnupgprocesscommand.cpp
index def36b50d..4a127e9f3 100644
--- a/commands/gnupgprocesscommand.cpp
+++ b/commands/gnupgprocesscommand.cpp
@@ -1,174 +1,168 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/gnupgprocesscommand.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 "gnupgprocesscommand.h"
#include "command_p.h"
#include <QString>
#include <QStringList>
#include <QByteArray>
#include <QTimer>
#include <KProcess>
#include <KMessageBox>
#include <KLocale>
static const int PROCESS_TERMINATE_TIMEOUT = 5000; // milliseconds
using namespace Kleo;
using namespace Kleo::Commands;
class GnuPGProcessCommand::Private : Command::Private {
friend class ::Kleo::Commands::GnuPGProcessCommand;
GnuPGProcessCommand * q_func() const { return static_cast<GnuPGProcessCommand*>( q ); }
public:
explicit Private( GnuPGProcessCommand * qq, KeyListController * c );
~Private();
private:
void init();
private:
void slotProcessFinished( int, QProcess::ExitStatus );
void slotProcessReadyReadStandardError();
private:
KProcess process;
QStringList arguments;
QByteArray errorBuffer;
bool canceled;
};
GnuPGProcessCommand::Private * GnuPGProcessCommand::d_func() { return static_cast<Private*>( d.get() ); }
const GnuPGProcessCommand::Private * GnuPGProcessCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
GnuPGProcessCommand::Private::Private( GnuPGProcessCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
process(),
errorBuffer(),
canceled( false )
{
process.setOutputChannelMode( KProcess::OnlyStderrChannel );
}
GnuPGProcessCommand::Private::~Private() {}
GnuPGProcessCommand::GnuPGProcessCommand( KeyListController * c )
: Command( new Private( this, c ) )
{
d->init();
}
GnuPGProcessCommand::GnuPGProcessCommand( QAbstractItemView * v, KeyListController * c )
: Command( v, new Private( this, c ) )
{
d->init();
}
-GnuPGProcessCommand::GnuPGProcessCommand( const GpgME::Key & key )
- : Command( key, new Private( this, 0 ) )
-{
- d->init();
-}
-
void GnuPGProcessCommand::Private::init() {
connect( &process, SIGNAL(finished(int,QProcess::ExitStatus)),
q, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
connect( &process, SIGNAL(readyReadStandardError()),
q, SLOT(slotProcessReadyReadStandardError()) );
}
GnuPGProcessCommand::~GnuPGProcessCommand() {}
bool GnuPGProcessCommand::preStartHook( QWidget * ) const {
return true;
}
void GnuPGProcessCommand::doStart() {
if ( !preStartHook( d->view() ) ) {
d->finished();
return;
}
d->arguments = arguments();
d->process << d->arguments;
d->process.start();
if ( !d->process.waitForStarted() ) {
KMessageBox::error( d->view(),
i18n( "Unable to start process %1. "
"Please check your installation.", d->arguments[0] ),
errorCaption() );
d->finished();
}
}
void GnuPGProcessCommand::doCancel() {
d->canceled = true;
if ( d->process.state() != QProcess::NotRunning ) {
d->process.terminate();
QTimer::singleShot( PROCESS_TERMINATE_TIMEOUT, &d->process, SLOT(kill()) );
}
}
void GnuPGProcessCommand::Private::slotProcessFinished( int code, QProcess::ExitStatus status ) {
if ( !canceled )
if ( status == QProcess::CrashExit )
KMessageBox::error( view(), q->crashExitMessage( arguments ), q->errorCaption() );
else if ( code )
KMessageBox::error( view(), q->errorExitMessage( arguments ), q->errorCaption() );
else
KMessageBox::information( view(), q->successMessage( arguments ), q->successCaption() );
finished();
}
void GnuPGProcessCommand::Private::slotProcessReadyReadStandardError() {
errorBuffer += process.readAllStandardError();
}
QString GnuPGProcessCommand::errorString() const {
return QString::fromLocal8Bit( d->errorBuffer );
}
#undef d
#undef q
#include "moc_gnupgprocesscommand.cpp"
diff --git a/commands/gnupgprocesscommand.h b/commands/gnupgprocesscommand.h
index 2d1ac5088..3938ded2b 100644
--- a/commands/gnupgprocesscommand.h
+++ b/commands/gnupgprocesscommand.h
@@ -1,82 +1,81 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/gnupgprocesscommand.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_COMMMANDS_GNUPGPROCESSCOMMAND_H__
#define __KLEOPATRA_COMMMANDS_GNUPGPROCESSCOMMAND_H__
#include <commands/command.h>
class QStringList;
class QString;
namespace Kleo {
namespace Commands {
class GnuPGProcessCommand : public Command {
Q_OBJECT
protected:
explicit GnuPGProcessCommand( QAbstractItemView * view, KeyListController * parent );
explicit GnuPGProcessCommand( KeyListController * parent );
- explicit GnuPGProcessCommand( const GpgME::Key & key );
~GnuPGProcessCommand();
private:
virtual bool preStartHook( QWidget * parentWidget ) const;
virtual QStringList arguments() const = 0;
virtual QString errorCaption() const = 0;
virtual QString successCaption() const = 0;
virtual QString crashExitMessage( const QStringList & args ) const = 0;
virtual QString errorExitMessage( const QStringList & args ) const = 0;
virtual QString successMessage( const QStringList & args ) const = 0;
protected:
QString errorString() const;
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
Q_PRIVATE_SLOT( d_func(), void slotProcessFinished( int, QProcess::ExitStatus ) )
Q_PRIVATE_SLOT( d_func(), void slotProcessReadyReadStandardError() )
};
}
}
#endif // __KLEOPATRA_COMMMANDS_GNUPGPROCESSCOMMAND_H__
diff --git a/commands/lookupcertificatescommand.cpp b/commands/lookupcertificatescommand.cpp
index 9afe378d6..3bd2f67c5 100644
--- a/commands/lookupcertificatescommand.cpp
+++ b/commands/lookupcertificatescommand.cpp
@@ -1,437 +1,392 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/lookupcertificatescommand.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 "lookupcertificatescommand.h"
#include "importcertificatescommand_p.h"
#include "detailscommand.h"
#include <dialogs/lookupcertificatesdialog.h>
#include <utils/stl_util.h>
#include <utils/formatting.h>
#include <kleo/downloadjob.h>
#include <kleo/importjob.h>
#include <kleo/keylistjob.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/cryptobackend.h>
-#include <kleo/cryptoconfig.h>
#include <gpgme++/key.h>
#include <gpgme++/keylistresult.h>
#include <KLocale>
#include <KMessageBox>
#include <kdebug.h>
#include <QBuffer>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <map>
#include <algorithm>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
using namespace boost;
class LookupCertificatesCommand::Private : public ImportCertificatesCommand::Private {
friend class ::Kleo::Commands::LookupCertificatesCommand;
LookupCertificatesCommand * q_func() const { return static_cast<LookupCertificatesCommand*>( q ); }
public:
explicit Private( LookupCertificatesCommand * qq, KeyListController * c );
~Private();
void init();
private:
void slotSearchTextChanged( const QString & str );
void slotNextKey( const Key & key ) {
keyListing.keys.push_back( key );
}
void slotKeyListResult( const KeyListResult & result );
void slotImportRequested( const std::vector<Key> & keys );
void slotOpenPGPDownloadResult( const Error & err, const QByteArray & data );
void slotCMSDownloadResult( const Error & err, const QByteArray & data );
void slotDetailsRequested( const Key & key );
void slotSaveAsRequested( const std::vector<Key> & keys );
- void slotDialogRejected() {
- canceled();
- }
private:
using ImportCertificatesCommand::Private::showError;
void showError( QWidget * parent, const KeyListResult & result );
void createDialog();
KeyListJob * createKeyListJob( GpgME::Protocol proto ) const {
const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto );
return cbp ? cbp->keyListJob( true ) : 0 ;
}
DownloadJob * createDownloadJob( GpgME::Protocol proto ) const {
const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto );
return cbp ? cbp->downloadJob() : 0 ;
}
void startKeyListJob( GpgME::Protocol proto, const QString & str );
void startDownloadJob( const Key & key );
void checkForDownloadFinished();
- bool checkConfig() const;
QWidget * dialogOrView() const { if ( dialog ) return dialog; else return view(); }
private:
QPointer<LookupCertificatesDialog> dialog;
struct KeyListingVariables {
QPointer<KeyListJob> cms, openpgp;
KeyListResult result;
std::vector<Key> keys;
void reset() { *this = KeyListingVariables(); }
} keyListing;
struct DownloadVariables {
Key key;
QPointer<DownloadJob> job;
Error error;
};
std::vector<DownloadVariables> downloads;
QByteArray openPGPDownloadData, cmsDownloadData;
};
LookupCertificatesCommand::Private * LookupCertificatesCommand::d_func() { return static_cast<Private*>( d.get() ); }
const LookupCertificatesCommand::Private * LookupCertificatesCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
LookupCertificatesCommand::Private::Private( LookupCertificatesCommand * qq, KeyListController * c )
: ImportCertificatesCommand::Private( qq, c ),
dialog()
{
}
LookupCertificatesCommand::Private::~Private() {
kDebug();
delete dialog;
}
LookupCertificatesCommand::LookupCertificatesCommand( KeyListController * c )
: ImportCertificatesCommand( new Private( this, c ) )
{
d->init();
}
LookupCertificatesCommand::LookupCertificatesCommand( QAbstractItemView * v, KeyListController * c )
: ImportCertificatesCommand( v, new Private( this, c ) )
{
d->init();
}
void LookupCertificatesCommand::Private::init() {
}
LookupCertificatesCommand::~LookupCertificatesCommand() { kDebug(); }
void LookupCertificatesCommand::doStart() {
- if ( !d->checkConfig() ) {
- d->finished();
- return;
- }
-
d->createDialog();
assert( d->dialog );
d->dialog->setPassive( false );
d->dialog->show();
}
void LookupCertificatesCommand::Private::createDialog() {
if ( dialog )
return;
dialog = new LookupCertificatesDialog( view() );
dialog->setAttribute( Qt::WA_DeleteOnClose );
connect( dialog, SIGNAL(searchTextChanged(QString)),
q, SLOT(slotSearchTextChanged(QString)) );
connect( dialog, SIGNAL(saveAsRequested(std::vector<GpgME::Key>)),
q, SLOT(slotSaveAsRequested(std::vector<GpgME::Key>)) );
connect( dialog, SIGNAL(importRequested(std::vector<GpgME::Key>)),
q, SLOT(slotImportRequested(std::vector<GpgME::Key>)) );
connect( dialog, SIGNAL(detailsRequested(GpgME::Key)),
q, SLOT(slotDetailsRequested(GpgME::Key)) );
connect( dialog, SIGNAL(rejected()),
- q, SLOT(slotDialogRejected()) );
+ q, SLOT(cancel()) );
}
void LookupCertificatesCommand::Private::slotSearchTextChanged( const QString & str ) {
- // pressing return might trigger both search and dialog destruction (search focused and default key set)
- // On Windows, the dialog is then destroyed before this slot is called
- if ( dialog ) { //thus test
- dialog->setPassive( true );
- dialog->setCertificates( std::vector<Key>() );
- }
+ dialog->setPassive( true );
startKeyListJob( CMS, str );
startKeyListJob( OpenPGP, str );
}
void LookupCertificatesCommand::Private::startKeyListJob( GpgME::Protocol proto, const QString & str ) {
KeyListJob * const klj = createKeyListJob( proto );
if ( !klj )
return;
connect( klj, SIGNAL(result(GpgME::KeyListResult)),
q, SLOT(slotKeyListResult(GpgME::KeyListResult)) );
connect( klj, SIGNAL(nextKey(GpgME::Key)),
q, SLOT(slotNextKey(GpgME::Key)) );
if ( const Error err = klj->start( QStringList( str ) ) )
keyListing.result.mergeWith( KeyListResult( err ) );
else
if ( proto == CMS )
keyListing.cms = klj;
else
keyListing.openpgp = klj;
}
void LookupCertificatesCommand::Private::slotKeyListResult( const KeyListResult & r ) {
if ( q->sender() == keyListing.cms )
keyListing.cms = 0;
else if ( q->sender() == keyListing.openpgp )
keyListing.openpgp = 0;
else
kDebug() << "unknown sender()" << q->sender();
keyListing.result.mergeWith( r );
if ( keyListing.cms || keyListing.openpgp ) // still waiting for jobs to complete
return;
if ( keyListing.result.error() && !keyListing.result.error().isCanceled() )
showError( dialogOrView(), keyListing.result );
if ( dialog ) {
dialog->setCertificates( keyListing.keys );
dialog->setPassive( false );
} else {
finished();
}
keyListing.reset();
}
void LookupCertificatesCommand::Private::slotImportRequested( const std::vector<Key> & keys ) {
dialog = 0;
assert( !keys.empty() );
kdtools::for_each( keys, bind( &Private::startDownloadJob, this, _1 ) );
}
static shared_ptr<QBuffer> make_open_qbuffer() {
const shared_ptr<QBuffer> buffer( new QBuffer );
if ( !buffer->open( QIODevice::WriteOnly ) )
kFatal() << "QBuffer::open failed";
return buffer;
}
void LookupCertificatesCommand::Private::startDownloadJob( const Key & key ) {
if ( key.isNull() )
return;
DownloadJob * const dlj = createDownloadJob( key.protocol() );
if ( !dlj )
return;
connect( dlj, SIGNAL(result(GpgME::Error,QByteArray)),
q, key.protocol() == CMS
? SLOT(slotCMSDownloadResult(GpgME::Error,QByteArray))
: SLOT(slotOpenPGPDownloadResult(GpgME::Error,QByteArray)) );
DownloadVariables var;
var.key = key;
if ( const Error err = dlj->start( QStringList( key.primaryFingerprint() ) ) )
var.error = err;
else
var.job = dlj;
downloads.push_back( var );
}
namespace {
template <typename T>
QStringList filter_and_format_successful_downloads( const T & t ) {
QStringList result;
-
+
return result;
}
template <typename T>
QByteArray combined_nonfailed_data( GpgME::Protocol proto, const T & t ) {
QByteArray result;
Q_FOREACH( const typename T::value_type & v, t )
if ( !v.error.code() && v.data && v.key.protocol() == proto )
result.append( v.data->data() );
return result;
}
}
void LookupCertificatesCommand::Private::slotOpenPGPDownloadResult( const GpgME::Error & err, const QByteArray & keyData ) {
const std::vector<DownloadVariables>::iterator it =
std::find_if( downloads.begin(), downloads.end(),
bind( &DownloadVariables::job, _1 ) == q->sender() );
assert( it != downloads.end() );
openPGPDownloadData.append( keyData );
it->job = 0;
it->error = err;
checkForDownloadFinished();
}
void LookupCertificatesCommand::Private::slotCMSDownloadResult( const GpgME::Error & err, const QByteArray & keyData ) {
const std::vector<DownloadVariables>::iterator it =
std::find_if( downloads.begin(), downloads.end(),
bind( &DownloadVariables::job, _1 ) == q->sender() );
assert( it != downloads.end() );
cmsDownloadData.append( keyData );
it->job = 0;
it->error = err;
checkForDownloadFinished();
}
void LookupCertificatesCommand::Private::checkForDownloadFinished() {
if ( kdtools::any( downloads, mem_fn( &DownloadVariables::job ) ) )
return; // still jobs to end
if ( kdtools::all( downloads, mem_fn( &DownloadVariables::error ) ) ) {
KMessageBox::information( dialogOrView(),
downloads.size() == 1 ?
i18n( "Download of certificate %1 failed. Error message: %2",
Formatting::formatForComboBox( downloads.front().key ),
QString::fromLocal8Bit( downloads.front().error.asString() ) ) :
i18n( "All certificate downloads failed. Sample error message: %1",
QString::fromLocal8Bit( downloads.front().error.asString() ) ),
i18n( "Certificate Downloads Failed" ) );
finished();
return;
} else if ( kdtools::any( downloads, mem_fn( &DownloadVariables::error ) ) &&
KMessageBox::questionYesNoList( dialogOrView(),
i18n( "Some certificates failed to download. "
"Do you want to proceed importing the following, succeded, downloads?" ),
filter_and_format_successful_downloads( downloads ),
i18n( "Certificate Downloads Failed" ) )
== KMessageBox::No )
{
finished();
return;
}
const QByteArray cms = cmsDownloadData;//combined_nonfailed_data( CMS, downloads );
const QByteArray pgp = openPGPDownloadData;//combined_nonfailed_data( OpenPGP, downloads );
if ( !cms.isEmpty() )
startImport( CMS, cms );
if ( !pgp.isEmpty() )
startImport( OpenPGP, pgp );
}
void LookupCertificatesCommand::Private::slotSaveAsRequested( const std::vector<Key> & keys ) {
kDebug() << "not implemented";
}
void LookupCertificatesCommand::Private::slotDetailsRequested( const Key & key ) {
( new DetailsCommand( key, view(), controller() ) )->start();
}
void LookupCertificatesCommand::doCancel() {
ImportCertificatesCommand::doCancel();
if ( QDialog * const dlg = d->dialog ) {
d->dialog = 0;
dlg->close();
}
}
void LookupCertificatesCommand::Private::showError( QWidget * parent, const KeyListResult & result ) {
if ( !result.error() )
return;
KMessageBox::information( parent, i18n( "Failed to search on keyserver. The error returned was:\n%1",
QString::fromLocal8Bit( result.error().asString() ) ) );
}
-static bool haveOpenPGPKeyserverConfigured() {
- const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
- if ( !config )
- return false;
- const Kleo::CryptoConfigEntry * const entry = config->entry( "gpg", "Keyserver", "keyserver" );
- return entry && !entry->stringValue().isEmpty();
-}
-
-
-static bool haveX509DirectoryServerConfigured() {
- const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
- if ( !config )
- return false;
- const Kleo::CryptoConfigEntry * const entry = config->entry( "dirmngr", "LDAP", "LDAP Server" );
- return entry && !entry->urlValueList().empty();
-}
-
-
-bool LookupCertificatesCommand::Private::checkConfig() const {
- const bool ok = haveOpenPGPKeyserverConfigured() || haveX509DirectoryServerConfigured();
- if ( !ok )
- KMessageBox::information( view(), i18nc("@info",
- "<para>You do not have any directory servers configured.</para>"
- "<para>You need to configure at least one directory server to "
- "search on one.</para>"
- "<para>You can configure directory servers here: "
- "<interface>Settings->Configure Kleopatra</interface>.</para>"),
- i18nc("@title", "No Directory Servers Configured") );
- return ok;
-}
#undef d
#undef q
#include "moc_lookupcertificatescommand.cpp"
diff --git a/commands/lookupcertificatescommand.h b/commands/lookupcertificatescommand.h
index 88a918cbd..4c36e5fb6 100644
--- a/commands/lookupcertificatescommand.h
+++ b/commands/lookupcertificatescommand.h
@@ -1,70 +1,69 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/lookupcertificatescommand.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_COMMMANDS_LOOKUPCERTIFICATESCOMMAND_H__
#define __KLEOPATRA_COMMMANDS_LOOKUPCERTIFICATESCOMMAND_H__
#include <commands/importcertificatescommand.h>
namespace Kleo {
namespace Commands {
class LookupCertificatesCommand : public ImportCertificatesCommand {
Q_OBJECT
public:
explicit LookupCertificatesCommand( QAbstractItemView * view, KeyListController * parent );
explicit LookupCertificatesCommand( KeyListController * parent );
~LookupCertificatesCommand();
private:
/* reimp */ void doStart();
/* reimp */ void doCancel();
private:
class Private;
inline Private * d_func();
inline const Private * d_func() const;
Q_PRIVATE_SLOT( d_func(), void slotSearchTextChanged(QString) )
Q_PRIVATE_SLOT( d_func(), void slotNextKey(GpgME::Key) )
Q_PRIVATE_SLOT( d_func(), void slotKeyListResult(GpgME::KeyListResult) )
Q_PRIVATE_SLOT( d_func(), void slotImportRequested(std::vector<GpgME::Key>) )
Q_PRIVATE_SLOT( d_func(), void slotOpenPGPDownloadResult(GpgME::Error,QByteArray) )
Q_PRIVATE_SLOT( d_func(), void slotCMSDownloadResult(GpgME::Error,QByteArray) )
Q_PRIVATE_SLOT( d_func(), void slotDetailsRequested(GpgME::Key) )
Q_PRIVATE_SLOT( d_func(), void slotSaveAsRequested(std::vector<GpgME::Key>) )
- Q_PRIVATE_SLOT( d_func(), void slotDialogRejected() )
};
}
}
#endif // __KLEOPATRA_COMMMANDS_LOOKUPCERTIFICATESCOMMAND_H__
diff --git a/commands/refreshopenpgpcertscommand.cpp b/commands/refreshopenpgpcertscommand.cpp
index 99b9881f0..cba7993ae 100644
--- a/commands/refreshopenpgpcertscommand.cpp
+++ b/commands/refreshopenpgpcertscommand.cpp
@@ -1,138 +1,138 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/refreshopenpgpcertscommand.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 "refreshopenpgpcertscommand.h"
#include <utils/gnupg-helper.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/cryptoconfig.h>
#include <KLocale>
#include <KMessageBox>
using namespace Kleo;
using namespace Kleo::Commands;
static bool haveKeyserverConfigured() {
const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
if ( !config )
return false;
const Kleo::CryptoConfigEntry * const entry = config->entry( "gpg", "Keyserver", "keyserver" );
return entry && !entry->stringValue().isEmpty();
}
RefreshOpenPGPCertsCommand::RefreshOpenPGPCertsCommand( KeyListController * c )
: GnuPGProcessCommand( c )
{
}
RefreshOpenPGPCertsCommand::RefreshOpenPGPCertsCommand( QAbstractItemView * v, KeyListController * c )
: GnuPGProcessCommand( v, c )
{
}
RefreshOpenPGPCertsCommand::~RefreshOpenPGPCertsCommand() {}
bool RefreshOpenPGPCertsCommand::preStartHook( QWidget * parent ) const {
if ( !haveKeyserverConfigured() )
if ( KMessageBox::warningContinueCancel( parent,
i18nc("@info",
"<para>No OpenPGP directory services have been configured.</para>"
"<para>If not all of the certificates carry the name of their preferred "
"certificate server (few do), a fallback server is needed to fetch from.</para>"
"<para>Since none is configured, <application>Kleopatra</application> will use "
"<resource>keys.gnupg.net</resource> as the fallback.</para>"
"<para>You can configure OpenPGP directory servers in Kleopatra's "
"configuration dialog.</para>"
"<para>Do you want to continue with <resource>keys.gnupg.net</resource> "
"as fallback server?</para>" ),
- i18n("OpenPGP Certificate Refresh"),
+ i18n("OpenPGP Certitifcate Refresh"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
QLatin1String( "warn-refresh-openpgp-missing-keyserver" ) )
!= KMessageBox::Continue )
return false;
return KMessageBox::warningContinueCancel( parent,
i18nc("@info",
"<para>Refreshing OpenPGP certificates implies downloading all certificates anew, "
"to check if any of them have been revoked in the meantime.</para>"
"<para>This can put a severe strain on your own as well as other people's network "
"connection, and can take up to an hour or more to complete, depending on "
"your network connection, and the number of certificates to check.</para> "
"<para>Are you sure you want to continue?</para>"),
- i18n("OpenPGP Certificate Refresh"),
+ i18n("OpenPGP Certitifcate Refresh"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
QLatin1String( "warn-refresh-openpgp-expensive" ) )
== KMessageBox::Continue;
}
QStringList RefreshOpenPGPCertsCommand::arguments() const {
QStringList result;
result << gpgPath();
if ( !haveKeyserverConfigured() )
result << "--keyserver" << "keys.gnupg.net";
result << "--refresh-keys";
return result;
}
QString RefreshOpenPGPCertsCommand::errorCaption() const {
return i18n( "OpenPGP Certificate Refresh Error" );
}
QString RefreshOpenPGPCertsCommand::successCaption() const {
return i18n( "OpenPGP Certificate Refresh Finished" );
}
QString RefreshOpenPGPCertsCommand::crashExitMessage( const QStringList & args ) const {
return i18nc("@info",
"<para>The GPG process that tried to refresh OpenPGP certificates "
"ended prematurely because of an unexpected error.</para>"
"<para>Please check the output of <icode>%1</icode> for details.</para>", args.join( " " ) ) ;
}
QString RefreshOpenPGPCertsCommand::errorExitMessage( const QStringList & args ) const {
return i18nc("@info",
"<para>An error occurred while trying to refresh OpenPGP certificates.</para> "
"<para>The output from <command>%1</command> was: <message>%2</message></para>",
args[0], errorString() );
}
QString RefreshOpenPGPCertsCommand::successMessage( const QStringList & ) const {
return i18n( "OpenPGP certificates refreshed successfully." );
// ### --check-trustdb
}
#include "moc_refreshopenpgpcertscommand.cpp"
diff --git a/commands/refreshx509certscommand.cpp b/commands/refreshx509certscommand.cpp
index 5887d7661..1005dbad4 100644
--- a/commands/refreshx509certscommand.cpp
+++ b/commands/refreshx509certscommand.cpp
@@ -1,104 +1,104 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/refreshx509certscommand.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 "refreshx509certscommand.h"
#include <utils/gnupg-helper.h>
#include <KLocale>
#include <KMessageBox>
using namespace Kleo;
using namespace Kleo::Commands;
RefreshX509CertsCommand::RefreshX509CertsCommand( KeyListController * c )
: GnuPGProcessCommand( c )
{
}
RefreshX509CertsCommand::RefreshX509CertsCommand( QAbstractItemView * v, KeyListController * c )
: GnuPGProcessCommand( v, c )
{
}
RefreshX509CertsCommand::~RefreshX509CertsCommand() {}
bool RefreshX509CertsCommand::preStartHook( QWidget * parent ) const {
return KMessageBox::warningContinueCancel( parent,
i18nc("@info",
"<para>Refreshing X.509 certificates implies downloading CRLs for all certificates, "
"even if they might otherwise still be valid.</para>"
"<para>This can put a severe strain on your own as well as other people's network "
"connection, and can take up to an hour or more to complete, depending on "
"your network connection, and the number of certificates to check.</para> "
"<para>Are you sure you want to continue?</para>"),
- i18n("X.509 Certificate Refresh"),
+ i18n("X.509 Certitifcate Refresh"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
QLatin1String( "warn-refresh-x509-expensive" ) )
== KMessageBox::Continue;
}
QStringList RefreshX509CertsCommand::arguments() const {
return QStringList() << gpgSmPath() << "-k" << "--with-validation" << "--force-crl-refresh" << "--enable-crl-checks";
}
QString RefreshX509CertsCommand::errorCaption() const {
return i18n( "X.509 Certificate Refresh Error" );
}
QString RefreshX509CertsCommand::successCaption() const {
return i18n( "X.509 Certificate Refresh Finished" );
}
QString RefreshX509CertsCommand::crashExitMessage( const QStringList & args ) const {
return i18nc( "@info",
"<para>The GpgSM process that tried to refresh X.509 certificates "
"ended prematurely because of an unexpected error.</para>"
"<para>Please check the output of <icode>%1</icode> for details.</para>", args.join( " " ) ) ;
}
QString RefreshX509CertsCommand::errorExitMessage( const QStringList & args ) const {
return i18nc( "@info",
"<para>An error occurred while trying to refresh X.509 certificates.</para>"
"<para>The output from <command>%1</command> was: <message>%2</message></para>",
args[0], errorString() );
}
QString RefreshX509CertsCommand::successMessage( const QStringList & ) const {
return i18n( "X.509 certificates refreshed successfully." );
}
#include "moc_refreshx509certscommand.cpp"
diff --git a/commands/selftestcommand.cpp b/commands/selftestcommand.cpp
index bb1ef031c..3444eacad 100644
--- a/commands/selftestcommand.cpp
+++ b/commands/selftestcommand.cpp
@@ -1,260 +1,247 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/selftestcommand.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 "selftestcommand.h"
#include "command_p.h"
#include <dialogs/selftestdialog.h>
#ifdef Q_OS_WIN
# include <selftest/registrycheck.h>
#endif
#include <selftest/enginecheck.h>
#include <selftest/gpgconfcheck.h>
#ifdef HAVE_KLEOPATRACLIENT_LIBRARY
# include <selftest/uiservercheck.h>
#endif
#include <utils/stl_util.h>
#include <KLocale>
#include <KGlobal>
#include <KConfigGroup>
#include <KSplashScreen>
#include <boost/shared_ptr.hpp>
#include <boost/mem_fn.hpp>
#include <vector>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace boost;
-static const char * const components[] = {
- 0, // gpgconf
- "gpg",
- "gpg-agent",
- "scdaemon",
- "gpgsm",
- "dirmngr",
-};
-static const unsigned int numComponents = sizeof components / sizeof *components;
-
class SelfTestCommand::Private : Command::Private {
friend class ::Kleo::Commands::SelfTestCommand;
SelfTestCommand * q_func() const { return static_cast<SelfTestCommand*>( q ); }
public:
explicit Private( SelfTestCommand * qq, KeyListController * c );
~Private();
private:
void init();
void ensureDialogCreated() {
if ( dialog )
return;
dialog = new SelfTestDialog( view() );
dialog->setAttribute( Qt::WA_DeleteOnClose );
connect( dialog, SIGNAL(updateRequested()),
q, SLOT(slotUpdateRequested()) );
connect( dialog, SIGNAL(accepted()),
q, SLOT(slotDialogAccepted()) );
connect( dialog, SIGNAL(rejected()),
q, SLOT(slotDialogRejected()) );
dialog->setRunAtStartUp( runAtStartUp() );
dialog->setAutomaticMode( automatic );
}
void ensureDialogShown() {
ensureDialogCreated();
if ( dialog->isVisible() )
dialog->raise();
else
dialog->show();
if ( splash )
splash->finish( dialog );
}
bool runAtStartUp() const {
const KConfigGroup config( KGlobal::config(), "Self-Test" );
return config.readEntry( "run-at-startup", true );
}
void setRunAtStartUp( bool on ) {
KConfigGroup config( KGlobal::config(), "Self-Test" );
config.writeEntry( "run-at-startup", on );
}
void runTests() {
std::vector< shared_ptr<Kleo::SelfTest> > tests;
#ifdef Q_OS_WIN
//emit q->info( i18n("Checking Windows Registry...") );
tests.push_back( makeGpgProgramRegistryCheckSelfTest() );
#endif
//emit q->info( i18n("Checking gpg installation...") );
tests.push_back( makeGpgEngineCheckSelfTest() );
//emit q->info( i18n("Checking gpgsm installation...") );
tests.push_back( makeGpgSmEngineCheckSelfTest() );
//emit q->info( i18n("Checking gpgconf installation...") );
tests.push_back( makeGpgConfEngineCheckSelfTest() );
- for ( unsigned int i = 0 ; i < numComponents ; ++i ) {
- //emit q->info( i18n("Checking %1 configuration...", components[i]) );
- tests.push_back( makeGpgConfCheckConfigurationSelfTest( components[i] ) );
- }
+ //emit q->info( i18n("Checking gpgconf configuration...") );
+ tests.push_back( makeGpgConfCheckConfigurationSelfTest() );
#ifdef HAVE_KLEOPATRACLIENT_LIBRARY
//emit q->info( i18n("Checking Ui Server connectivity...") );
tests.push_back( makeUiServerConnectivitySelfTest() );
#endif
if ( !dialog && kdtools::all( tests, mem_fn( &Kleo::SelfTest::passed ) ) ) {
finished();
return;
}
ensureDialogCreated();
dialog->clear();
dialog->addSelfTests( tests );
ensureDialogShown();
}
private:
void slotDialogAccepted() {
setRunAtStartUp( dialog->runAtStartUp() );
finished();
}
void slotDialogRejected() {
if ( automatic ) {
canceled = true;
Command::Private::canceled();
} else {
slotDialogAccepted();
}
}
void slotUpdateRequested() {
runTests();
}
private:
QPointer<KSplashScreen> splash;
QPointer<SelfTestDialog> dialog;
bool canceled;
bool automatic;
};
SelfTestCommand::Private * SelfTestCommand::d_func() { return static_cast<Private*>( d.get() ); }
const SelfTestCommand::Private * SelfTestCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
#define d d_func()
#define q q_func()
SelfTestCommand::Private::Private( SelfTestCommand * qq, KeyListController * c )
: Command::Private( qq, c ),
splash(),
dialog(),
canceled( false ),
automatic( false )
{
}
SelfTestCommand::Private::~Private() {
}
SelfTestCommand::SelfTestCommand( KeyListController * c )
: Command( new Private( this, c ) )
{
d->init();
}
SelfTestCommand::SelfTestCommand( QAbstractItemView * v, KeyListController * c )
: Command( v, new Private( this, c ) )
{
d->init();
}
void SelfTestCommand::Private::init() {
}
SelfTestCommand::~SelfTestCommand() {}
void SelfTestCommand::setAutomaticMode( bool on ) {
d->automatic = on;
if ( d->dialog )
d->dialog->setAutomaticMode( on );
}
void SelfTestCommand::setSplashScreen( KSplashScreen * splash ) {
d->splash = splash;
}
bool SelfTestCommand::isCanceled() const {
return d->canceled;
}
void SelfTestCommand::doStart() {
if ( d->automatic ) {
if ( !d->runAtStartUp() ) {
d->finished();
return;
}
- } else {
d->ensureDialogCreated();
}
d->runTests();
}
void SelfTestCommand::doCancel() {
d->canceled = true;
if ( d->dialog )
d->dialog->close();
d->dialog = 0;
}
#undef d
#undef q
#include "moc_selftestcommand.cpp"
diff --git a/conf/dirservconfigpage.cpp b/conf/dirservconfigpage.cpp
index cea5f7ed5..b40ea9c47 100644
--- a/conf/dirservconfigpage.cpp
+++ b/conf/dirservconfigpage.cpp
@@ -1,379 +1,346 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/dirservconfigpage.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2004,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 "dirservconfigpage.h"
#include "libkleo/ui/directoryserviceswidget.h"
#include "libkleo/kleo/cryptobackendfactory.h"
-#include <kdemacros.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kdebug.h>
#include <kconfig.h>
#include <knuminput.h>
#include <kdialog.h>
#include <kcomponentdata.h>
+#include <khbox.h>
#include <QLabel>
#include <qdatetimeedit.h>
#include <QCheckBox>
#include <QLayout>
+#include <kdemacros.h>
+
using namespace Kleo;
#if 0 // disabled, since it is apparently confusing
// For sync'ing kabldaprc
class KABSynchronizer
{
public:
KABSynchronizer()
: mConfig( "kabldaprc" ) {
mConfig.setGroup( "LDAP" );
}
KUrl::List readCurrentList() const {
KUrl::List lst;
// stolen from kabc/ldapclient.cpp
const uint numHosts = mConfig.readEntry( "NumSelectedHosts" );
for ( uint j = 0; j < numHosts; j++ ) {
const QString num = QString::number( j );
KUrl url;
url.setProtocol( "ldap" );
url.setPath( "/" ); // workaround KUrl parsing bug
const QString host = mConfig.readEntry( QString( "SelectedHost" ) + num ).trimmed();
url.setHost( host );
const int port = mConfig.readEntry( QString( "SelectedPort" ) + num );
if ( port != 0 )
url.setPort( port );
const QString base = mConfig.readEntry( QString( "SelectedBase" ) + num ).trimmed();
url.setQuery( base );
const QString bindDN = mConfig.readEntry( QString( "SelectedBind" ) + num ).trimmed();
url.setUser( bindDN );
const QString pwdBindDN = mConfig.readEntry( QString( "SelectedPwdBind" ) + num ).trimmed();
url.setPass( pwdBindDN );
lst.append( url );
}
return lst;
}
void writeList( const KUrl::List& lst ) {
mConfig.writeEntry( "NumSelectedHosts", lst.count() );
KUrl::List::const_iterator it = lst.begin();
KUrl::List::const_iterator end = lst.end();
unsigned j = 0;
for( ; it != end; ++it, ++j ) {
const QString num = QString::number( j );
KUrl url = *it;
Q_ASSERT( url.protocol() == "ldap" );
mConfig.writeEntry( QString( "SelectedHost" ) + num, url.host() );
mConfig.writeEntry( QString( "SelectedPort" ) + num, url.port() );
// KUrl automatically encoded the query (e.g. for spaces inside it),
// so decode it before writing it out
const QString base = KUrl::decode_string( url.query().mid(1) );
mConfig.writeEntry( QString( "SelectedBase" ) + num, base );
mConfig.writeEntry( QString( "SelectedBind" ) + num, url.user() );
mConfig.writeEntry( QString( "SelectedPwdBind" ) + num, url.pass() );
}
mConfig.sync();
}
private:
KConfig mConfig;
};
#endif
static const char s_x509services_componentName[] = "dirmngr";
static const char s_x509services_groupName[] = "LDAP";
static const char s_x509services_entryName[] = "LDAP Server";
-static const char s_x509services_new_componentName[] = "gpgsm";
-static const char s_x509services_new_groupName[] = "Configuration";
-static const char s_x509services_new_entryName[] = "keyserver";
-
static const char s_pgpservice_componentName[] = "gpg";
static const char s_pgpservice_groupName[] = "Keyserver";
static const char s_pgpservice_entryName[] = "keyserver";
static const char s_timeout_componentName[] = "dirmngr";
static const char s_timeout_groupName[] = "LDAP";
static const char s_timeout_entryName[] = "ldaptimeout";
static const char s_maxitems_componentName[] = "dirmngr";
static const char s_maxitems_groupName[] = "LDAP";
static const char s_maxitems_entryName[] = "max-replies";
static const char s_addnewservers_componentName[] = "dirmngr";
static const char s_addnewservers_groupName[] = "LDAP";
static const char s_addnewservers_entryName[] = "add-servers";
DirectoryServicesConfigurationPage::DirectoryServicesConfigurationPage( const KComponentData &instance, QWidget *parent, const QVariantList &args )
: KCModule( instance, parent, args )
{
mConfig = Kleo::CryptoBackendFactory::instance()->config();
QGridLayout * glay = new QGridLayout( this );
glay->setSpacing( KDialog::spacingHint() );
glay->setMargin( 0 );
int row = 0;
mWidget = new Kleo::DirectoryServicesWidget( this );
if ( QLayout * l = mWidget->layout() ) {
l->setSpacing( KDialog::spacingHint() );
l->setMargin( 0 );
}
glay->addWidget( mWidget, row, 0, 1, 3 );
connect( mWidget, SIGNAL(changed()), this, SLOT(changed()) );
// LDAP timeout
++row;
QLabel* label = new QLabel( i18n( "LDAP &timeout (minutes:seconds):" ), this );
mTimeout = new QTimeEdit( this );
mTimeout->setDisplayFormat( "mm:ss" );
connect( mTimeout, SIGNAL(timeChanged(QTime)), this, SLOT(changed()) );
label->setBuddy( mTimeout );
glay->addWidget( label, row, 0 );
glay->addWidget( mTimeout, row, 1 );
// Max number of items returned by queries
++row;
label = new QLabel( i18n( "&Maximum number of items returned by query:" ), this );
mMaxItems = new KIntNumInput( this );
mMaxItems->setMinimum( 0 );
label->setBuddy( mMaxItems );
connect( mMaxItems, SIGNAL(valueChanged(int)), this, SLOT(changed()) );
glay->addWidget( label, row, 0 );
glay->addWidget( mMaxItems, row, 1 );
#ifdef NOT_USEFUL_CURRENTLY
++row
mAddNewServersCB = new QCheckBox( i18n( "Automatically add &new servers discovered in CRL distribution points" ), this );
connect( mAddNewServersCB, SIGNAL(clicked()), this, SLOT(changed()) );
glay->addWidget( mAddNewServersCB, row, 0, 1, 3 );
#endif
glay->setRowStretch( ++row, 1 );
glay->setColumnStretch( 2, 1 );
#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
load();
#endif
}
static KUrl::List string2urls( const QString & str ) {
return str.isEmpty() ? KUrl::List() : KUrl( str ) ;
}
-static KUrl::List strings2urls( const QStringList & strs ) {
- KUrl::List urls;
- Q_FOREACH( const QString & str, strs )
- if ( !str.isEmpty() )
- urls.push_back( KUrl( str ) );
- return urls;
-}
-
-static QStringList urls2strings( const KUrl::List & urls ) {
- QStringList result;
- Q_FOREACH( const KUrl & url, urls )
- result.push_back( url.url() );
- return result;
-}
-
void DirectoryServicesConfigurationPage::load()
{
mWidget->clear();
- if ( ( mX509ServicesEntry = configEntry( s_x509services_new_componentName, s_x509services_new_groupName, s_x509services_new_entryName,
- Kleo::CryptoConfigEntry::ArgType_String, true ) ) )
- mWidget->addX509Services( strings2urls( mX509ServicesEntry->stringValueList() ) );
- else if ( ( mX509ServicesEntry = configEntry( s_x509services_componentName, s_x509services_groupName, s_x509services_entryName,
- Kleo::CryptoConfigEntry::ArgType_LDAPURL, true ) ) )
+ mX509ServicesEntry = configEntry( s_x509services_componentName, s_x509services_groupName, s_x509services_entryName,
+ Kleo::CryptoConfigEntry::ArgType_LDAPURL, true );
+ if ( mX509ServicesEntry )
mWidget->addX509Services( mX509ServicesEntry->urlValueList() );
- mWidget->setX509ReadOnly( mX509ServicesEntry && mX509ServicesEntry->isReadOnly() );
-
mOpenPGPServiceEntry = configEntry( s_pgpservice_componentName, s_pgpservice_groupName, s_pgpservice_entryName,
Kleo::CryptoConfigEntry::ArgType_String, false );
if ( mOpenPGPServiceEntry )
mWidget->addOpenPGPServices( string2urls( mOpenPGPServiceEntry->stringValue() ) );
- mWidget->setOpenPGPReadOnly( mOpenPGPServiceEntry && mOpenPGPServiceEntry->isReadOnly() );
-
if ( mX509ServicesEntry )
if ( mOpenPGPServiceEntry )
mWidget->setAllowedProtocols( DirectoryServicesWidget::AllProtocols );
else
mWidget->setAllowedProtocols( DirectoryServicesWidget::X509Protocol );
else
if ( mOpenPGPServiceEntry )
mWidget->setAllowedProtocols( DirectoryServicesWidget::OpenPGPProtocol );
else
mWidget->setDisabled( true );
- DirectoryServicesWidget::Protocols readOnlyProtocols;
- if ( mX509ServicesEntry && mX509ServicesEntry->isReadOnly() )
- readOnlyProtocols = DirectoryServicesWidget::X509Protocol;
-
mTimeoutConfigEntry = configEntry( s_timeout_componentName, s_timeout_groupName, s_timeout_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
if ( mTimeoutConfigEntry ) {
QTime time = QTime().addSecs( mTimeoutConfigEntry->uintValue() );
//kDebug() <<"timeout:" << mTimeoutConfigEntry->uintValue() <<" ->" << time;
mTimeout->setTime( time );
}
mMaxItemsConfigEntry = configEntry( s_maxitems_componentName, s_maxitems_groupName, s_maxitems_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
if ( mMaxItemsConfigEntry ) {
mMaxItems->blockSignals( true ); // KNumInput emits valueChanged from setValue!
mMaxItems->setValue( mMaxItemsConfigEntry->uintValue() );
mMaxItems->blockSignals( false );
}
#ifdef NOT_USEFUL_CURRENTLY
mAddNewServersConfigEntry = configEntry( s_addnewservers_componentName, s_addnewservers_groupName, s_addnewservers_entryName, Kleo::CryptoConfigEntry::ArgType_None, false );
if ( mAddNewServersConfigEntry ) {
mAddNewServersCB->setChecked( mAddNewServersConfigEntry->boolValue() );
}
#endif
}
void DirectoryServicesConfigurationPage::save()
{
if ( mX509ServicesEntry )
- if ( mX509ServicesEntry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL )
- mX509ServicesEntry->setURLValueList( mWidget->x509Services() );
- else
- mX509ServicesEntry->setStringValueList( urls2strings( mWidget->x509Services() ) );
+ mX509ServicesEntry->setURLValueList( mWidget->x509Services() );
if ( mOpenPGPServiceEntry ) {
const KUrl::List serv = mWidget->openPGPServices();
if ( serv.empty() )
mOpenPGPServiceEntry->setStringValue( QString() );
else
mOpenPGPServiceEntry->setStringValue( serv.front().url() );
}
QTime time( mTimeout->time() );
unsigned int timeout = time.minute() * 60 + time.second();
if ( mTimeoutConfigEntry && mTimeoutConfigEntry->uintValue() != timeout )
mTimeoutConfigEntry->setUIntValue( timeout );
if ( mMaxItemsConfigEntry && mMaxItemsConfigEntry->uintValue() != (uint)mMaxItems->value() )
mMaxItemsConfigEntry->setUIntValue( mMaxItems->value() );
#ifdef NOT_USEFUL_CURRENTLY
if ( mAddNewServersConfigEntry && mAddNewServersConfigEntry->boolValue() != mAddNewServersCB->isChecked() )
mAddNewServersConfigEntry->setBoolValue( mAddNewServersCB->isChecked() );
#endif
mConfig->sync( true );
#if 0
// Also write the LDAP URLs to kabldaprc so that they are used by kaddressbook
KABSynchronizer sync;
const KUrl::List toAdd = mWidget->urlList();
KUrl::List currentList = sync.readCurrentList();
KUrl::List::const_iterator it = toAdd.begin();
KUrl::List::const_iterator end = toAdd.end();
for( ; it != end; ++it ) {
// check if the URL is already in currentList
if ( currentList.find( *it ) == currentList.end() )
// if not, add it
currentList.append( *it );
}
sync.writeList( currentList );
#endif
}
void DirectoryServicesConfigurationPage::defaults()
{
// these guys don't have a default, to clear them:
if ( mX509ServicesEntry )
- if ( mX509ServicesEntry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL )
- mX509ServicesEntry->setURLValueList( KUrl() );
- else
- mX509ServicesEntry->setStringValueList( QStringList() );
+ mX509ServicesEntry->setURLValueList( KUrl() );
if ( mOpenPGPServiceEntry )
mOpenPGPServiceEntry->setStringValue( QString() );
// these presumably have a default, use that one:
if ( mTimeoutConfigEntry )
mTimeoutConfigEntry->resetToDefault();
if ( mMaxItemsConfigEntry )
mMaxItemsConfigEntry->resetToDefault();
#ifdef NOT_USEFUL_CURRENTLY
if ( mAddNewServersConfigEntry )
mAddNewServersConfigEntry->resetToDefault();
#endif
load();
}
extern "C"
{
KDE_EXPORT KCModule *create_kleopatra_config_dirserv( QWidget *parent=0, const QVariantList &args=QVariantList() )
{
DirectoryServicesConfigurationPage *page =
new DirectoryServicesConfigurationPage( KComponentData( "kleopatra" ), parent, args );
page->setObjectName( "kleopatra_config_dirserv" );
return page;
}
}
// Find config entry for ldap servers. Implements runtime checks on the configuration option.
Kleo::CryptoConfigEntry* DirectoryServicesConfigurationPage::configEntry( const char* componentName,
const char* groupName,
const char* entryName,
Kleo::CryptoConfigEntry::ArgType argType,
bool isList )
{
Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName );
if ( !entry ) {
KMessageBox::error( this, i18n( "Backend error: gpgconf does not seem to know the entry for %1/%2/%3", componentName, groupName, entryName ) );
return 0;
}
if( entry->argType() != argType || entry->isList() != isList ) {
KMessageBox::error( this, i18n( "Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5", componentName, groupName, entryName, entry->argType(), entry->isList() ) );
return 0;
}
return entry;
}
#include "dirservconfigpage.moc"
diff --git a/conf/kleopatra_config_dirserv.desktop b/conf/kleopatra_config_dirserv.desktop
index abf9412ee..e2e227216 100644
--- a/conf/kleopatra_config_dirserv.desktop
+++ b/conf/kleopatra_config_dirserv.desktop
@@ -1,133 +1,132 @@
[Desktop Entry]
Icon=preferences-system-network
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kleopatra/configuration.html#configuration-directory-services
X-KDE-ModuleType=Library
X-KDE-Library=kcm_kleopatra
X-KDE-FactoryName=kleopatra_config_dirserv
X-KDE-HasReadOnlyMode=false
X-KDE-ParentApp=kleopatra
X-KDE-ParentComponents=kleopatra
X-KDE-CfgDlgHierarchy=Kleopatra
Name=Directory Services
Name[bg]=Директорийни услуги
Name[ca]=Serveis de directori
Name[cs]=Adresářové služby
-Name[da]=Directory-tjenester
+Name[da]=Opslagstjeneste
Name[de]=Verzeichnisdienste
Name[el]=Υπηρεσίες καταλόγου
Name[eo]=Dosierujaj Servoj
Name[es]=Servicios de directorio
Name[et]=Kataloogiteenused
Name[eu]=Direktorio zerbitzuak
Name[fa]=خدمات فهرست راهنما
Name[fi]=Hakemistopalvelut
Name[fr]=Services d'annuaires
Name[fy]=Maptsjinsten
Name[ga]=Seirbhísí Eolaire
Name[gl]=Servicios de Directorio
Name[he]=שירותי ספרייה
Name[hu]=Címtárszolgáltatások
Name[is]=Nafnaþjónustur
Name[it]=Servizi Directory
Name[ja]=ディレクトリサービス
Name[ka]=საცნობარო მომსახურება
Name[kk]=Каталог қызметтері
Name[km]=សេវា​ថត
Name[ko]=디렉터리 서비스
Name[lt]=Aplankų tarnybos
Name[lv]=Direktoriju servisi
Name[mk]=Именички сервиси
Name[ms]=Servis Direktori
Name[nb]=Katalogtjenere
Name[nds]=Vertekendeensten
Name[ne]=डाइरेक्टरी सेवा
Name[nl]=Mapdiensten
Name[pa]=ਡਾਇਰੈਕਟਰੀ ਸਰਵਿਸਾਂ
Name[pl]=Usługi katalogowe
Name[pt]=Serviços de Directório
Name[pt_BR]=Serviços de Diretório
Name[ru]=Службы каталогов
Name[se]=Ohcobálvalusat
Name[sk]=Adresárové služby
Name[sl]=Imeniške storitve
Name[sv]=Katalogtjänster
Name[ta]= அடைவு சேவைகள்
Name[tg]=Кӯмакҳои каталог
Name[tr]=Dizin Servisleri
Name[uk]=Служби каталогів
Name[x-test]=xxDirectory Servicesxx
Name[zh_CN]=目录服务
Name[zh_TW]=目錄服務
Comment=Configuration of directory services
Comment[ca]=Configuració dels serveis de directori
-Comment[da]=Indstilling af directory-tjenester
Comment[de]=Einrichtung von Verzeichnisdiensten
Comment[el]=Ρυθμίσεις των υπηρεσιών καταλόγου
Comment[et]=Kataloogiteenuste seadistused
Comment[fr]=Configuration des annuaires
Comment[ga]=Cumraíocht seirbhísí eolaire
Comment[ja]=ディレクトリサービスの設定
Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​សេវា​ថត
Comment[lv]=Direktoriju servisu konfigurēšana
Comment[nds]=Vertekendeensten instellen
Comment[pl]=Konfiguracja usług katalogowych
Comment[pt]=Configuração dos serviços de directório
Comment[pt_BR]=Configuração dos serviços de diretório
Comment[sv]=Inställning av katalogtjänster
Comment[tr]=Dizin servisleri yapılandırması
Comment[uk]=Налаштування служб каталогів
Comment[x-test]=xxConfiguration of directory servicesxx
Comment[zh_CN]=目录服务配置
Comment[zh_TW]=目錄服務設定
X-KDE-Keywords=ldap,directory,services,hkp,keyserver
X-KDE-Keywords[af]=ldap,directory,services,gids
X-KDE-Keywords[be]=каталог,сэрвісы,ldap,directory,services
X-KDE-Keywords[bg]=Keywords=директорийни, услуги, ldap, directory, services
X-KDE-Keywords[br]=ldap,renkell,servijeroù
X-KDE-Keywords[ca]=ldap,directori,serveis
X-KDE-Keywords[cs]=LDAP,adresář,služby
X-KDE-Keywords[da]=ldap,opslag,tjenester
X-KDE-Keywords[de]=LDAP,Verzeichnis,Dienste
X-KDE-Keywords[el]=ldap,κατάλογος,υπηρεσίες
X-KDE-Keywords[es]=ldap,directorio,servicios
X-KDE-Keywords[et]=ldap,kataloog,teenused
X-KDE-Keywords[eu]=Idap, direktorio, zerbitzuak
X-KDE-Keywords[fa]=ldap، فهرست راهنما، خدمات
X-KDE-Keywords[fi]=ldap,hakemisto,palvelut
X-KDE-Keywords[fr]=ldap,dossier,dossiers,service,services
X-KDE-Keywords[fy]=ldap,directory,services,triemtafel,tsjinsten
X-KDE-Keywords[ga]=ldap,eolaire,seirbhísí
X-KDE-Keywords[gl]=ldap,directorio,servicios
X-KDE-Keywords[he]=ldap,directory,services,ספרייה,שירותים
X-KDE-Keywords[hu]=ldap,címtár,szolgáltatások
X-KDE-Keywords[is]=ldap,directory,services,nafnaþjónusta
X-KDE-Keywords[it]=ldap, servizi, directory
X-KDE-Keywords[ja]=ldap,ディレクトリ,サービス
X-KDE-Keywords[ka]=ldap,ცნობარი,მომსახურება
X-KDE-Keywords[km]=ldap,ថត,សេវា
X-KDE-Keywords[ko]=ldap,디렉터리,서비스
X-KDE-Keywords[lt]=ldap,directory,services,aplankai,tarnybos
X-KDE-Keywords[mk]=ldap,directory,services,именик,сервиси
X-KDE-Keywords[ms]=ldap,direktori,servis
X-KDE-Keywords[nb]=ldap,mappe,tjenester
X-KDE-Keywords[nds]=LDAP,Verteken,Deensten
X-KDE-Keywords[ne]=ldap,डाइरेक्टरी,कार्य
X-KDE-Keywords[pl]=ldap,katalog,usługi katalogowe,usługi,LDAP
X-KDE-Keywords[pt]=ldap,directório,serviços
X-KDE-Keywords[pt_BR]=ldap,diretório,serviços
X-KDE-Keywords[ru]=LDAP,службы каталогов
X-KDE-Keywords[se]=ldap,ohcu,bálvalusat
X-KDE-Keywords[sl]=ldap,imenik,storitve
X-KDE-Keywords[sr]=ldap,директоријум,сервиси
X-KDE-Keywords[sr@latin]=ldap,direktorijum,servisi
X-KDE-Keywords[sv]=ldap,katalog,tjänster
X-KDE-Keywords[ta]=ldap, அடைவு, சேவைகள்
X-KDE-Keywords[tg]=ldap,кӯмакҳои каталог
X-KDE-Keywords[tr]=ldap,dizin,servisler
X-KDE-Keywords[uk]=ldap,служби,каталогів
X-KDE-Keywords[x-test]=xxldap,directory,servicesxx
X-KDE-Keywords[zh_CN]=ldap,directory,services,目录,服务
diff --git a/conf/kleopatra_config_smimevalidation.desktop b/conf/kleopatra_config_smimevalidation.desktop
index 6115bbd34..a468d55ab 100644
--- a/conf/kleopatra_config_smimevalidation.desktop
+++ b/conf/kleopatra_config_smimevalidation.desktop
@@ -1,55 +1,53 @@
[Desktop Entry]
Icon=preferences-system-network
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kleopatra/configuration.html#configuration-smime-validation
X-KDE-ModuleType=Library
X-KDE-Library=kcm_kleopatra
X-KDE-FactoryName=kleopatra_config_smimevalidation
X-KDE-HasReadOnlyMode=false
X-KDE-ParentApp=kleopatra
X-KDE-ParentComponents=kleopatra
X-KDE-CfgDlgHierarchy=Kleopatra
Name=S/MIME Validation
Name[ca]=Validació S/MIME
-Name[da]=S/MIME-validering
Name[de]=S/MIME-Prüfung
Name[el]=Επαλήθευση S/MIME
Name[et]=S/MIME valideerimine
Name[fr]=Validation S/MIME
Name[ja]=S/MIME 検証
Name[km]=ការ​ធ្វើ​ឲ្យ S/MIME មាន​សុពលភាព
Name[lv]=S/MIME validācija
Name[nds]=S/MIME-Överpröven
Name[pl]=Walidacja S/MIME
Name[pt]=Validação do S/MIME
Name[pt_BR]=Validação S/MIME
Name[sv]=S/MIME-validering
Name[tr]=S/MIME Doğrulaması
Name[uk]=Перевірка S/MIME
Name[x-test]=xxS/MIME Validationxx
Name[zh_CN]=S/MIME 校验
Name[zh_TW]=S/MIME 確認
Comment=Configuration of S/MIME certificate validation options
Comment[ca]=Configuració de les opcions de validació dels certificats S/MIME
-Comment[da]=Indstilling af tilvalg for S/MIME-certifikatvalidering
Comment[de]=Einrichtung der Optionen zur S/MIME-Zertifikatüberprüfung
Comment[el]=Ρύθμιση επιλογών επαλήθευσης πιστοποιητικών S/MIME
Comment[et]=S/MIME sertifikaatide valideerimise valikute seadistamine
Comment[fr]=Configuration des options de validation des certificats S/MIME
Comment[ja]=S/MIME 証明書の検証オプションの設定
Comment[km]=ជម្រើស​ធ្វើ​ឲ្យ​ការ​កំណត់​​រចនា​សម្ព័ន្ធ​របស់​វិញ្ញាបនបត្រ​របស់ S/MIME ប្រើ​បាន
Comment[lv]=S/MIME sertifikātu validācijas konfigurēšana
Comment[nds]=Överpröven vun S/MIME-Zertifikaten instellen
Comment[pl]=Konfiguracja opcji walidacji certyfikatu S/MIME
Comment[pt]=Configuração das opções de validação do certificado de S/MIME
Comment[pt_BR]=Configuração das opções de validação do certificado de S/MIME
Comment[sv]=Anpassning av alternativ för S/MIME-certifikatvalidering
Comment[tr]=S/MIME sertifika geçerlilik doğrulaması seçeneklerinin yapılandırması
Comment[uk]=Налаштування параметрів перевірки сертифікатів S/MIME
Comment[x-test]=xxConfiguration of S/MIME certificate validation optionsxx
Comment[zh_CN]=配置 S/MIME 证书校验选项
Comment[zh_TW]=設定 S/MIME 憑證確認選項
X-KDE-Keywords=smime,validation,kleopatra,signing,encryption
diff --git a/crypto/decryptverifyemailcontroller.cpp b/crypto/decryptverifyemailcontroller.cpp
index 5b67e4771..aa53b2169 100644
--- a/crypto/decryptverifyemailcontroller.cpp
+++ b/crypto/decryptverifyemailcontroller.cpp
@@ -1,380 +1,380 @@
/* -*- mode: c++; c-basic-offset:4 -*-
decryptverifyemailcontroller.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 "emailoperationspreferences.h"
#include "decryptverifyemailcontroller.h"
#include <crypto/gui/resultlistwidget.h>
#include <crypto/decryptverifytask.h>
#include <crypto/taskcollection.h>
#include <utils/classify.h>
#include <utils/gnupg-helper.h>
#include <utils/input.h>
#include <utils/output.h>
#include <utils/kleo_assert.h>
#include <kleo/cryptobackendfactory.h>
#include <KDebug>
#include <KLocalizedString>
#include <QPoint>
#include <QPointer>
#include <QTimer>
#include <boost/shared_ptr.hpp>
#include <memory>
#include <vector>
using namespace boost;
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
class DecryptVerifyEMailController::Private {
DecryptVerifyEMailController* const q;
public:
explicit Private( DecryptVerifyEMailController* qq );
void slotWizardCanceled();
void schedule();
std::vector<shared_ptr<AbstractDecryptVerifyTask> > buildTasks();
void ensureWizardCreated();
void ensureWizardVisible();
void reportError( int err, const QString & details ) {
emit q->error( err, details );
}
void cancelAllTasks();
std::vector<shared_ptr<Input> > m_inputs, m_signedDatas;
std::vector<shared_ptr<Output> > m_outputs;
QPointer<ResultListWidget> m_wizard;
std::vector<shared_ptr<const DecryptVerifyResult> > m_results;
std::vector<shared_ptr<AbstractDecryptVerifyTask> > m_runnableTasks, m_completedTasks;
shared_ptr<AbstractDecryptVerifyTask> m_runningTask;
bool m_silent;
bool m_operationCompleted;
DecryptVerifyOperation m_operation;
Protocol m_protocol;
VerificationMode m_verificationMode;
};
DecryptVerifyEMailController::Private::Private( DecryptVerifyEMailController* qq )
: q( qq ),
m_silent( false ),
m_operationCompleted( false ),
m_operation( DecryptVerify ),
m_protocol( UnknownProtocol ),
m_verificationMode( Detached )
{
qRegisterMetaType<VerificationResult>();
}
void DecryptVerifyEMailController::Private::slotWizardCanceled()
{
kDebug();
if ( m_operationCompleted )
q->emitDoneOrError();
else
reportError( gpg_error( GPG_ERR_CANCELED ), i18n("User canceled") );
}
void DecryptVerifyEMailController::doTaskDone( const Task* task, const shared_ptr<const Task::Result> & result ) {
assert( task );
// 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 ( task == d->m_runningTask.get() ) {
d->m_completedTasks.push_back( d->m_runningTask );
const shared_ptr<const DecryptVerifyResult> & dvr = boost::dynamic_pointer_cast<const DecryptVerifyResult>( result );
assert( dvr );
d->m_results.push_back( dvr );
d->m_runningTask.reset();
}
QTimer::singleShot( 0, this, SLOT(schedule()) );
}
void DecryptVerifyEMailController::Private::schedule()
{
if ( !m_runningTask && !m_runnableTasks.empty() ) {
const shared_ptr<AbstractDecryptVerifyTask> t = m_runnableTasks.back();
m_runnableTasks.pop_back();
t->start();
m_runningTask = t;
}
if ( !m_runningTask ) {
kleo_assert( m_runnableTasks.empty() );
Q_FOREACH ( const shared_ptr<const DecryptVerifyResult> & i, m_results )
emit q->verificationResult( i->verificationResult() );
// if there is a popup, wait for either the client cancel or the user closing the popup.
// Otherwise (silent case), finish immediately
m_operationCompleted = true;
if ( m_silent )
q->emitDoneOrError();
}
}
void DecryptVerifyEMailController::Private::ensureWizardCreated()
{
if ( m_wizard )
return;
std::auto_ptr<ResultListWidget> w( new ResultListWidget );
w->setWindowTitle( i18n( "Decrypt/Verify E-Mail" ) );
w->setAttribute( Qt::WA_DeleteOnClose );
w->setStandaloneMode( true );
- const QRect preferredGeometry = EMailOperationsPreferences().decryptVerifyPopupGeometry();
- if ( preferredGeometry.isValid() )
- w->setGeometry( preferredGeometry );
+ const QPoint preferredPos = EMailOperationsPreferences().decryptVerifyPopupPosition();
+ if ( !preferredPos.isNull() )
+ w->move( preferredPos );
connect( w.get(), SIGNAL(destroyed()), q, SLOT(slotWizardCanceled()), Qt::QueuedConnection );
m_wizard = w.release();
}
std::vector< shared_ptr<AbstractDecryptVerifyTask> > DecryptVerifyEMailController::Private::buildTasks()
{
const uint numInputs = m_inputs.size();
const uint numMessages = m_signedDatas.size();
const uint numOutputs = m_outputs.size();
// these are duplicated from DecryptVerifyCommandEMailBase::Private::checkForErrors with slightly modified error codes/messages
if ( !numInputs )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_CONFLICT ),
i18n("At least one input needs to be provided") );
if ( numMessages )
if ( numMessages != numInputs )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_CONFLICT ), //TODO use better error code if possible
i18n("Signature/signed data count mismatch") );
else if ( m_operation != Verify || m_verificationMode != Detached )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_CONFLICT ),
i18n("Signed data can only be given for detached signature verification") );
if ( numOutputs )
if ( numOutputs != numInputs )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_CONFLICT ), //TODO use better error code if possible
i18n("Input/Output count mismatch") );
else if ( numMessages )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_CONFLICT ),
i18n("Cannot use output and signed data simultaneously") );
kleo_assert( m_protocol != UnknownProtocol );
const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( m_protocol );
if ( !backend )
throw Kleo::Exception( makeGnuPGError( GPG_ERR_UNSUPPORTED_PROTOCOL ),
m_protocol == OpenPGP ? i18n("No backend support for OpenPGP") :
m_protocol == CMS ? i18n("No backend support for S/MIME") : QString() );
if ( m_operation != Decrypt && !m_silent )
ensureWizardVisible();
std::vector< shared_ptr<AbstractDecryptVerifyTask> > tasks;
for ( unsigned int i = 0 ; i < numInputs ; ++i ) {
shared_ptr<AbstractDecryptVerifyTask> task;
switch ( m_operation ) {
case Decrypt:
{
shared_ptr<DecryptTask> t( new DecryptTask );
t->setInput( m_inputs.at( i ) );
assert( numOutputs );
t->setOutput( m_outputs.at( i ) );
t->setProtocol( m_protocol );
task = t;
}
break;
case Verify:
{
if ( m_verificationMode == Detached ) {
shared_ptr<VerifyDetachedTask> t( new VerifyDetachedTask );
t->setInput( m_inputs.at( i ) );
t->setSignedData( m_signedDatas.at( i ) );
t->setProtocol( m_protocol );
task = t;
} else {
shared_ptr<VerifyOpaqueTask> t( new VerifyOpaqueTask );
t->setInput( m_inputs.at( i ) );
if ( numOutputs )
t->setOutput( m_outputs.at( i ) );
t->setProtocol( m_protocol );
task = t;
}
}
break;
case DecryptVerify:
{
shared_ptr<DecryptVerifyTask> t( new DecryptVerifyTask );
t->setInput( m_inputs.at( i ) );
assert( numOutputs );
t->setOutput( m_outputs.at( i ) );
t->setProtocol( m_protocol );
task = t;
}
}
assert( task );
tasks.push_back( task );
}
return tasks;
}
void DecryptVerifyEMailController::Private::ensureWizardVisible()
{
ensureWizardCreated();
q->bringToForeground( m_wizard );
}
DecryptVerifyEMailController::DecryptVerifyEMailController( QObject* parent ) : Controller( parent ), d( new Private( this ) )
{
}
DecryptVerifyEMailController::DecryptVerifyEMailController( const shared_ptr<const ExecutionContext> & ctx, QObject* parent ) : Controller( ctx, parent ), d( new Private( this ) )
{
}
DecryptVerifyEMailController::~DecryptVerifyEMailController() { kDebug(); }
void DecryptVerifyEMailController::start()
{
d->m_runnableTasks = d->buildTasks();
const shared_ptr<TaskCollection> coll( new TaskCollection );
std::vector<shared_ptr<Task> > tsks;
Q_FOREACH( const shared_ptr<Task> & i, d->m_runnableTasks ) {
connectTask( i );
tsks.push_back( i );
}
coll->setTasks( tsks );
d->ensureWizardCreated();
d->m_wizard->setTaskCollection( coll );
d->ensureWizardVisible();
QTimer::singleShot( 0, this, SLOT(schedule()) );
}
void DecryptVerifyEMailController::setInput( const shared_ptr<Input> & input )
{
d->m_inputs.resize( 1, input );
}
void DecryptVerifyEMailController::setInputs( const std::vector<shared_ptr<Input> > & inputs )
{
d->m_inputs = inputs;
}
void DecryptVerifyEMailController::setSignedData( const shared_ptr<Input> & data )
{
d->m_signedDatas.resize( 1, data );
}
void DecryptVerifyEMailController::setSignedData( const std::vector<shared_ptr<Input> > & data )
{
d->m_signedDatas = data;
}
void DecryptVerifyEMailController::setOutput( const shared_ptr<Output> & output )
{
d->m_outputs.resize( 1, output );
}
void DecryptVerifyEMailController::setOutputs( const std::vector<shared_ptr<Output> > & outputs )
{
d->m_outputs = outputs;
}
void DecryptVerifyEMailController::setWizardShown( bool shown )
{
d->m_silent = !shown;
if ( d->m_wizard )
d->m_wizard->setVisible( shown );
}
void DecryptVerifyEMailController::setOperation( DecryptVerifyOperation operation )
{
d->m_operation = operation;
}
void DecryptVerifyEMailController::setVerificationMode( VerificationMode vm )
{
d->m_verificationMode = vm;
}
void DecryptVerifyEMailController::setProtocol( Protocol prot )
{
d->m_protocol = prot;
}
void DecryptVerifyEMailController::cancel()
{
kDebug();
try {
if ( d->m_wizard ) {
disconnect( d->m_wizard );
d->m_wizard->close();
}
d->cancelAllTasks();
} catch ( const std::exception & e ) {
qDebug( "Caught exception: %s", e.what() );
}
}
void DecryptVerifyEMailController::Private::cancelAllTasks() {
// we just kill all runnable tasks - this will not result in
// signal emissions.
m_runnableTasks.clear();
// a cancel() will result in a call to
if ( m_runningTask )
m_runningTask->cancel();
}
#include "decryptverifyemailcontroller.moc"
diff --git a/crypto/decryptverifytask.cpp b/crypto/decryptverifytask.cpp
index d43173106..48f965adb 100644
--- a/crypto/decryptverifytask.cpp
+++ b/crypto/decryptverifytask.cpp
@@ -1,1110 +1,1106 @@
/* -*- 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/cryptobackendfactory.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 <KLocale>
#include <KLocalizedString>
#include <QByteArray>
#include <QColor>
#include <QDateTime>
#include <QTextDocument> // Qt::escape
#include <boost/bind.hpp>
#include <algorithm>
using namespace Kleo::Crypto;
using namespace Kleo;
using namespace GpgME;
using namespace boost;
namespace {
static QString auditLogFromSender( QObject* sender ) {
const Job * const job = qobject_cast<const Job*>( sender );
return job ? job->auditLogAsHtml() : QString();
}
static QString signatureSummaryToString( int summary )
{
if ( summary & Signature::None )
return i18n( "Error: Signature not verified" );
else if ( summary & Signature::Valid || summary & Signature::Green )
return i18n( "Good signature" );
else if ( summary & Signature::Red )
return i18n( "Bad signature" );
else if ( summary & Signature::KeyRevoked )
return i18n( "Signing certificate revoked" );
else if ( summary & Signature::KeyExpired )
return i18n( "Signing certificate expired" );
else if ( summary & Signature::KeyMissing )
return i18n( "No public key to verify the signature" );
else if ( summary & Signature::SigExpired )
return i18n( "Signature expired" );
else if ( summary & Signature::KeyMissing )
return i18n( "Key missing" );
else if ( summary & Signature::CrlMissing )
return i18n( "CRL missing" );
else if ( summary & Signature::CrlTooOld )
return i18n( "CRL too old" );
else if ( summary & Signature::BadPolicy )
return i18n( "Bad policy" );
else if ( summary & Signature::SysError )
return i18n( "System error" ); //### retrieve system error details?
return QString();
}
static QString formatValidSignatureWithTrustLevel( const Key & key ) {
assert( !key.isNull() );
switch ( key.ownerTrust() ) {
case Key::Marginal:
return i18n( "The signature is valid but the trust in the certificate's validity is only marginal." );
case Key::Full:
return i18n( "The signature is valid and the certificate's validity is fully trusted." );
case Key::Ultimate:
return i18n( "The signature is valid and the certificate's validity is ultimately trusted." );
case Key::Never:
return i18n( "The signature is valid but the certificate's validity is <em>not trusted</em>." );
case Key::Unknown:
return i18n( "The signature is valid but the certificate's validity is unknown." );
case Key::Undefined:
default:
return i18n( "The signature is valid but the certificate's validity is undefined." );
}
}
static QString renderFingerprint( const char * fpr ) {
if ( !fpr )
return QString();
return QString( "0x%1" ).arg( QString::fromAscii( fpr ).toUpper() );
}
static 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 ) );
}
static QString renderKeyEMailOnlyNameAsFallback( const Key & key ) {
if ( key.isNull() )
return i18n( "Unknown key" );
const QString email = Formatting::prettyEMail( key );
const QString user = !email.isNull() ? email : Formatting::prettyName( key );
return QString::fromLatin1( "<a href=\"key:%1\">%2</a>" ).arg( key.primaryFingerprint(), user );
}
static QString formatDate( const QDateTime & dt ) {
return KGlobal::locale()->formatDateTime( dt );
}
static QString formatSigningInformation( const Signature & sig, const Key & key ) {
if ( sig.isNull() )
return QString();
const QDateTime dt = sig.creationTime() != 0 ? QDateTime::fromTime_t( sig.creationTime() ) : QDateTime();
const QString signer = key.isNull() ? QString() : renderKeyEMailOnlyNameAsFallback( key );
const bool haveKey = !key.isNull();
const bool haveSigner = !signer.isEmpty();
const bool haveDate = dt.isValid();
if ( !haveKey )
if ( haveDate )
return i18n( "Signed on %1 with unknown key %2.", formatDate( dt ), renderFingerprint( sig.fingerprint() ) );
else
return i18n( "Signed with unknown key %1.", renderFingerprint( sig.fingerprint() ) );
if ( haveSigner )
if ( haveDate )
return i18nc( "date, key owner, key ID",
- "Signed on %1 by %2 (Key ID: %3).",
+ "Signed on %1 by %2 (Key ID: %3).",
formatDate( dt ),
signer,
renderFingerprint( key.keyID() ) );
else
return i18n( "Signed by %1 with key %2.", signer, renderKey( key ) );
if ( haveDate )
return i18n( "Signed on %1 with key %2.", formatDate( dt ), renderKey( key ) );
return i18n( "Signed with key %1.", renderKey( key ) );
}
static QString strikeOut( const QString & str, bool strike ) {
return QString( strike ? "<s>%1</s>" : "%1" ).arg( Qt::escape( str ) );
}
static QString formatInputOutputLabel( const QString & input, const QString & output, bool inputDeleted, bool outputDeleted ) {
if ( output.isEmpty() )
return strikeOut( input, inputDeleted );
- return i18nc( "Input file --> Output file (rarr is arrow", "%1 &rarr; %2",
+ return i18nc( "Input file --> Output file (rarr is arrow", "%1 &rarr; %2",
strikeOut( input, inputDeleted ),
strikeOut( output, outputDeleted ) );
}
static const char * iconForSignature( const Signature & sig ) {
if ( sig.summary() & Signature::Green )
return "dialog-ok";
if ( sig.summary() & Signature::Red )
return "dialog-error";
return "dialog-warning";
}
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() );
}
static bool IsBad( const Signature & sig ) {
return sig.summary() & Signature::Red;
}
static bool IsValid( const Signature & sig ) {
return sig.summary() & Signature::Valid;
}
static Task::Result::VisualCode codeForVerificationResult( const VerificationResult & res )
{
if ( res.isNull() )
return Task::Result::NeutralSuccess;
const std::vector<Signature> sigs = res.signatures();
if ( sigs.empty() )
return Task::Result::Warning;
if ( !std::count_if( sigs.begin(), sigs.end(), IsBad ) )
return Task::Result::AllGood;
if ( std::find_if( sigs.begin(), sigs.end(), IsBad ) != sigs.end() )
return Task::Result::Danger;
return Task::Result::Warning;
}
static QString formatVerificationResultOverview( const VerificationResult & res ) {
if ( res.isNull() )
return QString();
const Error err = res.error();
if ( err.isCanceled() )
return i18n("<b>Verification canceled.</b>");
else if ( err )
return i18n( "<b>Verification failed: %1.</b>", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
const std::vector<Signature> sigs = res.signatures();
const std::vector<Key> signers = KeyCache::instance()->findSigners( res );
if ( sigs.empty() )
return i18n( "<b>No signatures found.</b>" );
const uint bad = std::count_if( sigs.begin(), sigs.end(), IsBad );
if ( bad > 0 ) {
return i18np("<b>Invalid signature.</b>", "<b>%1 invalid signatures.</b>", bad );
}
const uint warn = std::count_if( sigs.begin(), sigs.end(), !bind( IsValid, _1 ) );
if ( warn > 0 )
return i18np("<b>Not enough information to check signature validity.</b>", "<b>%1 signatures could not be verified.</b>", warn );
//All good:
if ( sigs.size() == 1 ) {
const Key key = DecryptVerifyResult::keyForSignature( sigs[0], signers );
if ( key.isNull() )
return i18n( "<b>Signature is valid.</b>" );
return i18n( "<b>Signed by %1</b>", renderKeyEMailOnlyNameAsFallback( key ) );
}
return i18np("<b>Valid signature.</b>", "<b>%1 valid signatures.</b>", sigs.size() );
}
static QString formatDecryptionResultOverview( const DecryptionResult & result )
{
const Error err = result.error();
if ( err.isCanceled() )
return i18n("<b>Decryption canceled.</b>");
else if ( err )
return i18n( "<b>Decryption failed: %1.</b>", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
return i18n("<b>Decryption succeeded.</b>" );
}
static QString formatSignature( const Signature & sig, const Key & key ) {
if ( sig.isNull() )
return QString();
QString text = formatSigningInformation( sig, key ) + "<br/>";
-
+
const bool red = sig.summary() & Signature::Red;
if ( sig.summary() & Signature::Valid )
return text + formatValidSignatureWithTrustLevel( key ); // ### TODO handle key.isNull()?
if ( red )
if ( key.isNull() )
if ( const char * fpr = sig.fingerprint() )
return text + i18n("Bad signature by unknown key %1.", renderFingerprint( fpr ) );
else
return text + i18n("Bad signature by an unknown key." );
else
return text + i18n("Bad signature by %1.", renderKey( key ) );
if ( key.isNull() )
if ( const char * fpr = sig.fingerprint() )
return text + i18n("Invalid signature by unknown key %1: %2", renderFingerprint( fpr ), signatureSummaryToString( sig.summary() ) );
else
return text + i18n("Invalid signature by an unknown key: %1", signatureSummaryToString( sig.summary() ) );
else
return text + i18n("Invalid signature by %1: %2", renderKey( key ), signatureSummaryToString( sig.summary() ) );
}
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 )
+ 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() && res.numRecipients() > 0 )
+ if ( recipients.empty() )
return QString( "<i>" + i18np( "One unknown recipient.", "%1 unknown recipients.", res.numRecipients() ) + "</i>" );
QString details;
- if ( !recipients.empty() ) {
- 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>";
-
- details += "</ul>";
- }
+ details += i18np( "Recipients:", "Recipients:", res.numRecipients() );
+ if ( res.numRecipients() == 1 )
+ return details + renderKey( recipients.front() );
- return details;
+ 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 )
{
if ( IsErrorOrCanceled( dr ) )
return formatDecryptionResultOverview( dr );
return 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 );
}
} // anon namespace
class DecryptVerifyResult::Private {
DecryptVerifyResult* const q;
public:
Private( DecryptVerifyOperation type,
const VerificationResult & vr,
const DecryptionResult & dr,
const QByteArray & stuff,
int errCode,
const QString & errString,
const QString & input,
const QString & output,
const QString & auditLog,
DecryptVerifyResult* qq ) :
q( qq ),
m_type( type ),
m_verificationResult( vr ),
m_decryptionResult( dr ),
m_stuff( stuff ),
m_error( errCode ),
m_errorString( errString ),
m_inputLabel( input ),
m_outputLabel( output ),
m_auditLog( auditLog )
{
}
QString label() const {
return formatInputOutputLabel( m_inputLabel, m_outputLabel, false, q->hasError() );
}
bool isDecryptOnly() const { return m_type == Decrypt; }
bool isVerifyOnly() const { return m_type == Verify; }
bool isDecryptVerify() const { return m_type == DecryptVerify; }
DecryptVerifyOperation m_type;
VerificationResult m_verificationResult;
DecryptionResult m_decryptionResult;
QByteArray m_stuff;
int m_error;
QString m_errorString;
QString m_inputLabel;
QString m_outputLabel;
const QString m_auditLog;
};
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptResult( const DecryptionResult & dr, const QByteArray & plaintext, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Decrypt,
VerificationResult(),
dr,
plaintext,
0,
QString(),
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptResult( const GpgME::Error & err, const QString& what, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Decrypt,
VerificationResult(),
DecryptionResult( err ),
QByteArray(),
err.code(),
what,
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptVerifyResult( const DecryptionResult & dr, const VerificationResult & vr, const QByteArray & plaintext, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
DecryptVerify,
vr,
dr,
plaintext,
0,
QString(),
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptVerifyResult( const GpgME::Error & err, const QString & details, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
DecryptVerify,
VerificationResult(),
DecryptionResult( err ),
QByteArray(),
err.code(),
details,
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyOpaqueResult( const VerificationResult & vr, const QByteArray & plaintext, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Verify,
vr,
DecryptionResult(),
plaintext,
0,
QString(),
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyOpaqueResult( const GpgME::Error & err, const QString & details, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Verify,
VerificationResult( err ),
DecryptionResult(),
QByteArray(),
err.code(),
details,
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyDetachedResult( const VerificationResult & vr, const QString & auditLog ) {
- return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
+ return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Verify,
vr,
DecryptionResult(),
QByteArray(),
0,
QString(),
inputLabel(),
outputLabel(),
auditLog ) );
}
shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyDetachedResult( const GpgME::Error & err, const QString & details, const QString & auditLog ) {
return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
Verify,
VerificationResult( err ),
DecryptionResult(),
QByteArray(),
err.code(),
details,
inputLabel(),
outputLabel(),
auditLog ) );
}
DecryptVerifyResult::DecryptVerifyResult( DecryptVerifyOperation type,
const VerificationResult& vr,
const DecryptionResult& dr,
const QByteArray& stuff,
int errCode,
const QString & errString,
const QString & inputLabel,
const QString & outputLabel,
const QString & auditLog )
: Task::Result(), d( new Private( type, vr, dr, stuff, errCode, errString, inputLabel, outputLabel, auditLog, this ) )
{
}
QString DecryptVerifyResult::overview() const
{
QString ov;
if ( d->isDecryptOnly() )
ov = formatDecryptionResultOverview( d->m_decryptionResult );
else if ( d->isVerifyOnly() )
ov = formatVerificationResultOverview( d->m_verificationResult );
- else
+ else
ov = formatDecryptVerifyResultOverview( d->m_decryptionResult, d->m_verificationResult );
return i18nc( "label: result example: foo.sig: Verification failed. ", "%1: %2", d->label(), ov );
}
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;
}
QString DecryptVerifyResult::auditLogAsHtml() const {
return d->m_auditLog;
}
Task::Result::VisualCode DecryptVerifyResult::code() const {
if ( d->m_type == DecryptVerify || d->m_type == Verify )
return codeForVerificationResult( d->m_verificationResult );
return hasError() ? NeutralError : NeutralSuccess;
}
GpgME::VerificationResult DecryptVerifyResult::verificationResult() const
{
return d->m_verificationResult;
}
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;
}
class AbstractDecryptVerifyTask::Private {
-
+
};
AbstractDecryptVerifyTask::AbstractDecryptVerifyTask( QObject * parent ) : Task( parent ), d( new Private ) {}
AbstractDecryptVerifyTask::~AbstractDecryptVerifyTask() {}
class DecryptVerifyTask::Private {
DecryptVerifyTask* const q;
public:
explicit Private( DecryptVerifyTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
void slotResult( const DecryptionResult&, const VerificationResult&, const QByteArray& );
void registerJob( DecryptVerifyJob * job ) {
q->connect( job, SIGNAL(result(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)),
q, SLOT(slotResult(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)) );
q->connect( job, SIGNAL(progress(QString,int,int)),
q, SLOT(setProgress(QString,int,int)) );
}
void emitResult( const shared_ptr<DecryptVerifyResult>& result );
-
+
shared_ptr<Input> m_input;
shared_ptr<Output> m_output;
const CryptoBackend::Protocol* m_backend;
Protocol m_protocol;
};
void DecryptVerifyTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
{
q->emitResult( result );
emit q->decryptVerifyResult( result );
}
void DecryptVerifyTask::Private::slotResult( const DecryptionResult& dr, const VerificationResult& vr, const QByteArray& plainText )
{
const QString auditLog = auditLogFromSender( q->sender() );
if ( dr.error().code() || vr.error().code() ) {
m_output->cancel();
} else {
try {
kleo_assert( !dr.isNull() || !vr.isNull() );
m_output->finalize();
} catch ( const GpgME::Exception & e ) {
emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
return;
}
}
emitResult( q->fromDecryptVerifyResult( dr, vr, plainText, auditLog ) );
}
DecryptVerifyTask::DecryptVerifyTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
{
}
DecryptVerifyTask::~DecryptVerifyTask()
{
}
void DecryptVerifyTask::setInput( const shared_ptr<Input> & input )
{
d->m_input = input;
kleo_assert( d->m_input && d->m_input->ioDevice() );
}
void DecryptVerifyTask::setOutput( const shared_ptr<Output> & output )
{
d->m_output = output;
kleo_assert( d->m_output && d->m_output->ioDevice() );
}
void DecryptVerifyTask::setProtocol( Protocol prot )
{
kleo_assert( prot != UnknownProtocol );
d->m_protocol = prot;
d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
kleo_assert( d->m_backend );
}
-void DecryptVerifyTask::autodetectProtocolFromInput()
+void DecryptVerifyTask::autodetectProtocolFromInput()
{
if ( d->m_input )
setProtocol( findProtocol( d->m_input->classification() ) );
}
QString DecryptVerifyTask::label() const
{
return i18n( "Decrypting: %1...", d->m_input->label() );
}
unsigned long long DecryptVerifyTask::inputSize() const
{
return d->m_input ? d->m_input->size() : 0;
}
QString DecryptVerifyTask::inputLabel() const
{
return d->m_input ? d->m_input->label() : QString();
}
QString DecryptVerifyTask::outputLabel() const
{
return d->m_output ? d->m_output->label() : QString();
}
Protocol DecryptVerifyTask::protocol() const
{
return d->m_protocol;
}
void DecryptVerifyTask::cancel()
{
-
+
}
void DecryptVerifyTask::doStart()
{
kleo_assert( d->m_backend );
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( fromDecryptVerifyResult( e.error(), QString::fromLocal8Bit( e.what() ), QString() ) );
}
}
class DecryptTask::Private {
DecryptTask* const q;
public:
explicit Private( DecryptTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
void slotResult( const DecryptionResult&, const QByteArray& );
void registerJob( DecryptJob * job ) {
q->connect( job, SIGNAL(result(GpgME::DecryptionResult,QByteArray)),
q, SLOT(slotResult(GpgME::DecryptionResult,QByteArray)) );
q->connect( job, SIGNAL(progress(QString,int,int)),
q, SLOT(setProgress(QString,int,int)) );
}
void emitResult( const shared_ptr<DecryptVerifyResult>& result );
-
+
shared_ptr<Input> m_input;
shared_ptr<Output> m_output;
const CryptoBackend::Protocol* m_backend;
Protocol m_protocol;
};
void DecryptTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
{
q->emitResult( result );
emit q->decryptVerifyResult( result );
}
void DecryptTask::Private::slotResult( const DecryptionResult& result, const QByteArray& plainText )
{
const QString auditLog = auditLogFromSender( q->sender() );
if ( result.error().code() ) {
m_output->cancel();
} else {
try {
kleo_assert( !result.isNull() );
m_output->finalize();
} catch ( const GpgME::Exception & e ) {
emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
return;
}
}
emitResult( q->fromDecryptResult( result, plainText, auditLog ) );
}
DecryptTask::DecryptTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
{
}
DecryptTask::~DecryptTask()
{
}
void DecryptTask::setInput( const shared_ptr<Input> & input )
{
d->m_input = input;
kleo_assert( d->m_input && d->m_input->ioDevice() );
}
void DecryptTask::setOutput( const shared_ptr<Output> & output )
{
d->m_output = output;
kleo_assert( d->m_output && d->m_output->ioDevice() );
}
void DecryptTask::setProtocol( Protocol prot )
{
kleo_assert( prot != UnknownProtocol );
d->m_protocol = prot;
d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
kleo_assert( d->m_backend );
}
-void DecryptTask::autodetectProtocolFromInput()
+void DecryptTask::autodetectProtocolFromInput()
{
if ( d->m_input )
setProtocol( findProtocol( d->m_input->classification() ) );
}
QString DecryptTask::label() const
{
return i18n( "Decrypting: %1...", d->m_input->label() );
}
unsigned long long DecryptTask::inputSize() const
{
return d->m_input ? d->m_input->size() : 0;
}
QString DecryptTask::inputLabel() const
{
return d->m_input ? d->m_input->label() : QString();
}
QString DecryptTask::outputLabel() const
{
return d->m_output ? d->m_output->label() : QString();
}
Protocol DecryptTask::protocol() const
{
kleo_assert( !"not implemented" );
return UnknownProtocol; // ### TODO
}
void DecryptTask::cancel()
{
-
+
}
void DecryptTask::doStart()
{
kleo_assert( d->m_backend );
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( fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), QString() ) );
}
}
class VerifyOpaqueTask::Private {
VerifyOpaqueTask* const q;
public:
explicit Private( VerifyOpaqueTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
void slotResult( const VerificationResult&, const QByteArray& );
void registerJob( VerifyOpaqueJob* job ) {
q->connect( job, SIGNAL(result(GpgME::VerificationResult,QByteArray)),
q, SLOT(slotResult(GpgME::VerificationResult,QByteArray)) );
q->connect( job, SIGNAL(progress(QString,int,int)),
q, SLOT(setProgress(QString,int,int)) );
}
void emitResult( const shared_ptr<DecryptVerifyResult>& result );
-
+
shared_ptr<Input> m_input;
shared_ptr<Output> m_output;
const CryptoBackend::Protocol* m_backend;
Protocol m_protocol;
};
void VerifyOpaqueTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
{
q->emitResult( result );
emit q->decryptVerifyResult( result );
}
void VerifyOpaqueTask::Private::slotResult( const VerificationResult& result, const QByteArray& plainText )
{
const QString auditLog = auditLogFromSender( q->sender() );
if ( result.error().code() ) {
m_output->cancel();
} else {
try {
kleo_assert( !result.isNull() );
m_output->finalize();
} catch ( const GpgME::Exception & e ) {
emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
return;
}
}
emitResult( q->fromVerifyOpaqueResult( result, plainText, auditLog ) );
}
VerifyOpaqueTask::VerifyOpaqueTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
{
}
VerifyOpaqueTask::~VerifyOpaqueTask()
{
}
void VerifyOpaqueTask::setInput( const shared_ptr<Input> & input )
{
d->m_input = input;
kleo_assert( d->m_input && d->m_input->ioDevice() );
}
void VerifyOpaqueTask::setOutput( const shared_ptr<Output> & output )
{
d->m_output = output;
kleo_assert( d->m_output && d->m_output->ioDevice() );
}
void VerifyOpaqueTask::setProtocol( Protocol prot )
{
kleo_assert( prot != UnknownProtocol );
d->m_protocol = prot;
d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
kleo_assert( d->m_backend );
}
-void VerifyOpaqueTask::autodetectProtocolFromInput()
+void VerifyOpaqueTask::autodetectProtocolFromInput()
{
if ( d->m_input )
setProtocol( findProtocol( d->m_input->classification() ) );
}
QString VerifyOpaqueTask::label() const
{
return i18n( "Verifying: %1...", d->m_input->label() );
}
unsigned long long VerifyOpaqueTask::inputSize() const
{
return d->m_input ? d->m_input->size() : 0;
}
QString VerifyOpaqueTask::inputLabel() const
{
return d->m_input ? d->m_input->label() : QString();
}
QString VerifyOpaqueTask::outputLabel() const
{
return d->m_output ? d->m_output->label() : QString();
}
Protocol VerifyOpaqueTask::protocol() const
{
return d->m_protocol;
}
void VerifyOpaqueTask::cancel()
{
-
+
}
void VerifyOpaqueTask::doStart()
{
kleo_assert( d->m_backend );
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( fromVerifyOpaqueResult( e.error(), QString::fromLocal8Bit( e.what() ), QString() ) );
}
}
class VerifyDetachedTask::Private {
VerifyDetachedTask* const q;
public:
explicit Private( VerifyDetachedTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
void slotResult( const VerificationResult& );
void registerJob( VerifyDetachedJob* job ) {
q->connect( job, SIGNAL(result(GpgME::VerificationResult)),
q, SLOT(slotResult(GpgME::VerificationResult)) );
q->connect( job, SIGNAL(progress(QString,int,int)),
q, SLOT(setProgress(QString,int,int)) );
}
void emitResult( const shared_ptr<DecryptVerifyResult>& result );
-
+
shared_ptr<Input> m_input, m_signedData;
const CryptoBackend::Protocol* m_backend;
Protocol m_protocol;
};
void VerifyDetachedTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
{
q->emitResult( result );
emit q->decryptVerifyResult( result );
}
void VerifyDetachedTask::Private::slotResult( const VerificationResult& result )
{
const QString auditLog = auditLogFromSender( q->sender() );
try {
kleo_assert( !result.isNull() );
emitResult( q->fromVerifyDetachedResult( result, auditLog ) );
} catch ( const GpgME::Exception & e ) {
emitResult( q->fromVerifyDetachedResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
}
}
VerifyDetachedTask::VerifyDetachedTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
{
}
VerifyDetachedTask::~VerifyDetachedTask()
{
}
void VerifyDetachedTask::setInput( const shared_ptr<Input> & input )
{
d->m_input = input;
kleo_assert( d->m_input && d->m_input->ioDevice() );
}
void VerifyDetachedTask::setSignedData( const shared_ptr<Input> & signedData )
{
d->m_signedData = signedData;
kleo_assert( d->m_signedData && d->m_signedData->ioDevice() );
}
void VerifyDetachedTask::setProtocol( Protocol prot )
{
kleo_assert( prot != UnknownProtocol );
d->m_protocol = prot;
d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
kleo_assert( d->m_backend );
}
-void VerifyDetachedTask::autodetectProtocolFromInput()
+void VerifyDetachedTask::autodetectProtocolFromInput()
{
if ( d->m_input )
setProtocol( findProtocol( d->m_input->classification() ) );
}
unsigned long long VerifyDetachedTask::inputSize() const
{
return d->m_signedData ? d->m_signedData->size() : 0;
}
QString VerifyDetachedTask::label() const
{
return i18n( "Verifying signature: %1...", d->m_input->label() );
}
QString VerifyDetachedTask::inputLabel() const
{
return d->m_input ? d->m_input->label() : QString();
}
QString VerifyDetachedTask::outputLabel() const
{
return QString();
}
Protocol VerifyDetachedTask::protocol() const
{
kleo_assert( !"not implemented" );
return UnknownProtocol; // ### TODO
}
void VerifyDetachedTask::cancel()
{
-
+
}
void VerifyDetachedTask::doStart()
{
kleo_assert( d->m_backend );
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( fromVerifyDetachedResult( e.error(), QString::fromLocal8Bit( e.what() ), QString() ) );
}
}
#include "decryptverifytask.moc"
diff --git a/crypto/gui/resolverecipientspage.cpp b/crypto/gui/resolverecipientspage.cpp
index ad522df15..d71cef257 100644
--- a/crypto/gui/resolverecipientspage.cpp
+++ b/crypto/gui/resolverecipientspage.cpp
@@ -1,700 +1,671 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resolverecipientspage.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>
#ifdef QT_NO_STL
#undef QT_NO_STL
#undef QT_STL
#define QT_STL
#endif
#include "resolverecipientspage.h"
#include "resolverecipientspage_p.h"
#include <dialogs/certificateselectiondialog.h>
#include <crypto/certificateresolver.h>
#include <models/keycache.h>
#include <utils/formatting.h>
#include <kmime/kmime_header_parsing.h>
#include <gpgme++/key.h>
#include <KLocalizedString>
#include <QButtonGroup>
#include <QComboBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QListWidget>
#include <QPointer>
#include <QPushButton>
#include <QRadioButton>
#include <QToolButton>
#include <QSignalMapper>
#include <QStringList>
#include <QVBoxLayout>
-#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <cassert>
using namespace GpgME;
using namespace boost;
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
using namespace KMime::Types;
ResolveRecipientsPage::ListWidget::ListWidget( QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags ), m_protocol( UnknownProtocol )
{
m_listWidget = new QListWidget;
m_listWidget->setSelectionMode( QAbstractItemView::MultiSelection );
QVBoxLayout * const layout = new QVBoxLayout( this );
layout->addWidget( m_listWidget );
connect( m_listWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChange() ) );
}
ResolveRecipientsPage::ListWidget::~ListWidget()
{
}
void ResolveRecipientsPage::ListWidget::onSelectionChange()
{
Q_FOREACH ( const QString& i, widgets.keys() )
{
assert( items.contains( i ) );
widgets[i]->setSelected( items[i]->isSelected() );
}
emit selectionChanged();
}
void ResolveRecipientsPage::ListWidget::addEntry( const Mailbox& mbox )
{
addEntry( mbox.prettyAddress(), mbox.prettyAddress(), mbox );
}
void ResolveRecipientsPage::ListWidget::addEntry( const QString& id, const QString& name )
{
addEntry( id, name, Mailbox() );
}
void ResolveRecipientsPage::ListWidget::addEntry( const QString& id, const QString& name, const Mailbox& mbox )
{
assert( !widgets.contains( id ) && !items.contains( id ) );
QListWidgetItem* item = new QListWidgetItem;
item->setData( IdRole, id );
ItemWidget* wid = new ItemWidget( id, name, mbox, this );
connect( wid, SIGNAL( changed() ), this, SIGNAL( completeChanged() ) );
wid->setProtocol( m_protocol );
item->setSizeHint( wid->sizeHint() );
m_listWidget->addItem( item );
- m_listWidget->setItemWidget( item, wid );
+ m_listWidget->setItemWidget( item, wid );
widgets[id] = wid;
items[id] = item;
}
Mailbox ResolveRecipientsPage::ListWidget::mailbox( const QString& id ) const
{
return widgets.contains( id ) ? widgets[id]->mailbox() : Mailbox();
}
void ResolveRecipientsPage::ListWidget::setCertificates( const QString& id, const std::vector<Key>& pgp, const std::vector<Key>& cms )
{
assert( widgets.contains( id ) );
widgets[id]->setCertificates( pgp, cms );
}
Key ResolveRecipientsPage::ListWidget::selectedCertificate( const QString& id ) const
{
return widgets.contains( id ) ? widgets[id]->selectedCertificate() : Key();
}
GpgME::Key ResolveRecipientsPage::ListWidget::selectedCertificate( const QString& id, GpgME::Protocol prot ) const
{
return widgets.contains( id ) ? widgets[id]->selectedCertificate( prot ) : Key();
}
QStringList ResolveRecipientsPage::ListWidget::identifiers() const
{
return widgets.keys();
}
void ResolveRecipientsPage::ListWidget::setProtocol( GpgME::Protocol prot )
{
if ( m_protocol == prot )
return;
m_protocol = prot;
Q_FOREACH ( ItemWidget* i, widgets.values() )
i->setProtocol( prot );
}
void ResolveRecipientsPage::ListWidget::removeEntry( const QString& id )
{
if ( !widgets.contains( id ) )
return;
delete items[id];
items.remove( id );
- delete widgets[id];
+ delete widgets[id];
widgets.remove( id );
}
void ResolveRecipientsPage::ListWidget::showSelectionDialog( const QString& id )
-{
+{
if ( !widgets.contains( id ) )
return;
widgets[id]->showSelectionDialog();
}
QStringList ResolveRecipientsPage::ListWidget::selectedEntries() const
{
QStringList entries;
const QList<QListWidgetItem*> items = m_listWidget->selectedItems();
Q_FOREACH ( const QListWidgetItem* i, items )
{
entries.append( i->data( IdRole ).toString() );
}
return entries;
}
ResolveRecipientsPage::ItemWidget::ItemWidget( const QString& id, const QString& name, const Mailbox& mbox,
QWidget* parent, Qt::WindowFlags flags ) : QWidget( parent, flags ), m_id( id ), m_mailbox( mbox ), m_protocol( UnknownProtocol ), m_selected( false )
{
assert( !m_id.isEmpty() );
setAutoFillBackground( true );
QHBoxLayout* layout = new QHBoxLayout( this );
layout->setMargin( 0 );
layout->addSpacing( 15 );
m_nameLabel = new QLabel;
m_nameLabel->setText( name );
layout->addWidget( m_nameLabel );
layout->addStretch();
m_certLabel = new QLabel;
m_certLabel->setText( i18n( "<i>No certificate selected</i>" ) );
layout->addWidget( m_certLabel );
m_certCombo = new QComboBox;
- connect( m_certCombo, SIGNAL( currentIndexChanged( int ) ),
+ connect( m_certCombo, SIGNAL( currentIndexChanged( int ) ),
this, SIGNAL( changed() ) );
layout->addWidget( m_certCombo );
m_selectButton = new QToolButton;
m_selectButton->setText( i18n( "..." ) );
- connect( m_selectButton, SIGNAL( clicked() ),
+ connect( m_selectButton, SIGNAL( clicked() ),
this, SLOT( showSelectionDialog() ) );
layout->addWidget( m_selectButton );
layout->addSpacing( 15 );
setCertificates( std::vector<Key>(), std::vector<Key>() );
}
void ResolveRecipientsPage::ItemWidget::updateVisibility()
{
m_certLabel->setVisible( m_certCombo->count() == 0 );
- m_certCombo->setVisible( m_certCombo->count() > 0 );
+ m_certCombo->setVisible( m_certCombo->count() > 0 );
}
ResolveRecipientsPage::ItemWidget::~ItemWidget()
{
}
QString ResolveRecipientsPage::ItemWidget::id() const
{
return m_id;
}
void ResolveRecipientsPage::ItemWidget::setSelected( bool selected )
{
if ( m_selected == selected )
return;
m_selected = selected;
setBackgroundRole( selected ? QPalette::Highlight : QPalette::Base );
const QPalette::ColorRole foreground = selected ? QPalette::HighlightedText : QPalette::Text;
setForegroundRole( foreground );
m_nameLabel->setForegroundRole( foreground );
m_certLabel->setForegroundRole( foreground );
}
bool ResolveRecipientsPage::ItemWidget::isSelected() const
{
return m_selected;
}
static CertificateSelectionDialog::Option protocol2option( GpgME::Protocol proto ) {
switch ( proto ) {
case OpenPGP: return CertificateSelectionDialog::OpenPGPFormat;
case CMS: return CertificateSelectionDialog::CMSFormat;
default: return CertificateSelectionDialog::AnyFormat;
}
}
-static CertificateSelectionDialog * createCertificateSelectionDialog( QWidget* parent, GpgME::Protocol prot ) {
- CertificateSelectionDialog * const dlg = new CertificateSelectionDialog( parent );
+void ResolveRecipientsPage::ItemWidget::showSelectionDialog()
+{
+ QPointer<CertificateSelectionDialog> dlg = new CertificateSelectionDialog( this );
const CertificateSelectionDialog::Options options =
CertificateSelectionDialog::SingleSelection |
- CertificateSelectionDialog::EncryptOnly |
- CertificateSelectionDialog::MultiSelection |
- protocol2option( prot );
+ CertificateSelectionDialog::EncryptOnly |
+ protocol2option( m_protocol ) ;
dlg->setOptions( options );
- return dlg;
-}
-
-void ResolveRecipientsPage::ItemWidget::showSelectionDialog()
-{
- QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog( this, m_protocol );
if ( dlg->exec() == QDialog::Accepted && dlg /* still with us? */ ) {
const GpgME::Key cert = dlg->selectedCertificate();
if ( !cert.isNull() ) {
addCertificateToComboBox( cert );
selectCertificateInComboBox( cert );
}
}
+
delete dlg;
}
Mailbox ResolveRecipientsPage::ItemWidget::mailbox() const
{
return m_mailbox;
}
void ResolveRecipientsPage::ItemWidget::selectCertificateInComboBox( const Key& key )
{
m_certCombo->setCurrentIndex( m_certCombo->findData( key.keyID() ) );
}
void ResolveRecipientsPage::ItemWidget::addCertificateToComboBox( const GpgME::Key& key )
{
- m_certCombo->addItem( Formatting::formatForComboBox( key ), QByteArray( key.keyID() ) );
+ m_certCombo->addItem( Formatting::formatForComboBox( key ), QByteArray( key.keyID() ) );
if ( m_certCombo->count() == 1 )
m_certCombo->setCurrentIndex( 0 );
updateVisibility();
}
-
+
void ResolveRecipientsPage::ItemWidget::resetCertificates()
{
std::vector<Key> certs;
Key selected;
switch ( m_protocol )
{
case OpenPGP:
certs = m_pgp;
break;
case CMS:
certs = m_cms;
break;
case UnknownProtocol:
certs = m_cms;
- certs.insert( certs.end(), m_pgp.begin(), m_pgp.end() );
+ certs.insert( certs.end(), m_pgp.begin(), m_pgp.end() );
}
-
+
m_certCombo->clear();
Q_FOREACH ( const Key& i, certs )
addCertificateToComboBox( i );
if ( !m_selectedCertificates[m_protocol].isNull() )
selectCertificateInComboBox( m_selectedCertificates[m_protocol] );
else if ( m_certCombo->count() > 0 )
m_certCombo->setCurrentIndex( 0 );
updateVisibility();
emit changed();
}
void ResolveRecipientsPage::ItemWidget::setProtocol( Protocol prot )
{
if ( m_protocol == prot )
return;
m_selectedCertificates[m_protocol] = selectedCertificate();
if ( m_protocol != UnknownProtocol )
( m_protocol == OpenPGP ? m_pgp : m_cms ) = certificates();
m_protocol = prot;
resetCertificates();
}
void ResolveRecipientsPage::ItemWidget::setCertificates( const std::vector<Key>& pgp, const std::vector<Key>& cms )
{
m_pgp = pgp;
m_cms = cms;
resetCertificates();
}
Key ResolveRecipientsPage::ItemWidget::selectedCertificate() const
{
return KeyCache::instance()->findByKeyIDOrFingerprint( m_certCombo->itemData( m_certCombo->currentIndex(), ListWidget::IdRole ).toString().toStdString() );
}
GpgME::Key ResolveRecipientsPage::ItemWidget::selectedCertificate( GpgME::Protocol prot ) const
{
return prot == m_protocol ? selectedCertificate() : m_selectedCertificates.value( prot );
}
std::vector<Key> ResolveRecipientsPage::ItemWidget::certificates() const
{
std::vector<Key> certs;
for ( int i = 0; i < m_certCombo->count(); ++i )
certs.push_back( KeyCache::instance()->findByKeyIDOrFingerprint( m_certCombo->itemData( i, ListWidget::IdRole ).toString().toStdString() ) );
return certs;
}
class ResolveRecipientsPage::Private {
friend class ::Kleo::Crypto::Gui::ResolveRecipientsPage;
ResolveRecipientsPage * const q;
public:
explicit Private( ResolveRecipientsPage * qq );
~Private();
-
+
void setSelectedProtocol( Protocol protocol );
void selectionChanged();
void removeSelectedEntries();
void addRecipient();
void addRecipient( const Mailbox& mbox );
void addRecipient( const QString& id, const QString& name );
void updateProtocolRBVisibility();
void protocolSelected( int prot );
void writeSelectedCertificatesToPreferences();
- void completeChangedInternal();
-
+
private:
ListWidget* m_listWidget;
QPushButton* m_addButton;
QPushButton* m_removeButton;
QRadioButton* m_pgpRB;
QRadioButton* m_cmsRB;
QLabel* m_additionalRecipientsLabel;
Protocol m_presetProtocol;
Protocol m_selectedProtocol;
bool m_multipleProtocolsAllowed;
boost::shared_ptr<RecipientPreferences> m_recipientPreferences;
};
ResolveRecipientsPage::Private::Private( ResolveRecipientsPage * qq )
: q( qq ), m_presetProtocol( UnknownProtocol ), m_selectedProtocol( m_presetProtocol ), m_multipleProtocolsAllowed( false ), m_recipientPreferences()
{
- connect( q, SIGNAL(completeChanged()), q, SLOT(completeChangedInternal()) );
q->setTitle( i18n( "<b>Recipients</b>" ) );
QVBoxLayout* const layout = new QVBoxLayout( q );
m_listWidget = new ListWidget;
connect( m_listWidget, SIGNAL( selectionChanged() ), q, SLOT( selectionChanged() ) );
connect( m_listWidget, SIGNAL( completeChanged() ), q, SIGNAL( completeChanged() ) );
layout->addWidget( m_listWidget );
m_additionalRecipientsLabel = new QLabel;
m_additionalRecipientsLabel->setWordWrap( true );
layout->addWidget( m_additionalRecipientsLabel );
m_additionalRecipientsLabel->setVisible( false );
QWidget* buttonWidget = new QWidget;
QHBoxLayout* buttonLayout = new QHBoxLayout( buttonWidget );
buttonLayout->setMargin( 0 );
m_addButton = new QPushButton;
connect( m_addButton, SIGNAL( clicked() ), q, SLOT( addRecipient() ) );
m_addButton->setText( i18n( "Add Recipient..." ) );
buttonLayout->addWidget( m_addButton );
m_removeButton = new QPushButton;
m_removeButton->setEnabled( false );
m_removeButton->setText( i18n( "Remove Selected" ) );
- connect( m_removeButton, SIGNAL( clicked() ),
- q, SLOT( removeSelectedEntries() ) );
+ connect( m_removeButton, SIGNAL( clicked() ),
+ q, SLOT( removeSelectedEntries() ) );
buttonLayout->addWidget( m_removeButton );
buttonLayout->addStretch();
layout->addWidget( buttonWidget );
QWidget* protocolWidget = new QWidget;
QHBoxLayout* protocolLayout = new QHBoxLayout( protocolWidget );
QButtonGroup* protocolGroup = new QButtonGroup( q );
connect( protocolGroup, SIGNAL( buttonClicked( int ) ), q, SLOT( protocolSelected( int ) ) );
m_pgpRB = new QRadioButton;
m_pgpRB->setText( i18n( "OpenPGP" ) );
protocolGroup->addButton( m_pgpRB, OpenPGP );
protocolLayout->addWidget( m_pgpRB );
m_cmsRB = new QRadioButton;
m_cmsRB->setText( i18n( "S/MIME" ) );
protocolGroup->addButton( m_cmsRB, CMS );
protocolLayout->addWidget( m_cmsRB );
protocolLayout->addStretch();
layout->addWidget( protocolWidget );
}
ResolveRecipientsPage::Private::~Private() {}
-void ResolveRecipientsPage::Private::completeChangedInternal()
-{
- const bool isComplete = q->isComplete();
- const std::vector<Key> keys = q->resolvedCertificates();
- const bool haveSecret = std::find_if( keys.begin(), keys.end(), bind( &Key::hasSecret, _1 ) ) != keys.end();
- if ( isComplete && !haveSecret )
- q->setExplanation( i18n( "<b>Warning:</b> None of the selected certificates seems to be your own certificate. You will not be able to decrypt the encrypted data again." ) );
- else
- q->setExplanation( QString() );
-}
-
void ResolveRecipientsPage::Private::updateProtocolRBVisibility()
{
const bool visible = !m_multipleProtocolsAllowed && m_presetProtocol == UnknownProtocol;
m_cmsRB->setVisible( visible );
m_pgpRB->setVisible( visible );
if ( visible )
{
if ( m_selectedProtocol == CMS )
m_cmsRB->click();
else
m_pgpRB->click();
}
}
-
+
bool ResolveRecipientsPage::isComplete() const
{
const QStringList ids = d->m_listWidget->identifiers();
if ( ids.isEmpty() )
return false;
-
+
Q_FOREACH ( const QString& i, ids )
{
if ( d->m_listWidget->selectedCertificate( i ).isNull() )
return false;
}
-
+
return true;
}
ResolveRecipientsPage::ResolveRecipientsPage( QWidget * parent )
: WizardPage( parent ), d( new Private( this ) )
{
}
ResolveRecipientsPage::~ResolveRecipientsPage() {}
Protocol ResolveRecipientsPage::selectedProtocol() const
{
return d->m_selectedProtocol;
}
void ResolveRecipientsPage::Private::setSelectedProtocol( Protocol protocol )
{
if ( m_selectedProtocol == protocol )
return;
m_selectedProtocol = protocol;
m_listWidget->setProtocol( m_selectedProtocol );
emit q->selectedProtocolChanged();
}
void ResolveRecipientsPage::Private::protocolSelected( int p )
{
const Protocol protocol = static_cast<Protocol>( p );
assert( protocol != UnknownProtocol );
setSelectedProtocol( protocol );
}
void ResolveRecipientsPage::setPresetProtocol( Protocol prot )
{
if ( d->m_presetProtocol == prot )
return;
d->m_presetProtocol = prot;
d->setSelectedProtocol( prot );
if ( prot != UnknownProtocol )
d->m_multipleProtocolsAllowed = false;
d->updateProtocolRBVisibility();
}
Protocol ResolveRecipientsPage::presetProtocol() const
{
return d->m_presetProtocol;
}
bool ResolveRecipientsPage::multipleProtocolsAllowed() const
{
return d->m_multipleProtocolsAllowed;
}
void ResolveRecipientsPage::setMultipleProtocolsAllowed( bool allowed )
{
if ( d->m_multipleProtocolsAllowed == allowed )
return;
d->m_multipleProtocolsAllowed = allowed;
if ( d->m_multipleProtocolsAllowed )
{
setPresetProtocol( UnknownProtocol );
d->setSelectedProtocol( UnknownProtocol );
}
d->updateProtocolRBVisibility();
}
void ResolveRecipientsPage::Private::addRecipient( const QString& id, const QString& name )
{
- m_listWidget->addEntry( id, name );
+ m_listWidget->addEntry( id, name );
}
void ResolveRecipientsPage::Private::addRecipient( const Mailbox& mbox )
{
- m_listWidget->addEntry( mbox );
+ m_listWidget->addEntry( mbox );
}
void ResolveRecipientsPage::Private::addRecipient()
{
- QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog( q, q->selectedProtocol() );
- if ( dlg->exec() != QDialog::Accepted || !dlg /*q already deleted*/ )
- return;
- const std::vector<Key> keys = dlg->selectedCertificates();
-
int i = 0;
- Q_FOREACH( const Key & key, keys ) {
- const QStringList existing = m_listWidget->identifiers();
- QString rec = i18n( "Recipient" );
- while ( existing.contains( rec ) )
- rec = i18nc( "%1 == number", "Recipient (%1)", ++i );
- addRecipient( rec, rec );
- const std::vector<Key> pgp = key.protocol() == OpenPGP ? std::vector<Key>( 1, key ) : std::vector<Key>();
- const std::vector<Key> cms = key.protocol() == CMS ? std::vector<Key>( 1, key ) : std::vector<Key>();
- m_listWidget->setCertificates( rec, pgp, cms );
- }
- emit q->completeChanged();
+ const QStringList existing = m_listWidget->identifiers();
+ QString rec = i18n( "Recipient" );
+ while ( existing.contains( rec ) )
+ rec = i18nc( "%1 == number", "Recipient (%1)", ++i );
+ addRecipient( rec, rec );
+ m_listWidget->showSelectionDialog( rec );
}
namespace {
std::vector<Key> makeSuggestions( const boost::shared_ptr<RecipientPreferences>& prefs, const Mailbox& mb, GpgME::Protocol prot )
{
std::vector<Key> suggestions;
const Key remembered = prefs ? prefs->preferredCertificate( mb, prot ) : Key();
if ( !remembered.isNull() )
suggestions.push_back( remembered );
else
suggestions = CertificateResolver::resolveRecipient( mb, prot );
return suggestions;
}
}
static QString listKeysForInfo( const std::vector<Key> & keys ) {
QStringList list;
std::transform( keys.begin(), keys.end(), list.begin(), &Formatting::formatKeyLink );
return list.join( "<br/>" );
}
void ResolveRecipientsPage::setAdditionalRecipientsInfo( const std::vector<Key> & recipients ) {
d->m_additionalRecipientsLabel->setVisible( !recipients.empty() );
if ( recipients.empty() )
return;
d->m_additionalRecipientsLabel->setText( i18n( "<qt><p>Recipients predefined via GnuPG settings:</p>%1", listKeysForInfo( recipients ) ) );
}
void ResolveRecipientsPage::setRecipients( const std::vector<Mailbox>& recipients )
{
uint cmsCount = 0;
uint pgpCount = 0;
Q_FOREACH( const Mailbox& i, recipients )
{
- //TODO:
+ //TODO:
const QString address = i.prettyAddress();
d->addRecipient( i );
const std::vector<Key> pgp = makeSuggestions( d->m_recipientPreferences, i, OpenPGP );
const std::vector<Key> cms = makeSuggestions( d->m_recipientPreferences, i, CMS );
pgpCount += pgp.empty() ? 0 : 1;
cmsCount += cms.empty() ? 0 : 1;
d->m_listWidget->setCertificates( address, pgp, cms );
}
if ( d->m_presetProtocol == UnknownProtocol && !d->m_multipleProtocolsAllowed )
( cmsCount > pgpCount ? d->m_cmsRB : d->m_pgpRB )->click();
}
std::vector<Key> ResolveRecipientsPage::resolvedCertificates() const
{
std::vector<Key> certs;
Q_FOREACH( const QString& i, d->m_listWidget->identifiers() )
{
const GpgME::Key cert = d->m_listWidget->selectedCertificate( i );
if ( !cert.isNull() )
certs.push_back( cert );
}
return certs;
}
void ResolveRecipientsPage::Private::selectionChanged()
{
m_removeButton->setEnabled( !m_listWidget->selectedEntries().isEmpty() );
}
void ResolveRecipientsPage::Private::removeSelectedEntries()
{
Q_FOREACH ( const QString& i, m_listWidget->selectedEntries() )
m_listWidget->removeEntry( i );
emit q->completeChanged();
}
void ResolveRecipientsPage::setRecipientsUserMutable( bool isMutable )
{
d->m_addButton->setVisible( isMutable );
d->m_removeButton->setVisible( isMutable );
}
bool ResolveRecipientsPage::recipientsUserMutable() const
{
return d->m_addButton->isVisible();
}
boost::shared_ptr<RecipientPreferences> ResolveRecipientsPage::recipientPreferences() const
{
return d->m_recipientPreferences;
}
void ResolveRecipientsPage::setRecipientPreferences( const boost::shared_ptr<RecipientPreferences>& prefs )
{
d->m_recipientPreferences = prefs;
}
void ResolveRecipientsPage::Private::writeSelectedCertificatesToPreferences()
{
if ( !m_recipientPreferences )
return;
-
+
Q_FOREACH ( const QString& i, m_listWidget->identifiers() )
{
const Mailbox mbox = m_listWidget->mailbox( i );
if ( !mbox.hasAddress() )
continue;
const Key pgp = m_listWidget->selectedCertificate( i, OpenPGP );
if ( !pgp.isNull() )
m_recipientPreferences->setPreferredCertificate( mbox, OpenPGP, pgp );
const Key cms = m_listWidget->selectedCertificate( i, CMS );
if ( !cms.isNull() )
m_recipientPreferences->setPreferredCertificate( mbox, CMS, cms );
}
}
-
+
void ResolveRecipientsPage::onNext() {
d->writeSelectedCertificatesToPreferences();
}
#include "moc_resolverecipientspage_p.cpp"
#include "moc_resolverecipientspage.cpp"
diff --git a/crypto/gui/resolverecipientspage.h b/crypto/gui/resolverecipientspage.h
index be865817b..86ac39ff9 100644
--- a/crypto/gui/resolverecipientspage.h
+++ b/crypto/gui/resolverecipientspage.h
@@ -1,128 +1,127 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resolverecipientspage.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_RESOLVERECIPIENTSPAGE_H__
#define __KLEOPATRA_CRYPTO_GUI_RESOLVERECIPIENTSPAGE_H__
#include <crypto/gui/wizardpage.h>
#include <utils/pimpl_ptr.h>
#include <gpgme++/global.h>
#include <boost/shared_ptr.hpp>
#include <vector>
namespace GpgME {
class Key;
}
namespace KMime {
-namespace Types {
+namespace Types {
class Mailbox;
}
}
namespace Kleo {
namespace Crypto {
class RecipientPreferences;
namespace Gui {
class ResolveRecipientsPage : public WizardPage {
Q_OBJECT
public:
explicit ResolveRecipientsPage( QWidget * parent=0 );
~ResolveRecipientsPage();
bool isComplete() const;
- /**
- * The protocol selected by the user (which is chosen by
+ /**
+ * The protocol selected by the user (which is chosen by
* the user in case none was preset)
*/
GpgME::Protocol selectedProtocol() const;
/**
- * the protocol set before the dialog is shown. Defaults to
+ * the protocol set before the dialog is shown. Defaults to
* GpgME::UnknownProtocol */
GpgME::Protocol presetProtocol() const;
void setPresetProtocol( GpgME::Protocol protocol );
bool multipleProtocolsAllowed() const;
void setMultipleProtocolsAllowed( bool allowed );
bool symmetricEncryptionSelected() const;
void setSymmetricEncryptionSelected( bool enabled );
bool symmetricEncryptionSelectable() const;
void setSymmetricEncryptionSelectable( bool selectable );
/** if true, the user is allowed to remove/add recipients via the UI.
* Defaults to @p false.
*/
bool recipientsUserMutable() const;
- void setRecipientsUserMutable( bool isMutable );
+ void setRecipientsUserMutable( bool isMutable );
void setAdditionalRecipientsInfo( const std::vector<GpgME::Key> & recipients );
void setRecipients( const std::vector<KMime::Types::Mailbox>& recipients );
std::vector<GpgME::Key> resolvedCertificates() const;
boost::shared_ptr<RecipientPreferences> recipientPreferences() const;
void setRecipientPreferences( const boost::shared_ptr<RecipientPreferences>& prefs );
Q_SIGNALS:
void selectedProtocolChanged();
private:
/*reimpl*/ void onNext();
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void selectionChanged() )
Q_PRIVATE_SLOT( d, void protocolSelected( int ) )
Q_PRIVATE_SLOT( d, void addRecipient() )
Q_PRIVATE_SLOT( d, void removeSelectedEntries() )
- Q_PRIVATE_SLOT( d, void completeChangedInternal() )
class ListWidget;
class ItemWidget;
};
}
}
}
#endif // __KLEOPATRA_CRYPTO_GUI_RESOLVERECIPIENTSPAGE_H__
diff --git a/crypto/gui/resolverecipientspage_p.h b/crypto/gui/resolverecipientspage_p.h
index 225c0b87b..3b34afbc8 100644
--- a/crypto/gui/resolverecipientspage_p.h
+++ b/crypto/gui/resolverecipientspage_p.h
@@ -1,133 +1,133 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resolverecipientspage_p.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_RESOLVERECIPIENTSPAGE_P_H__
#define __KLEOPATRA_CRYPTO_GUI_RESOLVERECIPIENTSPAGE_P_H__
#include <crypto/gui/resolverecipientspage.h>
#include <kmime/kmime_header_parsing.h>
#include <QHash>
class QComboBox;
class QLabel;
class QListWidget;
class QListWidgetItem;
class QPushButton;
class QStringList;
class QToolButton;
class Kleo::Crypto::Gui::ResolveRecipientsPage::ListWidget : public QWidget {
Q_OBJECT
public:
explicit ListWidget( QWidget* parent = 0, Qt::WindowFlags flags = 0 );
~ListWidget();
void addEntry( const QString& id, const QString& name );
void addEntry( const KMime::Types::Mailbox& mbox );
void removeEntry( const QString& id );
QStringList selectedEntries() const;
void setCertificates( const QString& id, const std::vector<GpgME::Key>& pgpCerts, const std::vector<GpgME::Key>& cmsCerts );
GpgME::Key selectedCertificate( const QString& id ) const;
GpgME::Key selectedCertificate( const QString& id, GpgME::Protocol prot ) const;
KMime::Types::Mailbox mailbox( const QString& id ) const;
QStringList identifiers() const;
void setProtocol( GpgME::Protocol prot );
void showSelectionDialog( const QString& id );
enum Role {
IdRole = Qt::UserRole
};
Q_SIGNALS:
void selectionChanged();
void completeChanged();
private:
void addEntry( const QString& id, const QString& name, const KMime::Types::Mailbox& mbox );
private Q_SLOTS:
void onSelectionChange();
-private:
+private:
QListWidget* m_listWidget;
-
+
QHash<QString,ItemWidget*> widgets;
QHash<QString,QListWidgetItem*> items;
GpgME::Protocol m_protocol;
};
-
+
class Kleo::Crypto::Gui::ResolveRecipientsPage::ItemWidget : public QWidget {
Q_OBJECT
public:
explicit ItemWidget( const QString& id, const QString& name, const KMime::Types::Mailbox& mbox, QWidget* parent = 0, Qt::WindowFlags flags = 0 );
~ItemWidget();
QString id() const;
KMime::Types::Mailbox mailbox() const;
void setCertificates( const std::vector<GpgME::Key>& pgp,
const std::vector<GpgME::Key>& cms );
GpgME::Key selectedCertificate() const;
GpgME::Key selectedCertificate( GpgME::Protocol prot ) const;
std::vector<GpgME::Key> certificates() const;
void setProtocol( GpgME::Protocol protocol );
void setSelected( bool selected );
bool isSelected() const;
public Q_SLOTS:
void showSelectionDialog();
Q_SIGNALS:
void changed();
private:
void addCertificateToComboBox( const GpgME::Key& key );
void resetCertificates();
void selectCertificateInComboBox( const GpgME::Key& key );
void updateVisibility();
-private:
+private:
QString m_id;
KMime::Types::Mailbox m_mailbox;
QLabel* m_nameLabel;
QLabel* m_certLabel;
QComboBox* m_certCombo;
QToolButton* m_selectButton;
GpgME::Protocol m_protocol;
QHash<GpgME::Protocol, GpgME::Key> m_selectedCertificates;
std::vector<GpgME::Key> m_pgp, m_cms;
bool m_selected;
};
#endif // __KLEOPATRA_CRYPTO_GUI_RESOLVERECIPIENTSPAGE_P_H__
diff --git a/crypto/gui/resultitemwidget.cpp b/crypto/gui/resultitemwidget.cpp
index edd48a19c..0c1beb903 100644
--- a/crypto/gui/resultitemwidget.cpp
+++ b/crypto/gui/resultitemwidget.cpp
@@ -1,206 +1,209 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resultitemwidget.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 "resultitemwidget.h"
#include <ui/messagebox.h>
#include <KDebug>
#include <KLocalizedString>
#include <KPushButton>
#include <KStandardGuiItem>
#include <QHBoxLayout>
#include <QLabel>
#include <QStringList>
#include <QUrl>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
using namespace boost;
-
+
namespace {
//### TODO move outta here, make colors configurable
static QColor colorForVisualCode( Task::Result::VisualCode code ) {
switch ( code ) {
case Task::Result::AllGood:
return Qt::green;
case Task::Result::NeutralError:
case Task::Result::Warning:
return Qt::yellow;
case Task::Result::Danger:
return Qt::red;
case Task::Result::NeutralSuccess:
default:
return Qt::blue;
}
}
}
class ResultItemWidget::Private {
ResultItemWidget* const q;
public:
explicit Private( const shared_ptr<const Task::Result> result, ResultItemWidget* qq ) : q( qq ), m_result( result ), m_detailsLabel( 0 ), m_showDetailsLabel( 0 ) { assert( m_result ); }
void slotLinkActivated( const QString & );
void updateShowDetailsLabel();
const shared_ptr<const Task::Result> m_result;
QLabel * m_detailsLabel;
QLabel * m_showDetailsLabel;
KPushButton * m_closeButton;
};
void ResultItemWidget::Private::updateShowDetailsLabel()
{
if ( !m_showDetailsLabel || !m_detailsLabel )
return;
-
+
const bool detailsVisible = m_detailsLabel->isVisible();
- const QString auditLogLink = !m_result->auditLogAsHtml().isEmpty() ? QString( "<a href=\"kleoresultitem://showauditlog/\">%1</a>" ).arg( i18n( "Show Audit Log" ) ) : i18n( "No Audit Log available" );
- m_showDetailsLabel->setText( QString( "<a href=\"kleoresultitem://toggledetails/\">%1</a><br/>%2" ).arg( detailsVisible ? i18n( "Hide Details" ) : i18n( "Show Details" ), auditLogLink ) );
+ const bool hasAuditLog = !m_result->auditLogAsHtml().isEmpty();
+ if ( detailsVisible )
+ m_showDetailsLabel->setText( QString("<a href=\"kleoresultitem://toggledetails/\">%1</a><br/>%2").arg( i18n( "Hide Details" ), hasAuditLog ? QString( "<a href=\"kleoresultitem://showauditlog/\">%1</a>" ).arg( i18n( "Show Audit Log" ) ) : i18n( "No Audit Log available" ) ) );
+ else
+ m_showDetailsLabel->setText( QString("<a href=\"kleoresultitem://toggledetails/\">%1</a>").arg( i18n( "Show Details" ) ) );
}
ResultItemWidget::ResultItemWidget( const shared_ptr<const Task::Result> & result, QWidget * parent, Qt::WindowFlags flags ) : QWidget( parent, flags ), d( new Private( result, this ) )
{
const QColor color = colorForVisualCode( d->m_result->code() );
setStyleSheet( QString( "* { background-color: %1; margin: 0px; } QFrame#resultFrame{ border-color: %2; border-style: solid; border-radius: 3px; border-width: 2px } QLabel { padding: 5px; border-radius: 3px }" ).arg( color.lighter( 150 ).name(), color.name() ) );
QVBoxLayout* topLayout = new QVBoxLayout( this );
topLayout->setMargin( 0 );
topLayout->setSpacing( 0 );
QFrame* frame = new QFrame;
frame->setObjectName( "resultFrame" );
topLayout->addWidget( frame );
QVBoxLayout* layout = new QVBoxLayout( frame );
layout->setMargin( 0 );
layout->setSpacing( 0 );
QWidget* hbox = new QWidget;
QHBoxLayout* hlay = new QHBoxLayout( hbox );
hlay->setMargin( 0 );
hlay->setSpacing( 0 );
QLabel* overview = new QLabel;
overview->setWordWrap( true );
overview->setTextFormat( Qt::RichText );
overview->setText( d->m_result->overview() );
connect( overview, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)) );
hlay->addWidget( overview, 1, Qt::AlignTop );
layout->addWidget( hbox );
const QString details = d->m_result->details();
-
+
d->m_showDetailsLabel = new QLabel;
connect( d->m_showDetailsLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)) );
hlay->addWidget( d->m_showDetailsLabel );
d->m_showDetailsLabel->setVisible( !details.isEmpty() );
-
+
d->m_detailsLabel = new QLabel;
d->m_detailsLabel->setWordWrap( true );
d->m_detailsLabel->setTextFormat( Qt::RichText );
d->m_detailsLabel->setText( details );
connect( d->m_detailsLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotLinkActivated(QString)) );
layout->addWidget( d->m_detailsLabel );
d->m_detailsLabel->setVisible( false );
-
+
d->m_closeButton = new KPushButton;
d->m_closeButton->setGuiItem( KStandardGuiItem::close() );
d->m_closeButton->setFixedSize( d->m_closeButton->sizeHint() );
connect( d->m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeButtonClicked()) );
layout->addWidget( d->m_closeButton, 0, Qt::AlignRight );
d->m_closeButton->setVisible( false );
d->updateShowDetailsLabel();
}
ResultItemWidget::~ResultItemWidget()
{
}
void ResultItemWidget::showCloseButton( bool show )
{
d->m_closeButton->setVisible( show );
}
bool ResultItemWidget::detailsVisible() const
{
return d->m_detailsLabel && d->m_detailsLabel->isVisible();
}
bool ResultItemWidget::hasErrorResult() const
{
return d->m_result->hasError();
}
void ResultItemWidget::Private::slotLinkActivated( const QString & link )
{
assert( m_result );
if ( link.startsWith( "key:" ) ) {
const QStringList split = link.split( ':' );
if ( split.size() == 3 || m_result->nonce() != split.value( 1 ) )
emit q->linkActivated( "key://" + split.value( 2 ) );
else
kWarning() << "key link invalid, or nonce not matching! link=" << link << " nonce" << m_result->nonce();
return;
}
const QUrl url( link );
if ( url.host() == "toggledetails" ) {
q->showDetails( !q->detailsVisible() );
return;
}
-
+
if ( url.host() == "showauditlog" ) {
q->showAuditLog();
return;
}
kWarning() << "Unexpected link scheme: " << link;
}
void ResultItemWidget::showAuditLog() {
- MessageBox::auditLog( parentWidget(), d->m_result->auditLogAsHtml() );
+ MessageBox::auditLog( this, d->m_result->auditLogAsHtml() );
}
void ResultItemWidget::showDetails( bool show )
{
if ( show == d->m_detailsLabel->isVisible() )
return;
d->m_detailsLabel->setVisible( show );
d->updateShowDetailsLabel();
emit detailsToggled( show );
}
#include "resultitemwidget.moc"
diff --git a/crypto/gui/resultlistwidget.cpp b/crypto/gui/resultlistwidget.cpp
index 6b77f0c61..922dbc83c 100644
--- a/crypto/gui/resultlistwidget.cpp
+++ b/crypto/gui/resultlistwidget.cpp
@@ -1,221 +1,221 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resultlistwidget.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 "resultlistwidget.h"
#include "emailoperationspreferences.h"
#include <crypto/gui/resultitemwidget.h>
#include <crypto/taskcollection.h>
#include <utils/scrollarea.h>
#include <KLocalizedString>
#include <KPushButton>
#include <KStandardGuiItem>
#include <QLabel>
#include <QMoveEvent>
#include <QVBoxLayout>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
using namespace boost;
class ResultListWidget::Private {
ResultListWidget* const q;
public:
explicit Private( ResultListWidget* qq );
void result( const shared_ptr<const Task::Result> & result );
void started( const shared_ptr<Task> & task );
void detailsToggled( bool );
void allTasksDone();
void addResultWidget( ResultItemWidget* widget );
void setupSingle();
void setupMulti();
void resizeIfStandalone();
shared_ptr<TaskCollection> m_tasks;
bool m_standaloneMode;
int m_lastErrorItemIndex;
ScrollArea * m_scrollArea;
KPushButton * m_closeButton;
QVBoxLayout * m_layout;
QLabel * m_progressLabel;
};
ResultListWidget::Private::Private( ResultListWidget* qq )
: q( qq ),
m_tasks(),
m_standaloneMode( false ),
m_lastErrorItemIndex( 0 ),
m_scrollArea( 0 ),
m_closeButton( 0 ),
m_layout( 0 ),
m_progressLabel( 0 )
{
m_layout = new QVBoxLayout( q );
m_layout->setMargin( 0 );
m_layout->setSpacing( 0 );
m_progressLabel = new QLabel;
m_progressLabel->setWordWrap( true );
m_layout->addWidget( m_progressLabel );
m_progressLabel->setVisible( false );
m_closeButton = new KPushButton;
m_closeButton->setGuiItem( KStandardGuiItem::close() );
q->connect( m_closeButton, SIGNAL(clicked()), q, SLOT(close()) );
m_layout->addWidget( m_closeButton );
m_closeButton->setVisible( false );
}
ResultListWidget::ResultListWidget( QWidget* parent, Qt::WindowFlags f ) : QWidget( parent, f ), d( new Private( this ) )
{
}
ResultListWidget::~ResultListWidget()
{
if ( !d->m_standaloneMode )
return;
EMailOperationsPreferences prefs;
- prefs.setDecryptVerifyPopupGeometry( geometry() );
+ prefs.setDecryptVerifyPopupPosition( pos() );
prefs.writeConfig();
}
void ResultListWidget::Private::setupSingle()
{
m_layout->addStretch();
}
void ResultListWidget::Private::resizeIfStandalone()
{
if ( m_standaloneMode )
q->resize( q->sizeHint() );
}
void ResultListWidget::Private::setupMulti()
{
m_scrollArea = new ScrollArea;
assert( qobject_cast<QBoxLayout*>( m_scrollArea->widget()->layout() ) );
static_cast<QBoxLayout*>( m_scrollArea->widget()->layout() )->setMargin( 0 );
static_cast<QBoxLayout*>( m_scrollArea->widget()->layout() )->setSpacing( 2 );
static_cast<QBoxLayout*>( m_scrollArea->widget()->layout() )->addStretch();
m_layout->insertWidget( 0, m_scrollArea );
}
void ResultListWidget::Private::addResultWidget( ResultItemWidget* widget )
{
assert( widget );
assert( m_tasks && !m_tasks->isEmpty() );
if ( m_tasks->size() > 1 ) {
assert( m_scrollArea );
assert( m_scrollArea->widget() );
assert( qobject_cast<QBoxLayout*>( m_scrollArea->widget()->layout() ) );
QBoxLayout & blay = *static_cast<QBoxLayout*>( m_scrollArea->widget()->layout() );
blay.insertWidget( widget->hasErrorResult() ? m_lastErrorItemIndex++ : ( blay.count() - 1 ), widget );
} else { // single task
widget->showCloseButton( m_standaloneMode );
m_layout->insertWidget( m_layout->count() - 1, widget, m_standaloneMode ? 1 : 0 );
}
widget->show();
resizeIfStandalone();
}
void ResultListWidget::Private::allTasksDone() {
m_progressLabel->setVisible( false );
resizeIfStandalone();
emit q->completeChanged();
}
void ResultListWidget::Private::result( const shared_ptr<const Task::Result> & result )
{
assert( result );
assert( m_tasks && !m_tasks->isEmpty() );
ResultItemWidget* wid = new ResultItemWidget( result );
q->connect( wid, SIGNAL(detailsToggled(bool)), q, SLOT(detailsToggled(bool)) );
q->connect( wid, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)) );
q->connect( wid, SIGNAL(closeButtonClicked()), q, SLOT(close()) );
addResultWidget( wid );
}
bool ResultListWidget::isComplete() const
{
return d->m_tasks ? d->m_tasks->allTasksCompleted() : false;
}
void ResultListWidget::setTaskCollection( const shared_ptr<TaskCollection> & coll )
{
assert( !d->m_tasks );
assert( coll && !coll->isEmpty() );
d->m_tasks = coll;
connect( d->m_tasks.get(), SIGNAL(result(boost::shared_ptr<const Kleo::Crypto::Task::Result>)),
this, SLOT(result(boost::shared_ptr<const Kleo::Crypto::Task::Result>)) );
connect( d->m_tasks.get(), SIGNAL(started(boost::shared_ptr<Kleo::Crypto::Task>)),
this, SLOT(started(boost::shared_ptr<Kleo::Crypto::Task>)) );
connect( d->m_tasks.get(), SIGNAL(done()), this, SLOT(allTasksDone()) );
if ( coll->size() == 1 )
d->setupSingle();
else
d->setupMulti();
setStandaloneMode( d->m_standaloneMode );
}
void ResultListWidget::Private::detailsToggled( bool ) {
resizeIfStandalone();
}
void ResultListWidget::Private::started( const shared_ptr<Task> & task )
{
assert( m_tasks );
assert( task );
assert( m_progressLabel );
m_progressLabel->setText( i18nc( "number, operation description", "Operation %1: %2", m_tasks->numberOfCompletedTasks() + 1, task->label() ) );
resizeIfStandalone();
}
void ResultListWidget::setStandaloneMode( bool standalone ) {
d->m_standaloneMode = standalone;
if ( !d->m_tasks || d->m_tasks->isEmpty() )
return;
d->m_closeButton->setVisible( standalone && d->m_tasks->size() > 1 );
d->m_progressLabel->setVisible( standalone );
}
#include "resultlistwidget.moc"
diff --git a/dialogs/adduseriddialog.cpp b/dialogs/adduseriddialog.cpp
index d4c57076a..e69de29bb 100644
--- a/dialogs/adduseriddialog.cpp
+++ b/dialogs/adduseriddialog.cpp
@@ -1,153 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/adduseriddialog.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 "adduseriddialog.h"
-
-#include "ui_adduseriddialog.h"
-
-#include <QString>
-#include <QStringList>
-#include <QRegExp>
-#include <QRegExpValidator>
-#include <QPushButton>
-
-#include <cassert>
-
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-
-class AddUserIDDialog::Private {
- friend class ::Kleo::Dialogs::AddUserIDDialog;
- AddUserIDDialog * const q;
-public:
- explicit Private( AddUserIDDialog * qq )
- : q( qq ),
- ui( q )
- {
-
- }
-
-private:
- void slotUserIDChanged();
-
-private:
- struct UI : public Ui_AddUserIDDialog {
- explicit UI( AddUserIDDialog * qq )
- : Ui_AddUserIDDialog()
- {
- setupUi( qq );
-
- // these are modeled after gnupg/g10/keygen.c:ask_user_id:
- const QRegExp nameRX( "[^0-9<>][^<>@]{4,}" );
- const QRegExp emailRX( "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" );
- const QRegExp commentRX( "[^()]*" );
-
- nameLE->setValidator( new QRegExpValidator( nameRX, nameLE ) );
- emailLE->setValidator( new QRegExpValidator( emailRX, emailLE ) );
- commentLE->setValidator( new QRegExpValidator( commentRX, commentLE ) );
- }
-
- QPushButton * okPB() const {
- return buttonBox->button( QDialogButtonBox::Ok );
- }
- } ui;
-};
-
-AddUserIDDialog::AddUserIDDialog( QWidget * p, Qt::WindowFlags f )
- : QDialog( p, f ), d( new Private( this ) )
-{
-
-}
-
-AddUserIDDialog::~AddUserIDDialog() {}
-
-
-void AddUserIDDialog::setName( const QString & name ) {
- d->ui.nameLE->setText( name );
-}
-
-QString AddUserIDDialog::name() const {
- return d->ui.nameLE->text().trimmed();
-}
-
-void AddUserIDDialog::setEmail( const QString & email ) {
- d->ui.emailLE->setText( email );
-}
-
-QString AddUserIDDialog::email() const {
- return d->ui.emailLE->text().trimmed();
-}
-
-void AddUserIDDialog::setComment( const QString & comment ) {
- d->ui.commentLE->setText( comment );
-}
-
-QString AddUserIDDialog::comment() const {
- return d->ui.commentLE->text().trimmed();
-}
-
-
-void AddUserIDDialog::Private::slotUserIDChanged() {
-
- bool ok = false;
- QString error;
-
- if ( !ui.nameLE->hasAcceptableInput() )
- error = i18nc("@info", "<interface>Real name</interface> must be at least 5 characters long.");
- else if ( !ui.emailLE->hasAcceptableInput() )
- error = i18nc("@info", "<interface>EMail address</interface> is invalid.");
- else if ( !ui.commentLE->hasAcceptableInput() )
- error = i18nc("@info", "<interface>Comment</interface> contains invalid characters.");
- else
- ok = true;
-
- ui.okPB()->setEnabled( ok );
- ui.errorLB->setText( error );
-
- const QString name = q->name();
- const QString email = q->email();
- const QString comment = q->comment();
-
- QStringList parts;
- if ( !name.isEmpty() )
- parts.push_back( name );
- if ( !comment.isEmpty() )
- parts.push_back( QLatin1Char( '(' ) + comment + QLatin1Char( ')' ) );
- if ( !email.isEmpty() )
- parts.push_back( QLatin1Char( '<' ) + email + QLatin1Char( '>' ) );
-
- ui.resultLB->setText( parts.join( QLatin1String( " " ) ) );
-}
-
-#include "moc_adduseriddialog.cpp"
diff --git a/dialogs/adduseriddialog.h b/dialogs/adduseriddialog.h
index 127b3709a..e69de29bb 100644
--- a/dialogs/adduseriddialog.h
+++ b/dialogs/adduseriddialog.h
@@ -1,72 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/addUserIDdialog.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_DIALOGS_ADDUSERIDDIALOG_H__
-#define __KLEOPATRA_DIALOGS_ADDUSERIDDIALOG_H__
-
-#include <QDialog>
-
-#include <utils/pimpl_ptr.h>
-
-class QString;
-
-namespace Kleo {
-namespace Dialogs {
-
- class AddUserIDDialog : public QDialog {
- Q_OBJECT
- Q_PROPERTY( QString name READ name WRITE setName )
- Q_PROPERTY( QString email READ email WRITE setEmail )
- Q_PROPERTY( QString comment READ comment WRITE setComment )
- public:
- explicit AddUserIDDialog( QWidget * parent=0, Qt::WindowFlags f=0 );
- ~AddUserIDDialog();
-
- void setName( const QString & name );
- QString name() const;
-
- void setEmail( const QString & email );
- QString email() const;
-
- void setComment( const QString & comment );
- QString comment() const;
-
- private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
- Q_PRIVATE_SLOT( d, void slotUserIDChanged() )
- };
-
-}
-}
-
-#endif /* __KLEOPATRA_DIALOGS_ADDUSERIDDIALOG_H__ */
diff --git a/dialogs/adduseriddialog.ui b/dialogs/adduseriddialog.ui
index 5adbe1970..e69de29bb 100644
--- a/dialogs/adduseriddialog.ui
+++ b/dialogs/adduseriddialog.ui
@@ -1,237 +0,0 @@
-<ui version="4.0" >
- <class>AddUserIDDialog</class>
- <widget class="QDialog" name="AddUserIDDialog" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>563</width>
- <height>242</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Add New User-ID</string>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>&amp;Real name:</string>
- </property>
- <property name="buddy" >
- <cstring>nameLE</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="nameLE" />
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>&amp;EMail address:</string>
- </property>
- <property name="buddy" >
- <cstring>emailLE</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QLineEdit" name="emailLE" />
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string>Co&amp;mment (optional):</string>
- </property>
- <property name="buddy" >
- <cstring>commentLE</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="QLineEdit" name="commentLE" />
- </item>
- <item row="3" column="0" colspan="2" >
- <widget class="Line" name="line" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="4" column="0" >
- <widget class="QLabel" name="label_4" >
- <property name="text" >
- <string>This is how it will look like:</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0" colspan="2" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="8" column="0" colspan="2" >
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons" >
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="4" column="1" >
- <widget class="QLabel" name="resultLB" >
- <property name="minimumSize" >
- <size>
- <width>300</width>
- <height>0</height>
- </size>
- </property>
- <property name="textFormat" >
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item row="6" column="0" colspan="2" >
- <widget class="QLabel" name="errorLB" >
- <property name="palette" >
- <palette>
- <active>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </active>
- <inactive>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </inactive>
- <disabled>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
- <red>114</red>
- <green>114</green>
- <blue>114</blue>
- </color>
- </brush>
- </colorrole>
- </disabled>
- </palette>
- </property>
- <property name="text" >
- <string>Foo</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>AddUserIDDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>236</x>
- <y>203</y>
- </hint>
- <hint type="destinationlabel" >
- <x>157</x>
- <y>212</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>AddUserIDDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>325</x>
- <y>203</y>
- </hint>
- <hint type="destinationlabel" >
- <x>286</x>
- <y>212</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>nameLE</sender>
- <signal>textChanged(QString)</signal>
- <receiver>AddUserIDDialog</receiver>
- <slot>slotUserIDChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>414</x>
- <y>16</y>
- </hint>
- <hint type="destinationlabel" >
- <x>448</x>
- <y>18</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>emailLE</sender>
- <signal>textChanged(QString)</signal>
- <receiver>AddUserIDDialog</receiver>
- <slot>slotUserIDChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>412</x>
- <y>54</y>
- </hint>
- <hint type="destinationlabel" >
- <x>450</x>
- <y>58</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>commentLE</sender>
- <signal>textChanged(QString)</signal>
- <receiver>AddUserIDDialog</receiver>
- <slot>slotUserIDChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>402</x>
- <y>96</y>
- </hint>
- <hint type="destinationlabel" >
- <x>446</x>
- <y>96</y>
- </hint>
- </hints>
- </connection>
- </connections>
- <slots>
- <slot>slotUserIDChanged()</slot>
- </slots>
-</ui>
diff --git a/dialogs/certificatedetailsdialog.cpp b/dialogs/certificatedetailsdialog.cpp
index df8be952a..e69de29bb 100644
--- a/dialogs/certificatedetailsdialog.cpp
+++ b/dialogs/certificatedetailsdialog.cpp
@@ -1,443 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/certificatedetailsdialog.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 "certificatedetailsdialog.h"
-
-#include "ui_certificatedetailsdialog.h"
-
-#include <models/useridlistmodel.h>
-#include <models/subkeylistmodel.h>
-#include <models/keycache.h>
-
-#include <commands/changepassphrasecommand.h>
-#include <commands/changeownertrustcommand.h>
-#include <commands/changeexpirycommand.h>
-#include <commands/adduseridcommand.h>
-#include <commands/certifycertificatecommand.h>
-#include <commands/dumpcertificatecommand.h>
-
-#include <utils/formatting.h>
-#include <utils/gnupg-helper.h>
-
-#include <kleo/cryptobackendfactory.h>
-#include <kleo/cryptobackend.h>
-#include <kleo/keylistjob.h>
-#include <kleo/dn.h>
-
-#include <gpgme++/key.h>
-#include <gpgme++/keylistresult.h>
-
-#include <KDebug>
-#include <KMessageBox>
-#include <KLocalizedString>
-#include <KGlobalSettings>
-
-#include <QPointer>
-#include <QHeaderView>
-
-#include <boost/mem_fn.hpp>
-
-#include <algorithm>
-#include <cassert>
-
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-using namespace Kleo::Commands;
-using namespace GpgME;
-using namespace boost;
-
-static bool own( const std::vector<UserID::Signature> & sigs ) {
- const shared_ptr<const KeyCache> kc = KeyCache::instance();
- Q_FOREACH( const UserID::Signature & sig, sigs ) {
- const Key signer = kc->findByKeyIDOrFingerprint( sig.signerKeyID() );
- if ( signer.isNull() || !signer.hasSecret() )
- return false;
- }
- return !sigs.empty();
-}
-
-class CertificateDetailsDialog::Private {
- friend class ::Kleo::Dialogs::CertificateDetailsDialog;
- CertificateDetailsDialog * const q;
-public:
- explicit Private( CertificateDetailsDialog * qq )
- : q( qq ),
- key(),
- certificationsModel(),
- subkeysModel(),
- ui( q )
- {
- ui.certificationsTV->setModel( &certificationsModel );
- connect( ui.certificationsTV->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- q, SLOT(slotCertificationSelectionChanged()) );
-
- ui.subkeyTV->setModel( &subkeysModel );
- // no selection (yet)
-
- connect( KeyCache::instance().get(), SIGNAL(keysMayHaveChanged()),
- q, SLOT(slotKeysMayHaveChanged()) );
- }
-
-private:
- void startCommandImplementation( const QPointer<Command> & ptr, const char * slot ) {
- connect( ptr, SIGNAL(finished()), q, slot );
- ptr->start();
- enableDisableWidgets();
- }
- template <typename T, typename A>
- void startCommand( QPointer<Command> & ptr, const A & arg, const char * slot ) {
- if ( ptr )
- return;
- ptr = new T( arg );
- startCommandImplementation( ptr, slot );
- }
- template <typename T>
- void startCommand( QPointer<Command> & ptr, const char * slot ) {
- startCommand<T>( ptr, this->key, slot );
- }
- void commandFinished( QPointer<Command> & ptr ) {
- ptr = 0;
- enableDisableWidgets();
- }
-
- void slotChangePassphraseClicked() {
- startCommand<ChangePassphraseCommand>( changePassphraseCommand, SLOT(slotChangePassphraseCommandFinished()) );
- }
- void slotChangePassphraseCommandFinished() {
- commandFinished( changePassphraseCommand );
- }
-
- void slotChangeTrustLevelClicked() {
- startCommand<ChangeOwnerTrustCommand>( changeOwnerTrustCommand, SLOT(slotChangeOwnerTrustCommandFinished()) );
- }
- void slotChangeOwnerTrustCommandFinished() {
- commandFinished( changeOwnerTrustCommand );
- }
-
- void slotChangeExpiryDateClicked() {
- startCommand<ChangeExpiryCommand>( changeExpiryDateCommand, SLOT(slotChangeExpiryDateCommandFinished()) );
- }
- void slotChangeExpiryDateCommandFinished() {
- commandFinished( changeExpiryDateCommand );
- }
-
- void slotAddUserIDClicked() {
- startCommand<AddUserIDCommand>( addUserIDCommand, SLOT(slotAddUserIDCommandFinished()) );
- }
- void slotAddUserIDCommandFinished() {
- commandFinished( addUserIDCommand );
- }
-
- void slotCertifyUserIDClicked() {
- const std::vector<UserID> uids = selectedUserIDs();
- if ( uids.empty() )
- return;
- startCommand<CertifyCertificateCommand>( signCertificateCommand, uids, SLOT(slotSignCertificateCommandFinished()) );
- }
- void slotSignCertificateCommandFinished() {
- commandFinished( signCertificateCommand );
- }
-
- void slotRevokeCertificateClicked() {
-
- }
-
- void slotRevokeUserIDClicked() {
-
- }
-
- void slotRevokeCertificationClicked() {
-
- }
-
- void slotShowCertificationsClicked() {
- startSignatureListing();
- enableDisableWidgets();
- }
-
- void startSignatureListing() {
- if ( keyListJob )
- return;
- const CryptoBackend::Protocol * const protocol = CryptoBackendFactory::instance()->protocol( key.protocol() );
- if ( !protocol )
- return;
- KeyListJob * const job = protocol->keyListJob( /*remote*/false, /*includeSigs*/true, /*validate*/true );
- if ( !job )
- return;
- connect( job, SIGNAL(result(GpgME::KeyListResult)),
- q, SLOT(slotSignatureListingDone(GpgME::KeyListResult)) );
- connect( job, SIGNAL(nextKey(GpgME::Key)),
- q, SLOT(slotSignatureListingNextKey(GpgME::Key)) );
- if ( const Error err = job->start( QStringList( QString::fromLatin1( key.primaryFingerprint() ) ) ) )
- showSignatureListingErrorDialog( err );
- else
- keyListJob = job;
- }
- void slotSignatureListingNextKey( const Key & key ) {
- // don't lose the secret flags ...
- Key merged = key;
- merged.mergeWith( this->key );
- q->setKey( merged );
-
- // fixup the tree view
- ui.certificationsTV->expandAll();
- ui.certificationsTV->header()->resizeSections( QHeaderView::ResizeToContents );
- }
- void slotSignatureListingDone( const KeyListResult & result ) {
- if ( result.error().isCanceled() )
- ;
- else if ( result.error() )
- showSignatureListingErrorDialog( result.error() );
- else
- ;
- keyListJob = 0;
- enableDisableWidgets();
- }
- void showSignatureListingErrorDialog( const Error & err ) {
- KMessageBox::information( q, i18nc("@info",
- "<para>An error occurred while loading the certifications: "
- "<message>%1</message></para>",
- QString::fromLocal8Bit( err.asString() ) ),
- i18nc("@title","Certifications Loading Failed") );
- }
-
- void slotCertificationSelectionChanged() {
- enableDisableWidgets();
- }
-
- void slotKeysMayHaveChanged() {
- if ( const char * const fpr = key.primaryFingerprint() )
- if ( !(key.keyListMode() & Extern) )
- q->setKey( KeyCache::instance()->findByFingerprint( fpr ) );
- }
-
- void slotDumpCertificate() {
-
- if ( dumpCertificateCommand )
- return;
-
- if ( key.protocol() != CMS ) {
- ui.dumpLTW->clear();
- return;
- }
-
- ui.dumpLTW->setLines( QStringList( i18n("Please wait while generating the dump...") ) );
-
- dumpCertificateCommand = new DumpCertificateCommand( key );
- dumpCertificateCommand->setUseDialog( false );
- QPointer<Command> cmd = dumpCertificateCommand.data();
- startCommandImplementation( cmd, SLOT(slotDumpCertificateCommandFinished()) );
- }
-
- void slotDumpCertificateCommandFinished() {
- ui.dumpLTW->setLines( dumpCertificateCommand->output() );
- }
-
-private:
- void updateWidgetVisibility() {
- const bool x509 = key.protocol() == CMS;
- const bool pgp = key.protocol() == OpenPGP;
- const bool secret = key.hasSecret();
- const bool sigs = (key.keyListMode() & Signatures);
- const bool ultimateTrust = key.ownerTrust() == Key::Ultimate;
- const bool external = (key.keyListMode() & Extern);
-
- // Overview Tab
- ui.overviewActionsGB->setVisible( !external );
- ui.changePassphrasePB->setVisible( secret );
- ui.changeTrustLevelPB->setVisible( pgp && ( !secret || !ultimateTrust ) );
- ui.changeExpiryDatePB->setVisible( pgp && secret );
-
- // Certifications Tab
- ui.userIDsActionsGB->setVisible( !external && pgp );
- ui.certificationsActionGB->setVisible( !external && pgp );
- ui.addUserIDPB->setVisible( secret );
- ui.expandAllCertificationsPB->setVisible( pgp && sigs );
- ui.collapseAllCertificationsPB->setVisible( pgp && sigs );
- ui.showCertificationsPB->setVisible( pgp && !sigs );
-
- // Technical Details Tab
- ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.detailsTab ), pgp );
-
- // Chain tab
- ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.chainTab ), x509 );
-
- // Dump tab
- ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.dumpTab ), x509 );
-
- // not implemented:
- ui.revokeCertificatePB->hide();
- ui.revokeUserIDPB->hide();
- ui.certificationsActionGB->hide();
- }
-
- QModelIndexList selectedCertificationsIndexes() const {
- return ui.certificationsTV->selectionModel()->selectedRows();
- }
-
- std::vector<UserID> selectedUserIDs() const {
- const QModelIndexList mil = selectedCertificationsIndexes();
- std::vector<UserID> uids = certificationsModel.userIDs( mil, true );
- uids.erase( std::remove_if( uids.begin(), uids.end(), mem_fn( &UserID::isNull ) ), uids.end() );
- return uids;
- }
-
- std::vector<UserID::Signature> selectedSignatures() const {
- const QModelIndexList mil = selectedCertificationsIndexes();
- std::vector<UserID::Signature> sigs = certificationsModel.signatures( mil );
- sigs.erase( std::remove_if( sigs.begin(), sigs.end(), mem_fn( &UserID::Signature::isNull ) ), sigs.end() );
- return sigs;
- }
-
- void enableDisableWidgets() {
- // Overview Tab
- ui.changePassphrasePB->setEnabled( !changePassphraseCommand );
- ui.changeTrustLevelPB->setEnabled( !changeOwnerTrustCommand );
- ui.changeExpiryDatePB->setEnabled( !changeExpiryDateCommand );
-
- // Certifications Tab
- ui.addUserIDPB->setEnabled( !addUserIDCommand );
- ui.showCertificationsPB->setEnabled( !keyListJob );
- ui.showCertificationsPB->setText( keyListJob
- ? i18n("(please wait while certifications are being loaded)")
- : i18n("Load Certifications (may take a while)") );
-
- const std::vector<UserID> uids = selectedUserIDs();
- const std::vector<UserID::Signature> sigs = selectedSignatures();
-
- ui.certifyUserIDPB->setEnabled( !uids.empty() && sigs.empty() && !signCertificateCommand );
- ui.revokeUserIDPB->setEnabled( !uids.empty() && sigs.empty() );
- ui.revokeCertificationPB->setEnabled( uids.empty() && !sigs.empty() && own( sigs ) );
- }
-
- void updateLabel() {
- ui.overviewLB->setText( Formatting::formatOverview( key ) );
- }
-
- void updateChainTab() {
- ui.chainTW->clear();
-
- if ( key.protocol() != CMS )
- return;
-
- QTreeWidgetItem * last = 0;
- const std::vector<Key> chain = KeyCache::instance()->findIssuers( key, KeyCache::RecursiveSearch|KeyCache::IncludeSubject );
- if ( chain.empty() )
- return;
- if ( !chain.back().isRoot() ) {
- last = new QTreeWidgetItem( ui.chainTW );
- last->setText( 0, i18n("Issuer Certificate Not Found (%1)",
- DN( chain.back().issuerName() ).prettyDN() ) );
- //last->setSelectable( false );
- const QBrush & fg = ui.chainTW->palette().brush( QPalette::Disabled, QPalette::WindowText );
- last->setForeground( 0, fg );
- }
- for ( std::vector<Key>::const_reverse_iterator it = chain.rbegin(), end = chain.rend() ; it != end ; ++it ) {
- last = last ? new QTreeWidgetItem( last ) : new QTreeWidgetItem( ui.chainTW ) ;
- last->setText( 0, DN( it->userID(0).id() ).prettyDN() );
- //last->setSelectable( true );
- }
- ui.chainTW->expandAll();
- }
-
- void propagateKey() {
- certificationsModel.setKey( key );
- const QModelIndexList uidIndexes = certificationsModel.indexes( key.userIDs() );
- Q_FOREACH( const QModelIndex & idx, uidIndexes )
- ui.certificationsTV->setFirstColumnSpanned( idx.row(), idx.parent(), true );
-
- subkeysModel.setKey( key );
- ui.subkeyTV->header()->resizeSections( QHeaderView::ResizeToContents );
-
- updateChainTab();
- slotDumpCertificate();
- }
-
-
-private:
- Key key;
- UserIDListModel certificationsModel;
- SubkeyListModel subkeysModel;
-
- QPointer<Command> changePassphraseCommand;
- QPointer<Command> changeOwnerTrustCommand;
- QPointer<Command> changeExpiryDateCommand;
-
- QPointer<Command> addUserIDCommand;
- QPointer<Command> signCertificateCommand;
-
- QPointer<DumpCertificateCommand> dumpCertificateCommand;
-
- QPointer<KeyListJob> keyListJob;
-
- struct UI : public Ui_CertificateDetailsDialog {
- explicit UI( Dialogs::CertificateDetailsDialog * qq )
- : Ui_CertificateDetailsDialog()
- {
- setupUi( qq );
-
- chainTW->header()->setResizeMode( 0, QHeaderView::Stretch );
-
- dumpLTW->setFont( KGlobalSettings::fixedFont() );
- dumpLTW->setMinimumVisibleLines( 15 );
- dumpLTW->setMinimumVisibleColumns( 40 );
-
- subkeyHLine->setTitle( i18nc("@title","Subkeys") );
- }
- } ui;
-};
-
-CertificateDetailsDialog::CertificateDetailsDialog( QWidget * p, Qt::WindowFlags f )
- : QDialog( p, f ), d( new Private( this ) )
-{
-
-}
-
-CertificateDetailsDialog::~CertificateDetailsDialog() {}
-
-
-void CertificateDetailsDialog::setKey( const Key & key ) {
- d->key = key;
- d->updateWidgetVisibility();
- d->updateLabel();
- d->propagateKey();
- d->enableDisableWidgets();
-}
-
-Key CertificateDetailsDialog::key() const {
- return d->key;
-}
-
-
-#include "moc_certificatedetailsdialog.cpp"
diff --git a/dialogs/certificatedetailsdialog.h b/dialogs/certificatedetailsdialog.h
index 3386fb8d1..e69de29bb 100644
--- a/dialogs/certificatedetailsdialog.h
+++ b/dialogs/certificatedetailsdialog.h
@@ -1,86 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/certificatedetailsdialog.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_DIALOGS_CERTIFICATEDETAILS_H__
-#define __KLEOPATRA_DIALOGS_CERTIFICATEDETAILS_H__
-
-#include <QDialog>
-
-#include <utils/pimpl_ptr.h>
-
-class QDate;
-
-namespace GpgME {
- class Key;
-}
-
-namespace Kleo {
-namespace Dialogs {
-
- class CertificateDetailsDialog : public QDialog {
- Q_OBJECT
- public:
- explicit CertificateDetailsDialog( QWidget * parent=0, Qt::WindowFlags f=0 );
- ~CertificateDetailsDialog();
-
- void setKey( const GpgME::Key & key );
- GpgME::Key key() const;
-
- private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
- Q_PRIVATE_SLOT( d, void slotChangePassphraseClicked() )
- Q_PRIVATE_SLOT( d, void slotChangePassphraseCommandFinished() )
- Q_PRIVATE_SLOT( d, void slotChangeTrustLevelClicked() )
- Q_PRIVATE_SLOT( d, void slotChangeOwnerTrustCommandFinished() )
- Q_PRIVATE_SLOT( d, void slotChangeExpiryDateClicked() )
- Q_PRIVATE_SLOT( d, void slotChangeExpiryDateCommandFinished() )
- Q_PRIVATE_SLOT( d, void slotRevokeCertificateClicked() )
- Q_PRIVATE_SLOT( d, void slotAddUserIDClicked() )
- Q_PRIVATE_SLOT( d, void slotAddUserIDCommandFinished() )
- Q_PRIVATE_SLOT( d, void slotRevokeUserIDClicked() )
- Q_PRIVATE_SLOT( d, void slotCertifyUserIDClicked() )
- Q_PRIVATE_SLOT( d, void slotSignCertificateCommandFinished() )
- Q_PRIVATE_SLOT( d, void slotRevokeCertificationClicked() )
- Q_PRIVATE_SLOT( d, void slotShowCertificationsClicked() )
- Q_PRIVATE_SLOT( d, void slotSignatureListingNextKey(GpgME::Key) )
- Q_PRIVATE_SLOT( d, void slotSignatureListingDone(GpgME::KeyListResult) )
- Q_PRIVATE_SLOT( d, void slotCertificationSelectionChanged() )
- Q_PRIVATE_SLOT( d, void slotKeysMayHaveChanged() )
- Q_PRIVATE_SLOT( d, void slotDumpCertificate() )
- Q_PRIVATE_SLOT( d, void slotDumpCertificateCommandFinished() )
- };
-
-}
-}
-
-#endif /* __KLEOPATRA_DIALOGS_CERTIFICATEDETAILS_H__ */
diff --git a/dialogs/certificatedetailsdialog.ui b/dialogs/certificatedetailsdialog.ui
index cc64911c3..e69de29bb 100644
--- a/dialogs/certificatedetailsdialog.ui
+++ b/dialogs/certificatedetailsdialog.ui
@@ -1,614 +0,0 @@
-<ui version="4.0" >
- <class>CertificateDetailsDialog</class>
- <widget class="QDialog" name="CertificateDetailsDialog" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>666</width>
- <height>514</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Certificate Details</string>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QTabWidget" name="tabWidget" >
- <widget class="QWidget" name="overviewTab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>644</width>
- <height>417</height>
- </rect>
- </property>
- <attribute name="title" >
- <string>Overview</string>
- </attribute>
- <layout class="QGridLayout" >
- <item row="1" column="1" >
- <widget class="QGroupBox" name="overviewActionsGB" >
- <property name="title" >
- <string>Actions</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout" >
- <item>
- <widget class="QPushButton" name="changePassphrasePB" >
- <property name="text" >
- <string>Change Passphrase...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="changeTrustLevelPB" >
- <property name="text" >
- <string>Trust Certifications made by this Certificate...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="changeExpiryDatePB" >
- <property name="text" >
- <string>Change Expiry Date...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="revokeCertificatePB" >
- <property name="text" >
- <string>Revoke this Certificate...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>0</width>
- <height>1</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item row="0" column="0" colspan="2" >
- <widget class="QTextBrowser" name="overviewLB" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
- <horstretch>0</horstretch>
- <verstretch>1</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape" >
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="openLinks" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QGroupBox" name="groupBox_2" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
- <horstretch>1</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title" >
- <string>Photo</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
- <item>
- <widget class="QLabel" name="photoLB" >
- <property name="text" >
- <string>&lt;p>At the moment, Kleopatra does not support photos in certificates. It has no support for adding, nor for displaying them. This is for the following reasons:&lt;/p>
-&lt;ul>
-&lt;li>Photos give a false sense of security.&lt;/li>
-&lt;li>Photos increase the size of certificates.&lt;/li>
-&lt;/ul></string>
- </property>
- <property name="scaledContents" >
- <bool>false</bool>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="certificationsTab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>644</width>
- <height>417</height>
- </rect>
- </property>
- <attribute name="title" >
- <string>User-IDs and Certifications</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_6" >
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2" >
- <item>
- <widget class="QTreeView" name="certificationsTV" >
- <property name="selectionMode" >
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- <property name="allColumnsShowFocus" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_5" >
- <item>
- <widget class="QGroupBox" name="userIDsActionsGB" >
- <property name="title" >
- <string>User-IDs</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3" >
- <item>
- <widget class="QPushButton" name="addUserIDPB" >
- <property name="text" >
- <string>Add...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="revokeUserIDPB" >
- <property name="text" >
- <string>Revoke...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="certifyUserIDPB" >
- <property name="text" >
- <string>Certify...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="certificationsActionGB" >
- <property name="title" >
- <string>Certifications</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4" >
- <item>
- <widget class="QPushButton" name="revokeCertificationPB" >
- <property name="text" >
- <string>Revoke...</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="expandAllCertificationsPB" >
- <property name="text" >
- <string>Expand All</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="collapseAllCertificationsPB" >
- <property name="text" >
- <string>Collapse All</string>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QPushButton" name="showCertificationsPB" >
- <property name="text" >
- <string/>
- </property>
- <property name="autoDefault" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="detailsTab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>644</width>
- <height>417</height>
- </rect>
- </property>
- <attribute name="title" >
- <string>Technical Details</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_7" >
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout" >
- <item>
- <widget class="QLabel" name="detailsLeftLB" />
- </item>
- <item>
- <widget class="QLabel" name="detailsRightLB" />
- </item>
- </layout>
- </item>
- <item>
- <widget class="KDHorizontalLine" name="subkeyHLine" />
- </item>
- <item>
- <widget class="QTreeView" name="subkeyTV" >
- <property name="selectionMode" >
- <enum>QAbstractItemView::NoSelection</enum>
- </property>
- <property name="rootIsDecorated" >
- <bool>false</bool>
- </property>
- <property name="allColumnsShowFocus" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="chainTab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>644</width>
- <height>417</height>
- </rect>
- </property>
- <attribute name="title" >
- <string>Chain</string>
- </attribute>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QTreeWidget" name="chainTW" >
- <property name="allColumnsShowFocus" >
- <bool>true</bool>
- </property>
- <property name="headerHidden" >
- <bool>true</bool>
- </property>
- <column>
- <property name="text" >
- <string>1</string>
- </property>
- </column>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="dumpTab" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>644</width>
- <height>417</height>
- </rect>
- </property>
- <attribute name="title" >
- <string>Dump</string>
- </attribute>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>This is a dump of all information the backend has about this certificate:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="KDLogTextWidget" native="1" name="dumpLTW" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons" >
- <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KDLogTextWidget</class>
- <extends>QWidget</extends>
- <header>utils/kdlogtextwidget.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>KDHorizontalLine</class>
- <extends>QFrame</extends>
- <header>ui/kdhorizontalline.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>295</x>
- <y>573</y>
- </hint>
- <hint type="destinationlabel" >
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>changePassphrasePB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotChangePassphraseClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>748</x>
- <y>390</y>
- </hint>
- <hint type="destinationlabel" >
- <x>782</x>
- <y>350</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>changeTrustLevelPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotChangeTrustLevelClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>742</x>
- <y>400</y>
- </hint>
- <hint type="destinationlabel" >
- <x>784</x>
- <y>402</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>changeExpiryDatePB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotChangeExpiryDateClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>742</x>
- <y>448</y>
- </hint>
- <hint type="destinationlabel" >
- <x>780</x>
- <y>450</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>revokeCertificatePB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotRevokeCertificateClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>728</x>
- <y>496</y>
- </hint>
- <hint type="destinationlabel" >
- <x>778</x>
- <y>498</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>addUserIDPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotAddUserIDClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>738</x>
- <y>100</y>
- </hint>
- <hint type="destinationlabel" >
- <x>780</x>
- <y>100</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>revokeUserIDPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotRevokeUserIDClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>738</x>
- <y>150</y>
- </hint>
- <hint type="destinationlabel" >
- <x>778</x>
- <y>152</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>certifyUserIDPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotCertifyUserIDClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>736</x>
- <y>190</y>
- </hint>
- <hint type="destinationlabel" >
- <x>780</x>
- <y>190</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>revokeCertificationPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotRevokeCertificationClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>732</x>
- <y>272</y>
- </hint>
- <hint type="destinationlabel" >
- <x>780</x>
- <y>272</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>showCertificationsPB</sender>
- <signal>clicked()</signal>
- <receiver>CertificateDetailsDialog</receiver>
- <slot>slotShowCertificationsClicked()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>748</x>
- <y>510</y>
- </hint>
- <hint type="destinationlabel" >
- <x>776</x>
- <y>490</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>expandAllCertificationsPB</sender>
- <signal>clicked()</signal>
- <receiver>certificationsTV</receiver>
- <slot>expandAll()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>665</x>
- <y>424</y>
- </hint>
- <hint type="destinationlabel" >
- <x>525</x>
- <y>320</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>collapseAllCertificationsPB</sender>
- <signal>clicked()</signal>
- <receiver>certificationsTV</receiver>
- <slot>collapseAll()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>701</x>
- <y>464</y>
- </hint>
- <hint type="destinationlabel" >
- <x>585</x>
- <y>352</y>
- </hint>
- </hints>
- </connection>
- </connections>
- <slots>
- <slot>slotChangePassphraseClicked()</slot>
- <slot>slotChangeTrustLevelClicked()</slot>
- <slot>slotChangeExpiryDateClicked()</slot>
- <slot>slotRevokeCertificateClicked()</slot>
- <slot>slotAddUserIDClicked()</slot>
- <slot>slotCertifyUserIDClicked()</slot>
- <slot>slotRevokeUserIDClicked()</slot>
- <slot>slotRevokeCertificationClicked()</slot>
- <slot>slotShowCertificationsClicked()</slot>
- </slots>
-</ui>
diff --git a/dialogs/certificateselectiondialog.cpp b/dialogs/certificateselectiondialog.cpp
index 4c3e64a4f..877c45885 100644
--- a/dialogs/certificateselectiondialog.cpp
+++ b/dialogs/certificateselectiondialog.cpp
@@ -1,331 +1,331 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/certificateselectiondialog.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 "certificateselectiondialog.h"
#include <view/searchbar.h>
#include <view/tabwidget.h>
#include <models/keylistmodel.h>
#include <models/keycache.h>
#include <commands/reloadkeyscommand.h>
#include <gpgme++/key.h>
#include <KLocale>
#include <KConfigGroup>
#include <KSharedConfig>
#include <KDebug>
#include <QLabel>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QLayout>
#include <QItemSelectionModel>
#include <QAbstractItemView>
#include <QPointer>
#include <boost/bind.hpp>
#include <algorithm>
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace boost;
using namespace GpgME;
class CertificateSelectionDialog::Private {
friend class ::Kleo::Dialogs::CertificateSelectionDialog;
CertificateSelectionDialog * const q;
public:
explicit Private( CertificateSelectionDialog * qq );
private:
void reload();
void slotReloaded();
void slotCurrentViewChanged( QAbstractItemView * newView );
void slotSelectionChanged();
void slotDoubleClicked( const QModelIndex & idx );
private:
bool acceptable( const std::vector<Key> & keys ) {
return !keys.empty();
}
void filterAllowedKeys( std::vector<Key> & keys );
void updateLabelText() {
ui.label.setText( !customLabelText.isEmpty() ? customLabelText :
(options & MultiSelection)
? i18n( "Please select one or more of the following certificates:" )
: i18n( "Please select one of the following certificates:" ) );
}
private:
QPointer<QAbstractItemView> lastView;
QString customLabelText;
Options options;
struct UI {
QLabel label;
SearchBar searchBar;
TabWidget tabWidget;
QDialogButtonBox buttonBox;
QVBoxLayout vlay;
explicit UI( CertificateSelectionDialog * q )
: label( q ),
searchBar( q ),
tabWidget( q ),
buttonBox( q ),
vlay( q )
{
KDAB_SET_OBJECT_NAME( label );
KDAB_SET_OBJECT_NAME( searchBar );
KDAB_SET_OBJECT_NAME( tabWidget );
KDAB_SET_OBJECT_NAME( buttonBox );
KDAB_SET_OBJECT_NAME( vlay );
vlay.addWidget( &label );
vlay.addWidget( &searchBar );
vlay.addWidget( &tabWidget, 1 );
vlay.addWidget( &buttonBox );
QPushButton * const ok = buttonBox.addButton( QDialogButtonBox::Ok );
ok->setEnabled( false );
QPushButton * const cancel = buttonBox.addButton( QDialogButtonBox::Close );
QPushButton * const reload = buttonBox.addButton( i18n("&Reload Certificates"), QDialogButtonBox::ActionRole );
connect( &buttonBox, SIGNAL(accepted()), q, SLOT(accept()) );
connect( &buttonBox, SIGNAL(rejected()), q, SLOT(reject()) );
connect( reload, SIGNAL(clicked()), q, SLOT(reload()) );
}
} ui;
};
CertificateSelectionDialog::Private::Private( CertificateSelectionDialog * qq )
: q( qq ),
ui( q )
{
ui.tabWidget.setFlatModel( AbstractKeyListModel::createFlatKeyListModel() );
ui.tabWidget.setHierarchicalModel( AbstractKeyListModel::createHierarchicalKeyListModel() );
ui.tabWidget.connectSearchBar( &ui.searchBar );
connect( &ui.tabWidget, SIGNAL(currentViewChanged(QAbstractItemView*)),
q, SLOT(slotCurrentViewChanged(QAbstractItemView*)) );
updateLabelText();
q->setWindowTitle( i18n( "Certificate Selection" ) );
}
CertificateSelectionDialog::CertificateSelectionDialog( QWidget * parent, Qt::WindowFlags f )
: QDialog( parent, f ), d( new Private( this ) )
{
const KSharedConfig::Ptr config = KSharedConfig::openConfig( "kleopatracertificateselectiondialogrc" );
d->ui.tabWidget.loadViews( config.data() );
const KConfigGroup geometry( config, "Geometry" );
resize( geometry.readEntry( "size", size() ) );
d->slotReloaded();
}
CertificateSelectionDialog::~CertificateSelectionDialog() {}
void CertificateSelectionDialog::setCustomLabelText( const QString & txt ) {
if ( txt == d->customLabelText )
return;
d->customLabelText = txt;
d->updateLabelText();
}
QString CertificateSelectionDialog::customLabelText() const {
return d->customLabelText;
}
void CertificateSelectionDialog::setOptions( Options options ) {
if ( d->options == options )
return;
d->options = options;
d->ui.tabWidget.setMultiSelection( options & MultiSelection );
d->slotReloaded();
}
CertificateSelectionDialog::Options CertificateSelectionDialog::options() const {
return d->options;
}
void CertificateSelectionDialog::setStringFilter( const QString & filter ) {
d->ui.tabWidget.setStringFilter( filter );
}
void CertificateSelectionDialog::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
d->ui.tabWidget.setKeyFilter( filter );
}
void CertificateSelectionDialog::selectCertificates( const std::vector<Key> & keys ) {
const QAbstractItemView * const view = d->ui.tabWidget.currentView();
if ( !view )
return;
const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
assert( model );
QItemSelectionModel * const sm = view->selectionModel();
assert( sm );
Q_FOREACH( const QModelIndex & idx, model->indexes( keys ) )
if ( idx.isValid() )
sm->select( idx, QItemSelectionModel::Select | QItemSelectionModel::Rows );
}
void CertificateSelectionDialog::selectCertificate( const Key & key ) {
selectCertificates( std::vector<Key>( 1, key ) );
}
std::vector<Key> CertificateSelectionDialog::selectedCertificates() const {
const QAbstractItemView * const view = d->ui.tabWidget.currentView();
if ( !view )
return std::vector<Key>();
const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
assert( model );
const QItemSelectionModel * const sm = view->selectionModel();
assert( sm );
return model->keys( sm->selectedRows() );
}
Key CertificateSelectionDialog::selectedCertificate() const {
const std::vector<Key> keys = selectedCertificates();
return keys.empty() ? Key() : keys.front() ;
}
void CertificateSelectionDialog::hideEvent( QHideEvent * e ) {
KSharedConfig::Ptr config = KSharedConfig::openConfig( "kleopatracertificateselectiondialogrc" );
d->ui.tabWidget.saveViews( config.data() );
KConfigGroup geometry( config, "Geometry" );
geometry.writeEntry( "size", size() );
QDialog::hideEvent( e );
}
void CertificateSelectionDialog::Private::reload() {
Command * const cmd = new ReloadKeysCommand( 0 );
connect( cmd, SIGNAL(finsihed()), q, SLOT(slotReloaded()) );
cmd->start();
}
void CertificateSelectionDialog::Private::slotReloaded() {
q->setEnabled( true );
std::vector<Key> keys = (options & SecretKeys) ? KeyCache::instance()->secretKeys() : KeyCache::instance()->keys() ;
filterAllowedKeys( keys );
const std::vector<Key> selected = q->selectedCertificates();
if ( AbstractKeyListModel * const model = ui.tabWidget.flatModel() )
- model->setKeys( keys );
+ model->addKeys( keys );
if ( AbstractKeyListModel * const model = ui.tabWidget.hierarchicalModel() )
- model->setKeys( keys );
+ model->addKeys( keys );
q->selectCertificates( selected );
}
void CertificateSelectionDialog::Private::filterAllowedKeys( std::vector<Key> & keys ) {
std::vector<Key>::iterator end = keys.end();
switch ( options & AnyFormat ) {
case OpenPGPFormat:
end = std::remove_if( keys.begin(), end, bind( &Key::protocol, _1 ) != GpgME::OpenPGP );
break;
case CMSFormat:
end = std::remove_if( keys.begin(), end, bind( &Key::protocol, _1 ) != GpgME::CMS );
break;
default:
case AnyFormat:
;
}
switch ( options & AnyCertificate ) {
case SignOnly:
end = std::remove_if( keys.begin(), end, !bind( &Key::canSign, _1 ) );
break;
case EncryptOnly:
end = std::remove_if( keys.begin(), end, !bind( &Key::canEncrypt, _1 ) );
break;
default:
case AnyCertificate:
;
}
if ( options & SecretKeys )
end = std::remove_if( keys.begin(), end, !bind( &Key::hasSecret, _1 ) );
keys.erase( end, keys.end() );
}
void CertificateSelectionDialog::Private::slotCurrentViewChanged( QAbstractItemView * newView ) {
if ( lastView ) {
disconnect( lastView, SIGNAL(doubleClicked(QModelIndex)),
q, SLOT(slotDoubleClicked(QModelIndex)) );
assert( lastView->selectionModel() );
disconnect( lastView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged()) );
}
lastView = newView;
if ( newView ) {
connect( newView, SIGNAL(doubleClicked(QModelIndex)),
q, SLOT(slotDoubleClicked(QModelIndex)) );
assert( newView->selectionModel() );
connect( newView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged()) );
}
slotSelectionChanged();
}
void CertificateSelectionDialog::Private::slotSelectionChanged() {
if ( QPushButton * const pb = ui.buttonBox.button( QDialogButtonBox::Ok ) )
pb->setEnabled( acceptable( q->selectedCertificates() ) );
}
void CertificateSelectionDialog::Private::slotDoubleClicked( const QModelIndex & idx ) {
QAbstractItemView * const view = ui.tabWidget.currentView();
assert( view );
const KeyListModelInterface * const model = dynamic_cast<KeyListModelInterface*>( view->model() );
assert( model );
QItemSelectionModel * const sm = view->selectionModel();
assert( sm );
- sm->select( idx, QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows );
+ sm->select( idx, QItemSelectionModel::ClearAndSelect );
QMetaObject::invokeMethod( q, "accept", Qt::QueuedConnection );
}
void CertificateSelectionDialog::accept() {
if ( d->acceptable( selectedCertificates() ) )
QDialog::accept();
}
#include "moc_certificateselectiondialog.cpp"
diff --git a/dialogs/certificationoptionswidget.ui b/dialogs/certificationoptionswidget.ui
index 6f352c1de..e69de29bb 100644
--- a/dialogs/certificationoptionswidget.ui
+++ b/dialogs/certificationoptionswidget.ui
@@ -1,159 +0,0 @@
-<ui version="4.0" >
- <class>Kleo::Dialogs::CertifyCertificateDialogPrivate::CertificationOptionsWidget</class>
- <widget class="QWidget" name="Kleo::Dialogs::CertifyCertificateDialogPrivate::CertificationOptionsWidget" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>879</width>
- <height>523</height>
- </rect>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="3" >
- <widget class="QLabel" name="label_6" >
- <property name="text" >
- <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
-p, li { white-space: pre-wrap; }
-&lt;/style>&lt;/head>&lt;body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-weight:600;">Step 3: &lt;/span>Choose how to certify&lt;/p>&lt;/body>&lt;/html></string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="3" >
- <widget class="QStackedWidget" name="stackedWidget" >
- <property name="currentIndex" >
- <number>1</number>
- </property>
- <widget class="QWidget" name="multipleKeysPage" >
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QLabel" name="label_7" >
- <property name="text" >
- <string>Choose which of your keys to sign with:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="keyListView" />
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="singleKeyPage" >
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QLabel" name="singleKeyLabel" >
- <property name="text" >
- <string>Certification will be performed using certificate %1.</string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item rowspan="2" row="3" column="1" >
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QRadioButton" name="localSignatureRB" >
- <property name="text" >
- <string>Certify only for myself</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="exportableSignatureRB" >
- <property name="text" >
- <string>Certify for everyone to see</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="sendToServerCB" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>Send certified certificate to server afterwards</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item row="3" column="2" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="5" column="1" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections>
- <connection>
- <sender>exportableSignatureRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>sendToServerCB</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>439</x>
- <y>338</y>
- </hint>
- <hint type="destinationlabel" >
- <x>455</x>
- <y>368</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/dialogs/certifycertificatedialog.cpp b/dialogs/certifycertificatedialog.cpp
index f964fcec5..e69de29bb 100644
--- a/dialogs/certifycertificatedialog.cpp
+++ b/dialogs/certifycertificatedialog.cpp
@@ -1,371 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/signcertificatedialog.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 "certifycertificatedialog.h"
-#include "certifycertificatedialog_p.h"
-
-#include <utils/formatting.h>
-
-#include <KDebug>
-#include <KLocalizedString>
-
-#include <QGridLayout>
-#include <QStandardItem>
-#include <QStandardItemModel>
-#include <QListView>
-#include <QListWidgetItem>
-#include <QVBoxLayout>
-#include <QWizardPage>
-
-#include <QTextDocument> // Qt::escape
-
-#include <cassert>
-
-using namespace boost;
-using namespace GpgME;
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-using namespace Kleo::Dialogs::CertifyCertificateDialogPrivate;
-
-
-void UserIDModel::setCertificateToCertify( const Key & key ) {
- m_key = key;
- clear();
- const std::vector<UserID> ids = key.userIDs();
- for ( unsigned int i = 0; i < ids.size(); ++i ) {
- QStandardItem * const item = new QStandardItem;
- item->setText( Formatting::prettyUserID( key.userID( i ) ) );
- item->setData( i, UserIDIndex );
- item->setCheckable( true );
- item->setEditable( false );
- appendRow( item );
- }
-}
-
-std::vector<unsigned int> UserIDModel::checkedUserIDs() const {
- std::vector<unsigned int> ids;
- for ( int i = 0; i < rowCount(); ++i )
- if ( item( i )->checkState() == Qt::Checked )
- ids.push_back( item( i )->data( UserIDIndex ).toUInt() );
- return ids;
-}
-
-void SecretKeysModel::setSecretKeys( const std::vector<Key> & keys ) {
- clear();
- m_secretKeys = keys;
- for ( unsigned int i = 0; i < m_secretKeys.size(); ++i ) {
- const Key key = m_secretKeys[i];
- QStandardItem * const item = new QStandardItem;
- item->setText( Formatting::prettyNameAndEMail( key ) );
- item->setData( i, IndexRole );
- item->setEditable( false );
- appendRow( item );
- }
-}
-
-Key SecretKeysModel::keyFromItem( const QStandardItem * item ) const {
- assert( item );
- const unsigned int idx = item->data( IndexRole ).toUInt();
- assert( idx < m_secretKeys.size() );
- return m_secretKeys[idx];
-}
-
-Key SecretKeysModel::keyFromIndex( const QModelIndex & idx ) const {
- return keyFromItem( itemFromIndex( idx ) );
-}
-
-SelectUserIDsPage::SelectUserIDsPage( QWidget * parent ) : QWizardPage( parent ), m_userIDModel() {
- QVBoxLayout * const layout = new QVBoxLayout ( this );
- QLabel * const label = new QLabel;
- label->setText( i18n( "<b>Step 1:</b> Please select the user IDs you wish to certify." ) );
- layout->addWidget( label );
- m_listView = new QListView;
- m_listView->setModel( &m_userIDModel );
- connect( &m_userIDModel, SIGNAL(itemChanged(QStandardItem*)), this, SIGNAL(completeChanged()) );
- layout->addWidget( m_listView );
-}
-
-bool SelectUserIDsPage::isComplete() const {
- return !selectedUserIDs().empty();
-}
-
-std::vector<unsigned int> SelectUserIDsPage::selectedUserIDs() const {
- return m_userIDModel.checkedUserIDs();
-}
-
-void SelectUserIDsPage::setCertificateToCertify( const Key & key ) {
- m_userIDModel.setCertificateToCertify( key );
-
-}
-
-SelectCheckLevelPage::SelectCheckLevelPage( QWidget * parent ) : QWizardPage( parent ), m_ui() {
- m_ui.setupUi( this );
-}
-
-unsigned int SelectCheckLevelPage::checkLevel() const {
- if ( m_ui.checkLevelNotCheckedRB->isChecked() )
- return 1;
- if ( m_ui.checkLevelCasualRB->isChecked() )
- return 2;
- if ( m_ui.checkLevelThoroughlyRB->isChecked() )
- return 3;
- assert( !"No check level radiobutton checked" );
- return 0;
-}
-
-OptionsPage::OptionsPage( QWidget * parent ) : QWizardPage( parent ), m_ui() {
- m_ui.setupUi( this );
- m_ui.keyListView->setModel( &m_model );
- connect( m_ui.keyListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SIGNAL(completeChanged()) );
- setCommitPage( true );
- setButtonText( QWizard::CommitButton, i18n( "Certify" ) );
-}
-
-
-bool OptionsPage::exportableCertificationSelected() const {
- return m_ui.exportableSignatureRB->isChecked();
-}
-
-void OptionsPage::setCertificatesWithSecretKeys( const std::vector<Key> & keys ) {
- assert( !keys.empty() );
- m_model.setSecretKeys( keys );
- if ( keys.size() == 1 ) {
- m_ui.stackedWidget->setCurrentWidget( m_ui.singleKeyPage );
- m_ui.singleKeyLabel->setText( i18n( "Certification will be performed using certificate %1.", Formatting::prettyNameAndEMail( keys[0] ) ) );
- } else {
- m_ui.stackedWidget->setCurrentWidget( m_ui.multipleKeysPage );
- }
- emit completeChanged();
-}
-
-Key OptionsPage::selectedSecretKey() const {
- const QModelIndexList idxs = m_ui.keyListView->selectionModel()->selectedIndexes();
- assert( idxs.size() <= 1 );
- return idxs.isEmpty() ? Key() : m_model.keyFromIndex( idxs[0] );
-}
-
-bool OptionsPage::sendToServer() const {
- return m_ui.sendToServerCB->isChecked();
-}
-
-bool OptionsPage::validatePage() {
- emit nextClicked();
- return true;
-}
-
-bool OptionsPage::isComplete() const {
- return !selectedSecretKey().isNull();
-}
-
-SummaryPage::SummaryPage( QWidget * parent ) : QWizardPage( parent ), m_complete( false ) {
- QGridLayout * const layout = new QGridLayout( this );
- QLabel * const uidLabelLabel = new QLabel( i18n( "Signed user IDs:" ) );
- uidLabelLabel->setAlignment( Qt::AlignTop );
- layout->addWidget( new QLabel( i18n( "<b>Summary:</b>" ) ), 0, 0, 1, 2 );
- layout->addWidget( uidLabelLabel, 1, 0 );
- layout->addWidget( m_userIDsLabel = new QLabel, 1, 1 );
- layout->addWidget( new QLabel( i18n( "Check level:" ) ), 2, 0 );
- layout->addWidget( m_checkLevelLabel = new QLabel, 2, 1 );
- layout->addWidget( new QLabel( i18n( "Selected secret certificate:" ) ), 3, 0 );
- layout->addWidget( m_secretKeyLabel = new QLabel, 3, 1 );
- m_secretKeyLabel->setTextFormat( Qt::PlainText );
- layout->addWidget( m_resultLabel = new QLabel, 4, 0, 1, 2, Qt::AlignCenter );
- layout->setRowStretch( 4, 1 );
- m_resultLabel->setAlignment( Qt::AlignCenter );
-}
-
-bool SummaryPage::isComplete() const {
- return m_complete;
-}
-
-void SummaryPage::setSummary( const SummaryPage::Summary & sum ) {
- const Key key = sum.certificateToCertify;
- QStringList ids;
- Q_FOREACH ( const unsigned int i, sum.selectedUserIDs )
- ids += Qt::escape( Formatting::prettyUserID( key.userID( i ) ) );
- m_userIDsLabel->setText( "<qt>" + ids.join( "<br/>" ) + "</qt>" );
- m_secretKeyLabel->setText( sum.secretKey.isNull() ? i18n( "Default certificate" ) : Formatting::prettyNameAndEMail( sum.secretKey ) );
- switch( sum.checkLevel ) {
- case 0:
- m_checkLevelLabel->setText( i18n( "No statement made" ) );
- break;
- case 1:
- m_checkLevelLabel->setText( i18n( "Not checked" ) );
- break;
- case 2:
- m_checkLevelLabel->setText( i18n( "Casually checked" ) );
- break;
- case 3:
- m_checkLevelLabel->setText( i18n( "Thoroughly checked" ) );
- break;
- }
-}
-
-void SummaryPage::setComplete( bool complete ) {
- if ( complete == m_complete )
- return;
- m_complete = complete;
- emit completeChanged();
-}
-void SummaryPage::setResult( const Error & err ) {
- if ( err && !err.isCanceled() )
- m_resultLabel->setText( i18n( "The certificate could not be certified. <b>Error</b>: %1", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) ) );
- else if ( err.isCanceled() )
- m_resultLabel->setText( "Certification canceled." );
- else
- m_resultLabel->setText("Certification successful." );
-}
-
-class CertifyCertificateDialog::Private {
- friend class ::Kleo::Dialogs::CertifyCertificateDialog;
- CertifyCertificateDialog * const q;
-
-public:
- explicit Private( CertifyCertificateDialog * qq )
- : q( qq ),
- summaryPageId( 0 ),
- selectUserIDsPage( 0 ),
- selectCheckLevelPage( 0 ),
- optionsPage( 0 ),
- summaryPage( 0 )
- {
- selectUserIDsPage = new SelectUserIDsPage( q );
- q->addPage( selectUserIDsPage );
- selectCheckLevelPage = new SelectCheckLevelPage( q );
- q->addPage( selectCheckLevelPage );
- optionsPage = new OptionsPage( q );
- q->addPage( optionsPage );
- summaryPage = new SummaryPage( q );
- summaryPageId = q->addPage( summaryPage );
- connect( optionsPage, SIGNAL(nextClicked()), q, SIGNAL(certificationPrepared()) );
- }
-
- void ensureSummaryPageVisible();
-
- void certificationResult( const Error & error );
-
- void setOperationCompleted() {
- summaryPage->setComplete( true );
- }
-
- SummaryPage::Summary createSummary() const {
- SummaryPage::Summary sum;
- sum.selectedUserIDs = selectUserIDsPage->selectedUserIDs();
- sum.secretKey = optionsPage->selectedSecretKey();
- sum.certificateToCertify = selectUserIDsPage->certificateToCertify();
- sum.checkLevel = selectCheckLevelPage->checkLevel();
- sum.exportable = optionsPage->exportableCertificationSelected();
- sum.sendToServer = optionsPage->sendToServer();
- return sum;
- }
-
- int summaryPageId;
- SelectUserIDsPage * selectUserIDsPage;
- SelectCheckLevelPage * selectCheckLevelPage;
- OptionsPage * optionsPage;
- SummaryPage * summaryPage;
-};
-
-
-
-CertifyCertificateDialog::CertifyCertificateDialog( QWidget * p, Qt::WindowFlags f )
- : QWizard( p, f ), d( new Private( this ) )
-{
-}
-
-CertifyCertificateDialog::~CertifyCertificateDialog() {}
-
-void CertifyCertificateDialog::setCertificateToCertify( const Key & key ) {
- setWindowTitle( i18nc( "arg is name, email of certificate holder", "Certify Certificate: %1", Formatting::prettyName( key ) ) );
- d->selectUserIDsPage->setCertificateToCertify( key );
-}
-
-void CertifyCertificateDialog::setCertificatesWithSecretKeys( const std::vector<Key> & keys ) {
- d->optionsPage->setCertificatesWithSecretKeys( keys );
-}
-
-bool CertifyCertificateDialog::exportableCertificationSelected() const {
- return d->optionsPage->exportableCertificationSelected();
-}
-
-bool CertifyCertificateDialog::trustCertificationSelected() const {
- return false;
-}
-
-bool CertifyCertificateDialog::nonRevocableCertificationSelected() const {
- return false;
-}
-
-Key CertifyCertificateDialog::selectedSecretKey() const {
- return d->optionsPage->selectedSecretKey();
-}
-
-bool CertifyCertificateDialog::sendToServer() const {
- return d->optionsPage->sendToServer();
-}
-
-unsigned int CertifyCertificateDialog::selectedCheckLevel() const {
- return d->selectCheckLevelPage->checkLevel();
-}
-
-void CertifyCertificateDialog::connectJob( SignKeyJob * job ) {
- connect( job, SIGNAL(result(GpgME::Error)), this, SLOT(certificationResult(GpgME::Error)) );
- d->summaryPage->setSummary( d->createSummary() );
-}
-
-void CertifyCertificateDialog::setError( const Error & error ) {
- d->setOperationCompleted();
- d->summaryPage->setResult( error );
- d->ensureSummaryPageVisible();
- if ( error.isCanceled() )
- close();
-}
-
-void CertifyCertificateDialog::Private::certificationResult( const Error & err ) {
- setOperationCompleted();
- summaryPage->setResult( err );
- ensureSummaryPageVisible();
-}
-
-std::vector<unsigned int> CertifyCertificateDialog::selectedUserIDs() const {
- return d->selectUserIDsPage->selectedUserIDs();
-}
-
-void CertifyCertificateDialog::Private::ensureSummaryPageVisible() {
- while ( q->currentId() != summaryPageId )
- q->next();
-}
-
-#include "moc_certifycertificatedialog.cpp"
-#include "moc_certifycertificatedialog_p.cpp"
diff --git a/dialogs/certifycertificatedialog.h b/dialogs/certifycertificatedialog.h
index 6190aac68..e69de29bb 100644
--- a/dialogs/certifycertificatedialog.h
+++ b/dialogs/certifycertificatedialog.h
@@ -1,93 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/signcertificatedialog.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_DIALOGS_SIGNCERTIFICATEDIALOG_H__
-#define __KLEOPATRA_DIALOGS_SIGNCERTIFICATEDIALOG_H__
-
-#include <QDialog>
-
-#include <QWizard>
-
-#include <kleo/signkeyjob.h>
-
-#include <gpgme++/key.h>
-
-#include <utils/pimpl_ptr.h>
-
-namespace GpgME {
- class Error;
-}
-
-namespace Kleo {
- class SignKeyJob;
-
-namespace Dialogs {
-
- class CertifyCertificateDialog : public QWizard {
- Q_OBJECT
- public:
- explicit CertifyCertificateDialog( QWidget * parent=0, Qt::WindowFlags f=0 );
- ~CertifyCertificateDialog();
-
- bool exportableCertificationSelected() const;
-
- bool trustCertificationSelected() const;
-
- bool nonRevocableCertificationSelected() const;
-
- std::vector<unsigned int> selectedUserIDs() const;
-
- void setCertificatesWithSecretKeys( const std::vector<GpgME::Key> & keys );
- GpgME::Key selectedSecretKey() const;
-
- bool sendToServer() const;
-
- unsigned int selectedCheckLevel() const;
-
- void setCertificateToCertify( const GpgME::Key & key );
-
- void connectJob( Kleo::SignKeyJob * job );
- void setError( const GpgME::Error & error );
-
- Q_SIGNALS:
- void certificationPrepared();
-
- private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
- Q_PRIVATE_SLOT( d, void certificationResult(GpgME::Error) )
- };
-
-}
-}
-
-#endif /* __KLEOPATRA_DIALOGS_SIGNCERTIFICATEDIALOG_H__ */
diff --git a/dialogs/certifycertificatedialog_p.h b/dialogs/certifycertificatedialog_p.h
index fe5750dd3..e69de29bb 100644
--- a/dialogs/certifycertificatedialog_p.h
+++ b/dialogs/certifycertificatedialog_p.h
@@ -1,157 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/signcertificatedialog_p.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_DIALOGS_SIGNCERTIFICATEDIALOG_P_H__
-#define __KLEOPATRA_DIALOGS_SIGNCERTIFICATEDIALOG_P_H__
-
-#include "ui_selectchecklevelwidget.h"
-#include "ui_certificationoptionswidget.h"
-
-#include <kleo/signkeyjob.h>
-
-#include <gpgme++/key.h>
-
-#include <QStandardItemModel>
-#include <QWizardPage>
-
-class QListView;
-
-namespace Kleo {
- namespace Dialogs {
- namespace CertifyCertificateDialogPrivate {
- class UserIDModel : public QStandardItemModel {
- Q_OBJECT
- public:
- enum Role {
- UserIDIndex=Qt::UserRole
- };
- explicit UserIDModel( QObject * parent=0 ) : QStandardItemModel( parent ) {}
- GpgME::Key certificateToCertify() const { return m_key; }
- void setCertificateToCertify( const GpgME::Key & key );
- std::vector<unsigned int> checkedUserIDs() const;
-
- private:
- GpgME::Key m_key;
- };
-
- class SecretKeysModel : public QStandardItemModel {
- Q_OBJECT
- public:
- enum Role {
- IndexRole=Qt::UserRole
- };
- explicit SecretKeysModel( QObject * parent=0 ) : QStandardItemModel( parent ) {}
- void setSecretKeys( const std::vector<GpgME::Key> & keys );
- GpgME::Key keyFromItem( const QStandardItem * item ) const;
- GpgME::Key keyFromIndex( const QModelIndex & index ) const;
-
- private:
- std::vector<GpgME::Key> m_secretKeys;
- };
-
- class SelectUserIDsPage : public QWizardPage {
- Q_OBJECT
- public:
- explicit SelectUserIDsPage( QWidget * parent=0 );
- /* reimp */ bool isComplete() const;
-
- std::vector<unsigned int> selectedUserIDs() const;
- void setCertificateToCertify( const GpgME::Key & ids );
- GpgME::Key certificateToCertify() const { return m_userIDModel.certificateToCertify(); }
-
- private:
- QListView * m_listView;
- UserIDModel m_userIDModel;
- };
-
- class SelectCheckLevelPage : public QWizardPage {
- Q_OBJECT
- public:
- explicit SelectCheckLevelPage( QWidget * parent=0 );
- unsigned int checkLevel() const;
- private:
- Ui::SelectCheckLevelWidget m_ui;
- };
-
- class OptionsPage : public QWizardPage {
- Q_OBJECT
- public:
- explicit OptionsPage( QWidget * parent=0 );
-
- bool exportableCertificationSelected() const;
- void setCertificatesWithSecretKeys( const std::vector<GpgME::Key> & keys );
- GpgME::Key selectedSecretKey() const;
- bool sendToServer() const;
-
- /* reimp */ bool validatePage();
- /* reimp */ bool isComplete() const;
-
- Q_SIGNALS:
- void nextClicked();
-
- private:
- Ui::CertificationOptionsWidget m_ui;
- SecretKeysModel m_model;
- };
-
- class SummaryPage : public QWizardPage {
- Q_OBJECT
- public:
- explicit SummaryPage( QWidget * parent=0 );
- /* reimp */ bool isComplete() const;
- void setComplete( bool complete );
-
- void setResult( const GpgME::Error & err );
-
- struct Summary {
- std::vector<unsigned int> selectedUserIDs;
- unsigned int checkLevel;
- GpgME::Key certificateToCertify;
- GpgME::Key secretKey;
- bool exportable;
- bool sendToServer;
- };
-
- void setSummary( const Summary & summary );
-
- private:
- bool m_complete;
- QLabel * m_userIDsLabel;
- QLabel * m_secretKeyLabel;
- QLabel * m_checkLevelLabel;
- QLabel * m_resultLabel;
- };
- }
- }
-}
-
-#endif
diff --git a/dialogs/exportcertificatesdialog.cpp b/dialogs/exportcertificatesdialog.cpp
index b107ef2d3..e69de29bb 100644
--- a/dialogs/exportcertificatesdialog.cpp
+++ b/dialogs/exportcertificatesdialog.cpp
@@ -1,125 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/exportcertificatesdialog.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 "exportcertificatesdialog.h"
-
-#include "libkleo/ui/filenamerequester.h"
-
-#include <KGuiItem>
-#include <KLocale>
-#include <KPushButton>
-
-#include <QGridLayout>
-#include <QLabel>
-
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-
-class ExportCertificatesDialog::Private {
- friend class ::Kleo::Dialogs::ExportCertificatesDialog;
- ExportCertificatesDialog * const q;
-public:
- explicit Private( ExportCertificatesDialog * qq );
- ~Private();
- void fileNamesChanged();
-
-private:
- FileNameRequester* pgpRequester;
- FileNameRequester* cmsRequester;
-};
-
-
-ExportCertificatesDialog::Private::Private( ExportCertificatesDialog * qq )
- : q( qq )
-{
- q->setButtons( KDialog::Ok | KDialog::Cancel );
- q->setButtonGuiItem( KDialog::Ok, KGuiItem( i18n( "Export" ) ) );
- QWidget* const main = new QWidget;
- QGridLayout* const grid = new QGridLayout( main );
- QLabel* const pgpLabel = new QLabel;
- pgpLabel->setText( i18n(" OpenPGP export file:" ) );
- grid->addWidget( pgpLabel, 0, 0 );
- pgpRequester = new FileNameRequester;
- connect( pgpRequester, SIGNAL( fileNameChanged( QString ) ), q, SLOT( fileNamesChanged() ) );
- grid->addWidget( pgpRequester, 0, 1 );
- QLabel* const cmsLabel = new QLabel;
- cmsLabel->setText( i18n( "S/MIME export file:" ) );
- grid->addWidget( cmsLabel, 1, 0 );
- cmsRequester = new FileNameRequester;
- connect( cmsRequester, SIGNAL( fileNameChanged( QString ) ), q, SLOT( fileNamesChanged() ) );
- grid->addWidget( cmsRequester, 1, 1 );
- q->setMainWidget( main );
- fileNamesChanged();
-}
-
-ExportCertificatesDialog::Private::~Private() {}
-
-
-
-ExportCertificatesDialog::ExportCertificatesDialog( QWidget * parent, Qt::WFlags f )
- : KDialog( parent, f ), d( new Private( this ) )
-{
-
-}
-
-void ExportCertificatesDialog::Private::fileNamesChanged()
-{
- q->button( KDialog::Ok )->setEnabled( !pgpRequester->fileName().isEmpty() && !cmsRequester->fileName().isEmpty() );
-}
-
-ExportCertificatesDialog::~ExportCertificatesDialog() {}
-
-
-void ExportCertificatesDialog::setOpenPgpExportFileName( const QString & fileName )
-{
- d->pgpRequester->setFileName( fileName );
-}
-
-QString ExportCertificatesDialog::openPgpExportFileName() const
-{
- return d->pgpRequester->fileName();
-}
-
-void ExportCertificatesDialog::setCmsExportFileName( const QString & fileName )
-{
- d->cmsRequester->setFileName( fileName );
-}
-
-QString ExportCertificatesDialog::cmsExportFileName() const
-{
- return d->cmsRequester->fileName();
-}
-
-#include "moc_exportcertificatesdialog.cpp"
-
diff --git a/dialogs/exportcertificatesdialog.h b/dialogs/exportcertificatesdialog.h
index 98677339d..e69de29bb 100644
--- a/dialogs/exportcertificatesdialog.h
+++ b/dialogs/exportcertificatesdialog.h
@@ -1,65 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/exportcertificatesdialog.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_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
-#define __KLEOPATRA_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
-
-#include <KDialog>
-
-#include <utils/pimpl_ptr.h>
-
-class QString;
-
-namespace Kleo {
-namespace Dialogs {
-
- class ExportCertificatesDialog : public KDialog {
- Q_OBJECT
- public:
- explicit ExportCertificatesDialog( QWidget * parent=0, Qt::WFlags f=0 );
- ~ExportCertificatesDialog();
-
- void setOpenPgpExportFileName( const QString & fileName );
- QString openPgpExportFileName() const;
-
- void setCmsExportFileName( const QString & fileName );
- QString cmsExportFileName() const;
-
- private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
- Q_PRIVATE_SLOT( d, void fileNamesChanged() )
- };
-}
-}
-
-#endif // __KLEOPATRA_DIALOGS_EXPORTCERTIFICATESDIALOG_H__
diff --git a/dialogs/exportsecretkeydialog.cpp b/dialogs/exportsecretkeydialog.cpp
index 194763781..e69de29bb 100644
--- a/dialogs/exportsecretkeydialog.cpp
+++ b/dialogs/exportsecretkeydialog.cpp
@@ -1,192 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/exportsecretkeydialog.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 "exportsecretkeydialog.h"
-
-#include "ui_exportsecretkeydialog.h"
-
-#include <utils/formatting.h>
-
-#include <gpgme++/key.h>
-
-#include <KDebug>
-#include <KMessageBox>
-#include <KLocalizedString>
-
-#include <cassert>
-
-using namespace Kleo;
-using namespace Kleo::Dialogs;
-using namespace GpgME;
-
-// This comes from gnupg's sources, agent/minip12.c
-// In fact, any charset supported by iconv would work, but we don't link to iconv directly...
-static const char *charsets[] = {
- "utf8",
- "iso-8859-1",
- "iso-8859-15",
- "iso-8859-2",
- "iso-8859-3",
- "iso-8859-4",
- "iso-8859-5",
- "iso-8859-6",
- "iso-8859-7",
- "iso-8859-8",
- "iso-8859-9",
- "koi8-r",
- "ibm437",
- "ibm850",
- "euc-jp",
- "big5",
-};
-static const unsigned int numCharsets = sizeof charsets / sizeof *charsets;
-
-class ExportSecretKeyDialog::Private {
- friend class ::Kleo::Dialogs::ExportSecretKeyDialog;
- ExportSecretKeyDialog * const q;
-public:
- explicit Private( ExportSecretKeyDialog * qq )
- : q( qq ),
- ui( q )
- {
-
- }
-
-private:
- void updateWidgets() {
- const bool x509 = key.protocol() == CMS;
- ui.charsetCB->setVisible( x509 );
- ui.charsetLB->setVisible( x509 );
- }
-
- void updateLabel() {
- ui.descriptionLB->setText( i18nc("@info",
- "Please select export options for %1:",
- Formatting::formatForComboBox( key ) ) );
- }
-private:
- Key key;
-
- struct UI : public Ui_ExportSecretKeyDialog {
- explicit UI( Dialogs::ExportSecretKeyDialog * qq )
- : Ui_ExportSecretKeyDialog()
- {
- setupUi( qq );
-
- outputFileFR->setExistingOnly( false );
- outputFileFR->setFilter( QDir::Files );
-
- for ( unsigned int i = 0 ; i < numCharsets ; ++i )
- charsetCB->addItem( QString::fromLatin1( charsets[i] ) );
- charsetCB->setCurrentIndex( -1 );
-
- }
- } ui;
-};
-
-ExportSecretKeyDialog::ExportSecretKeyDialog( QWidget * p, Qt::WindowFlags f )
- : QDialog( p, f ), d( new Private( this ) )
-{
-
-}
-
-ExportSecretKeyDialog::~ExportSecretKeyDialog() {}
-
-
-void ExportSecretKeyDialog::setKey( const Key & key ) {
- if ( qstricmp( key.primaryFingerprint(), d->key.primaryFingerprint() ) == 0 )
- return;
- d->key = key;
- d->updateWidgets();
- d->updateLabel();
-}
-
-Key ExportSecretKeyDialog::key() const {
- return d->key;
-}
-
-void ExportSecretKeyDialog::setFileName( const QString & fileName ) {
- d->ui.outputFileFR->setFileName( fileName );
-}
-
-QString ExportSecretKeyDialog::fileName() const {
- return d->ui.outputFileFR->fileName();
-}
-
-void ExportSecretKeyDialog::setCharset( const QByteArray & charset ) {
- for ( unsigned int i = 0 ; i < sizeof charsets / sizeof *charsets ; ++i )
- if ( charset == charsets[i] ) {
- d->ui.charsetCB->setCurrentIndex( i );
- return;
- }
-}
-
-QByteArray ExportSecretKeyDialog::charset() const {
- if ( d->ui.charsetCB->isVisible() )
- return d->ui.charsetCB->currentText().toLatin1();
- else
- return QByteArray();
-}
-
-void ExportSecretKeyDialog::setUseArmor( bool on ) {
- d->ui.armorCB->setChecked( on );
-}
-
-bool ExportSecretKeyDialog::useArmor() const {
- return d->ui.armorCB->isChecked();
-}
-
-void ExportSecretKeyDialog::accept() {
- const QString fn = fileName();
- if ( fn.isEmpty() ) {
- KMessageBox::information( this, i18nc("@info",
- "You have to enter an output filename." ),
- i18nc("@title", "Incomplete data") );
- d->ui.outputFileFR->setFocus();
- return;
- }
-
- const QByteArray cs = charset();
- if ( d->key.protocol() == CMS && cs.isEmpty() ) {
- KMessageBox::information( this, i18nc("@info",
- "You have to choose a passphrase character set." ),
- i18nc("@title", "Incomplete data") );
- d->ui.charsetCB->setFocus();
- return;
- }
-
- QDialog::accept();
-}
-
-#include "moc_exportsecretkeydialog.cpp"
diff --git a/dialogs/exportsecretkeydialog.h b/dialogs/exportsecretkeydialog.h
index da7df3632..e69de29bb 100644
--- a/dialogs/exportsecretkeydialog.h
+++ b/dialogs/exportsecretkeydialog.h
@@ -1,78 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- dialogs/exportsecretkeydialog.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_DIALOGS_EXPORTSECRETKEY_H__
-#define __KLEOPATRA_DIALOGS_EXPORTSECRETKEY_H__
-
-#include <QDialog>
-
-#include <utils/pimpl_ptr.h>
-
-class QDate;
-
-namespace GpgME {
- class Key;
-}
-
-namespace Kleo {
-namespace Dialogs {
-
- class ExportSecretKeyDialog : public QDialog {
- Q_OBJECT
- public:
- explicit ExportSecretKeyDialog( QWidget * parent=0, Qt::WindowFlags f=0 );
- ~ExportSecretKeyDialog();
-
- void setKey( const GpgME::Key & key );
- GpgME::Key key() const;
-
- void setFileName( const QString & fileName );
- QString fileName() const;
-
- void setCharset( const QByteArray & charset );
- QByteArray charset() const;
-
- void setUseArmor( bool armor );
- bool useArmor() const;
-
- protected Q_SLOTS:
- /* reimp */ void accept();
-
- private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
- };
-
-}
-}
-
-#endif /* __KLEOPATRA_DIALOGS_EXPORTSECRETKEY_H__ */
diff --git a/dialogs/exportsecretkeydialog.ui b/dialogs/exportsecretkeydialog.ui
index bd4d29ae0..e69de29bb 100644
--- a/dialogs/exportsecretkeydialog.ui
+++ b/dialogs/exportsecretkeydialog.ui
@@ -1,131 +0,0 @@
-<ui version="4.0" >
- <class>ExportSecretKeyDialog</class>
- <widget class="QDialog" name="ExportSecretKeyDialog" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>372</width>
- <height>194</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Export Secret Key</string>
- </property>
- <layout class="QGridLayout" name="gridLayout" >
- <item row="0" column="0" colspan="2" >
- <widget class="QLabel" name="descriptionLB" >
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="outputFileLB" >
- <property name="text" >
- <string>Output file:</string>
- </property>
- <property name="buddy" >
- <cstring>outputFileFR</cstring>
- </property>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QLabel" name="charsetLB" >
- <property name="text" >
- <string>Passphrase charset:</string>
- </property>
- <property name="buddy" >
- <cstring>charsetCB</cstring>
- </property>
- </widget>
- </item>
- <item row="3" column="1" >
- <widget class="QComboBox" name="charsetCB" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="5" column="0" colspan="2" >
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons" >
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2" >
- <widget class="QCheckBox" name="armorCB" >
- <property name="text" >
- <string>ASCII armor</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="2" >
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1" >
- <widget class="Kleo::FileNameRequester" native="1" name="outputFileFR" />
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>Kleo::FileNameRequester</class>
- <extends>QWidget</extends>
- <header>ui/filenamerequester.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>ExportSecretKeyDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>227</x>
- <y>165</y>
- </hint>
- <hint type="destinationlabel" >
- <x>157</x>
- <y>193</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>ExportSecretKeyDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>295</x>
- <y>171</y>
- </hint>
- <hint type="destinationlabel" >
- <x>286</x>
- <y>193</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/dialogs/lookupcertificatesdialog.cpp b/dialogs/lookupcertificatesdialog.cpp
index 59afea39f..46c67992e 100644
--- a/dialogs/lookupcertificatesdialog.cpp
+++ b/dialogs/lookupcertificatesdialog.cpp
@@ -1,240 +1,239 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/lookupcertificatesdialog.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 "lookupcertificatesdialog.h"
#include "ui_lookupcertificatesdialog.h"
#include <models/keylistmodel.h>
#include <models/keylistsortfilterproxymodel.h>
#include <utils/headerview.h>
#include <utils/stl_util.h>
#include <gpgme++/key.h>
#include <KLineEdit>
#include <KLocale>
#include <QTreeView>
#include <QLayout>
#include <QPushButton>
#include <QHeaderView>
#include <QLabel>
#include <boost/bind.hpp>
#include <cassert>
static const bool ALLOW_MULTI_SELECTION = false;
static const bool ALLOW_MULTI_PROTOCOL = false;
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace GpgME;
using namespace boost;
static const int minimalSearchTextLength = 2; // ### TODO: make that KIOSK-able
static const QHeaderView::ResizeMode resize_modes[AbstractKeyListModel::NumColumns] = {
QHeaderView::Stretch, // Name
QHeaderView::Stretch, // EMail
QHeaderView::Fixed, // Valid From
QHeaderView::Fixed, // Valid Until
QHeaderView::Fixed, // Details
QHeaderView::Fixed, // Fingerprint
};
static void adjust_header( HeaderView * hv ) {
for ( int i = 0, end = AbstractKeyListModel::NumColumns ; i < end ; ++i )
hv->setSectionResizeMode( i, resize_modes[i] );
}
class LookupCertificatesDialog::Private {
friend class ::Kleo::Dialogs::LookupCertificatesDialog;
LookupCertificatesDialog * const q;
public:
explicit Private( LookupCertificatesDialog * qq );
~Private();
private:
void slotSelectionChanged() {
enableDisableWidgets();
}
void slotSearchTextChanged() {
enableDisableWidgets();
}
void slotSearchClicked() {
emit q->searchTextChanged( ui.findED->text() );
}
void slotDetailsClicked() {
assert( q->selectedCertificates().size() == 1 );
emit q->detailsRequested( q->selectedCertificates().front() );
}
void slotSaveAsClicked() {
emit q->saveAsRequested( q->selectedCertificates() );
}
void enableDisableWidgets();
QString searchText() const { return ui.findED->text().trimmed(); }
QModelIndexList selectedIndexes() const {
if ( const QItemSelectionModel * const sm = ui.resultTV->selectionModel() )
return sm->selectedRows();
else
return QModelIndexList();
}
private:
AbstractKeyListModel * model;
KeyListSortFilterProxyModel proxy;
bool passive;
struct Ui : Ui_LookupCertificatesDialog {
explicit Ui( LookupCertificatesDialog * q )
: Ui_LookupCertificatesDialog()
{
setupUi( q );
saveAsPB->hide(); // ### not yet implemented in LookupCertificatesCommand
if ( !ALLOW_MULTI_SELECTION ) {
resultTV->setSelectionMode( QAbstractItemView::SingleSelection );
selectAllPB->hide();
deselectAllPB->hide();
}
findED->setClearButtonShown( true );
importPB()->setText( i18n("Import") );
importPB()->setEnabled( false );
HeaderView * hv = new HeaderView( Qt::Horizontal );
KDAB_SET_OBJECT_NAME( hv );
resultTV->setHeader( hv );
adjust_header( hv );
connect( resultTV, SIGNAL(doubleClicked(QModelIndex)),
importPB(), SLOT(animateClick()) );
findED->setFocus();
}
QPushButton * importPB() const { return buttonBox->button( QDialogButtonBox::Save ); }
QPushButton * closePB() const { return buttonBox->button( QDialogButtonBox::Close ); }
} ui;
};
LookupCertificatesDialog::Private::Private( LookupCertificatesDialog * qq )
: q( qq ),
model( AbstractKeyListModel::createFlatKeyListModel() ),
proxy(),
passive( false ),
ui( q )
{
KDAB_SET_OBJECT_NAME( model );
KDAB_SET_OBJECT_NAME( proxy );
proxy.setSourceModel( model );
ui.resultTV->setModel( &proxy );
connect( ui.resultTV->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged()) );
}
LookupCertificatesDialog::Private::~Private() {}
LookupCertificatesDialog::LookupCertificatesDialog( QWidget * p, Qt::WindowFlags f )
: QDialog( p, f ), d( new Private( this ) )
{
}
LookupCertificatesDialog::~LookupCertificatesDialog() {}
void LookupCertificatesDialog::setCertificates( const std::vector<Key> & certs ) {
d->model->setKeys( certs );
}
std::vector<Key> LookupCertificatesDialog::selectedCertificates() const {
return d->proxy.keys( d->selectedIndexes() );
}
void LookupCertificatesDialog::setPassive( bool on ) {
if ( d->passive == on )
return;
d->passive = on;
d->enableDisableWidgets();
}
bool LookupCertificatesDialog::isPassive() const {
return d->passive;
}
void LookupCertificatesDialog::accept() {
assert( !d->selectedIndexes().empty() );
emit importRequested( selectedCertificates() );
QDialog::accept();
}
void LookupCertificatesDialog::Private::enableDisableWidgets() {
// enable/disable everything except 'close', based on passive:
Q_FOREACH( QObject * const o, q->children() )
if ( QWidget * const w = qobject_cast<QWidget*>( o ) )
- w->setDisabled( passive && w != ui.closePB() && w != ui.buttonBox );
+ w->setDisabled( passive && w != ui.closePB() );
if ( passive )
return;
ui.findPB->setEnabled( searchText().length() > minimalSearchTextLength );
const std::vector<Key> selection = q->selectedCertificates();
ui.detailsPB->setEnabled( selection.size() == 1 );
ui.saveAsPB->setEnabled( selection.size() == 1 );
if ( ALLOW_MULTI_SELECTION ) {
// this is commented out until such a time as we know how to
// import more than one key in one go.
ui.importPB()->setEnabled( !selection.empty() &&
ALLOW_MULTI_PROTOCOL ||
// suppress mixed imports:
kdtools::all( selection, bind( &Key::protocol, _1 ) == selection.front().protocol() ) );
} else {
ui.importPB()->setEnabled( selection.size() == 1 );
}
- ui.importPB()->setDefault( false ); // otherwise Import becomes default button if enabled and return triggers both a search and accept()
}
#include "moc_lookupcertificatesdialog.cpp"
diff --git a/dialogs/lookupcertificatesdialog.ui b/dialogs/lookupcertificatesdialog.ui
index d5b55341b..c90c29e39 100644
--- a/dialogs/lookupcertificatesdialog.ui
+++ b/dialogs/lookupcertificatesdialog.ui
@@ -1,306 +1,306 @@
<ui version="4.0" >
<class>LookupCertificatesDialog</class>
<widget class="QDialog" name="LookupCertificatesDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
- <width>553</width>
+ <width>544</width>
<height>292</height>
</rect>
</property>
<property name="windowTitle" >
<string>Keyserver Certificate Lookup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="1" >
<widget class="KLineEdit" name="findED" />
</item>
<item row="0" column="2" >
<widget class="QPushButton" name="findPB" >
<property name="text" >
<string>Search</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3" >
<widget class="Line" name="hr" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="2" >
<widget class="QPushButton" name="detailsPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Details...</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item rowspan="2" row="6" column="2" >
<widget class="QPushButton" name="saveAsPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Save As...</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QPushButton" name="selectAllPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Select All</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="2" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2" >
<widget class="QPushButton" name="deselectAllPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Deselect All</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="findLB" >
<property name="text" >
<string>Find:</string>
</property>
<property name="buddy" >
<cstring>findED</cstring>
</property>
</widget>
</item>
<item rowspan="6" row="2" column="0" colspan="2" >
<widget class="QTreeView" name="resultTV" >
<property name="enabled" >
- <bool>true</bool>
+ <bool>false</bool>
</property>
<property name="minimumSize" >
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="selectionMode" >
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="sortingEnabled" >
<bool>true</bool>
</property>
<property name="allColumnsShowFocus" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="standardButtons" >
<set>QDialogButtonBox::Close|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header location="global" >KLineEdit</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>findED</sender>
<signal>returnPressed()</signal>
<receiver>findPB</receiver>
<slot>animateClick()</slot>
<hints>
<hint type="sourcelabel" >
<x>409</x>
<y>19</y>
</hint>
<hint type="destinationlabel" >
<x>430</x>
<y>19</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>28</x>
<y>265</y>
</hint>
<hint type="destinationlabel" >
<x>46</x>
<y>291</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>188</x>
<y>273</y>
</hint>
<hint type="destinationlabel" >
<x>218</x>
<y>291</y>
</hint>
</hints>
</connection>
<connection>
<sender>selectAllPB</sender>
<signal>clicked()</signal>
<receiver>resultTV</receiver>
<slot>selectAll()</slot>
<hints>
<hint type="sourcelabel" >
<x>437</x>
<y>79</y>
</hint>
<hint type="destinationlabel" >
<x>409</x>
<y>77</y>
</hint>
</hints>
</connection>
<connection>
<sender>deselectAllPB</sender>
<signal>clicked()</signal>
<receiver>resultTV</receiver>
<slot>clearSelection()</slot>
<hints>
<hint type="sourcelabel" >
<x>465</x>
<y>115</y>
</hint>
<hint type="destinationlabel" >
<x>409</x>
<y>119</y>
</hint>
</hints>
</connection>
<connection>
<sender>findPB</sender>
<signal>clicked()</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>slotSearchClicked()</slot>
<hints>
<hint type="sourcelabel" >
<x>437</x>
<y>39</y>
</hint>
<hint type="destinationlabel" >
<x>443</x>
<y>45</y>
</hint>
</hints>
</connection>
<connection>
<sender>detailsPB</sender>
<signal>clicked()</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>slotDetailsClicked()</slot>
<hints>
<hint type="sourcelabel" >
<x>523</x>
<y>177</y>
</hint>
<hint type="destinationlabel" >
<x>541</x>
<y>177</y>
</hint>
</hints>
</connection>
<connection>
<sender>saveAsPB</sender>
<signal>clicked()</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>slotSaveAsClicked()</slot>
<hints>
<hint type="sourcelabel" >
<x>517</x>
<y>221</y>
</hint>
<hint type="destinationlabel" >
<x>539</x>
<y>219</y>
</hint>
</hints>
</connection>
<connection>
<sender>findED</sender>
<signal>textChanged(QString)</signal>
<receiver>LookupCertificatesDialog</receiver>
<slot>slotSearchTextChanged()</slot>
<hints>
<hint type="sourcelabel" >
<x>93</x>
<y>19</y>
</hint>
<hint type="destinationlabel" >
<x>93</x>
<y>3</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>slotSearchClicked()</slot>
<slot>slotDetailsClicked()</slot>
<slot>slotSaveAsClicked()</slot>
<slot>slotSearchTextChanged()</slot>
</slots>
</ui>
diff --git a/dialogs/ownertrustdialog.cpp b/dialogs/ownertrustdialog.cpp
index 1b4ad35a6..3aeffe2da 100644
--- a/dialogs/ownertrustdialog.cpp
+++ b/dialogs/ownertrustdialog.cpp
@@ -1,169 +1,119 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/ownertrustdialog.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 <utils/formatting.h>
#include "ownertrustdialog.h"
#include "ui_ownertrustdialog.h"
-#include <QPushButton>
+#include <KDebug>
#include <cassert>
+using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Dialogs;
-using namespace GpgME;
class OwnerTrustDialog::Private {
friend class ::Kleo::Dialogs::OwnerTrustDialog;
OwnerTrustDialog * const q;
public:
explicit Private( OwnerTrustDialog * qq )
: q( qq ),
- formattedCertificateName( i18n("(unknown certificate)") ),
- hasSecret( false ),
- advancedMode( false ),
ui( qq )
{
-
+#if 0
+ connect( ui.inSB, SIGNAL(valueChanged(int)),
+ q, SLOT(slotInAmountChanged()) );
+ connect( ui.inCB, SIGNAL(currentIndexChanged(int)),
+ q, SLOT(slotInUnitChanged()) );
+ connect( ui.onCW, SIGNAL(selectionChanged()),
+ q, SLOT(slotOnDateChanged()) );
+
+ assert( ui.inCB->currentIndex() == inUnit );
+#endif
}
private:
- void slotTrustLevelChanged() {
- enableDisableWidgets();
- }
-
- void enableDisableWidgets();
-
+ void slotOwnerTrustChanged( Key::OwnerTrust );
+
private:
- QString formattedCertificateName;
- bool hasSecret : 1;
- bool advancedMode : 1;
struct UI : public Ui::OwnerTrustDialog {
explicit UI( Dialogs::OwnerTrustDialog * qq )
: Ui::OwnerTrustDialog()
{
setupUi( qq );
- }
-
- QPushButton * okPB() const {
- return buttonBox->button( QDialogButtonBox::Ok );
+#define addTrustItem(item) trustCB->addItem( Formatting::ownerTrustShort( item ), item );
+ addTrustItem( Key::Unknown )
+ addTrustItem( Key::Undefined )
+ addTrustItem( Key::Never)
+ addTrustItem( Key::Marginal )
+ addTrustItem( Key::Full )
+ addTrustItem( Key::Ultimate )
+#undef addTrustItem
}
} ui;
};
OwnerTrustDialog::OwnerTrustDialog( QWidget * p, Qt::WindowFlags f )
: QDialog( p, f ), d( new Private( this ) )
{
}
OwnerTrustDialog::~OwnerTrustDialog() {}
-void OwnerTrustDialog::setFormattedCertificateName( const QString & formatted ) {
- if ( formatted.isEmpty() )
- return;
- d->formattedCertificateName = formatted;
- setWindowTitle( i18nc( "@title", "Change Trust Level of %1", formatted ) );
- d->ui.label->setText( i18nc( "@info", "How much do you trust certifications made by <b>%1</b> to correctly verify authenticity of certificates?", formatted ) );
-}
-
-QString OwnerTrustDialog::formattedCertificateName() const {
- return d->formattedCertificateName;
-}
-void OwnerTrustDialog::setHasSecretKey( bool secret ) {
- d->hasSecret = secret;
- d->enableDisableWidgets();
- setOwnerTrust( ownerTrust() );
-}
-
-bool OwnerTrustDialog::hasSecretKey() const {
- return d->hasSecret;
+void OwnerTrustDialog::setOwnerTrust( Key::OwnerTrust trust ) {
+ const int idx = d->ui.trustCB->findData( trust );
+ assert( idx != -1 );
+ d->ui.trustCB->setCurrentIndex( idx );
}
-void OwnerTrustDialog::setAdvancedMode( bool advanced ) {
- d->advancedMode = advanced;
- d->enableDisableWidgets();
- setOwnerTrust( ownerTrust() );
+Key::OwnerTrust OwnerTrustDialog::ownerTrust() const {
+ return static_cast<Key::OwnerTrust>( d->ui.trustCB->itemData( d->ui.trustCB->currentIndex() ).toUInt() );
}
-bool OwnerTrustDialog::isAdvancedMode() const {
- return d->advancedMode;
-}
-void OwnerTrustDialog::Private::enableDisableWidgets() {
- ui.unknownRB ->setEnabled( !hasSecret || advancedMode );
- ui.neverRB ->setEnabled( !hasSecret || advancedMode );
- ui.marginalRB->setEnabled( !hasSecret || advancedMode );
- ui.fullRB ->setEnabled( !hasSecret || advancedMode );
- ui.ultimateRB->setEnabled( hasSecret || advancedMode );
- ui.okPB()->setEnabled( q->ownerTrust() != Key::Undefined );
+void OwnerTrustDialog::Private::slotOwnerTrustChanged( Key::OwnerTrust trust ) {
+
}
-static void force_set_checked( QAbstractButton * b, bool on ) {
- // work around Qt bug (tested: 4.1.4, 4.2.3, 4.3.4)
- const bool autoExclusive = b->autoExclusive();
- b->setAutoExclusive( false );
- b->setChecked( b->isEnabled() && on );
- b->setAutoExclusive( autoExclusive );
-}
-void OwnerTrustDialog::setOwnerTrust( Key::OwnerTrust trust ) {
- force_set_checked( d->ui.unknownRB, trust == Key::Unknown );
- force_set_checked( d->ui.neverRB, trust == Key::Never );
- force_set_checked( d->ui.marginalRB,trust == Key::Marginal );
- force_set_checked( d->ui.fullRB, trust == Key::Full );
- force_set_checked( d->ui.ultimateRB,trust == Key::Ultimate );
- d->enableDisableWidgets();
-}
-Key::OwnerTrust OwnerTrustDialog::ownerTrust() const {
- if ( d->ui.unknownRB->isChecked() )
- return Key::Unknown;
- if ( d->ui.neverRB->isChecked() )
- return Key::Never;
- if ( d->ui.marginalRB->isChecked() )
- return Key::Marginal;
- if ( d->ui.fullRB->isChecked() )
- return Key::Full;
- if ( d->ui.ultimateRB->isChecked() )
- return Key::Ultimate;
- return Key::Undefined;
-}
#include "moc_ownertrustdialog.cpp"
diff --git a/dialogs/ownertrustdialog.h b/dialogs/ownertrustdialog.h
index 725489d01..f36691280 100644
--- a/dialogs/ownertrustdialog.h
+++ b/dialogs/ownertrustdialog.h
@@ -1,72 +1,63 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/ownertrustdialog.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_DIALOGS_OWNERTRUSTDIALOG_H__
#define __KLEOPATRA_DIALOGS_OWNERTRUSTDIALOG_H__
#include <QDialog>
#include <utils/pimpl_ptr.h>
#include <gpgme++/key.h>
namespace Kleo {
namespace Dialogs {
class OwnerTrustDialog : public QDialog {
Q_OBJECT
public:
explicit OwnerTrustDialog( QWidget * parent=0, Qt::WindowFlags f=0 );
~OwnerTrustDialog();
- void setFormattedCertificateName( const QString & formatted );
- QString formattedCertificateName() const;
-
- void setHasSecretKey( bool secret );
- bool hasSecretKey() const;
-
- void setAdvancedMode( bool advanced );
- bool isAdvancedMode() const;
-
- void setOwnerTrust( GpgME::Key::OwnerTrust );
+ void setOwnerTrust( GpgME::Key::OwnerTrust );
GpgME::Key::OwnerTrust ownerTrust() const;
private:
class Private;
kdtools::pimpl_ptr<Private> d;
- Q_PRIVATE_SLOT( d, void slotTrustLevelChanged() )
+ Q_PRIVATE_SLOT( d, void slotOwnerTrustChanged(GpgME::Key::OwnerTrust) )
};
}
}
#endif /* __KLEOPATRA_DIALOGS_OWNERTRUSTDIALOG_H__ */
diff --git a/dialogs/ownertrustdialog.ui b/dialogs/ownertrustdialog.ui
index 9d16f5a94..58f0ebb7b 100644
--- a/dialogs/ownertrustdialog.ui
+++ b/dialogs/ownertrustdialog.ui
@@ -1,630 +1,97 @@
<ui version="4.0" >
- <class>OwnerTrustDialog</class>
- <widget class="QDialog" name="OwnerTrustDialog" >
+ <class>Kleo::Dialogs::OwnerTrustDialog</class>
+ <widget class="QDialog" name="Kleo::Dialogs::OwnerTrustDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
- <width>700</width>
- <height>680</height>
+ <width>442</width>
+ <height>356</height>
</rect>
</property>
- <layout class="QVBoxLayout" name="verticalLayout" >
- <property name="sizeConstraint" >
- <enum>QLayout::SetMinimumSize</enum>
- </property>
+ <property name="windowTitle" >
+ <string>Change Trust in Certificate Owner</string>
+ </property>
+ <layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="label" >
- <property name="wordWrap" >
- <bool>true</bool>
+ <property name="text" >
+ <string>TODO: Display Certificate information and text about trust levels</string>
</property>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_10" >
- <item>
- <widget class="QRadioButton" name="unknownRB" >
- <property name="text" >
- <string>I don't know</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_7" >
- <property name="enabled" >
- <bool>true</bool>
- </property>
- <property name="text" >
- <string>&lt;i>(unknown trust)&lt;/i></string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
+ <layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="label_2" >
- <property name="enabled" >
- <bool>true</bool>
- </property>
- <property name="text" >
- <string>&lt;font size="-1">Choose this if you have no opinion about the trustworthyness of the certificate's owner.&lt;br>Certifications at this trust level are ignored when checking the validity of OpenPGP certificates.&lt;/font></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_9" >
- <item>
- <widget class="QRadioButton" name="neverRB" >
- <property name="text" >
- <string>I do NOT trust them</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_8" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;i>(never trust)&lt;/i></string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_3" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;font size="-1">Choose this if you explicitly do &lt;em>not&lt;/em> trust the certificate owner, e.g. because you have knowledge of him certifying without checking or without the certificate owner's consent.&lt;br>Certifications at this trust level are ignored when checking the validity of OpenPGP certificates.&lt;/font></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_8" >
- <item>
- <widget class="QRadioButton" name="marginalRB" >
- <property name="text" >
- <string>I believe checks are casual</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_9" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;i>(marginal trust)&lt;/i></string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_4" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;font size="-1">Choose this if you trust certifications are not done blindly, but not very accuratly, either.&lt;br>Certificates will only become valid with multiple certifications (typically three) at this trust level. This is usually a good choice.&lt;/font></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7" >
- <item>
- <widget class="QRadioButton" name="fullRB" >
- <property name="text" >
- <string>I believe checks are very accurate</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_10" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;i>(full trust)&lt;/i></string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_5" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
<property name="text" >
- <string>&lt;font size="-1">Choose this if you trust certifications are done very accurately.&lt;br>Certificates will become valid with just a single certification at this trust level, so assign this much trust with care.&lt;/font></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6" >
- <item>
- <widget class="QRadioButton" name="ultimateRB" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>This is my certificate</string>
+ <string>New trust level:</string>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="label_11" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;i>(ultimate trust)&lt;/i></string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label_6" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&lt;font size="-1">Choose this if and only if this is your certificate. This is the default if the secret key is available, but if you imported this certificate, you might need to adjust the trust level yourself.&lt;br>Certificates will become valid with just a single certification at this trust level.&lt;/font></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
+ <widget class="QComboBox" name="trustCB" />
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" >
<size>
- <width>501</width>
+ <width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
- <zorder>label</zorder>
- <zorder>unknownRB</zorder>
- <zorder>neverRB</zorder>
- <zorder>marginalRB</zorder>
- <zorder>fullRB</zorder>
- <zorder>ultimateRB</zorder>
- <zorder>buttonBox</zorder>
- <zorder>label_7</zorder>
- <zorder>label_8</zorder>
- <zorder>label_9</zorder>
- <zorder>label_10</zorder>
- <zorder>label_11</zorder>
- <zorder>label_6</zorder>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
- <receiver>OwnerTrustDialog</receiver>
+ <receiver>Kleo::Dialogs::OwnerTrustDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
- <x>434</x>
- <y>670</y>
+ <x>227</x>
+ <y>369</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
- <receiver>OwnerTrustDialog</receiver>
+ <receiver>Kleo::Dialogs::OwnerTrustDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
- <x>502</x>
- <y>670</y>
+ <x>295</x>
+ <y>375</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
- <connection>
- <sender>unknownRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_2</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>248</x>
- <y>56</y>
- </hint>
- <hint type="destinationlabel" >
- <x>246</x>
- <y>106</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>neverRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_3</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>217</x>
- <y>174</y>
- </hint>
- <hint type="destinationlabel" >
- <x>243</x>
- <y>262</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>marginalRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_4</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>257</x>
- <y>300</y>
- </hint>
- <hint type="destinationlabel" >
- <x>285</x>
- <y>368</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>fullRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_5</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>311</x>
- <y>406</y>
- </hint>
- <hint type="destinationlabel" >
- <x>345</x>
- <y>474</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>ultimateRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_6</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>217</x>
- <y>512</y>
- </hint>
- <hint type="destinationlabel" >
- <x>247</x>
- <y>580</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>unknownRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_7</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>317</x>
- <y>46</y>
- </hint>
- <hint type="destinationlabel" >
- <x>468</x>
- <y>54</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>neverRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_8</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>319</x>
- <y>162</y>
- </hint>
- <hint type="destinationlabel" >
- <x>368</x>
- <y>168</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>marginalRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_9</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>321</x>
- <y>284</y>
- </hint>
- <hint type="destinationlabel" >
- <x>370</x>
- <y>288</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>fullRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_10</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>323</x>
- <y>382</y>
- </hint>
- <hint type="destinationlabel" >
- <x>364</x>
- <y>388</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>ultimateRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>label_11</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>325</x>
- <y>496</y>
- </hint>
- <hint type="destinationlabel" >
- <x>380</x>
- <y>497</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>unknownRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>OwnerTrustDialog</receiver>
- <slot>slotTrustLevelChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>35</x>
- <y>54</y>
- </hint>
- <hint type="destinationlabel" >
- <x>21</x>
- <y>78</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>neverRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>OwnerTrustDialog</receiver>
- <slot>slotTrustLevelChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>61</x>
- <y>160</y>
- </hint>
- <hint type="destinationlabel" >
- <x>11</x>
- <y>184</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>marginalRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>OwnerTrustDialog</receiver>
- <slot>slotTrustLevelChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>41</x>
- <y>282</y>
- </hint>
- <hint type="destinationlabel" >
- <x>13</x>
- <y>310</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>fullRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>OwnerTrustDialog</receiver>
- <slot>slotTrustLevelChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>83</x>
- <y>386</y>
- </hint>
- <hint type="destinationlabel" >
- <x>17</x>
- <y>416</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>ultimateRB</sender>
- <signal>toggled(bool)</signal>
- <receiver>OwnerTrustDialog</receiver>
- <slot>slotTrustLevelChanged()</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>57</x>
- <y>496</y>
- </hint>
- <hint type="destinationlabel" >
- <x>19</x>
- <y>538</y>
- </hint>
- </hints>
- </connection>
</connections>
- <slots>
- <slot>slotTrustLevelChanged()</slot>
- </slots>
</ui>
diff --git a/dialogs/selectchecklevelwidget.ui b/dialogs/selectchecklevelwidget.ui
index a2198ef99..e69de29bb 100644
--- a/dialogs/selectchecklevelwidget.ui
+++ b/dialogs/selectchecklevelwidget.ui
@@ -1,148 +0,0 @@
-<ui version="4.0" >
- <class>Kleo::Dialogs::CertifyCertificateDialogPrivate::SelectCheckLevelWidget</class>
- <widget class="QWidget" name="Kleo::Dialogs::CertifyCertificateDialogPrivate::SelectCheckLevelWidget" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>959</width>
- <height>606</height>
- </rect>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="2" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>&lt;b>Step 2:&lt;/b> How thoroughly have you checked that this key actually belongs to the person it claims it's from?</string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2" >
- <widget class="QRadioButton" name="checkLevelNotCheckedRB" >
- <property name="text" >
- <string>I have not checked at all</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="1" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string>Describe semantics here...</string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="2" >
- <widget class="QRadioButton" name="checkLevelCasualRB" >
- <property name="text" >
- <string>I have checked casually</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="4" column="1" >
- <widget class="QLabel" name="label_4" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>Choose this if you know the person, and have asked him whether this was his key, but you have not verified he is actually in posession of the secret key.</string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="5" column="0" colspan="2" >
- <widget class="QRadioButton" name="checkLevelThoroughlyRB" >
- <property name="text" >
- <string>I have checked very thoroughly</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="6" column="1" >
- <widget class="QLabel" name="label_5" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>Choose this if you have e.g. checked the ID card of the person, and have verified that he is in posession of the secret key (e.g. by sending encrypted mails to him and asking him to decrypt them).</string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="7" column="1" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/dialogs/selftestdialog.cpp b/dialogs/selftestdialog.cpp
index 1ded5fe7b..36f60d6d6 100644
--- a/dialogs/selftestdialog.cpp
+++ b/dialogs/selftestdialog.cpp
@@ -1,265 +1,257 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/selftestdialog.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 "selftestdialog.h"
#include "ui_selftestdialog.h"
#include <selftest/selftest.h>
#include <QAbstractTableModel>
-#include <QHeaderView>
#include <boost/shared_ptr.hpp>
#include <cassert>
#include <vector>
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace boost;
namespace {
class Model : public QAbstractTableModel {
Q_OBJECT
public:
explicit Model( QObject * parent=0 )
: QAbstractTableModel( parent ),
m_tests()
{
}
enum Column {
TestName,
TestResult,
NumColumns
};
const shared_ptr<SelfTest> & fromModelIndex( const QModelIndex & idx ) const {
const unsigned int row = idx.row();
if ( row < m_tests.size() )
return m_tests[row];
static const shared_ptr<SelfTest> null;
return null;
}
/* reimp */ int rowCount( const QModelIndex & idx ) const { return idx.isValid() ? 0 : m_tests.size() ; }
/* reimp */ int columnCount( const QModelIndex & ) const { return NumColumns; }
/* reimp */ QVariant data( const QModelIndex & idx, int role ) const {
const unsigned int row = idx.row();
if ( idx.isValid() && row < m_tests.size() )
switch ( role ) {
case Qt::DisplayRole:
case Qt::ToolTipRole:
switch ( idx.column() ) {
case TestName:
return m_tests[row]->name();
case TestResult:
if ( m_tests[row]->passed() )
return i18n("Passed");
else
if ( role == Qt::ToolTipRole )
return m_tests[row]->longError();
else
return m_tests[row]->shortError();
}
break;
case Qt::BackgroundRole:
return QColor( m_tests[row]->passed() ? Qt::green : Qt::red );
}
return QVariant();
}
/* reimp */ QVariant headerData( int section, Qt::Orientation o, int role ) const {
if ( o == Qt::Horizontal &&
section >= 0 && section < NumColumns &&
role == Qt::DisplayRole )
switch ( section ) {
case TestName: return i18n("Test Name");
case TestResult: return i18n("Result");
}
return QVariant();
}
void clear() {
if ( m_tests.empty() )
return;
beginRemoveRows( QModelIndex(), 0, m_tests.size() - 1 );
m_tests.clear();
endRemoveRows();
}
void append( const std::vector< shared_ptr<SelfTest> > & tests ) {
if ( tests.empty() )
return;
beginInsertRows( QModelIndex(), m_tests.size(), m_tests.size() + tests.size() );
m_tests.insert( m_tests.end(), tests.begin(), tests.end() );
endInsertRows();
}
void reloadData() {
if ( !m_tests.empty() )
emit dataChanged( index( 0, 0 ), index( m_tests.size() - 1, NumColumns - 1 ) );
}
const shared_ptr<SelfTest> & at( unsigned int idx ) const {
return m_tests.at( idx );
}
private:
std::vector< shared_ptr<SelfTest> > m_tests;
};
}
class SelfTestDialog::Private {
friend class ::Kleo::Dialogs::SelfTestDialog;
SelfTestDialog * const q;
public:
explicit Private( SelfTestDialog * qq )
: q( qq ),
ui( q )
{
ui.resultsTV->setModel( &model );
connect( ui.resultsTV->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged()) );
}
private:
void slotSelectionChanged() {
const int row = selectedRowIndex();
if ( row < 0 ) {
ui.proposedCorrectiveActionLB->setText( i18n("(select test first)" ) );
ui.proposedCorrectiveActionGB->setEnabled( false );
} else {
ui.proposedCorrectiveActionGB->setEnabled( true );
ui.proposedCorrectiveActionLB->setText( model.at(row)->proposedFix() );
ui.doItPB->setEnabled( !model.at(row)->passed() && model.at(row)->canFixAutomatically() );
}
}
void slotDoItClicked() {
if ( const shared_ptr<SelfTest> st = model.fromModelIndex( selectedRow() ) )
if ( st->fix() )
model.reloadData();
}
-private:
- void updateColumnSizes() {
- ui.resultsTV->header()->resizeSections( QHeaderView::ResizeToContents );
- }
-
private:
QModelIndex selectedRow() const {
const QItemSelectionModel * const ism = ui.resultsTV->selectionModel();
if ( !ism )
return QModelIndex();
const QModelIndexList mil = ism->selectedRows();
return mil.empty() ? QModelIndex() : mil.front() ;
}
int selectedRowIndex() const {
return selectedRow().row();
}
private:
Model model;
struct UI : public Ui_SelfTestDialog {
QPushButton * rerunPB;
explicit UI( SelfTestDialog * qq )
: Ui_SelfTestDialog(),
rerunPB( new QPushButton( i18n("Rerun Tests") ) )
{
setupUi( qq );
buttonBox->addButton( rerunPB, QDialogButtonBox::ActionRole );
buttonBox->button( QDialogButtonBox::Ok )->setText( i18n("Continue") );
connect( rerunPB, SIGNAL(clicked()),
qq, SIGNAL(updateRequested()) );
}
} ui;
};
SelfTestDialog::SelfTestDialog( QWidget * p, Qt::WindowFlags f )
: QDialog( p, f ), d( new Private( this ) )
{
setAutomaticMode( false );
}
SelfTestDialog::SelfTestDialog( const std::vector< shared_ptr<SelfTest> > & tests, QWidget * p, Qt::WindowFlags f )
: QDialog( p, f ), d( new Private( this ) )
{
addSelfTests( tests );
setAutomaticMode( false );
}
SelfTestDialog::~SelfTestDialog() {}
void SelfTestDialog::clear() {
d->model.clear();
}
void SelfTestDialog::addSelfTest( const shared_ptr<SelfTest> & test ) {
d->model.append( std::vector< shared_ptr<SelfTest> >( 1, test ) );
- d->updateColumnSizes();
}
void SelfTestDialog::addSelfTests( const std::vector< shared_ptr<SelfTest> > & tests ) {
d->model.append( tests );
- d->updateColumnSizes();
}
void SelfTestDialog::setRunAtStartUp( bool on ) {
d->ui.runAtStartUpCB->setChecked( on );
}
bool SelfTestDialog::runAtStartUp() const {
return d->ui.runAtStartUpCB->isChecked();
}
void SelfTestDialog::setAutomaticMode( bool automatic ) {
d->ui.buttonBox->button( QDialogButtonBox::Ok )->setVisible( automatic );
d->ui.buttonBox->button( QDialogButtonBox::Cancel )->setVisible( automatic );
d->ui.buttonBox->button( QDialogButtonBox::Close )->setVisible( !automatic );
}
#include "selftestdialog.moc"
#include "moc_selftestdialog.cpp"
diff --git a/dialogs/selftestdialog.ui b/dialogs/selftestdialog.ui
index 44c01cf6d..ef6922eec 100644
--- a/dialogs/selftestdialog.ui
+++ b/dialogs/selftestdialog.ui
@@ -1,215 +1,206 @@
<ui version="4.0" >
<class>SelfTestDialog</class>
<widget class="QDialog" name="SelfTestDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>500</height>
</rect>
</property>
<property name="windowTitle" >
<string>Kleopatra Self-Test Results</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" >
- <property name="sizeConstraint" >
- <enum>QLayout::SetMinimumSize</enum>
- </property>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
- <string comment="@info" >&lt;para>These are the results of the Kleopatra self-test suite. Details are available in tooltips.&lt;/para>&lt;para>Note that all but the first failure might be due to prior tests failing.&lt;/para></string>
+ <string comment="@info" >&lt;para>These are the results of the Kleopatra self-test suite. Details are available in tooltips.&lt;/para>&lt;para>Note that all but the first failure might be consecutive.&lt;/para></string>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="childrenCollapsible" >
<bool>false</bool>
</property>
<widget class="QTreeView" name="resultsTV" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
- <horstretch>0</horstretch>
- <verstretch>1</verstretch>
- </sizepolicy>
- </property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<property name="allColumnsShowFocus" >
<bool>true</bool>
</property>
</widget>
<widget class="QGroupBox" name="proposedCorrectiveActionGB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="title" >
<string>Proposed Corrective Action</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="Kleo::ScrollArea" name="scrollArea" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy" >
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>336</width>
<height>100</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="proposedCorrectiveActionLB" >
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<spacer name="horizontalSpacer" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="doItPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Do It!</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QCheckBox" name="runAtStartUpCB" >
<property name="text" >
<string>Run these tests at startup</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Kleo::ScrollArea</class>
<extends>QScrollArea</extends>
<header>utils/scrollarea.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelfTestDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>236</x>
<y>490</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelfTestDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>304</x>
<y>490</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>doItPB</sender>
<signal>clicked()</signal>
<receiver>SelfTestDialog</receiver>
<slot>slotDoItClicked()</slot>
<hints>
<hint type="sourcelabel" >
<x>354</x>
- <y>398</y>
+ <y>467</y>
</hint>
<hint type="destinationlabel" >
<x>375</x>
<y>304</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>slotDoItClicked()</slot>
</slots>
</ui>
diff --git a/kcfg/emailoperationspreferences.kcfg b/kcfg/emailoperationspreferences.kcfg
index 01f09588b..444e0951c 100644
--- a/kcfg/emailoperationspreferences.kcfg
+++ b/kcfg/emailoperationspreferences.kcfg
@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="kleopatrarc" />
<group name="EMailOperations">
<entry name="QuickSignEMail" key="quick-sign-email" type="Bool">
<label>Quick Sign EMail</label>
<whatsthis>Minimize the number of steps when signing emails, use preset defaults unless problems occurr</whatsthis>
<default>false</default>
</entry>
<entry name="QuickEncryptEMail" key="quick-encrypt-email" type="Bool">
<label>Quick Encrypt EMail</label>
<whatsthis>Minimize the number of steps when encrypting emails, use preset defaults unless problems occurr</whatsthis>
<default>false</default>
</entry>
- <entry name="DecryptVerifyPopupGeometry" key="decrypt-verify-popup-geometry" type="Rect">
- <label>Decrypt/Verify Popup Geometry</label>
- <whatsthis>The remembered size and position of the Decrypt/Verify Result Popup used by clients which do not support inline display of D/V results, such as MS Outlook.</whatsthis>
+ <entry name="DecryptVerifyPopupPosition" key="decrypt-verify-popup-position" type="Point">
+ <label>Decrypt/Verify Popup Position</label>
+ <whatsthis>The remembered position of the Decrypt/Verify Result Popup used by clients which do not support inline display of D/V results, such as MS Outlook.</whatsthis>
</entry>
</group>
</kcfg>
diff --git a/kleopatra.rc b/kleopatra.rc
index 8bae97e53..16f23adc4 100644
--- a/kleopatra.rc
+++ b/kleopatra.rc
@@ -1,104 +1,97 @@
<!DOCTYPE kpartgui >
-<kpartgui name="kleopatra" version="433" >
+<kpartgui name="kleopatra" version="425" >
<MenuBar>
<Menu name="file">
<text>&amp;File</text>
<Action name="file_new_certificate"/>
<Separator/>
<Action name="file_lookup_certificates"/>
<Action name="file_import_certificates"/>
<Action name="file_import_crls"/>
<Separator/>
<Action name="file_export_certificates"/>
<Action name="file_export_secret_keys"/>
- <Action name="file_export_certificates_to_server"/>
<Separator/>
<Action name="file_decrypt_verify_files"/>
<Action name="file_sign_encrypt_files"/>
<Separator/>
<Action name="quit" />
</Menu>
<Menu name="view">
<text>&amp;View</text>
<Action name="view_redisplay"/>
<Separator/>
<Action name="view_stop_operations"/>
<Action name="view_certificate_details"/>
<Separator/>
<Action name="window_view_hierarchical"/>
<Separator/>
<Action name="window_expand_all"/>
<Action name="window_collapse_all"/>
</Menu>
<Menu name="certMenu">
<text>&amp;Certificates</text>
<Action name="certificates_delete"/>
- <Action name="certificates_certify_certificate"/>
+ <Action name="certificates_sign_certificate"/>
<Action name="certificates_change_owner_trust"/>
<Action name="certificates_change_expiry"/>
- <Action name="certificates_change_passphrase"/>
- <Action name="certificates_add_userid"/>
- <Action name="certificates_dump_certificate"/>
</Menu>
<Menu name="tools">
<text>&amp;Tools</text>
- <Action name="tools_start_kwatchgnupg"/>
- <Separator/>
- <Action name="tools_refresh_x509_certificates"/>
- <Action name="tools_refresh_openpgp_certificates"/>
+ <action name="tools_refresh_x509_certificates"/>
+ <action name="tools_refresh_openpgp_certificates"/>
<Separator/>
<Action name="crl_import_crl"/>
<Separator/>
<Action name="crl_clear_crl_cache"/>
<Action name="crl_dump_crl_cache"/>
- <Separator/>
- <Action name="configure_backend"/>
</Menu>
<Menu name="settings">
<text>&amp;Settings</text>
<Action name="settings_self_test"/>
+ <Action name="configure_backend"/>
</Menu>
<Menu name="window" append="settings_merge">
<text>&amp;Window</text>
<Action name="window_rename_tab"/>
<Separator/>
<Action name="window_new_tab"/>
<Action name="window_duplicate_tab"/>
<Action name="window_close_tab"/>
<Separator/>
<Action name="window_move_tab_left"/>
<Action name="window_move_tab_right"/>
</Menu>
<Menu name="help"/>
</MenuBar>
<ToolBar fullWidth="false" name="mainToolBar">
<text>Main Toolbar</text>
<Action name="file_sign_encrypt_files"/>
<Action name="file_decrypt_verify_files"/>
<Separator/>
<Action name="view_redisplay"/>
<Action name="view_stop_operations"/>
<Separator/>
<Action name="certificates_delete"/>
<Action name="certificates_change_expiry"/>
</ToolBar>
<ToolBar position="Top" newline="true" iconText="IconOnly" noMerge="1" name="searchToolBar" noEdit="true">
<text>Search Toolbar</text>
<Action name="key_search_bar" />
</ToolBar>
<Menu name="listview_popup">
<text>&amp;Certificates</text>
- <Action name="certificates_sign_certificate"/>
+ <Action name="certificates_sign_certificate"/>
<Action name="certificates_change_expiry"/>
<Action name="certificates_change_owner_trust"/>
<Action name="certificates_delete"/>
<Separator/>
<Action name="file_export_certificates"/>
<Separator/>
<Action name="view_certificate_details"/>
</Menu>
</kpartgui>
diff --git a/kleopatraapplication.cpp b/kleopatraapplication.cpp
index 690def269..e69de29bb 100644
--- a/kleopatraapplication.cpp
+++ b/kleopatraapplication.cpp
@@ -1,213 +0,0 @@
-/*
- kleopatraapplication.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 "kleopatraapplication.h"
-
-#include "mainwindow.h"
-#include "systemtrayicon.h"
-
-#include <utils/gnupg-helper.h>
-#include <utils/filesystemwatcher.h>
-#include <utils/kdpipeiodevice.h>
-#include <utils/log.h>
-#include <utils/getpid.h>
-
-#include <models/keycache.h>
-
-#ifdef HAVE_USABLE_ASSUAN
-# include <uiserver/uiserver.h>
-#endif
-
-#include <KGlobal>
-#include <KIconLoader>
-#include <KLocale>
-#include <KCmdLineOptions>
-#include <KDebug>
-
-#include <QFile>
-#include <QDir>
-
-#include <boost/shared_ptr.hpp>
-
-#include <memory>
-
-using namespace Kleo;
-using namespace boost;
-
-static void add_resources() {
- KGlobal::locale()->insertCatalog( "libkleopatra" );
- KIconLoader::global()->addAppDir( "libkleopatra" );
- KIconLoader::global()->addAppDir( "kdepim" );
-}
-
-static KCmdLineOptions make_kleopatra_args() {
- KCmdLineOptions options;
- options.add("daemon", ki18n("Run UI server only, hide main window"));
- options.add("import-certificate ", ki18n("Name of certificate file to import"));
-#ifdef HAVE_USABLE_ASSUAN
- options.add("uiserver-socket <argument>", ki18n("Location of the socket the ui server is listening on" ));
-#endif
- return options;
-}
-
-// static
-KCmdLineOptions KleopatraApplication::commandLineOptions() {
- static KCmdLineOptions options = make_kleopatra_args();
- return options;
-}
-
-static QList<QByteArray> default_logging_options() {
- QList<QByteArray> result;
- result.push_back( "io" );
- return result;
-}
-
-class KleopatraApplication::Private {
-public:
- Private() : ignoreNewInstance( true ) {}
-
-public:
- bool ignoreNewInstance;
- SystemTrayIconFor<MainWindow> sysTray;
- shared_ptr<KeyCache> keyCache;
- shared_ptr<Log> log;
- shared_ptr<FileSystemWatcher> watcher;
-
-public:
- void setupKeyCache() {
- keyCache = KeyCache::mutableInstance();
- watcher.reset( new FileSystemWatcher );
-
- watcher->addPaths( gnupgFileWatchList() );
- watcher->setDelay( 1000 );
- keyCache->addFileSystemWatcher( watcher );
- }
-
- void setupLogging() {
- log = Log::mutableInstance();
-
- const QByteArray envOptions = qgetenv( "KLEOPATRA_LOGOPTIONS" );
- const bool logAll = envOptions.trimmed() == "all";
- const QList<QByteArray> options = envOptions.isEmpty() ? default_logging_options() : envOptions.split( ',' ) ;
-
- const QByteArray dirNative = qgetenv( "KLEOPATRA_LOGDIR" );
- if ( dirNative.isEmpty() )
- return;
- const QString dir = QFile::decodeName( dirNative );
- const QString logFileName = QDir( dir ).absoluteFilePath( QString::fromLatin1( "kleopatra.log.%1" ).arg( mygetpid() ) );
- std::auto_ptr<QFile> logFile( new QFile( logFileName ) );
- if ( !logFile->open( QIODevice::WriteOnly | QIODevice::Append ) ) {
- kDebug() << "Could not open file for logging: " << logFileName << "\nLogging disabled";
- return;
- }
-
- log->setOutputDirectory( dir );
- if ( logAll || options.contains( "io" ) )
- log->setIOLoggingEnabled( true );
- qInstallMsgHandler( Log::messageHandler );
-
-#ifdef HAVE_USABLE_ASSUAN
- if ( logAll || options.contains( "pipeio" ) )
- KDPipeIODevice::setDebugLevel( KDPipeIODevice::Debug );
- UiServer::setLogStream( log->logFile() );
-#endif
-
- }
-};
-
-
-KleopatraApplication::KleopatraApplication()
- : KUniqueApplication(), d( new Private )
-{
- add_resources();
- d->setupKeyCache();
- d->setupLogging();
- d->sysTray.show();
- setQuitOnLastWindowClosed( false );
-}
-
-KleopatraApplication::~KleopatraApplication() {
- // work around kdelibs bug https://bugs.kde.org/show_bug.cgi?id=162514
- KGlobal::config()->sync();
-}
-
-int KleopatraApplication::newInstance() {
- kDebug() << d->ignoreNewInstance;
- if ( d->ignoreNewInstance )
- return 0;
- KCmdLineArgs * const args = KCmdLineArgs::parsedArgs();
- importCertificatesFromFile( args->getOptionList("import-certificate") );
- args->clear();
- return 0;
-}
-
-const SystemTrayIconFor<MainWindow> * KleopatraApplication::sysTrayIcon() const {
- return &d->sysTray;
-}
-
-SystemTrayIconFor<MainWindow> * KleopatraApplication::sysTrayIcon() {
- return &d->sysTray;
-}
-
-const MainWindow * KleopatraApplication::mainWindow() const {
- return d->sysTray.mainWindow();
-}
-
-MainWindow * KleopatraApplication::mainWindow() {
- return d->sysTray.mainWindow();
-}
-
-void KleopatraApplication::openOrRaiseMainWindow() {
- d->sysTray.openOrRaiseMainWindow();
-}
-
-void KleopatraApplication::openOrRaiseConfigDialog() {
- d->sysTray.openOrRaiseConfigDialog();
-}
-
-void KleopatraApplication::importCertificatesFromFile( const QStringList & files ) {
- d->sysTray.openOrRaiseMainWindow();
- if ( !files.empty() )
- d->sysTray.mainWindow()->importCertificatesFromFile( files );
-}
-
-void KleopatraApplication::setIgnoreNewInstance( bool ignore ) {
- d->ignoreNewInstance = ignore;
-}
-
-bool KleopatraApplication::ignoreNewInstance() const {
- return d->ignoreNewInstance;
-}
-
-#include "moc_kleopatraapplication.cpp"
diff --git a/kleopatraapplication.h b/kleopatraapplication.h
index b05379b66..e69de29bb 100644
--- a/kleopatraapplication.h
+++ b/kleopatraapplication.h
@@ -1,73 +0,0 @@
-/*
- kleopatraapplication.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 __KLEOPATRAAPPLICATION_H__
-#define __KLEOPATRAAPPLICATION_H__
-
-#include <KUniqueApplication>
-
-#include <utils/pimpl_ptr.h>
-
-class KCmdLineOptions;
-class MainWindow;
-template <typename T> class SystemTrayIconFor;
-
-class KleopatraApplication : public KUniqueApplication {
- Q_OBJECT
-public:
- KleopatraApplication();
- ~KleopatraApplication();
-
- static KCmdLineOptions commandLineOptions();
-
- /* reimp */ int newInstance();
-
- const MainWindow * mainWindow() const;
- MainWindow * mainWindow();
-
- const SystemTrayIconFor<MainWindow> * sysTrayIcon() const;
- SystemTrayIconFor<MainWindow> * sysTrayIcon();
-
- void setIgnoreNewInstance( bool on );
- bool ignoreNewInstance() const;
-
-public Q_SLOTS:
- void openOrRaiseMainWindow();
- void openOrRaiseConfigDialog();
- void importCertificatesFromFile( const QStringList & files );
-
-private:
- class Private;
- kdtools::pimpl_ptr<Private> d;
-};
-
-#endif // __KLEOPATRAAPPLICATION_H__
diff --git a/libkleopatraclient/CMakeLists.txt b/libkleopatraclient/CMakeLists.txt
index 8a2a230d6..34520f067 100644
--- a/libkleopatraclient/CMakeLists.txt
+++ b/libkleopatraclient/CMakeLists.txt
@@ -1,12 +1,10 @@
-set( libkleopatraclient_soversion 0.2.0 )
+set( libkleopatraclient_soversion 0.1.0 )
set( libkleopatraclient_version ${libkleopatraclient_soversion} )
add_subdirectory( core )
add_subdirectory( gui )
-add_subdirectory( tests )
-
install(
FILES kleopatraclient_export.h
DESTINATION ${INCLUDE_INSTALL_DIR}/libkleopatraclient
)
diff --git a/libkleopatraclient/core/CMakeLists.txt b/libkleopatraclient/core/CMakeLists.txt
index d1c43fa3f..845bf9179 100644
--- a/libkleopatraclient/core/CMakeLists.txt
+++ b/libkleopatraclient/core/CMakeLists.txt
@@ -1,49 +1,47 @@
include_directories( ${ASSUAN_INCLUDES} ${CMAKE_SOURCE_DIR}/kleopatra )
add_definitions( -D_ASSUAN_ONLY_GPG_ERRORS -DQT_NO_CAST_FROM_ASCII -DQT_NO_KEYWORDS -DQT_NO_CAST_TO_ASCII )
if ( WIN32 )
set( _kleopatraclientcore_extra_SRCS
../../utils/gnupg-registry.c
)
else ( WIN32 )
set( _kleopatraclientcore_extra_SRCS )
endif ( WIN32 )
kde4_add_library( kleopatraclientcore SHARED
${_kleopatraclientcore_extra_SRCS}
initialization.cpp
command.cpp
selectcertificatecommand.cpp
- signencryptfilescommand.cpp
- decryptverifyfilescommand.cpp
+ #connection.cpp
)
set_target_properties( kleopatraclientcore
PROPERTIES
VERSION ${libkleopatraclient_version}
SOVERSION ${libkleopatraclient_soversion}
)
if ( WIN32 )
- target_link_libraries( kleopatraclientcore ${QT_QTCORE_LIBRARY} ${ASSUAN_VANILLA_LIBRARIES} ws2_32 )
+ target_link_libraries( kleopatraclientcore ${QT_QTCORE_LIBRARY} ${ASSUAN_VANILLA_LIBRARIES} Ws2_32 )
else ( WIN32 )
target_link_libraries( kleopatraclientcore ${QT_QTCORE_LIBRARY} ${ASSUAN_PTHREAD_LIBRARIES} )
endif ( WIN32 )
install(
TARGETS kleopatraclientcore
DESTINATION ${LIB_INSTALL_DIR}
)
install(
FILES
initialization.h
command.h
selectcertificatecommand.h
- signencryptfilescommand.h
DESTINATION ${INCLUDE_INSTALL_DIR}/libkleopatraclient/core
)
diff --git a/libkleopatraclient/core/command.cpp b/libkleopatraclient/core/command.cpp
index f6ad5bf8c..d22921d78 100644
--- a/libkleopatraclient/core/command.cpp
+++ b/libkleopatraclient/core/command.cpp
@@ -1,483 +1,411 @@
/* -*- mode: c++; c-basic-offset:4 -*-
command.cpp
This file is part of KleopatraClient, the Kleopatra interface library
Copyright (c) 2008 Klarälvdalens Datakonsult AB
KleopatraClient is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
KleopatraClient 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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
*/
#include <config-kleopatra.h>
#include "command.h"
#include "command_p.h"
#include <QtGlobal> // Q_OS_WIN
#ifdef Q_OS_WIN // HACK: AllowSetForegroundWindow needs _WIN32_WINDOWS >= 0x0490 set
# ifndef _WIN32_WINDOWS
# define _WIN32_WINDOWS 0x0500
# define _WIN32_WINNT 0x0500 // good enough for Vista too
# endif
# include <utils/gnupg-registry.h>
# include <windows.h>
#endif
#include <QMutexLocker>
#include <QFile>
#include <QDebug>
#include <QDir>
#include <assuan.h>
#include <gpg-error.h>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <algorithm>
-#include <string>
using namespace KLEOPATRACLIENT_NAMESPACE;
using namespace boost;
-// copied from kleopatra/utils/hex.cpp
-static std::string hexencode( const std::string & in ) {
- std::string result;
- result.reserve( 3 * in.size() );
-
- static const char hex[] = "0123456789ABCDEF";
-
- for ( std::string::const_iterator it = in.begin(), end = in.end() ; it != end ; ++it )
- switch ( const unsigned char ch = *it ) {
- default:
- if ( ch >= '!' && ch <= '~' || ch > 0xA0 ) {
- result += ch;
- break;
- }
- // else fall through
- case ' ':
- result += '+';
- break;
- case '"':
- case '#':
- case '$':
- case '%':
- case '\'':
- case '+':
- case '=':
- result += '%';
- result += hex[ (ch & 0xF0) >> 4 ];
- result += hex[ (ch & 0x0F) ];
- break;
- }
-
- return result;
-}
-
-#ifdef UNUSED
-static std::string hexencode( const char * in ) {
- if ( !in )
- return std::string();
- return hexencode( std::string( in ) );
-}
-#endif
-
-static QByteArray hexencode( const QByteArray & in ) {
- if ( in.isNull() )
- return QByteArray();
- const std::string result = hexencode( std::string( in.constData() ) );
- return QByteArray( result.data(), result.size() );
-}
-// end copied from kleopatra/utils/hex.cpp
-
Command::Command( QObject * p )
: QObject( p ), d( new Private( this ) )
{
d->init();
}
Command::Command( Private * pp, QObject * p )
: QObject( p ), d( pp )
{
d->init();
}
Command::~Command() {
delete d; d = 0;
}
void Command::Private::init() {
connect( this, SIGNAL(started()), q, SIGNAL(started()) );
connect( this, SIGNAL(finished()), q, SIGNAL(finished()) );
}
void Command::setParentWId( WId wid ) {
const QMutexLocker locker( &d->mutex );
d->inputs.parentWId = wid;
}
WId Command::parentWId() const {
const QMutexLocker locker( &d->mutex );
return d->inputs.parentWId;
}
void Command::setServerLocation( const QString & location ) {
const QMutexLocker locker( &d->mutex );
d->outputs.serverLocation = location;
}
QString Command::serverLocation() const {
const QMutexLocker locker( &d->mutex );
return d->outputs.serverLocation;
}
bool Command::waitForFinished() {
return d->wait();
}
bool Command::waitForFinished( unsigned long ms ) {
return d->wait( ms );
}
bool Command::error() const {
const QMutexLocker locker( &d->mutex );
return !d->outputs.errorString.isEmpty();
}
bool Command::wasCanceled() const {
const QMutexLocker locker( &d->mutex );
return d->outputs.canceled;
}
QString Command::errorString() const {
const QMutexLocker locker( &d->mutex );
return d->outputs.errorString;
}
qint64 Command::serverPid() const {
const QMutexLocker locker( &d->mutex );
return d->outputs.serverPid;
}
void Command::start() {
d->start();
}
void Command::cancel() {
qDebug( "Sorry, not implemented: KleopatraClient::Command::Cancel" );
}
void Command::setOptionValue( const char * name, const QVariant & value, bool critical ) {
if ( !name || !*name )
return;
const QMutexLocker locker( &d->mutex );
const Private::Option opt = {
value,
true,
critical
};
d->inputs.options[name] = opt;
}
QVariant Command::optionValue( const char * name ) const {
if ( !name || !*name )
return QVariant();
const QMutexLocker locker( &d->mutex );
const std::map<std::string,Private::Option>::const_iterator it = d->inputs.options.find( name );
if ( it == d->inputs.options.end() )
return QVariant();
else
return it->second.value;
}
void Command::setOption( const char * name, bool critical ) {
if ( !name || !*name )
return;
const QMutexLocker locker( &d->mutex );
if ( isOptionSet( name ) )
unsetOption( name );
const Private::Option opt = {
QVariant(),
false,
critical
};
d->inputs.options[name] = opt;
}
void Command::unsetOption( const char * name ) {
if ( !name || !*name )
return;
const QMutexLocker locker( &d->mutex );
d->inputs.options.erase( name );
}
bool Command::isOptionSet( const char * name ) const {
if ( !name || !*name )
return false;
const QMutexLocker locker( &d->mutex );
return d->inputs.options.count( name );
}
bool Command::isOptionCritical( const char * name ) const {
if ( !name || !*name )
return false;
const QMutexLocker locker( &d->mutex );
const std::map<std::string,Private::Option>::const_iterator it = d->inputs.options.find( name );
return it != d->inputs.options.end() && it->second.isCritical;
}
-void Command::setFilePaths( const QStringList & filePaths ) {
- const QMutexLocker locker( &d->mutex );
- d->inputs.filePaths = filePaths;
-}
-
-QStringList Command::filePaths() const {
- const QMutexLocker locker( &d->mutex );
- return d->inputs.filePaths;
-}
-
QByteArray Command::receivedData() const {
const QMutexLocker locker( &d->mutex );
return d->outputs.data;
}
void Command::setCommand( const char * command ) {
const QMutexLocker locker( &d->mutex );
d->inputs.command = command;
}
QByteArray Command::command() const {
const QMutexLocker locker( &d->mutex );
return d->inputs.command;
}
//
// here comes the ugly part
//
typedef shared_ptr< remove_pointer<assuan_context_t>::type > AssuanContextBase;
namespace {
struct AssuanClientContext : AssuanContextBase {
AssuanClientContext() : AssuanContextBase() {}
explicit AssuanClientContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &assuan_disconnect ) {}
void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &assuan_disconnect ); }
};
}
static assuan_error_t
my_assuan_transact( const AssuanClientContext & ctx,
const char *command,
int (*data_cb)( void *, const void *, size_t )=0,
void * data_cb_arg=0,
int (*inquire_cb)( void *, const char * )=0,
void * inquire_cb_arg=0,
int (*status_cb)( void *, const char * )=0,
void * status_cb_arg=0)
{
return assuan_transact( ctx.get(), command, data_cb, data_cb_arg, inquire_cb, inquire_cb_arg, status_cb, status_cb_arg );
}
static QString to_error_string( int err ) {
char buffer[1024];
gpg_strerror_r( static_cast<gpg_error_t>(err),
buffer, sizeof buffer );
buffer[sizeof buffer - 1] = '\0';
return QString::fromLocal8Bit( buffer );
}
static QString gnupg_home_directory() {
#ifdef Q_OS_WIN
return QFile::decodeName( default_homedir() );
#else
const QByteArray gnupgHome = qgetenv( "GNUPGHOME" );
if ( !gnupgHome.isEmpty() )
return QFile::decodeName( gnupgHome );
else
return QDir::homePath() + QLatin1String( "/.gnupg" );
#endif
}
static QString get_default_socket_name() {
const QString homeDir = gnupg_home_directory();
if ( homeDir.isEmpty() )
return QString();
return QDir( homeDir ).absoluteFilePath( QLatin1String( "S.uiserver" ) );
}
static QString default_socket_name() {
static QString name = get_default_socket_name();
return name;
}
static QString start_uiserver() {
return Command::tr("start_uiserver: not yet implemented");
}
static int getinfo_pid_cb( void * opaque, const void * buffer, size_t length ) {
qint64 & pid = *static_cast<qint64*>( opaque );
pid = QByteArray( static_cast<const char*>( buffer ), length ).toLongLong();
return 0;
}
static int command_data_cb( void * opaque, const void * buffer, size_t length ) {
QByteArray & ba = *static_cast<QByteArray*>( opaque );
ba.append( QByteArray( static_cast<const char*>(buffer), length ) );
return 0;
}
static int send_option( const AssuanClientContext & ctx, const char * name, const QVariant & value ) {
if ( value.isValid() )
return my_assuan_transact( ctx, QString().sprintf( "OPTION %s=%s", name, value.toString().toUtf8().constData() ).toUtf8().constData() );
else
return my_assuan_transact( ctx, QString().sprintf( "OPTION %s", name ).toUtf8().constData() );
}
-static int send_file( const AssuanClientContext & ctx, const QString & file ) {
- return my_assuan_transact( ctx, QString().sprintf( "FILE %s", hexencode( QFile::encodeName( file ) ).constData() ).toUtf8().constData() );
-}
-
void Command::Private::run() {
// Take a snapshot of the input data, and clear the output data:
Inputs in;
Outputs out;
{
const QMutexLocker locker( &mutex );
in = inputs;
outputs = out;
}
out.canceled = false;
int err = 0;
assuan_context_t naked_ctx = 0;
AssuanClientContext ctx;
if ( out.serverLocation.isEmpty() )
out.serverLocation = default_socket_name();
const QString socketName = out.serverLocation;
if ( socketName.isEmpty() ) {
out.errorString = tr("Invalid socket name!");
goto leave;
}
err = assuan_socket_connect( &naked_ctx, QFile::encodeName( socketName ).constData(), -1 );
if ( err ) {
qDebug( "UI server not running, starting it" );
const QString errorString = start_uiserver();
if ( !errorString.isEmpty() ) {
out.errorString = errorString;
goto leave;
}
// give it a bit of time to start up and try a couple of times
for ( int i = 0 ; err && i < 20 ; ++i ) {
msleep( 500 );
err = assuan_socket_connect( &naked_ctx, QFile::encodeName( socketName ).constData(), -1 );
}
}
if ( err ) {
out.errorString = tr( "Could not connect to Kleopatra UI server at %1: %2" )
.arg( socketName, to_error_string( err ) );
goto leave;
}
ctx.reset( naked_ctx );
naked_ctx = 0;
out.serverPid = -1;
err = my_assuan_transact( ctx, "GETINFO pid", &getinfo_pid_cb, &out.serverPid );
if ( err || out.serverPid <= 0 ) {
out.errorString = tr( "Could not get the process-id of the Kleopatra UI server at %1: %2" )
.arg( socketName, to_error_string( err ) );
goto leave;
}
qDebug() << "Server PID =" << out.serverPid;
#ifdef Q_OS_WIN
if ( !AllowSetForegroundWindow( (pid_t)out.serverPid ) )
qDebug() << "AllowSetForegroundWindow(" << out.serverPid << ") failed: " << GetLastError();
#endif
if ( in.command.isEmpty() )
goto leave;
if ( in.parentWId ) {
#ifdef Q_OS_WIN32
err = send_option( ctx, "window-id", QString().sprintf( "%lx", reinterpret_cast<unsigned long>( in.parentWId ) ) );
#else
err = send_option( ctx, "window-id", QString().sprintf( "%lx", static_cast<unsigned long>( in.parentWId ) ) );
#endif
if ( err )
qDebug( "sending option window-id failed - ignoring" );
}
for ( std::map<std::string,Option>::const_iterator it = in.options.begin(), end = in.options.end() ; it != end ; ++it )
if ( ( err = send_option( ctx, it->first.c_str(), it->second.hasValue ? it->second.value.toString() : QVariant() ) ) )
if ( it->second.isCritical ) {
out.errorString = tr("Failed to send critical option %1: %2")
.arg( QString::fromLatin1( it->first.c_str() ), to_error_string( err ) );
goto leave;
} else {
qDebug() << "Failed to send non-critical option" << it->first.c_str() << ":" << to_error_string( err );
}
- Q_FOREACH( const QString & filePath, in.filePaths )
- if ( ( err = send_file( ctx, filePath ) ) ) {
- out.errorString = tr("Failed to send file path %1: %2")
- .arg( filePath, to_error_string( err ) );
- goto leave;
- }
-
#if 0
setup I/O;
#endif
err = my_assuan_transact( ctx, in.command.constData(), &command_data_cb, &out.data );
if ( err ) {
if ( gpg_err_code( err ) == GPG_ERR_CANCELED )
out.canceled = true;
else
out.errorString = tr( "Command (%1) failed: %2" )
.arg( QString::fromLatin1( in.command.constData() ) ).arg( to_error_string( err ) );
goto leave;
}
leave:
const QMutexLocker locker( &mutex );
// copy outputs to where Command can see them:
outputs = out;
}
#include "moc_command_p.cpp"
#include "moc_command.cpp"
diff --git a/libkleopatraclient/core/command.h b/libkleopatraclient/core/command.h
index 7e6c458a9..1570565ae 100644
--- a/libkleopatraclient/core/command.h
+++ b/libkleopatraclient/core/command.h
@@ -1,90 +1,87 @@
/* -*- mode: c++; c-basic-offset:4 -*-
core/command.h
This file is part of KleopatraClient, the Kleopatra interface library
Copyright (c) 2008 Klarälvdalens Datakonsult AB
KleopatraClient is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
KleopatraClient 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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
*/
#ifndef __LIBKLEOPATRACLIENT_CORE_COMMAND_H__
#define __LIBKLEOPATRACLIENT_CORE_COMMAND_H__
#include <libkleopatraclient/kleopatraclient_export.h>
#include <QtCore/QObject>
#include <QtGui/QWidget> // only for WId, doesn't prevent linking against QtCore-only
class QString;
class QByteArray;
class QVariant;
namespace KLEOPATRACLIENT_NAMESPACE {
class KLEOPATRACLIENTCORE_EXPORT Command : public QObject {
Q_OBJECT
public:
explicit Command( QObject * parent=0 );
~Command();
void setParentWId( WId wid );
WId parentWId() const;
void setServerLocation( const QString & location );
QString serverLocation() const;
bool waitForFinished();
bool waitForFinished( unsigned long ms );
bool error() const;
bool wasCanceled() const;
QString errorString() const;
qint64 serverPid() const;
public Q_SLOTS:
void start();
void cancel();
Q_SIGNALS:
void started();
void finished();
protected:
void setOptionValue( const char * name, const QVariant & value, bool critical=true );
void setOption( const char * name, bool critical=true );
void unsetOption( const char * name );
QVariant optionValue( const char * name ) const;
bool isOptionSet( const char * name ) const;
bool isOptionCritical( const char * name ) const;
- void setFilePaths( const QStringList & filePaths );
- QStringList filePaths() const;
-
QByteArray receivedData() const;
void setCommand( const char * command );
QByteArray command() const;
protected:
class Private;
Private * d;
Command( Private * p, QObject * parent );
};
}
#endif /* __LIBKLEOPATRACLIENT_CORE_COMMAND_H__ */
diff --git a/libkleopatraclient/core/command_p.h b/libkleopatraclient/core/command_p.h
index 26d315b97..cb381eae9 100644
--- a/libkleopatraclient/core/command_p.h
+++ b/libkleopatraclient/core/command_p.h
@@ -1,84 +1,82 @@
/* -*- mode: c++; c-basic-offset:4 -*-
command_p.h
This file is part of KleopatraClient, the Kleopatra interface library
Copyright (c) 2008 Klarälvdalens Datakonsult AB
KleopatraClient is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
KleopatraClient 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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
*/
#ifndef __LIBKLEOPATRACLIENT_CORE_COMMAND_P_H__
#define __LIBKLEOPATRACLIENT_CORE_COMMAND_P_H__
#include "command.h"
#include <QThread>
#include <QMutex>
#include <QString>
-#include <QStringList>
#include <QByteArray>
#include <QVariant>
#include <map>
#include <string>
class KLEOPATRACLIENT_NAMESPACE::Command::Private : public QThread {
Q_OBJECT
private:
friend class ::KLEOPATRACLIENT_NAMESPACE::Command;
Command * const q;
public:
explicit Private( Command * qq )
: QThread(),
q( qq ),
mutex( QMutex::Recursive ),
inputs(),
outputs()
{
}
~Private() {}
private:
void init();
private:
/* reimp */ void run();
private:
QMutex mutex;
struct Option {
QVariant value;
bool hasValue : 1;
bool isCritical : 1;
};
struct Inputs {
Inputs() : parentWId( 0 ) {}
std::map<std::string,Option> options;
- QStringList filePaths;
WId parentWId;
QByteArray command;
} inputs;
struct Outputs {
Outputs() : canceled( false ), serverPid( 0 ) {}
QString errorString;
bool canceled : 1;
QByteArray data;
qint64 serverPid;
QString serverLocation;
} outputs;
};
#endif /* __LIBKLEOPATRACLIENT_CORE_COMMAND_P_H__ */
diff --git a/libkleopatraclient/core/decryptverifyfilescommand.cpp b/libkleopatraclient/core/decryptverifyfilescommand.cpp
index c3afa47fc..e69de29bb 100644
--- a/libkleopatraclient/core/decryptverifyfilescommand.cpp
+++ b/libkleopatraclient/core/decryptverifyfilescommand.cpp
@@ -1,35 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- core/decryptverifyfilescommand.cpp
-
- This file is part of KleopatraClient, the Kleopatra interface library
- Copyright (c) 2008 Klarälvdalens Datakonsult AB
-
- KleopatraClient is free software; you can redistribute it and/or modify
- it under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- KleopatraClient 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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
-*/
-
-#include "decryptverifyfilescommand.h"
-
-using namespace KLEOPATRACLIENT_NAMESPACE;
-
-DecryptVerifyFilesCommand::DecryptVerifyFilesCommand( QObject * p )
- : Command( p )
-{
- setCommand( "DECRYPT_VERIFY_FILES" );
- setOption( "nohup" );
-}
-
-DecryptVerifyFilesCommand::~DecryptVerifyFilesCommand() {}
-
-#include "moc_decryptverifyfilescommand.cpp"
diff --git a/libkleopatraclient/core/decryptverifyfilescommand.h b/libkleopatraclient/core/decryptverifyfilescommand.h
index aae3b7f4a..e69de29bb 100644
--- a/libkleopatraclient/core/decryptverifyfilescommand.h
+++ b/libkleopatraclient/core/decryptverifyfilescommand.h
@@ -1,45 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- core/decryptverifyfilescommand.h
-
- This file is part of KleopatraClient, the Kleopatra interface library
- Copyright (c) 2008 Klarälvdalens Datakonsult AB
-
- KleopatraClient is free software; you can redistribute it and/or modify
- it under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- KleopatraClient 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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
-*/
-
-#ifndef __LIBKLEOPATRACLIENT_CORE_DECRYPTVERIFYFILESCOMMAND_H__
-#define __LIBKLEOPATRACLIENT_CORE_DECRYPTVERIFYFILESCOMMAND_H__
-
-#include <libkleopatraclient/core/command.h>
-
-namespace KLEOPATRACLIENT_NAMESPACE {
-
- class KLEOPATRACLIENTCORE_EXPORT DecryptVerifyFilesCommand : public Command {
- Q_OBJECT
- public:
- explicit DecryptVerifyFilesCommand( QObject * parent=0 );
- ~DecryptVerifyFilesCommand();
-
- // Inputs
-
- using Command::setFilePaths;
- using Command::filePaths;
-
- // No Outputs
- };
-
-}
-
-#endif /* __LIBKLEOPATRACLIENT_CORE_DECRYPTVERIFYFILESCOMMAND_H__ */
diff --git a/libkleopatraclient/core/signencryptfilescommand.cpp b/libkleopatraclient/core/signencryptfilescommand.cpp
index 16ea362b6..e69de29bb 100644
--- a/libkleopatraclient/core/signencryptfilescommand.cpp
+++ b/libkleopatraclient/core/signencryptfilescommand.cpp
@@ -1,35 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- core/signencryptfilescommand.cpp
-
- This file is part of KleopatraClient, the Kleopatra interface library
- Copyright (c) 2008 Klarälvdalens Datakonsult AB
-
- KleopatraClient is free software; you can redistribute it and/or modify
- it under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- KleopatraClient 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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
-*/
-
-#include "signencryptfilescommand.h"
-
-using namespace KLEOPATRACLIENT_NAMESPACE;
-
-SignEncryptFilesCommand::SignEncryptFilesCommand( QObject * p )
- : Command( p )
-{
- setCommand( "SIGN_ENCRYPT_FILES" );
- setOption( "nohup" );
-}
-
-SignEncryptFilesCommand::~SignEncryptFilesCommand() {}
-
-#include "moc_signencryptfilescommand.cpp"
diff --git a/libkleopatraclient/core/signencryptfilescommand.h b/libkleopatraclient/core/signencryptfilescommand.h
index 560e6915e..e69de29bb 100644
--- a/libkleopatraclient/core/signencryptfilescommand.h
+++ b/libkleopatraclient/core/signencryptfilescommand.h
@@ -1,45 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- core/signencryptfilescommand.h
-
- This file is part of KleopatraClient, the Kleopatra interface library
- Copyright (c) 2008 Klarälvdalens Datakonsult AB
-
- KleopatraClient is free software; you can redistribute it and/or modify
- it under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- KleopatraClient 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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
-*/
-
-#ifndef __LIBKLEOPATRACLIENT_CORE_SIGNENCRYPTFILESCOMMAND_H__
-#define __LIBKLEOPATRACLIENT_CORE_SIGNENCRYPTFILESCOMMAND_H__
-
-#include <libkleopatraclient/core/command.h>
-
-namespace KLEOPATRACLIENT_NAMESPACE {
-
- class KLEOPATRACLIENTCORE_EXPORT SignEncryptFilesCommand : public Command {
- Q_OBJECT
- public:
- explicit SignEncryptFilesCommand( QObject * parent=0 );
- ~SignEncryptFilesCommand();
-
- // Inputs
-
- using Command::setFilePaths;
- using Command::filePaths;
-
- // No Outputs
- };
-
-}
-
-#endif /* __LIBKLEOPATRACLIENT_CORE_SIGNENCRYPTFILESCOMMAND_H__ */
diff --git a/main.cpp b/main.cpp
index 0bcdf92c9..a31a8bc23 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,220 +1,316 @@
/*
main.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2001,2002,2004 Klar�vdalens 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 "aboutdata.h"
-#include "kleopatraapplication.h"
+#include "systemtrayicon.h"
#include "mainwindow.h"
#include <commands/reloadkeyscommand.h>
#include <commands/selftestcommand.h>
+#include "libkleo/kleo/cryptobackendfactory.h"
+
#include <utils/gnupg-helper.h>
+#include <utils/filesystemwatcher.h>
+#include <utils/kdpipeiodevice.h>
+#include <utils/log.h>
#ifdef HAVE_USABLE_ASSUAN
+# include "kleo-assuan.h"
# include <uiserver/uiserver.h>
# include <uiserver/assuancommand.h>
# include <uiserver/echocommand.h>
# include <uiserver/decryptcommand.h>
# include <uiserver/verifycommand.h>
# include <uiserver/decryptverifyfilescommand.h>
# include <uiserver/decryptfilescommand.h>
# include <uiserver/verifyfilescommand.h>
# include <uiserver/prepencryptcommand.h>
# include <uiserver/encryptcommand.h>
# include <uiserver/signcommand.h>
# include <uiserver/signencryptfilescommand.h>
# include <uiserver/selectcertificatecommand.h>
#else
namespace Kleo {
class UiServer;
}
#endif
+#include <models/keycache.h>
+
#include <kcmdlineargs.h>
#include <klocale.h>
+#include <kglobal.h>
#include <kiconloader.h>
#include <ksplashscreen.h>
+#include <KUniqueApplication>
#include <KDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
#include <QTextDocument> // for Qt::escape
+#include <QProcess>
#include <QStringList>
#include <QMessageBox>
+#include <QPointer>
#include <QTimer>
-#include <QEventLoop>
-#include <QThreadPool>
#include <boost/shared_ptr.hpp>
+#include <boost/mem_fn.hpp>
+#include <memory>
#include <cassert>
using namespace boost;
namespace {
template <typename T>
boost::shared_ptr<T> make_shared_ptr( T * t ) {
return t ? boost::shared_ptr<T>( t ) : boost::shared_ptr<T>() ;
}
}
+static QStringList watchList() {
+ const QString home = Kleo::gnupgHomeDirectory();
+ QFileInfo info( home );
+ if ( !info.isDir() )
+ return QStringList();
+ QDir homeDir( home );
+ QStringList fileList = homeDir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot );
+ fileList.removeAll( "dirmngr-cache.d" );
+ QStringList result;
+ Q_FOREACH( const QString& i, fileList )
+ result.push_back( homeDir.absoluteFilePath( i ) );
+ return result;
+}
+
static bool selfCheck( KSplashScreen & splash ) {
splash.showMessage( i18n("Performing Self-Check...") );
Kleo::Commands::SelfTestCommand cmd( 0 );
cmd.setAutoDelete( false );
cmd.setAutomaticMode( true );
cmd.setSplashScreen( &splash );
QEventLoop loop;
QObject::connect( &cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
QObject::connect( &cmd, SIGNAL(info(QString)), &splash, SLOT(showMessage(QString)) );
QTimer::singleShot( 0, &cmd, SLOT(start()) ); // start() may emit finished()...
loop.exec();
if ( cmd.isCanceled() ) {
splash.showMessage( i18nc("didn't pass", "Self-Check Failed") );
return false;
} else {
splash.showMessage( i18n("Self-Check Passed") );
return true;
}
}
+static QString environmentVariable( const QString& var, const QString& defaultValue=QString() )
+{
+ const QStringList env = QProcess::systemEnvironment();
+ Q_FOREACH ( const QString& i, env )
+ {
+ if ( !i.startsWith( var + '=' ) )
+ continue;
+
+ const int equalPos = i.indexOf( '=' );
+ assert( equalPos >= 0 );
+ return i.mid( equalPos + 1 );
+ }
+ return defaultValue;
+}
+
+static void setupLogging()
+{
+ const QString envOptions = environmentVariable( "KLEOPATRA_LOGOPTIONS", "io" );
+ const bool logAll = envOptions.trimmed() == "all";
+ const QStringList options = envOptions.split( ',' );
+
+ const QString dir = environmentVariable( "KLEOPATRA_LOGDIR" );
+ if ( dir.isEmpty() )
+ return;
+ std::auto_ptr<QFile> logFile( new QFile( dir + "/kleo-log" ) );
+ if ( !logFile->open( QIODevice::WriteOnly | QIODevice::Append ) ) {
+ kDebug() << "Could not open file for logging: " << dir + "/kleo-log\nLogging disabled";
+ return;
+ }
+
+ Kleo::Log::mutableInstance()->setOutputDirectory( dir );
+ if ( logAll || options.contains( "io" ) )
+ Kleo::Log::mutableInstance()->setIOLoggingEnabled( true );
+ qInstallMsgHandler( Kleo::Log::messageHandler );
+
+#ifdef HAVE_USABLE_ASSUAN
+ if ( logAll || options.contains( "pipeio" ) )
+ KDPipeIODevice::setDebugLevel( KDPipeIODevice::Debug );
+
+ assuan_set_assuan_log_stream( Kleo::Log::instance()->logFile() );
+#endif
+}
+
static void fillKeyCache( KSplashScreen * splash, Kleo::UiServer * server ) {
QEventLoop loop;
Kleo::ReloadKeysCommand * cmd = new Kleo::ReloadKeysCommand( 0 );
QObject::connect( cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
#ifdef HAVE_USABLE_ASSUAN
QObject::connect( cmd, SIGNAL(finished()), server, SLOT(enableCryptoCommands()) );
#else
Q_UNUSED( server );
#endif
splash->showMessage( i18n("Loading certificate cache...") );
cmd->start();
loop.exec();
splash->showMessage( i18n("Certificate cache loaded.") );
}
int main( int argc, char** argv )
{
- {
- const unsigned int threads = QThreadPool::globalInstance()->maxThreadCount();
- QThreadPool::globalInstance()->setMaxThreadCount( qMin( 2U, threads ) );
- }
-
AboutData aboutData;
KCmdLineArgs::init(argc, argv, &aboutData);
- KCmdLineArgs::addCmdLineOptions( KleopatraApplication::commandLineOptions() );
+ KCmdLineOptions options;
+ options.add("daemon", ki18n("Run UI server only, hide main window"));
+ options.add("import-certificate ", ki18n("Name of certificate file to import"));
+#ifdef HAVE_USABLE_ASSUAN
+ options.add("uiserver-socket <argument>", ki18n("Location of the socket the ui server is listening on" ) );
+#endif
+
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KUniqueApplication app;
+
+ // pin KeyCache to a shared_ptr to define it's minimum lifetime:
+ const boost::shared_ptr<Kleo::KeyCache> keyCache = Kleo::KeyCache::mutableInstance();
+ const boost::shared_ptr<Kleo::Log> log = Kleo::Log::mutableInstance();
+ const boost::shared_ptr<Kleo::FileSystemWatcher> watcher( new Kleo::FileSystemWatcher );
+
+ watcher->addPaths( watchList() );
+ watcher->setDelay( 1000 );
+ keyCache->addFileSystemWatcher( watcher );
+ setupLogging();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
- KleopatraApplication app;
+ KGlobal::locale()->insertCatalog( "libkleopatra" );
+ KIconLoader::global()->addAppDir( "libkleopatra" );
+ KIconLoader::global()->addAppDir( "kdepim" );
- KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ SystemTrayIconFor<MainWindow> sysTray;
+ sysTray.show();
KSplashScreen splash( UserIcon( "kleopatra_splashscreen" ), Qt::WindowStaysOnTopHint );
int rc;
#ifdef HAVE_USABLE_ASSUAN
try {
Kleo::UiServer server( args->getOption("uiserver-socket") );
- QObject::connect( &server, SIGNAL(startKeyManagerRequested()),
- &app, SLOT(openOrRaiseMainWindow()) );
+ server.enableCryptoCommands( false );
- QObject::connect( &server, SIGNAL(startConfigDialogRequested()),
- &app, SLOT(openOrRaiseConfigDialog()) );
+ QObject::connect( &server, SIGNAL(startKeyManagerRequested()),
+ &sysTray, SLOT(openOrRaiseMainWindow()) );
#define REGISTER( Command ) server.registerCommandFactory( boost::shared_ptr<Kleo::AssuanCommandFactory>( new Kleo::GenericAssuanCommandFactory<Kleo::Command> ) )
REGISTER( DecryptCommand );
REGISTER( DecryptFilesCommand );
REGISTER( DecryptVerifyFilesCommand );
REGISTER( EchoCommand );
REGISTER( EncryptCommand );
REGISTER( EncryptFilesCommand );
REGISTER( EncryptSignFilesCommand );
REGISTER( PrepEncryptCommand );
REGISTER( SelectCertificateCommand );
REGISTER( SignCommand );
REGISTER( SignEncryptFilesCommand );
REGISTER( SignFilesCommand );
REGISTER( VerifyCommand );
REGISTER( VerifyFilesCommand );
#undef REGISTER
server.start();
+
+ sysTray.setToolTip( i18n( "Kleopatra UI Server listening on %1", server.socketName() ) );
#endif
const bool daemon = args->isSet("daemon");
+ const QStringList certificateToImport = args->getOptionList("import-certificate");
if ( !daemon )
splash.show();
if ( !selfCheck( splash ) )
return 1;
#ifdef HAVE_USABLE_ASSUAN
fillKeyCache( &splash, &server );
#else
fillKeyCache( &splash, 0 );
#endif
- app.setIgnoreNewInstance( false );
-
if ( !daemon ) {
- app.newInstance();
- splash.finish( app.mainWindow() );
+ MainWindow* mainWindow = new MainWindow;
+ if ( !certificateToImport.isEmpty() )
+ mainWindow->importCertificatesFromFile( certificateToImport );
+ mainWindow->show();
+ sysTray.setMainWindow( mainWindow );
+ splash.finish( mainWindow );
}
+ args->clear();
+ QApplication::setQuitOnLastWindowClosed( false );
rc = app.exec();
#ifdef HAVE_USABLE_ASSUAN
- app.setIgnoreNewInstance( true );
QObject::disconnect( &server, SIGNAL(startKeyManagerRequested()),
- &app, SLOT(openOrRaiseMainWindow()) );
- QObject::disconnect( &server, SIGNAL(startConfigDialogRequested()),
- &app, SLOT(openOrRaiseConfigDialog()) );
+ &sysTray, SLOT(openOrRaiseMainWindow()) );
server.stop();
server.waitForStopped();
} catch ( const std::exception & e ) {
QMessageBox::information( 0, i18n("GPG UI Server Error"),
i18n("<qt>The Kleopatra GPG UI Server Module couldn't be initialized.<br/>"
"The error given was: <b>%1</b><br/>"
"You can use Kleopatra as a certificate manager, but cryptographic plugins that "
"rely on a GPG UI Server being present might not work correctly, or at all.</qt>",
Qt::escape( QString::fromUtf8( e.what() ) ) ));
- app.setIgnoreNewInstance( false );
rc = app.exec();
- app.setIgnoreNewInstance( true );
}
#endif
+ // work around kdelibs bug https://bugs.kde.org/show_bug.cgi?id=162514
+ KGlobal::config()->sync();
+
+
return rc;
}
diff --git a/mainwindow.cpp b/mainwindow.cpp
index d2a1caa45..5bc757296 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1,635 +1,587 @@
/* -*- mode: c++; c-basic-offset:4 -*-
mainwindow.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 "mainwindow.h"
-#include "newcertificatewizard/newcertificatewizard.h"
+#include "certificatewizardimpl.h"
#include "models/keylistmodel.h"
#include "models/keylistsortfilterproxymodel.h"
#include "view/searchbar.h"
#include "view/tabwidget.h"
#include "view/keylistcontroller.h"
#include "commands/exportcertificatecommand.h"
-#include "commands/exportopenpgpcertstoservercommand.h"
-#include "commands/exportsecretkeycommand.h"
#include "commands/importcertificatefromfilecommand.h"
-#include "commands/changepassphrasecommand.h"
#include "commands/lookupcertificatescommand.h"
#include "commands/reloadkeyscommand.h"
#include "commands/refreshx509certscommand.h"
#include "commands/refreshopenpgpcertscommand.h"
#include "commands/detailscommand.h"
#include "commands/deletecertificatescommand.h"
#include "commands/decryptverifyfilescommand.h"
#include "commands/signencryptfilescommand.h"
#include "commands/clearcrlcachecommand.h"
#include "commands/dumpcrlcachecommand.h"
-#include "commands/dumpcertificatecommand.h"
#include "commands/importcrlcommand.h"
#include "commands/changeexpirycommand.h"
#include "commands/changeownertrustcommand.h"
#include "commands/selftestcommand.h"
-#include "commands/certifycertificatecommand.h"
-#include "commands/adduseridcommand.h"
+#include "commands/signcertificatecommand.h"
+
+#include "conf/configuredialog.h"
#include "utils/detail_p.h"
#include "utils/gnupg-helper.h"
#include "utils/stl_util.h"
#include "utils/action_data.h"
-#include "utils/classify.h"
#include <KActionCollection>
#include <KLocale>
#include <KTabWidget>
#include <KStatusBar>
#include <KStandardAction>
#include <KAction>
#include <KAboutData>
#include <KMessageBox>
#include <KStandardGuiItem>
#include <KStandardDirs>
#include <KShortcutsDialog>
#include <KXMLGUIFactory>
#include <KEditToolBar>
#include <kdebug.h>
#include <QAbstractItemView>
#include <QFile>
#include <QFileDialog>
#include <QToolBar>
#include <QWidgetAction>
#include <QProgressBar>
#include <QApplication>
#include <QCloseEvent>
#include <QMenu>
#include <QTimer>
-#include <QProcess>
-#include <QPointer>
#include <kleo/cryptobackendfactory.h>
#include <ui/cryptoconfigdialog.h>
#include <kleo/cryptoconfig.h>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
-#ifdef Q_OS_WIN32
-static const bool OS_WIN = true;
-#else
-static const bool OS_WIN = false;
-#endif
-
using namespace Kleo;
using namespace Kleo::Commands;
using namespace boost;
using namespace GpgME;
namespace {
class ProgressBar : public QProgressBar {
Q_OBJECT
public:
explicit ProgressBar( QWidget * p=0 ) : QProgressBar( p ) {}
public Q_SLOTS:
void setProgress( int current, int total ) {
setRange( 0, total );
setValue( current );
}
};
}
static KGuiItem KStandardGuiItem_quit() {
static const QString app = KGlobal::mainComponent().aboutData()->programName();
KGuiItem item = KStandardGuiItem::quit();
item.setText( i18nc( "Quit [ApplicationName]", "&Quit %1", app ) );
return item;
}
static KGuiItem KStandardGuiItem_close() {
KGuiItem item = KStandardGuiItem::close();
item.setText( i18n("Only &Close Window" ) );
return item;
}
class MainWindow::Private {
friend class ::MainWindow;
MainWindow * const q;
public:
explicit Private( MainWindow * qq );
~Private();
template <typename T>
void createAndStart() {
( new T( this->currentView(), &this->controller ) )->start();
}
template <typename T>
void createAndStart( QAbstractItemView * view ) {
( new T( view, &this->controller ) )->start();
}
template <typename T>
void createAndStart( const QStringList & a ) {
( new T( a, this->currentView(), &this->controller ) )->start();
}
template <typename T>
void createAndStart( const QStringList & a, QAbstractItemView * view ) {
( new T( a, view, &this->controller ) )->start();
}
void closeAndQuit() {
const QString app = KGlobal::mainComponent().aboutData()->programName();
const int rc = KMessageBox::questionYesNoCancel( q,
i18n("%1 may be used by other applications as a service.\n"
"You may instead want to close this window without exiting %1.", app ),
i18n("Really Quit?"), KStandardGuiItem_quit(), KStandardGuiItem_close(), KStandardGuiItem::cancel(),
"really-quit-" + app.toLower() );
if ( rc == KMessageBox::Cancel )
return;
if ( !q->close() )
return;
// WARNING: 'this' might be deleted at this point!
if ( rc == KMessageBox::Yes )
qApp->quit();
}
void certificateDetails() {
createAndStart<DetailsCommand>();
}
void reloadCertificates() {
createAndStart<ReloadKeysCommand>();
}
void refreshX509Certificates() {
createAndStart<RefreshX509CertsCommand>();
}
void refreshOpenPGPCertificates() {
createAndStart<RefreshOpenPGPCertsCommand>();
}
- void changePassphrase() {
- createAndStart<ChangePassphraseCommand>();
- }
+
void deleteCertificates() {
createAndStart<DeleteCertificatesCommand>();
}
void changeCertificateExpiry() {
createAndStart<ChangeExpiryCommand>();
}
void changeCertificateOwnerTrust() {
createAndStart<ChangeOwnerTrustCommand>();
}
void signEncryptFiles() {
createAndStart<SignEncryptFilesCommand>();
}
- void certifyCertificate() {
- createAndStart<CertifyCertificateCommand>();
- }
- void addUserID() {
- createAndStart<AddUserIDCommand>();
+ void signCertificate() {
+ createAndStart<SignCertificateCommand>();
}
void decryptVerifyFiles() {
createAndStart<DecryptVerifyFilesCommand>();
}
void exportCertificates() {
createAndStart<ExportCertificateCommand>();
}
- void exportCertificatesToServer() {
- createAndStart<ExportOpenPGPCertsToServerCommand>();
- }
- void exportSecretKey() {
- createAndStart<ExportSecretKeyCommand>();
- }
void importCertificatesFromFile() {
createAndStart<ImportCertificateFromFileCommand>();
}
void lookupCertificates() {
createAndStart<LookupCertificatesCommand>();
}
void clearCrlCache() {
createAndStart<ClearCrlCacheCommand>();
}
void dumpCrlCache() {
createAndStart<DumpCrlCacheCommand>();
}
- void dumpCertificate() {
- createAndStart<DumpCertificateCommand>();
- }
void importCrlFromFile() {
createAndStart<ImportCrlCommand>();
}
void configureToolbars() {
KEditToolBar dlg( q->factory() );
dlg.exec();
}
void editKeybindings() {
KShortcutsDialog::configure( q->actionCollection(), KShortcutsEditor::LetterShortcutsAllowed );
}
void newCertificate();
void selfTest() {
createAndStart<SelfTestCommand>();
}
void configureBackend();
-
- void gnupgLogViewer() {
- if( !QProcess::startDetached("kwatchgnupg" ) )
- KMessageBox::error( q, i18n( "Could not start the GnuPG Log Viewer (kwatchgnupg). "
- "Please check your installation!" ),
- i18n( "Error Starting KWatchGnuPG" ) );
- }
-
- void gnupgAdministrativeConsole() {
- if( !QProcess::startDetached("kgpgconf" ) )
- KMessageBox::error( q, i18n( "Could not start the GnuPG Administrative Console (kgpgconf). "
- "Please check your installation!" ),
- i18n( "Error Starting KGpgConf" ) );
- }
+ void preferences();
void slotConfigCommitted();
void slotContextMenuRequested( QAbstractItemView *, const QPoint & p ) {
if ( QMenu * const menu = qobject_cast<QMenu*>( q->factory()->container( "listview_popup", q ) ) )
menu->exec( p );
else
kDebug() << "no \"listview_popup\" <Menu> in kleopatra's ui.rc file";
}
private:
void setupActions();
unsigned int numViews() const {
return ui.tabWidget.count();
}
QAbstractItemView * currentView() const {
return ui.tabWidget.currentView();
}
private:
Kleo::AbstractKeyListModel * flatModel;
Kleo::AbstractKeyListModel * hierarchicalModel;
Kleo::KeyListController controller;
+ QPointer<ConfigureDialog> configureDialog;
+
struct UI {
TabWidget tabWidget;
ProgressBar progressBar;
explicit UI( MainWindow * q )
: tabWidget( q ),
progressBar( q->statusBar() )
{
KDAB_SET_OBJECT_NAME( tabWidget );
KDAB_SET_OBJECT_NAME( progressBar );
progressBar.setFixedSize( progressBar.sizeHint() );
q->setCentralWidget( &tabWidget );
q->statusBar()->addPermanentWidget( &progressBar );
}
} ui;
};
MainWindow::Private::Private( MainWindow * qq )
: q( qq ),
flatModel( AbstractKeyListModel::createFlatKeyListModel( q ) ),
hierarchicalModel( AbstractKeyListModel::createHierarchicalKeyListModel( q ) ),
controller( q ),
+ configureDialog(),
ui( q )
{
KDAB_SET_OBJECT_NAME( controller );
KDAB_SET_OBJECT_NAME( flatModel );
KDAB_SET_OBJECT_NAME( hierarchicalModel );
controller.setFlatModel( flatModel );
controller.setHierarchicalModel( hierarchicalModel );
controller.setTabWidget( &ui.tabWidget );
ui.tabWidget.setFlatModel( flatModel );
ui.tabWidget.setHierarchicalModel( hierarchicalModel );
setupActions();
connect( &controller, SIGNAL(progress(int,int)), &ui.progressBar, SLOT(setProgress(int,int)) );
connect( &controller, SIGNAL(message(QString,int)), q->statusBar(), SLOT(showMessage(QString,int)) );
connect( &controller, SIGNAL(contextMenuRequested(QAbstractItemView*,QPoint)),
q, SLOT(slotContextMenuRequested(QAbstractItemView*,QPoint)) );
q->createGUI( "kleopatra.rc" );
q->setAcceptDrops( true );
q->setAutoSaveSettings();
}
MainWindow::Private::~Private() {}
MainWindow::MainWindow( QWidget* parent, Qt::WindowFlags flags )
: KXmlGuiWindow( parent, flags ), d( new Private( this ) )
{
}
MainWindow::~MainWindow() {}
void MainWindow::Private::setupActions() {
KActionCollection * const coll = q->actionCollection();
QWidgetAction * const searchBarAction = new QWidgetAction( q );
SearchBar * const searchBar = new SearchBar( q );
ui.tabWidget.connectSearchBar( searchBar );
searchBarAction->setDefaultWidget( searchBar );
coll->addAction( "key_search_bar", searchBarAction );
const action_data action_data[] = {
// File menu
{ "file_new_certificate", i18n("New Certificate..."), QString(),
"document-new", q, SLOT(newCertificate()), "Ctrl+N", false, true },
{ "file_export_certificates", i18n("Export Certificates..."), QString(),
"document-export", q, SLOT(exportCertificates()), "Ctrl+E", false, true },
- { "file_export_certificates_to_server", i18n("Export Certificates to Server..."), QString(),
- "document-export", q, SLOT(exportCertificatesToServer()), "Ctrl+Shift+E", false, true },
- { "file_export_secret_keys", i18n("Export Secret Key..."), QString(),
- "document-export", q, SLOT(exportSecretKey()), QString(), false, true },
{ "file_lookup_certificates", i18n("Lookup Certificates on Server..."), QString(),
"edit-find", q, SLOT(lookupCertificates()), "Shift+Ctrl+I", false, true },
{ "file_import_certificates", i18n("Import Certificates..."), QString(),
"document-import", q, SLOT(importCertificatesFromFile()), "Ctrl+I", false, true },
{ "file_decrypt_verify_files", i18n("Decrypt/Verify Files..."), QString(),
"document-decrypt" /*"file-decrypt-verify"*/, q, SLOT(decryptVerifyFiles()), QString(), false, true },
{ "file_sign_encrypt_files", i18n("Sign/Encrypt Files..."), QString(),
"document-encrypt" /*"file-encrypt-sign"*/, q, SLOT(signEncryptFiles()), QString(), false, true },
// View menu
{ "view_redisplay", i18n("Redisplay"), QString(),
"view-refresh", q, SLOT(reloadCertificates()), "F5", false, true },
{ "view_stop_operations", i18n( "Stop Operation" ), QString(),
"process-stop", &controller, SLOT(cancelCommands()), "Escape", false, false },
{ "view_certificate_details", i18n( "Certificate Details" ), QString(),
0, q, SLOT(certificateDetails()), QString(), false, true },
// Certificate menu
{ "certificates_delete", i18n("Delete" ), QString()/*i18n("Delete selected certificates")*/,
"edit-delete", q, SLOT(deleteCertificates()), "Delete", false, true },
- { "certificates_certify_certificate", i18n("Certify Certificate..."), QString(),
- 0, q, SLOT(certifyCertificate()), QString(), false, true },
+ { "certificates_sign_certificate", i18n("Sign Certificate..."), QString(),
+ 0, q, SLOT(signCertificate()), QString(), false, true },
{ "certificates_change_expiry", i18n("Change Expiry Date..."), QString(),
0, q, SLOT(changeCertificateExpiry()), QString(), false, true },
{ "certificates_change_owner_trust", i18n("Change Owner Trust..."), QString(),
- 0, q, SLOT(changeCertificateOwnerTrust()), QString(), false, true },
- { "certificates_change_passphrase", i18n("Change Passphrase..."), QString(),
- 0, q, SLOT(changePassphrase()), QString(), false, true },
- { "certificates_add_userid", i18n("Add User-ID..."), QString(),
- 0, q, SLOT(addUserID()), QString(), false, true },
- { "certificates_dump_certificate", i18n("Dump Certificate"), QString(),
- 0, q, SLOT(dumpCertificate()), QString(), false, true },
+ 0, q, SLOT(changeCertificateOwnerTrust()), QString(), false, true },
// Tools menu
- { "tools_start_kwatchgnupg", i18n("GnuPG Log Viewer"), QString(),
- "kwatchgnupg", q, SLOT(gnupgLogViewer()), QString(), false, !OS_WIN },
-#if 0
- { "tools_start_kgpgconf", i18n("GnuPG Administrative Console"), QString(),
- "kgpgconf", q, SLOT(gnupgLogViewer()), QString(), false, true },
-#endif
{ "tools_refresh_x509_certificates", i18n("Refresh X.509 Certificates"), QString(),
"view-refresh", q, SLOT(refreshX509Certificates()), QString(), false, true },
{ "tools_refresh_openpgp_certificates", i18n("Refresh OpenPGP Certificates"), QString(),
"view-refresh", q, SLOT(refreshOpenPGPCertificates()), QString(), false, true },
{ "crl_clear_crl_cache", i18n("Clear CRL Cache"), QString(),
0, q, SLOT(clearCrlCache()), QString(), false, true },
{ "crl_dump_crl_cache", i18n("Dump CRL Cache"), QString(),
0, q, SLOT(dumpCrlCache()), QString(), false, true },
{ "crl_import_crl", i18n("Import CRL From File..."), QString(),
0, q, SLOT(importCrlFromFile()), QString(), false, true },
- { "configure_backend", i18n("Configure GnuPG Backend..."), QString(),
- 0, q, SLOT(configureBackend()), QString(), false, true },
// Settings menu
{ "settings_self_test", i18n("Perform Self-Test"), QString(),
0, q, SLOT(selfTest()), QString(), false, true },
+ { "configure_backend", i18n("Configure GnuPG Backend..."), QString(),
+ 0, q, SLOT(configureBackend()), QString(), false, true },
// Window menu
// (come from ui.tabWidget)
};
make_actions_from_data( action_data, /*sizeof action_data / sizeof *action_data,*/ coll );
if ( QAction * action = coll->action( "view_stop_operations" ) )
connect( &controller, SIGNAL(commandsExecuting(bool)), action, SLOT(setEnabled(bool)) );
if ( QAction * action = coll->action( "configure_backend" ) )
action->setMenuRole( QAction::NoRole ); //prevent Qt OS X heuristics for config* actions
KStandardAction::close( q, SLOT(close()), q->actionCollection() );
KStandardAction::quit( q, SLOT(closeAndQuit()), q->actionCollection() );
KStandardAction::configureToolbars( q, SLOT(configureToolbars()), q->actionCollection() );
KStandardAction::keyBindings( q, SLOT(editKeybindings()), q->actionCollection() );
- KStandardAction::preferences( q, SIGNAL(configDialogRequested()), q->actionCollection() );
- q->createStandardStatusBarAction();
- q->setStandardToolBarMenuEnabled( true );
+ KStandardAction::preferences( q, SLOT(preferences()), q->actionCollection() );
// ### somehow make this better...
controller.registerActionForCommand<DetailsCommand>( coll->action( "view_certificate_details" ) );
controller.registerActionForCommand<ReloadKeysCommand>( coll->action( "view_redisplay" ) );
controller.registerActionForCommand<RefreshX509CertsCommand>( coll->action( "view_redisplay" ) );
controller.registerActionForCommand<RefreshOpenPGPCertsCommand>( coll->action( "view_redisplay" ) );
controller.registerActionForCommand<DeleteCertificatesCommand>( coll->action( "certificates_delete" ) );
controller.registerActionForCommand<ChangeExpiryCommand>( coll->action( "certificates_change_expiry" ) );
- controller.registerActionForCommand<ChangeOwnerTrustCommand>( coll->action( "certificates_change_owner_trust" ) );
- controller.registerActionForCommand<ChangePassphraseCommand>( coll->action( "certificates_change_passphrase" ) );
- controller.registerActionForCommand<CertifyCertificateCommand>( coll->action( "certificates_certify_certificate" ) );
- controller.registerActionForCommand<AddUserIDCommand>( coll->action( "certificates_add_userid" ) );
- controller.registerActionForCommand<DumpCertificateCommand>( coll->action( "certificates_dump_certificate" ) );
controller.registerActionForCommand<SignEncryptFilesCommand>( coll->action( "file_sign_encrypt_files" ) );
controller.registerActionForCommand<DecryptVerifyFilesCommand>( coll->action( "file_decrypt_verify_files" ) );
controller.registerActionForCommand<ExportCertificateCommand>( coll->action( "file_export_certificates" ) );
- controller.registerActionForCommand<ExportOpenPGPCertsToServerCommand>( coll->action( "file_export_certificates_to_server" ) );
- controller.registerActionForCommand<ExportSecretKeyCommand>( coll->action( "file_export_secret_keys" ) );
controller.registerActionForCommand<ImportCertificateFromFileCommand>( coll->action( "file_import_certificates" ) );
controller.registerActionForCommand<LookupCertificatesCommand>( coll->action( "file_lookup_certificates" ) );
controller.registerActionForCommand<ClearCrlCacheCommand>( coll->action( "crl_clear_crl_cache" ) );
controller.registerActionForCommand<DumpCrlCacheCommand>( coll->action( "crl_dump_crl_cache" ) );
controller.registerActionForCommand<ImportCrlCommand>( coll->action( "crl_import_crl" ) );
controller.registerActionForCommand<SelfTestCommand>( coll->action( "settings_self_test" ) );
controller.enableDisableActions( 0 );
ui.tabWidget.createActions( coll );
}
void MainWindow::Private::newCertificate() {
- QPointer<NewCertificateWizard> wiz( new NewCertificateWizard( q ) );
+ QPointer<CertificateWizardImpl> wiz( new CertificateWizardImpl( q ) );
wiz->exec();
delete wiz;
}
void MainWindow::Private::configureBackend() {
Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
if ( !config ) {
KMessageBox::error( q, i18n( "Could not configure the cryptography backend (gpgconf tool not found)" ), i18n( "Configuration Error" ) );
return;
}
Kleo::CryptoConfigDialog dlg( config );
const int result = dlg.exec();
// Forget all data parsed from gpgconf, so that we show updated information
// when reopening the configuration dialog.
config->clear();
if ( result == QDialog::Accepted ) {
#if 0
// Tell other apps (e.g. kmail) that the gpgconf data might have changed
QDBusMessage message =
QDBusMessage::createSignal(QString(), "org.kde.kleo.CryptoConfig", "changed");
QDBusConnection::sessionBus().send(message);
#endif
}
}
+void MainWindow::Private::preferences() {
+ if ( !configureDialog ) {
+ configureDialog = new ConfigureDialog( q );
+ configureDialog->setAttribute( Qt::WA_DeleteOnClose );
+ connect( configureDialog, SIGNAL(configCommitted()), q, SLOT(slotConfigCommitted()) );
+ }
+
+ if ( configureDialog->isVisible() )
+ configureDialog->raise();
+ else
+ configureDialog->show();
+}
+
void MainWindow::Private::slotConfigCommitted() {
controller.updateConfig();
}
void MainWindow::closeEvent( QCloseEvent * e ) {
// KMainWindow::closeEvent() insists on quitting the application,
// so do not let it touch the event...
kDebug();
if ( d->controller.hasRunningCommands() ) {
- if ( d->controller.shutdownWarningRequired() ) {
- const int ret = KMessageBox::warningContinueCancel( this, i18n("There are still some background operations ongoing. "
- "These will be terminated when closing the window. "
- "Proceed?"),
- i18n("Ongoing Background Tasks") );
- if ( ret != KMessageBox::Continue ) {
- e->ignore();
- return;
- }
+ const int ret = KMessageBox::warningContinueCancel( this, i18n("There are still some background operations ongoing. "
+ "These will be terminated when closing the window. "
+ "Proceed?"),
+ i18n("Ongoing Background Tasks") );
+ if ( ret != KMessageBox::Continue ) {
+ e->ignore();
+ return;
}
d->controller.cancelCommands();
if ( d->controller.hasRunningCommands() ) {
// wait for them to be finished:
setEnabled( false );
QEventLoop ev;
QTimer::singleShot( 100, &ev, SLOT(quit()) );
connect( &d->controller, SIGNAL(commandsExecuting(bool)), &ev, SLOT(quit()) );
ev.exec();
kWarning( d->controller.hasRunningCommands() )
<< "controller still has commands running, this may crash now...";
setEnabled( true );
}
}
d->ui.tabWidget.saveViews( KGlobal::config().data() );
saveMainWindowSettings( KConfigGroup( KGlobal::config(), autoSaveGroup() ) );
e->accept();
}
void MainWindow::showEvent( QShowEvent * e ) {
KXmlGuiWindow::showEvent( e );
d->ui.tabWidget.loadViews( KGlobal::config().data() );
}
void MainWindow::importCertificatesFromFile( const QStringList & files ) {
if ( !files.empty() )
d->createAndStart<ImportCertificateFromFileCommand>( files );
}
static QStringList extract_local_files( const QMimeData * data ) {
const QList<QUrl> urls = data->urls();
// begin workaround KDE/Qt misinterpretation of text/uri-list
QList<QUrl>::const_iterator end = urls.end();
if ( urls.size() > 1 && !urls.back().isValid() )
--end;
// end workaround
QStringList result;
std::transform( urls.begin(), end,
std::back_inserter( result ),
bind( &QUrl::toLocalFile, _1 ) );
result.erase( std::remove_if( result.begin(), result.end(),
bind( &QString::isEmpty, _1 ) ), result.end() );
return result;
}
static bool can_decode_local_files( const QMimeData * data ) {
if ( !data )
return false;
return !extract_local_files( data ).empty();
}
void MainWindow::dragEnterEvent( QDragEnterEvent * e ) {
kDebug();
- if ( can_decode_local_files( e->mimeData() ) )
+ if ( ( e->possibleActions() & Qt::CopyAction ) &&
+ can_decode_local_files( e->mimeData() ) )
e->acceptProposedAction();
}
void MainWindow::dropEvent( QDropEvent * e ) {
kDebug();
- if ( !can_decode_local_files( e->mimeData() ) )
+ if ( !( e->possibleActions() & Qt::CopyAction ) ||
+ !can_decode_local_files( e->mimeData() ) )
return;
e->setDropAction( Qt::CopyAction );
const QStringList files = extract_local_files( e->mimeData() );
// ### todo: classify further
QMenu menu;
QAction * const signEncrypt = menu.addAction( i18n("Sign/Encrypt...") );
menu.addSeparator();
QAction * const importCerts = menu.addAction( i18n("Import Certificates") );
QAction * const importCRLs = menu.addAction( i18n("Import CRLs") );
menu.addSeparator();
menu.addAction( i18n("Cancel") );
const QAction * const chosen = menu.exec( mapToGlobal( e->pos() ) );
if ( chosen == signEncrypt )
d->createAndStart<SignEncryptFilesCommand>( files );
else if ( chosen == importCerts )
d->createAndStart<ImportCertificateFromFileCommand>( files );
else if ( chosen == importCRLs )
d->createAndStart<ImportCrlCommand>( files );
if ( chosen )
e->accept();
}
#include "mainwindow.moc"
#include "moc_mainwindow.cpp"
diff --git a/mainwindow.h b/mainwindow.h
index a12db7730..c6b1e9e7f 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -1,95 +1,86 @@
/* -*- mode: c++; c-basic-offset:4 -*-
mainwindow.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_MAINWINDOW_H__
#define __KLEOPATRA_MAINWINDOW_H__
#include <KXmlGuiWindow>
#include <utils/pimpl_ptr.h>
class MainWindow : public KXmlGuiWindow {
Q_OBJECT
public:
explicit MainWindow( QWidget * parent=0, Qt::WindowFlags f=KDE_DEFAULT_WINDOWFLAGS );
~MainWindow();
public Q_SLOTS:
void importCertificatesFromFile( const QStringList & files );
-Q_SIGNALS:
- void configDialogRequested();
-
protected:
void closeEvent( QCloseEvent * e );
void showEvent( QShowEvent * e );
void dragEnterEvent( QDragEnterEvent * );
void dropEvent( QDropEvent * );
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void changeCertificateExpiry() )
Q_PRIVATE_SLOT( d, void changeCertificateOwnerTrust() )
- Q_PRIVATE_SLOT( d, void changePassphrase() )
Q_PRIVATE_SLOT( d, void closeAndQuit() )
Q_PRIVATE_SLOT( d, void signEncryptFiles() )
- Q_PRIVATE_SLOT( d, void certifyCertificate() )
+ Q_PRIVATE_SLOT( d, void signCertificate() )
Q_PRIVATE_SLOT( d, void decryptVerifyFiles() )
Q_PRIVATE_SLOT( d, void certificateDetails() )
Q_PRIVATE_SLOT( d, void deleteCertificates() )
Q_PRIVATE_SLOT( d, void importCertificatesFromFile() )
Q_PRIVATE_SLOT( d, void lookupCertificates() )
Q_PRIVATE_SLOT( d, void exportCertificates() )
- Q_PRIVATE_SLOT( d, void exportCertificatesToServer() )
- Q_PRIVATE_SLOT( d, void exportSecretKey() )
Q_PRIVATE_SLOT( d, void reloadCertificates() )
Q_PRIVATE_SLOT( d, void refreshX509Certificates() )
Q_PRIVATE_SLOT( d, void refreshOpenPGPCertificates() )
Q_PRIVATE_SLOT( d, void clearCrlCache() )
Q_PRIVATE_SLOT( d, void dumpCrlCache() )
- Q_PRIVATE_SLOT( d, void dumpCertificate() )
Q_PRIVATE_SLOT( d, void importCrlFromFile() )
Q_PRIVATE_SLOT( d, void newCertificate() )
- Q_PRIVATE_SLOT( d, void addUserID() )
Q_PRIVATE_SLOT( d, void selfTest() )
Q_PRIVATE_SLOT( d, void configureBackend() )
Q_PRIVATE_SLOT( d, void configureToolbars() )
Q_PRIVATE_SLOT( d, void editKeybindings() )
- Q_PRIVATE_SLOT( d, void gnupgLogViewer() )
- Q_PRIVATE_SLOT( d, void gnupgAdministrativeConsole() )
+ Q_PRIVATE_SLOT( d, void preferences() )
Q_PRIVATE_SLOT( d, void slotConfigCommitted() )
Q_PRIVATE_SLOT( d, void slotContextMenuRequested(QAbstractItemView*,QPoint) )
};
#endif /* __KLEOPATRA_MAINWINDOW_H__ */
diff --git a/models/keycache.cpp b/models/keycache.cpp
index 15758db2f..1b2874a73 100644
--- a/models/keycache.cpp
+++ b/models/keycache.cpp
@@ -1,915 +1,823 @@
/* -*- mode: c++; c-basic-offset:4 -*-
models/keycache.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2007,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 "keycache.h"
#include "keycache_p.h"
#include "predicates.h"
#include "smimevalidationpreferences.h"
#include <utils/filesystemwatcher.h>
#include <utils/stl_util.h>
#include <kleo/cryptobackendfactory.h>
#include <kleo/dn.h>
#include <kleo/keylistjob.h>
#include <gpgme++/error.h>
#include <gpgme++/key.h>
#include <gpgme++/decryptionresult.h>
#include <gpgme++/verificationresult.h>
#include <gpgme++/keylistresult.h>
#include <gpg-error.h>
#include <QPointer>
#include <QStringList>
#include <QTimer>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/weak_ptr.hpp>
-#include <boost/iterator/filter_iterator.hpp>
#include <deque>
#include <utility>
#include <algorithm>
#include <functional>
#include <iterator>
using namespace Kleo;
using namespace GpgME;
using namespace boost;
static const unsigned int hours2ms = 1000 * 60 * 60;
//
//
// KeyCache
//
//
namespace {
make_comparator_str( ByEMail, .first.c_str() );
struct is_empty : std::unary_function<const char*,bool> {
bool operator()( const char * s ) const { return !s || !*s; }
};
template <typename ForwardIterator, typename BinaryPredicate>
ForwardIterator unique_by_merge( ForwardIterator first, ForwardIterator last, BinaryPredicate pred ) {
first = std::adjacent_find( first, last, pred );
if ( first == last )
return last;
ForwardIterator dest = first;
dest->mergeWith( *++first );
while ( ++first != last )
if ( pred( *dest, *first ) )
dest->mergeWith( *first );
else
*++dest = *first;
return ++dest;
}
}
class KeyCache::Private {
friend class ::Kleo::KeyCache;
KeyCache * const q;
public:
explicit Private( KeyCache * qq ) : q( qq ) {
connect( &m_autoKeyListingTimer, SIGNAL( timeout() ), q, SLOT( startKeyListing() ) );
updateAutoKeyListingTimer();
}
- template < template <template <typename U> class Op> class Comp>
+ template < template <template <typename U> class Op> class Comp >
std::vector<Key>::const_iterator find( const std::vector<Key> & keys, const char * key ) const {
const std::vector<Key>::const_iterator it =
std::lower_bound( keys.begin(), keys.end(), key, Comp<std::less>() );
if ( it == keys.end() || Comp<std::equal_to>()( *it, key ) )
return it;
else
return keys.end();
}
- template < template <template <typename U> class Op> class Comp>
- std::vector<Subkey>::const_iterator find( const std::vector<Subkey> & keys, const char * key ) const {
- const std::vector<Subkey>::const_iterator it =
- std::lower_bound( keys.begin(), keys.end(), key, Comp<std::less>() );
- if ( it == keys.end() || Comp<std::equal_to>()( *it, key ) )
- return it;
- else
- return keys.end();
- }
-
std::vector<Key>::const_iterator find_fpr( const char * fpr ) const {
return find<_detail::ByFingerprint>( by.fpr, fpr );
}
std::pair< std::vector< std::pair<std::string,Key> >::const_iterator,
std::vector< std::pair<std::string,Key> >::const_iterator >
find_email( const char * email ) const {
return std::equal_range( by.email.begin(), by.email.end(),
email, ByEMail<std::less>() );
}
- std::vector<Subkey>::const_iterator find_subkeyid( const char * subkeyid ) const {
- return find<_detail::ByKeyID>( by.subkeyid, subkeyid );
- }
-
std::vector<Key>::const_iterator find_keyid( const char * keyid ) const {
return find<_detail::ByKeyID>( by.keyid, keyid );
}
std::vector<Key>::const_iterator find_shortkeyid( const char * shortkeyid ) const {
return find<_detail::ByShortKeyID>( by.shortkeyid, shortkeyid );
}
std::pair<
std::vector<Key>::const_iterator,
std::vector<Key>::const_iterator
> find_subjects( const char * chain_id ) const {
return std::equal_range( by.chainid.begin(), by.chainid.end(),
chain_id, _detail::ByChainID<std::less>() );
}
void refreshJobDone( const KeyListResult & result );
void updateAutoKeyListingTimer() {
setAutoKeyListingInterval( hours2ms * SMimeValidationPreferences().refreshInterval() );
}
void setAutoKeyListingInterval( int ms ) {
m_autoKeyListingTimer.stop();
m_autoKeyListingTimer.setInterval( ms );
if ( ms != 0 )
m_autoKeyListingTimer.start();
}
private:
QPointer<RefreshKeysJob> m_refreshJob;
std::vector<shared_ptr<FileSystemWatcher> > m_fsWatchers;
QTimer m_autoKeyListingTimer;
struct By {
std::vector<Key> fpr, keyid, shortkeyid, chainid;
std::vector< std::pair<std::string,Key> > email;
- std::vector<Subkey> subkeyid;
} by;
};
shared_ptr<const KeyCache> KeyCache::instance() {
return mutableInstance();
}
shared_ptr<KeyCache> KeyCache::mutableInstance() {
static weak_ptr<KeyCache> self;
try {
return shared_ptr<KeyCache>( self );
} catch ( const bad_weak_ptr & ) {
const shared_ptr<KeyCache> s( new KeyCache );
self = s;
return s;
}
}
KeyCache::KeyCache()
: QObject(), d( new Private( this ) )
{
}
KeyCache::~KeyCache() {}
void KeyCache::startKeyListing()
{
if ( d->m_refreshJob )
return;
d->updateAutoKeyListingTimer();
Q_FOREACH( const shared_ptr<FileSystemWatcher>& i, d->m_fsWatchers )
i->setEnabled( false );
d->m_refreshJob = new RefreshKeysJob( this );
connect( d->m_refreshJob, SIGNAL(done(GpgME::KeyListResult)), this, SLOT(refreshJobDone(GpgME::KeyListResult)) );
d->m_refreshJob->start();
}
void KeyCache::cancelKeyListing()
{
if ( !d->m_refreshJob )
return;
d->m_refreshJob->cancel();
}
void KeyCache::addFileSystemWatcher( const shared_ptr<FileSystemWatcher>& watcher )
{
if ( !watcher )
return;
d->m_fsWatchers.push_back( watcher );
connect( watcher.get(), SIGNAL( directoryChanged( QString ) ),
this, SLOT( startKeyListing() ) );
connect( watcher.get(), SIGNAL( fileChanged( QString ) ),
this, SLOT( startKeyListing() ) );
watcher->setEnabled( d->m_refreshJob == 0 );
}
void KeyCache::Private::refreshJobDone( const KeyListResult& result )
{
emit q->keyListingDone( result );
Q_FOREACH( const shared_ptr<FileSystemWatcher>& i, m_fsWatchers )
i->setEnabled( true );
}
const Key & KeyCache::findByFingerprint( const char * fpr ) const {
const std::vector<Key>::const_iterator it = d->find_fpr( fpr );
if ( it == d->by.fpr.end() ) {
static const Key null;
return null;
} else {
return *it;
}
}
std::vector<Key> KeyCache::findByFingerprint( const std::vector<std::string> & fprs ) const {
std::vector<std::string> sorted;
sorted.reserve( fprs.size() );
std::remove_copy_if( fprs.begin(), fprs.end(), std::back_inserter( sorted ),
bind( is_empty(), bind( &std::string::c_str, _1 ) ) );
std::sort( sorted.begin(), sorted.end(), _detail::ByFingerprint<std::less>() );
std::vector<Key> result;
kdtools::set_intersection( d->by.fpr.begin(), d->by.fpr.end(),
sorted.begin(), sorted.end(),
std::back_inserter( result ),
_detail::ByFingerprint<std::less>() );
return result;
}
std::vector<Key> KeyCache::findByEMailAddress( const char * email ) const {
const std::pair<
std::vector< std::pair<std::string,Key> >::const_iterator,
std::vector< std::pair<std::string,Key> >::const_iterator
> pair = d->find_email( email );
std::vector<Key> result;
result.reserve( std::distance( pair.first, pair.second ) );
std::transform( pair.first, pair.second,
std::back_inserter( result ),
bind( &std::pair<std::string,Key>::second, _1 ) );
return result;
}
std::vector<Key> KeyCache::findByEMailAddress( const std::string & email ) const {
return findByEMailAddress( email.c_str() );
}
const Key & KeyCache::findByShortKeyID( const char * id ) const {
const std::vector<Key>::const_iterator it = d->find_shortkeyid( id );
if ( it != d->by.shortkeyid.end() )
return *it;
static const Key null;
return null;
}
const Key & KeyCache::findByKeyIDOrFingerprint( const char * id ) const {
{
// try by.fpr first:
const std::vector<Key>::const_iterator it = d->find_fpr( id );
if ( it != d->by.fpr.end() )
return *it;
}{
// try by.keyid next:
const std::vector<Key>::const_iterator it = d->find_keyid( id );
if ( it != d->by.keyid.end() )
return *it;
}
static const Key null;
return null;
}
std::vector<Key> KeyCache::findByKeyIDOrFingerprint( const std::vector<std::string> & ids ) const {
std::vector<std::string> keyids;
std::remove_copy_if( ids.begin(), ids.end(), std::back_inserter( keyids ),
bind( is_empty(), bind( &std::string::c_str, _1 ) ) );
// this is just case-insensitive string search:
std::sort( keyids.begin(), keyids.end(), _detail::ByFingerprint<std::less>() );
std::vector<Key> result;
result.reserve( keyids.size() ); // dups shouldn't happen
kdtools::set_intersection( d->by.fpr.begin(), d->by.fpr.end(),
keyids.begin(), keyids.end(),
std::back_inserter( result ),
_detail::ByFingerprint<std::less>() );
- if ( result.size() < keyids.size() ) {
+ if ( result.size() < keyids.size() )
// note that By{Fingerprint,KeyID,ShortKeyID} define the same
// order for _strings_
kdtools::set_intersection( d->by.keyid.begin(), d->by.keyid.end(),
keyids.begin(), keyids.end(),
std::back_inserter( result ),
_detail::ByKeyID<std::less>() );
- }
+
// duplicates shouldn't happen, but make sure nonetheless:
std::sort( result.begin(), result.end(), _detail::ByFingerprint<std::less>() );
result.erase( std::unique( result.begin(), result.end(), _detail::ByFingerprint<std::equal_to>() ), result.end() );
// we skip looking into short key ids here, as it's highly
// unlikely they're used for this purpose. We might need to revise
// this decision, but only after testing.
return result;
}
-
-std::vector<Subkey> KeyCache::findSubkeysByKeyID( const std::vector<std::string> & ids ) const {
- std::vector<std::string> sorted;
- sorted.reserve( ids.size() );
- std::remove_copy_if( ids.begin(), ids.end(), std::back_inserter( sorted ),
- bind( is_empty(), bind( &std::string::c_str, _1 ) ) );
-
- std::sort( sorted.begin(), sorted.end(), _detail::ByKeyID<std::less>() );
-
- std::vector<Subkey> result;
- kdtools::set_intersection( d->by.subkeyid.begin(), d->by.subkeyid.end(),
- sorted.begin(), sorted.end(),
- std::back_inserter( result ),
- _detail::ByKeyID<std::less>() );
- return result;
-}
-
std::vector<Key> KeyCache::findRecipients( const DecryptionResult & res ) const {
std::vector<std::string> keyids;
Q_FOREACH( const DecryptionResult::Recipient & r, res.recipients() )
keyids.push_back( r.keyID() );
- const std::vector<Subkey> subkeys = findSubkeysByKeyID( keyids );
- std::vector<Key> result;
- result.reserve( subkeys.size() );
- std::transform( subkeys.begin(), subkeys.end(), std::back_inserter( result ), bind( &Subkey::parent, _1 ) );
-
- std::sort( result.begin(), result.end(), _detail::ByFingerprint<std::less>() );
- result.erase( std::unique( result.begin(), result.end(), _detail::ByFingerprint<std::equal_to>() ), result.end() );
- return result;
+ return findByKeyIDOrFingerprint( keyids );
}
std::vector<Key> KeyCache::findSigners( const VerificationResult & res ) const {
std::vector<std::string> fprs;
Q_FOREACH( const Signature & s, res.signatures() )
fprs.push_back( s.fingerprint() );
return findByKeyIDOrFingerprint( fprs );
}
-std::vector<Key> KeyCache::findSubjects( const GpgME::Key & key, Options options ) const {
+std::vector<Key> KeyCache::findSubjects( const GpgME::Key & key, Option options ) const {
return findSubjects( std::vector<Key>( 1, key ), options );
}
-std::vector<Key> KeyCache::findSubjects( const std::vector<Key> & keys, Options options ) const {
+std::vector<Key> KeyCache::findSubjects( const std::vector<Key> & keys, Option options ) const {
return findSubjects( keys.begin(), keys.end(), options );
}
-std::vector<Key> KeyCache::findSubjects( std::vector<Key>::const_iterator first, std::vector<Key>::const_iterator last, Options options ) const {
+std::vector<Key> KeyCache::findSubjects( std::vector<Key>::const_iterator first, std::vector<Key>::const_iterator last, Option options ) const {
if ( first == last )
return std::vector<Key>();
std::vector<Key> result;
while ( first != last ) {
const std::pair<
std::vector<Key>::const_iterator,
std::vector<Key>::const_iterator
> pair = d->find_subjects( first->primaryFingerprint() );
result.insert( result.end(), pair.first, pair.second );
++first;
}
std::sort( result.begin(), result.end(), _detail::ByFingerprint<std::less>() );
result.erase( std::unique( result.begin(), result.end(), _detail::ByFingerprint<std::equal_to>() ), result.end() );
if ( options & RecursiveSearch )
return findSubjects( result, options );
else
return result;
}
static const unsigned int LIKELY_CHAIN_DEPTH = 3;
-std::vector<Key> KeyCache::findIssuers( const Key & key, Options options ) const {
-
- if ( key.isNull() )
- return std::vector<Key>();
-
- std::vector<Key> result;
- if ( options & IncludeSubject )
- result.push_back( key );
-
- if ( key.isRoot() )
- return result;
+std::vector<Key> KeyCache::findIssuers( const Key & key, Option options ) const {
const Key & issuer = findByFingerprint( key.chainID() );
if ( issuer.isNull() )
- return result;
-
- result.push_back( issuer );
+ return std::vector<Key>();
+ std::vector<Key> result( 1, issuer );
if ( !( options & RecursiveSearch ) )
return result;
- while ( !result.back().isNull() && !result.back().isRoot() )
+ do {
result.push_back( findByFingerprint( result.back().chainID() ) );
-
- if ( result.back().isNull() )
- result.pop_back();
+ } while ( !result.back().isNull() );
+ result.pop_back();
return result;
}
-std::vector<Key> KeyCache::findIssuers( const std::vector<Key> & keys, Options options ) const {
+std::vector<Key> KeyCache::findIssuers( const std::vector<Key> & keys, Option options ) const {
return findIssuers( keys.begin(), keys.end(), options );
}
-std::vector<Key> KeyCache::findIssuers( std::vector<Key>::const_iterator first, std::vector<Key>::const_iterator last, Options options ) const {
+std::vector<Key> KeyCache::findIssuers( std::vector<Key>::const_iterator first, std::vector<Key>::const_iterator last, Option options ) const {
if ( first == last )
return std::vector<Key>();
// extract chain-ids, identifying issuers:
std::vector<const char *> chainIDs;
chainIDs.reserve( last - first );
- std::transform( boost::make_filter_iterator( !bind( &Key::isRoot, _1 ), first, last ),
- boost::make_filter_iterator( !bind( &Key::isRoot, _1 ), last, last ),
+ std::transform( first, last,
std::back_inserter( chainIDs ),
bind( &Key::chainID, _1 ) );
std::sort( chainIDs.begin(), chainIDs.end(), _detail::ByFingerprint<std::less>() );
const std::vector<const char*>::iterator lastUniqueChainID = std::unique( chainIDs.begin(), chainIDs.end(), _detail::ByFingerprint<std::less>() );
std::vector<Key> result;
result.reserve( lastUniqueChainID - chainIDs.begin() );
kdtools::set_intersection( d->by.fpr.begin(), d->by.fpr.end(),
chainIDs.begin(), lastUniqueChainID,
std::back_inserter( result ),
_detail::ByFingerprint<std::less>() );
- if ( options & IncludeSubject ) {
- const unsigned int rs = result.size();
- result.insert( result.end(), first, last );
- std::inplace_merge( result.begin(), result.begin() + rs, result.end(),
- _detail::ByFingerprint<std::less>() );
- }
-
if ( !( options & RecursiveSearch ) )
return result;
- const std::vector<Key> l2result = findIssuers( result, options & ~IncludeSubject );
+ const std::vector<Key> l2result = findIssuers( result, options );
const unsigned long result_size = result.size();
result.insert( result.end(), l2result.begin(), l2result.end() );
std::inplace_merge( result.begin(), result.begin() + result_size, result.end(),
_detail::ByFingerprint<std::less>() );
return result;
}
static std::string email( const UserID & uid ) {
const std::string email = uid.email();
if ( email.empty() )
return DN( uid.id() )["EMAIL"].trimmed().toUtf8().constData();
if ( email[0] == '<' && email[email.size()-1] == '>' )
return email.substr( 1, email.size() - 2 );
else
return email;
}
static std::vector<std::string> emails( const Key & key ) {
std::vector<std::string> emails;
Q_FOREACH( const UserID & uid, key.userIDs() ) {
const std::string e = email( uid );
if ( !e.empty() )
emails.push_back( e );
}
std::sort( emails.begin(), emails.end() );
emails.erase( std::unique( emails.begin(), emails.end() ), emails.end() );
return emails;
}
void KeyCache::remove( const Key & key ) {
if ( key.isNull() )
return;
const char * fpr = key.primaryFingerprint();
if ( !fpr )
return;
emit aboutToRemove( key );
-
+
{
const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
= std::equal_range( d->by.fpr.begin(), d->by.fpr.end(), fpr,
_detail::ByFingerprint<std::less>() );
d->by.fpr.erase( range.first, range.second );
}
if ( const char * keyid = key.keyID() ) {
const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
= std::equal_range( d->by.keyid.begin(), d->by.keyid.end(), keyid,
_detail::ByKeyID<std::less>() );
const std::vector<Key>::iterator it
= std::remove_if( begin( range ), end( range ), bind( _detail::ByFingerprint<std::equal_to>(), fpr, _1 ) );
d->by.keyid.erase( it, end( range ) );
}
if ( const char * shortkeyid = key.shortKeyID() ) {
const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
= std::equal_range( d->by.shortkeyid.begin(), d->by.shortkeyid.end(), shortkeyid,
_detail::ByShortKeyID<std::less>() );
const std::vector<Key>::iterator it
= std::remove_if( begin( range ), end( range ), bind( _detail::ByFingerprint<std::equal_to>(), fpr, _1 ) );
d->by.shortkeyid.erase( it, end( range ) );
}
if ( const char * chainid = key.chainID() ) {
const std::pair<std::vector<Key>::iterator,std::vector<Key>::iterator> range
= std::equal_range( d->by.chainid.begin(), d->by.chainid.end(), chainid,
_detail::ByChainID<std::less>() );
const std::pair< std::vector<Key>::iterator, std::vector<Key>::iterator > range2
= std::equal_range( begin( range ), end( range ), fpr, _detail::ByFingerprint<std::less>() );
d->by.chainid.erase( begin( range2 ), end( range2 ) );
}
-
+
Q_FOREACH( const std::string & email, emails( key ) ) {
const std::pair<std::vector<std::pair<std::string,Key> >::iterator,std::vector<std::pair<std::string,Key> >::iterator> range
= std::equal_range( d->by.email.begin(), d->by.email.end(), email, ByEMail<std::less>() );
const std::vector< std::pair<std::string,Key> >::iterator it
= std::remove_if( begin( range ), end( range ), bind( qstricmp, fpr, bind( &Key::primaryFingerprint, bind( &std::pair<std::string,Key>::second,_1 ) ) ) == 0 );
d->by.email.erase( it, end( range ) );
- }
-
- Q_FOREACH( const Subkey & subkey, key.subkeys() ) {
- if ( const char * keyid = subkey.keyID() ) {
- const std::pair<std::vector<Subkey>::iterator,std::vector<Subkey>::iterator> range
- = std::equal_range( d->by.subkeyid.begin(), d->by.subkeyid.end(), keyid,
- _detail::ByKeyID<std::less>() );
- const std::pair< std::vector<Subkey>::iterator, std::vector<Subkey>::iterator > range2
- = std::equal_range( begin( range ), end( range ), fpr, _detail::ByKeyID<std::less>() );
- d->by.subkeyid.erase( begin( range2 ), end( range2 ) );
- }
- }
+ }
}
void KeyCache::remove( const std::vector<Key> & keys ) {
Q_FOREACH( const Key & key, keys )
remove( key );
}
std::vector<GpgME::Key> KeyCache::keys() const
{
return d->by.fpr;
}
std::vector<Key> KeyCache::secretKeys() const
{
std::vector<Key> keys = this->keys();
- keys.erase( std::remove_if( keys.begin(), keys.end(), !bind( &Key::hasSecret, _1 ) ), keys.end() );
+ keys.erase( std::remove_if( keys.begin(), keys.end(), !bind( &Key::hasSecret, _1 ) ) );
return keys;
}
void KeyCache::refresh( const std::vector<Key> & keys ) {
// make this better...
clear();
insert( keys );
}
void KeyCache::insert( const Key & key ) {
insert( std::vector<Key>( 1, key ) );
}
namespace {
template <
template <template <typename T> class Op> class T1,
template <template <typename T> class Op> class T2
> struct lexicographically {
typedef bool result_type;
template <typename U, typename V>
bool operator()( const U & lhs, const V & rhs ) const {
return
T1<std::less>()( lhs, rhs ) ||
T1<std::equal_to>()( lhs, rhs ) &&
T2<std::less>()( lhs, rhs )
;
}
};
}
void KeyCache::insert( const std::vector<Key> & keys ) {
// 1. remove those with empty fingerprints:
std::vector<Key> sorted;
sorted.reserve( keys.size() );
std::remove_copy_if( keys.begin(), keys.end(),
std::back_inserter( sorted ),
bind( is_empty(), bind( &Key::primaryFingerprint, _1 ) ) );
Q_FOREACH( const Key & key, sorted )
- remove( key ); // this is sub-optimal, but makes implementation from here on much easier
+ remove( key ); // this is sub-optimal, but makes implementation from here on much easier
// 2. sort by fingerprint:
std::sort( sorted.begin(), sorted.end(), _detail::ByFingerprint<std::less>() );
// 2a. insert into fpr index:
std::vector<Key> by_fpr;
by_fpr.reserve( sorted.size() + d->by.fpr.size() );
std::merge( sorted.begin(), sorted.end(),
d->by.fpr.begin(), d->by.fpr.end(),
std::back_inserter( by_fpr ),
_detail::ByFingerprint<std::less>() );
// 3. build email index:
std::vector< std::pair<std::string,Key> > pairs;
pairs.reserve( sorted.size() );
Q_FOREACH( const Key & key, sorted ) {
const std::vector<std::string> emails = ::emails( key );
std::vector< std::pair<std::string,Key> > tmp, merge_tmp;
tmp.reserve( emails.size() );
Q_FOREACH( const std::string & e, emails )
pairs.push_back( std::make_pair( e, key ) );
merge_tmp.reserve( tmp.size() + pairs.size() );
std::merge( pairs.begin(), pairs.end(),
tmp.begin(), tmp.end(),
std::back_inserter( merge_tmp ),
ByEMail<std::less>() );
pairs.swap( merge_tmp );
}
// 3a. insert into email index:
std::vector< std::pair<std::string,Key> > by_email;
by_email.reserve( pairs.size() + d->by.email.size() );
std::merge( pairs.begin(), pairs.end(),
d->by.email.begin(), d->by.email.end(),
std::back_inserter( by_email ),
ByEMail<std::less>() );
// 3.5: stable-sort by chain-id (effectively lexicographically<ByChainID,ByFingerprint>)
std::stable_sort( sorted.begin(), sorted.end(), _detail::ByChainID<std::less>() );
-
+
// 3.5a: insert into chain-id index:
std::vector<Key> by_chainid;
by_chainid.reserve( sorted.size() + d->by.chainid.size() );
std::merge( sorted.begin(), sorted.end(),
d->by.chainid.begin(), d->by.chainid.end(),
std::back_inserter( by_chainid ),
lexicographically<_detail::ByChainID,_detail::ByFingerprint>() );
// 4. sort by key id:
std::sort( sorted.begin(), sorted.end(), _detail::ByKeyID<std::less>() );
// 4a. insert into keyid index:
std::vector<Key> by_keyid;
by_keyid.reserve( sorted.size() + d->by.keyid.size() );
std::merge( sorted.begin(), sorted.end(),
d->by.keyid.begin(), d->by.keyid.end(),
std::back_inserter( by_keyid ),
_detail::ByKeyID<std::less>() );
// 5. sort by short key id:
std::sort( sorted.begin(), sorted.end(), _detail::ByShortKeyID<std::less>() );
// 5a. insert into short keyid index:
std::vector<Key> by_shortkeyid;
by_shortkeyid.reserve( sorted.size() + d->by.shortkeyid.size() );
std::merge( sorted.begin(), sorted.end(),
d->by.shortkeyid.begin(), d->by.shortkeyid.end(),
std::back_inserter( by_shortkeyid ),
_detail::ByShortKeyID<std::less>() );
- // 6. build subkey ID index:
- std::vector<Subkey> subkeys;
- subkeys.reserve( sorted.size() );
- Q_FOREACH( const Key & key, sorted )
- Q_FOREACH( const Subkey & subkey, key.subkeys() )
- subkeys.push_back( subkey );
-
- // 6a sort by key id:
- std::sort( subkeys.begin(), subkeys.end(), _detail::ByKeyID<std::less>() );
-
- // 6b. insert into subkey ID index:
- std::vector<Subkey> by_subkeyid;
- by_email.reserve( subkeys.size() + d->by.subkeyid.size() );
- std::merge( subkeys.begin(), subkeys.end(),
- d->by.subkeyid.begin(), d->by.subkeyid.end(),
- std::back_inserter( by_subkeyid ),
- _detail::ByKeyID<std::less>() );
-
// now commit (well, we already removed keys...)
by_fpr.swap( d->by.fpr );
by_keyid.swap( d->by.keyid );
by_shortkeyid.swap( d->by.shortkeyid );
by_email.swap( d->by.email );
- by_subkeyid.swap( d->by.subkeyid );
Q_FOREACH( const Key & key, sorted )
- emit added( key );
-
- emit keysMayHaveChanged();
+ emit added( key );
}
void KeyCache::clear() {
d->by = Private::By();
}
//
//
// RefreshKeysJob
//
//
class KeyCache::RefreshKeysJob::Private
{
RefreshKeysJob * const q;
public:
enum KeyType {
PublicKeys,
SecretKeys
};
-
+
Private( KeyCache * cache, RefreshKeysJob * qq );
void doStart();
Error startKeyListing( const char* protocol, KeyType type );
void jobDone( const KeyListResult & res );
void emitDone( const KeyListResult & result );
void nextSecretKey( const Key & key );
void nextPublicKey( const Key & key );
void mergeKeysAndUpdateKeyCache();
KeyCache * m_cache;
uint m_jobsPending;
std::deque<Key> m_publicKeys;
std::deque<Key> m_secretKeys;
KeyListResult m_mergedResult;
};
KeyCache::RefreshKeysJob::Private::Private( KeyCache * cache, RefreshKeysJob * qq ) : q( qq ), m_cache( cache ), m_jobsPending( 0 )
{
assert( m_cache );
}
void KeyCache::RefreshKeysJob::Private::jobDone( const KeyListResult & result )
{
QObject* const sender = q->sender();
if ( sender )
sender->disconnect( q );
assert( m_jobsPending > 0 );
--m_jobsPending;
m_mergedResult.mergeWith( result );
if ( m_jobsPending > 0 )
return;
mergeKeysAndUpdateKeyCache();
emitDone( m_mergedResult );
}
void KeyCache::RefreshKeysJob::Private::emitDone( const KeyListResult & res )
{
q->deleteLater();
emit q->done( res );
}
void KeyCache::RefreshKeysJob::Private::nextSecretKey( const Key & key )
{
m_secretKeys.push_back( key );
}
void KeyCache::RefreshKeysJob::Private::nextPublicKey( const Key & key )
{
m_publicKeys.push_back( key );
}
KeyCache::RefreshKeysJob::RefreshKeysJob( KeyCache * cache, QObject * parent ) : QObject( parent ), d( new Private( cache, this ) )
{
}
KeyCache::RefreshKeysJob::~RefreshKeysJob() {}
void KeyCache::RefreshKeysJob::start()
{
QTimer::singleShot( 0, this, SLOT( doStart() ) );
}
void KeyCache::RefreshKeysJob::cancel()
{
emit canceled();
}
void KeyCache::RefreshKeysJob::Private::doStart()
{
assert( m_jobsPending == 0 );
m_mergedResult.mergeWith( KeyListResult( startKeyListing( "openpgp", PublicKeys ) ) );
- m_mergedResult.mergeWith( KeyListResult( startKeyListing( "smime", PublicKeys ) ) );
m_mergedResult.mergeWith( KeyListResult( startKeyListing( "openpgp", SecretKeys ) ) );
+ m_mergedResult.mergeWith( KeyListResult( startKeyListing( "smime", PublicKeys ) ) );
m_mergedResult.mergeWith( KeyListResult( startKeyListing( "smime", SecretKeys ) ) );
-
+
if ( m_jobsPending != 0 )
return;
const bool hasError = m_mergedResult.error() || m_mergedResult.error().isCanceled();
emitDone( hasError ? m_mergedResult : KeyListResult( Error( GPG_ERR_UNSUPPORTED_OPERATION ) ) );
}
void KeyCache::RefreshKeysJob::Private::mergeKeysAndUpdateKeyCache()
{
std::sort( m_publicKeys.begin(), m_publicKeys.end(), _detail::ByFingerprint<std::less>() );
std::sort( m_secretKeys.begin(), m_secretKeys.end(), _detail::ByFingerprint<std::less>() );
std::vector<Key> keys;
keys.reserve( m_publicKeys.size() + m_secretKeys.size() );
std::merge( m_publicKeys.begin(), m_publicKeys.end(),
m_secretKeys.begin(), m_secretKeys.end(),
std::back_inserter( keys ),
_detail::ByFingerprint<std::less>() );
keys.erase( unique_by_merge( keys.begin(), keys.end(), _detail::ByFingerprint<std::equal_to>() ),
keys.end() );
std::vector<Key> cachedKeys = m_cache->keys();
std::sort( cachedKeys.begin(), cachedKeys.end(), _detail::ByFingerprint<std::less>() );
std::vector<Key> keysToRemove;
std::set_difference( cachedKeys.begin(), cachedKeys.end(), keys.begin(), keys.end(), std::back_inserter( keysToRemove ), _detail::ByFingerprint<std::less>() );
m_cache->remove( keysToRemove );
m_cache->refresh( keys );
}
Error KeyCache::RefreshKeysJob::Private::startKeyListing( const char* backend, KeyType type )
{
const Kleo::CryptoBackend::Protocol * const protocol = Kleo::CryptoBackendFactory::instance()->protocol( backend );
if ( !protocol )
return Error();
Kleo::KeyListJob * const job = protocol->keyListJob( /*remote*/false, /*includeSigs*/false, /*validate*/true );
if ( !job )
return Error();
connect( job, SIGNAL(result(GpgME::KeyListResult)),
q, SLOT(jobDone(GpgME::KeyListResult)) );
#if 0
connect( job, SIGNAL(progress(QString,int,int)),
q, SIGNAL(progress(QString,int,int)) );
#endif
connect( q, SIGNAL(canceled()),
job, SLOT(slotCancel()) );
if ( type == PublicKeys )
connect( job, SIGNAL(nextKey(GpgME::Key)),
q, SLOT(nextPublicKey(GpgME::Key)) );
else
connect( job, SIGNAL(nextKey(GpgME::Key)),
q, SLOT(nextSecretKey(GpgME::Key)) );
-
+
const Error error = job->start( QStringList(), type == SecretKeys );
-
+
if ( !error && !error.isCanceled() )
++m_jobsPending;
return error;
}
#include "moc_keycache_p.cpp"
#include "moc_keycache.cpp"
diff --git a/models/keycache.h b/models/keycache.h
index 2c6c17f88..113d227c1 100644
--- a/models/keycache.h
+++ b/models/keycache.h
@@ -1,145 +1,136 @@
/* -*- mode: c++; c-basic-offset:4 -*-
models/keycache.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_MODELS_KEYCACHE_H__
#define __KLEOPATRA_MODELS_KEYCACHE_H__
#include <QObject>
#include <utils/pimpl_ptr.h>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
namespace GpgME {
class Key;
class DecryptionResult;
class VerificationResult;
class KeyListResult;
- class Subkey;
}
namespace Kleo {
class FileSystemWatcher;
class KeyCache : public QObject {
Q_OBJECT
protected:
explicit KeyCache();
public:
static boost::shared_ptr<const KeyCache> instance();
static boost::shared_ptr<KeyCache> mutableInstance();
~KeyCache();
void insert( const GpgME::Key & key );
void insert( const std::vector<GpgME::Key> & keys );
void refresh( const std::vector<GpgME::Key> & keys );
void remove( const GpgME::Key & key );
void remove( const std::vector<GpgME::Key> & keys );
void addFileSystemWatcher( const boost::shared_ptr<FileSystemWatcher>& watcher );
std::vector<GpgME::Key> keys() const;
std::vector<GpgME::Key> secretKeys() const;
const GpgME::Key & findByFingerprint( const char * fpr ) const;
const GpgME::Key & findByFingerprint( const std::string & fpr ) const {
return findByFingerprint( fpr.c_str() );
}
std::vector<GpgME::Key> findByFingerprint( const std::vector<std::string> & fprs ) const;
std::vector<GpgME::Key> findByEMailAddress( const char * email ) const;
std::vector<GpgME::Key> findByEMailAddress( const std::string & email ) const;
const GpgME::Key & findByShortKeyID( const char * id ) const;
const GpgME::Key & findByShortKeyID( const std::string & id ) const {
return findByShortKeyID( id.c_str() );
}
const GpgME::Key & findByKeyIDOrFingerprint( const char * id ) const;
const GpgME::Key & findByKeyIDOrFingerprint( const std::string & id ) const {
return findByKeyIDOrFingerprint( id.c_str() );
}
std::vector<GpgME::Key> findByKeyIDOrFingerprint( const std::vector<std::string> & ids ) const;
- std::vector<GpgME::Subkey> findSubkeysByKeyID( const std::vector<std::string> & ids ) const;
-
std::vector<GpgME::Key> findRecipients( const GpgME::DecryptionResult & result ) const;
std::vector<GpgME::Key> findSigners( const GpgME::VerificationResult & result ) const;
enum Option {
NoOption = 0,
- RecursiveSearch = 1,
- IncludeSubject = 2
+ RecursiveSearch = 1
};
- Q_DECLARE_FLAGS( Options, Option )
- std::vector<GpgME::Key> findSubjects( const GpgME::Key & key, Options option=RecursiveSearch ) const;
- std::vector<GpgME::Key> findSubjects( const std::vector<GpgME::Key> & keys, Options options=RecursiveSearch ) const;
- std::vector<GpgME::Key> findSubjects( std::vector<GpgME::Key>::const_iterator first, std::vector<GpgME::Key>::const_iterator last, Options options=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findSubjects( const GpgME::Key & key, Option option=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findSubjects( const std::vector<GpgME::Key> & keys, Option options=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findSubjects( std::vector<GpgME::Key>::const_iterator first, std::vector<GpgME::Key>::const_iterator last, Option options=RecursiveSearch ) const;
- std::vector<GpgME::Key> findIssuers( const GpgME::Key & key, Options options=RecursiveSearch ) const;
- std::vector<GpgME::Key> findIssuers( const std::vector<GpgME::Key> & keys, Options options=RecursiveSearch ) const;
- std::vector<GpgME::Key> findIssuers( std::vector<GpgME::Key>::const_iterator first, std::vector<GpgME::Key>::const_iterator last, Options options=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findIssuers( const GpgME::Key & key, Option options=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findIssuers( const std::vector<GpgME::Key> & keys, Option options=RecursiveSearch ) const;
+ std::vector<GpgME::Key> findIssuers( std::vector<GpgME::Key>::const_iterator first, std::vector<GpgME::Key>::const_iterator last, Option options=RecursiveSearch ) const;
public Q_SLOTS:
void clear();
void startKeyListing();
void cancelKeyListing();
Q_SIGNALS:
- //void changed( const GpgME::Key & key );
+ void changed( const GpgME::Key & key );
void aboutToRemove( const GpgME::Key & key );
void added( const GpgME::Key & key );
void keyListingDone( const GpgME::KeyListResult & result );
- void keysMayHaveChanged();
private:
class RefreshKeysJob;
-
+
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void refreshJobDone( GpgME::KeyListResult ) )
};
-
}
-Q_DECLARE_OPERATORS_FOR_FLAGS( Kleo::KeyCache::Options )
-
#endif /* __KLEOPATRA_MODELS_KEYCACHE_H__ */
diff --git a/models/keylistmodel.cpp b/models/keylistmodel.cpp
index a2f3421c6..8e91c2d7b 100644
--- a/models/keylistmodel.cpp
+++ b/models/keylistmodel.cpp
@@ -1,835 +1,834 @@
/* -*- mode: c++; c-basic-offset:4 -*-
models/keylistmodel.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 "keylistmodel.h"
#include "predicates.h"
#ifdef KLEO_MODEL_TEST
# include "modeltest.h"
#endif
#include <utils/formatting.h>
#include <kleo/keyfiltermanager.h>
#include <kleo/keyfilter.h>
#include <KLocale>
#include <KIcon>
#include <QDateTime>
#include <QFont>
#include <QColor>
#include <QApplication>
#include <gpgme++/key.h>
#include <boost/bind.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <iterator>
#include <cassert>
#ifdef __GNUC__
#include <ext/algorithm> // for is_sorted
#endif
using namespace GpgME;
using namespace Kleo;
using namespace boost;
class AbstractKeyListModel::Private {
public:
Private() : m_toolTipOptions( Formatting::Validity ) {}
int m_toolTipOptions;
};
AbstractKeyListModel::AbstractKeyListModel( QObject * p )
: QAbstractItemModel( p ), KeyListModelInterface(), d( new Private )
{
}
AbstractKeyListModel::~AbstractKeyListModel() {}
void AbstractKeyListModel::setToolTipOptions( int opts )
{
d->m_toolTipOptions = opts;
}
int AbstractKeyListModel::toolTipOptions() const
{
return d->m_toolTipOptions;
}
Key AbstractKeyListModel::key( const QModelIndex & idx ) const {
if ( idx.isValid() )
return doMapToKey( idx );
else
return Key::null;
}
std::vector<Key> AbstractKeyListModel::keys( const QList<QModelIndex> & indexes ) const {
std::vector<Key> result;
result.reserve( indexes.size() );
std::transform( indexes.begin(), indexes.end(),
std::back_inserter( result ),
bind( &AbstractKeyListModel::key, this, _1 ) );
result.erase( std::unique( result.begin(), result.end(), _detail::ByFingerprint<std::equal_to>() ), result.end() );
return result;
}
QModelIndex AbstractKeyListModel::index( const Key & key, int col ) const {
if ( key.isNull() || col < 0 || col >= NumColumns )
return QModelIndex();
else
return doMapFromKey( key, col );
}
QList<QModelIndex> AbstractKeyListModel::indexes( const std::vector<Key> & keys ) const {
QList<QModelIndex> result;
std::transform( keys.begin(), keys.end(),
std::back_inserter( result ),
// if some compilers are complaining about ambigious overloads, use this line instead:
//bind( static_cast<QModelIndex(AbstractKeyListModel::*)(const Key&,int)const>( &AbstractKeyListModel::index ), this, _1, 0 ) );
bind( &AbstractKeyListModel::index, this, _1, 0 ) );
return result;
}
void AbstractKeyListModel::setKeys( const std::vector<Key> & keys ) {
clear();
addKeys( keys );
}
QModelIndex AbstractKeyListModel::addKey( const Key & key ) {
const std::vector<Key> vec( 1, key );
const QList<QModelIndex> l = doAddKeys( vec );
return l.empty() ? QModelIndex() : l.front() ;
}
void AbstractKeyListModel::removeKey( const Key & key ) {
if ( key.isNull() )
return;
doRemoveKey( key );
}
QList<QModelIndex> AbstractKeyListModel::addKeys( const std::vector<Key> & keys ) {
std::vector<Key> sorted;
sorted.reserve( keys.size() );
std::remove_copy_if( keys.begin(), keys.end(),
std::back_inserter( sorted ),
bind( &Key::isNull, _1 ) );
std::sort( sorted.begin(), sorted.end(), _detail::ByFingerprint<std::less>() );
return doAddKeys( sorted );
}
void AbstractKeyListModel::clear() {
doClear();
reset();
}
int AbstractKeyListModel::columnCount( const QModelIndex & ) const {
return NumColumns;
}
QVariant AbstractKeyListModel::headerData( int section, Qt::Orientation o, int role ) const {
if ( o == Qt::Horizontal )
if ( role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole )
switch ( section ) {
case PrettyName: return i18n( "Name" );
case PrettyEMail: return i18n( "E-Mail" );
case ValidFrom: return i18n( "Valid From" );
case ValidUntil: return i18n( "Valid Until" );
case TechnicalDetails: return i18n( "Details" );
case Fingerprint: return i18n( "Fingerprint" );
case NumColumns: ;
}
return QVariant();
}
static QVariant returnIfValid( const QColor & t ) {
if ( t.isValid() )
return t;
else
return QVariant();
}
static QVariant returnIfValidIcon( const QString & t ) {
if ( !t.isEmpty() )
return QIcon( KIcon( t ) );
else
return QVariant();
}
QVariant AbstractKeyListModel::data( const QModelIndex & index, int role ) const {
const Key key = this->key( index );
if ( key.isNull() )
return QVariant();
const int column = index.column();
if ( role == Qt::DisplayRole || role == Qt::EditRole )
switch ( column ) {
case PrettyName:
return Formatting::prettyName( key );
case PrettyEMail:
return Formatting::prettyEMail( key );
case ValidFrom:
if ( role == Qt::EditRole )
return Formatting::creationDate( key );
else
return Formatting::creationDateString( key );
case ValidUntil:
if ( role == Qt::EditRole )
return Formatting::expirationDate( key );
else
return Formatting::expirationDateString( key );
case TechnicalDetails:
return Formatting::type( key );
case Fingerprint:
return QString::fromLatin1( key.primaryFingerprint() );
case NumColumns:
break;
}
else if ( role == Qt::ToolTipRole )
return Formatting::toolTip( key, toolTipOptions() );
else if ( role == Qt::FontRole ) {
QFont font = qApp->font(); // ### correct font?
if ( column == Fingerprint )
font.setFamily( "courier" );
if ( const shared_ptr<KeyFilter> & filter = KeyFilterManager::instance()->filterMatching( key, KeyFilter::Appearance ) )
return filter->font( font );
else
return font;
} else if ( role == Qt::DecorationRole || role == Qt::BackgroundRole || role == Qt::ForegroundRole ) {
if ( const shared_ptr<KeyFilter> & filter = KeyFilterManager::instance()->filterMatching( key, KeyFilter::Appearance ) ) {
switch ( role ) {
case Qt::DecorationRole: return column == Icon ? returnIfValidIcon( filter->icon() ) : QVariant() ;
case Qt::BackgroundRole: return returnIfValid( filter->bgColor() );
case Qt::ForegroundRole: return returnIfValid( filter->fgColor() );
default: ; // silence compiler
}
}
} else if ( role == Qt::TextAlignmentRole ) { // needed?
}
return QVariant();
}
namespace {
template <typename Base>
class TableModelMixin : public Base {
public:
explicit TableModelMixin( QObject * p=0 ) : Base( p ) {}
~TableModelMixin() {}
using Base::index;
/* reimp */ QModelIndex index( int row, int column, const QModelIndex & pidx=QModelIndex() ) const {
return this->hasIndex( row, column, pidx ) ? this->createIndex( row, column, 0 ) : QModelIndex() ;
}
private:
/* reimp */ QModelIndex parent( const QModelIndex & ) const { return QModelIndex(); }
/* reimp */ bool hasChildren( const QModelIndex & pidx ) const {
return ( pidx.model() == this || !pidx.isValid() ) && this->rowCount( pidx ) > 0 && this->columnCount( pidx ) > 0 ;
}
};
class FlatKeyListModel
#ifndef Q_MOC_RUN
: public TableModelMixin<AbstractKeyListModel>
#else
: public AbstractKeyListModel
#endif
{
Q_OBJECT
public:
explicit FlatKeyListModel( QObject * parent=0 );
~FlatKeyListModel();
/* reimp */ int rowCount( const QModelIndex & pidx ) const { return pidx.isValid() ? 0 : mKeysByFingerprint.size() ; }
private:
/* reimp */ Key doMapToKey( const QModelIndex & index ) const;
/* reimp */ QModelIndex doMapFromKey( const Key & key, int col ) const;
/* reimp */ QList<QModelIndex> doAddKeys( const std::vector<Key> & keys );
/* reimp */ void doRemoveKey( const Key & key );
/* reimp */ void doClear() {
mKeysByFingerprint.clear();
}
private:
std::vector<Key> mKeysByFingerprint;
};
class HierarchicalKeyListModel : public AbstractKeyListModel {
Q_OBJECT
public:
explicit HierarchicalKeyListModel( QObject * parent=0 );
~HierarchicalKeyListModel();
/* reimp */ int rowCount( const QModelIndex & pidx ) const;
using AbstractKeyListModel::index;
/* reimp */ QModelIndex index( int row, int col, const QModelIndex & pidx ) const;
/* reimp */ QModelIndex parent( const QModelIndex & idx ) const;
bool hasChildren( const QModelIndex & pidx ) const { return rowCount( pidx ) > 0 ; }
private:
/* reimp */ Key doMapToKey( const QModelIndex & index ) const;
/* reimp */ QModelIndex doMapFromKey( const Key & key, int col ) const;
/* reimp */ QList<QModelIndex> doAddKeys( const std::vector<Key> & keys );
/* reimp */ void doRemoveKey( const Key & key );
/* reimp */ void doClear() {
- mTopLevels.clear();
mKeysByFingerprint.clear();
mKeysByExistingParent.clear();
mKeysByNonExistingParent.clear();
}
private:
void addTopLevelKey( const Key & key );
void addKeyWithParent( const char * issuer_fpr, const Key & key );
void addKeyWithoutParent( const char * issuer_fpr, const Key & key );
-
+
private:
typedef std::map< std::string, std::vector<Key> > Map;
std::vector<Key> mKeysByFingerprint; // all keys
Map mKeysByExistingParent, mKeysByNonExistingParent; // parent->child map
std::vector<Key> mTopLevels; // all roots + parent-less
};
-
+
static const char * cleanChainID( const Key & key ) {
if ( key.isRoot() )
return "";
if ( const char * chid = key.chainID() )
return chid;
return "";
}
}
FlatKeyListModel::FlatKeyListModel( QObject * p )
: TableModelMixin<AbstractKeyListModel>( p ),
mKeysByFingerprint()
{
}
FlatKeyListModel::~FlatKeyListModel() {}
Key FlatKeyListModel::doMapToKey( const QModelIndex & idx ) const {
assert( idx.isValid() );
if ( static_cast<unsigned>( idx.row() ) < mKeysByFingerprint.size() && idx.column() < NumColumns )
return mKeysByFingerprint[ idx.row() ];
else
return Key::null;
}
QModelIndex FlatKeyListModel::doMapFromKey( const Key & key, int col ) const {
assert( !key.isNull() );
const std::vector<Key>::const_iterator it
= qBinaryFind( mKeysByFingerprint.begin(), mKeysByFingerprint.end(),
key, _detail::ByFingerprint<std::less>() );
if ( it == mKeysByFingerprint.end() )
return QModelIndex();
else
return createIndex( it - mKeysByFingerprint.begin(), col );
}
QList<QModelIndex> FlatKeyListModel::doAddKeys( const std::vector<Key> & keys ) {
#ifdef __GNUC__
assert( __gnu_cxx::is_sorted( keys.begin(), keys.end(), _detail::ByFingerprint<std::less>() ) );
#endif
if ( keys.empty() )
return QList<QModelIndex>();
for ( std::vector<Key>::const_iterator it = keys.begin(), end = keys.end() ; it != end ; ++it ) {
// find an insertion point:
const std::vector<Key>::iterator pos = std::upper_bound( mKeysByFingerprint.begin(), mKeysByFingerprint.end(), *it, _detail::ByFingerprint<std::less>() );
const unsigned int idx = std::distance( mKeysByFingerprint.begin(), pos );
if ( idx > 0 && qstrcmp( mKeysByFingerprint[idx-1].primaryFingerprint(), it->primaryFingerprint() ) == 0 ) {
// key existed before - replace with new one:
mKeysByFingerprint[idx-1] = *it;
emit dataChanged( createIndex( idx-1, 0 ), createIndex( idx-1, NumColumns-1 ) );
} else {
// new key - insert:
beginInsertRows( QModelIndex(), idx, idx );
mKeysByFingerprint.insert( pos, *it );
endInsertRows();
}
}
return indexes( keys );
}
void FlatKeyListModel::doRemoveKey( const Key & key ) {
const std::vector<Key>::iterator it
= qBinaryFind( mKeysByFingerprint.begin(), mKeysByFingerprint.end(),
key, _detail::ByFingerprint<std::less>() );
if ( it == mKeysByFingerprint.end() )
return;
-
+
const unsigned int row = std::distance( mKeysByFingerprint.begin(), it );
beginRemoveRows( QModelIndex(), row, row );
mKeysByFingerprint.erase( it );
endRemoveRows();
}
HierarchicalKeyListModel::HierarchicalKeyListModel( QObject * p )
: AbstractKeyListModel( p ),
mKeysByFingerprint(),
mKeysByExistingParent(),
mKeysByNonExistingParent(),
mTopLevels()
{
}
HierarchicalKeyListModel::~HierarchicalKeyListModel() {}
int HierarchicalKeyListModel::rowCount( const QModelIndex & pidx ) const {
// toplevel item:
if ( !pidx.isValid() )
return mTopLevels.size();
-
+
if ( pidx.column() != 0 )
return 0;
-
+
// non-toplevel item - find the number of subjects for this issuer:
const Key issuer = this->key( pidx );
const char * const fpr = issuer.primaryFingerprint();
if ( !fpr || !*fpr )
return 0;
const Map::const_iterator it = mKeysByExistingParent.find( fpr );
if ( it == mKeysByExistingParent.end() )
return 0;
return it->second.size();
}
QModelIndex HierarchicalKeyListModel::index( int row, int col, const QModelIndex & pidx ) const {
if ( row < 0 || col < 0 || col >= NumColumns )
return QModelIndex();
// toplevel item:
if ( !pidx.isValid() )
if ( static_cast<unsigned>( row ) < mTopLevels.size() )
return index( mTopLevels[row], col );
else
return QModelIndex();
// non-toplevel item - find the row'th subject of this key:
const Key issuer = this->key( pidx );
const char * const fpr = issuer.primaryFingerprint();
if ( !fpr || !*fpr )
return QModelIndex();
const Map::const_iterator it = mKeysByExistingParent.find( fpr );
if ( it == mKeysByExistingParent.end() || static_cast<unsigned>( row ) >= it->second.size() )
return QModelIndex();
return index( it->second[row], col );
}
QModelIndex HierarchicalKeyListModel::parent( const QModelIndex & idx ) const {
const Key key = this->key( idx );
if ( key.isNull() || key.isRoot() )
return QModelIndex();
const std::vector<Key>::const_iterator it
= qBinaryFind( mKeysByFingerprint.begin(), mKeysByFingerprint.end(),
cleanChainID( key ), _detail::ByFingerprint<std::less>() );
return it != mKeysByFingerprint.end() ? index( *it ) : QModelIndex();
}
Key HierarchicalKeyListModel::doMapToKey( const QModelIndex & idx ) const {
if ( !idx.isValid() )
return Key::null;
const char * const issuer_fpr = static_cast<const char*>( idx.internalPointer() );
if ( !issuer_fpr || !*issuer_fpr )
// top-level:
if ( static_cast<unsigned>( idx.row() ) >= mTopLevels.size() )
return Key::null;
else
return mTopLevels[idx.row()];
// non-toplevel:
const Map::const_iterator it
= mKeysByExistingParent.find( issuer_fpr );
if ( it == mKeysByExistingParent.end() || static_cast<unsigned>( idx.row() ) >= it->second.size() )
return Key::null;
return it->second[idx.row()];
}
QModelIndex HierarchicalKeyListModel::doMapFromKey( const Key & key, int col ) const {
if ( key.isNull() )
return QModelIndex();
const char * issuer_fpr = cleanChainID( key );
// we need to look in the toplevels list,...
const std::vector<Key> * v = &mTopLevels;
if ( issuer_fpr && *issuer_fpr ) {
const std::map< std::string, std::vector<Key> >::const_iterator it
= mKeysByExistingParent.find( issuer_fpr );
// ...unless we find an existing parent:
if ( it != mKeysByExistingParent.end() )
v = &it->second;
else
issuer_fpr = 0; // force internalPointer to zero for toplevels
}
const std::vector<Key>::const_iterator it
= qBinaryFind( v->begin(), v->end(), key, _detail::ByFingerprint<std::less>() );
if ( it == v->end() )
return QModelIndex();
const unsigned int row = std::distance( v->begin(), it );
- return createIndex( row, col, const_cast<char* /* thanks, Trolls :/ */ >( issuer_fpr ) );
+ return createIndex( row, col, const_cast<char* /* thanks, Trolls :/ */ >( issuer_fpr ) );
}
void HierarchicalKeyListModel::addKeyWithParent( const char * issuer_fpr, const Key & key ) {
assert( issuer_fpr ); assert( *issuer_fpr ); assert( !key.isNull() );
std::vector<Key> & subjects = mKeysByExistingParent[issuer_fpr];
// find insertion point:
const std::vector<Key>::iterator it = std::lower_bound( subjects.begin(), subjects.end(), key, _detail::ByFingerprint<std::less>() );
const int row = std::distance( subjects.begin(), it );
if ( it != subjects.end() && qstricmp( it->primaryFingerprint(), key.primaryFingerprint() ) == 0 ) {
// exists -> replace
*it = key;
emit dataChanged( createIndex( row, 0, const_cast<char*>( issuer_fpr ) ), createIndex( row, NumColumns-1, const_cast<char*>( issuer_fpr ) ) );
} else {
// doesn't exist -> insert
const std::vector<Key>::const_iterator pos = qBinaryFind( mKeysByFingerprint.begin(), mKeysByFingerprint.end(), issuer_fpr, _detail::ByFingerprint<std::less>() );
assert( pos != mKeysByFingerprint.end() );
beginInsertRows( index( *pos ), row, row );
subjects.insert( it, key );
endInsertRows();
}
}
void HierarchicalKeyListModel::addKeyWithoutParent( const char * issuer_fpr, const Key & key ) {
assert( issuer_fpr ); assert( *issuer_fpr ); assert( !key.isNull() );
std::vector<Key> & subjects = mKeysByNonExistingParent[issuer_fpr];
// find insertion point:
const std::vector<Key>::iterator it = std::lower_bound( subjects.begin(), subjects.end(), key, _detail::ByFingerprint<std::less>() );
if ( it != subjects.end() && qstricmp( it->primaryFingerprint(), key.primaryFingerprint() ) == 0 )
// exists -> replace
*it = key;
else
// doesn't exist -> insert
subjects.insert( it, key );
addTopLevelKey( key );
}
void HierarchicalKeyListModel::addTopLevelKey( const Key & key ) {
// find insertion point:
const std::vector<Key>::iterator it = std::lower_bound( mTopLevels.begin(), mTopLevels.end(), key, _detail::ByFingerprint<std::less>() );
const int row = std::distance( mTopLevels.begin(), it );
if ( it != mTopLevels.end() && qstricmp( it->primaryFingerprint(), key.primaryFingerprint() ) == 0 ) {
// exists -> replace
*it = key;
emit dataChanged( createIndex( row, 0 ), createIndex( row, NumColumns-1 ) );
} else {
// doesn't exist -> insert
beginInsertRows( QModelIndex(), row, row );
mTopLevels.insert( it, key );
endInsertRows();
}
}
namespace {
// sorts 'keys' such that parent always come before their children:
std::vector<Key> topological_sort( const std::vector<Key> & keys ) {
adjacency_list<> graph( keys.size() );
// add edges from children to parents:
for ( unsigned int i = 0, end = keys.size() ; i != end ; ++i ) {
const char * const issuer_fpr = cleanChainID( keys[i] );
if ( !issuer_fpr || !*issuer_fpr )
continue;
const std::vector<Key>::const_iterator it
= qBinaryFind( keys.begin(), keys.end(), issuer_fpr, _detail::ByFingerprint<std::less>() );
if ( it == keys.end() )
continue;
add_edge( i, std::distance( keys.begin(), it ), graph );
}
std::vector<int> order;
order.reserve( keys.size() );
topological_sort( graph, std::back_inserter( order ) );
assert( order.size() == keys.size() );
std::vector<Key> result;
result.reserve( keys.size() );
Q_FOREACH( int i, order )
result.push_back( keys[i] );
return result;
}
}
QList<QModelIndex> HierarchicalKeyListModel::doAddKeys( const std::vector<Key> & keys ) {
#ifdef __GNUC__
assert( __gnu_cxx::is_sorted( keys.begin(), keys.end(), _detail::ByFingerprint<std::less>() ) );
#endif
if ( keys.empty() )
return QList<QModelIndex>();
const std::vector<Key> oldKeys = mKeysByFingerprint;
std::vector<Key> merged;
merged.reserve( keys.size() + mKeysByFingerprint.size() );
std::set_union( keys.begin(), keys.end(),
mKeysByFingerprint.begin(), mKeysByFingerprint.end(),
std::back_inserter( merged ), _detail::ByFingerprint<std::less>() );
-
+
mKeysByFingerprint = merged;
std::set<Key, _detail::ByFingerprint<std::less> > changedParents;
Q_FOREACH( const Key & key, topological_sort( keys ) ) {
// check to see whether this key is a parent for a previously parent-less group:
const char * const fpr = key.primaryFingerprint();
if ( !fpr || !*fpr )
continue;
-
+
const bool keyAlreadyExisted = qBinaryFind( oldKeys.begin(), oldKeys.end(), key, _detail::ByFingerprint<std::less>() ) != oldKeys.end();
const Map::iterator it = mKeysByNonExistingParent.find( fpr );
const std::vector<Key> children = it != mKeysByNonExistingParent.end() ? it->second : std::vector<Key>();
if ( it != mKeysByNonExistingParent.end() )
mKeysByNonExistingParent.erase( it );
// Step 1: For new keys, remove children from toplevel:
if ( !keyAlreadyExisted ) {
std::vector<Key>::iterator last = mTopLevels.begin();
std::vector<Key>::iterator lastFP = mKeysByFingerprint.begin();
-
+
Q_FOREACH( const Key & k, children ) {
last = qBinaryFind( last, mTopLevels.end(), k, _detail::ByFingerprint<std::less>() );
assert( last != mTopLevels.end() );
const int row = std::distance( mTopLevels.begin(), last );
-
+
lastFP = qBinaryFind( lastFP, mKeysByFingerprint.end(), k, _detail::ByFingerprint<std::less>() );
assert( lastFP != mKeysByFingerprint.end() );
emit rowAboutToBeMoved( QModelIndex(), row );
beginRemoveRows( QModelIndex(), row, row );
last = mTopLevels.erase( last );
lastFP = mKeysByFingerprint.erase( lastFP );
endRemoveRows();
}
}
// Step 2: add/update key
const char * const issuer_fpr = cleanChainID( key );
if ( !issuer_fpr || !*issuer_fpr )
// root or something...
addTopLevelKey( key );
else if ( std::binary_search( mKeysByFingerprint.begin(), mKeysByFingerprint.end(), issuer_fpr, _detail::ByFingerprint<std::less>() ) )
// parent exists...
addKeyWithParent( issuer_fpr, key );
else
// parent does't exist yet...
addKeyWithoutParent( issuer_fpr, key );
const QModelIndex key_idx = index( key );
QModelIndex key_parent = key_idx.parent();
while ( key_parent.isValid() ) {
changedParents.insert( doMapToKey( key_parent ) );
key_parent = key_parent.parent();
}
// Step 3: Add children to new parent ( == key )
if ( !keyAlreadyExisted && !children.empty() ) {
addKeys( children );
const QModelIndex new_parent = index( key );
// emit the rowMoved() signals in reversed direction, so the
// implementation can use a stack for mapping.
for ( int i = children.size() - 1 ; i >= 0 ; --i )
emit rowMoved( new_parent, i );
}
}
//emit dataChanged for all parents with new children. This triggers KeyListSortFilterProxyModel to
- //show a parent node if it just got children matching the proxy's filter
+ //show a parent node if it just got children matching the proxy's filter
Q_FOREACH( const Key & i, changedParents ) {
const QModelIndex idx = index( i );
if ( idx.isValid() )
emit dataChanged( idx.sibling( idx.row(), 0 ), idx.sibling( idx.row(), NumColumns - 1 ) );
}
return indexes( keys );
}
void HierarchicalKeyListModel::doRemoveKey( const Key & key ) {
const QModelIndex idx = index( key );
if ( !idx.isValid() )
return;
-
+
const char * const fpr = key.primaryFingerprint();
//TODO: only removal of leaf nodes is implemented so far
if ( mKeysByExistingParent.find( fpr ) != mKeysByExistingParent.end() )
return;
const std::vector<Key>::iterator it = qBinaryFind( mKeysByFingerprint.begin(), mKeysByFingerprint.end(),
key, _detail::ByFingerprint<std::less>() );
-
+
assert( it != mKeysByFingerprint.end() );
assert( mKeysByNonExistingParent.find( fpr ) == mKeysByNonExistingParent.end() );
assert( mKeysByExistingParent.find( fpr ) == mKeysByExistingParent.end() );
beginRemoveRows( parent( idx ), idx.row(), idx.row() );
mKeysByFingerprint.erase( it );
const char * const issuer_fpr = static_cast<const char*>( idx.internalPointer() );
if ( !issuer_fpr || !*issuer_fpr ) {
const std::vector<Key>::iterator tlIt = qBinaryFind( mTopLevels.begin(), mTopLevels.end(), key, _detail::ByFingerprint<std::less>() );
assert( tlIt != mTopLevels.end() );
mTopLevels.erase( tlIt );
} else {
const Map::iterator nexIt = mKeysByNonExistingParent.find( issuer_fpr );
if ( nexIt != mKeysByNonExistingParent.end() ) {
const std::vector<Key>::iterator eit = qBinaryFind( nexIt->second.begin(), nexIt->second.end(), key, _detail::ByFingerprint<std::less>() );
if ( eit != nexIt->second.end() )
nexIt->second.erase( eit );
if ( nexIt->second.empty() )
mKeysByNonExistingParent.erase( nexIt );
}
-
+
const Map::iterator exIt = mKeysByExistingParent.find( issuer_fpr );
if ( exIt != mKeysByExistingParent.end() ) {
const std::vector<Key>::iterator eit = qBinaryFind( exIt->second.begin(), exIt->second.end(), key, _detail::ByFingerprint<std::less>() );
if ( eit != exIt->second.end() )
exIt->second.erase( eit );
if ( exIt->second.empty() )
mKeysByExistingParent.erase( exIt );
}
}
endRemoveRows();
}
// static
AbstractKeyListModel * AbstractKeyListModel::createFlatKeyListModel( QObject * p ) {
AbstractKeyListModel * const m = new FlatKeyListModel( p );
#ifdef KLEO_MODEL_TEST
new ModelTest( m, p );
#endif
return m;
}
// static
AbstractKeyListModel * AbstractKeyListModel::createHierarchicalKeyListModel( QObject * p ) {
AbstractKeyListModel * const m = new HierarchicalKeyListModel( p );
#ifdef KLEO_MODEL_TEST
new ModelTest( m, p );
#endif
return m;
}
#include "moc_keylistmodel.cpp"
#include "keylistmodel.moc"
/*!
\fn AbstractKeyListModel::rowAboutToBeMoved( const QModelIndex & old_parent, int old_row )
Emitted before the removal of a row from that model. It will later
be added to the model again, in reponse to which rowMoved() will be
emitted. If multiple rows are moved in one go, multiple
rowAboutToBeMoved() signals are emitted before the corresponding
number of rowMoved() signals is emitted - in reverse order.
This works around the absence of move semantics in
QAbstractItemModel. Clients can maintain a stack to perform the
QModelIndex-mapping themselves, or, e.g., to preserve the selection
status of the row:
\code
std::vector<bool> mMovingRowWasSelected; // transient, used when rows are moved
// ...
void slotRowAboutToBeMoved( const QModelIndex & p, int row ) {
mMovingRowWasSelected.push_back( selectionModel()->isSelected( model()->index( row, 0, p ) ) );
}
void slotRowMoved( const QModelIndex & p, int row ) {
const bool wasSelected = mMovingRowWasSelected.back();
mMovingRowWasSelected.pop_back();
if ( wasSelected )
selectionModel()->select( model()->index( row, 0, p ), Select|Rows );
}
\endcode
A similar mechanism could be used to preserve the current item during moves.
*/
/*!
\fn AbstractKeyListModel::rowMoved( const QModelIndex & new_parent, int new_parent )
See rowAboutToBeMoved()
*/
diff --git a/models/useridlistmodel.cpp b/models/useridlistmodel.cpp
index f0bbedfab..9dce7a119 100644
--- a/models/useridlistmodel.cpp
+++ b/models/useridlistmodel.cpp
@@ -1,320 +1,334 @@
/* -*- mode: c++; c-basic-offset:4 -*-
models/useridlistmodel.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 "useridlistmodel.h"
#include <utils/formatting.h>
#include <gpgme++/key.h>
#include <KLocalizedString>
#include <QVariant>
#include <QDate>
#include <boost/bind.hpp>
#include <algorithm>
#include <iterator>
using namespace GpgME;
using namespace Kleo;
using namespace boost;
namespace {
static inline bool is_userid_level( const QModelIndex & idx ) {
return idx.isValid() && idx.internalId() < 0 ;
}
static inline int extract_uid_number( const QModelIndex & idx ) {
return idx.internalId();
}
static inline bool is_signature_level( const QModelIndex & idx ) {
return idx.isValid() && idx.internalId() >= 0 ;
}
}
class UserIDListModel::Private {
friend class ::Kleo::UserIDListModel;
UserIDListModel * const q;
public:
explicit Private( UserIDListModel * qq )
: q( qq ), key() {}
private:
Key key;
};
UserIDListModel::UserIDListModel( QObject * p )
: QAbstractItemModel( p ), d( new Private( this ) )
{
}
UserIDListModel::~UserIDListModel() {}
Key UserIDListModel::key() const {
return d->key;
}
// slot
void UserIDListModel::setKey( const Key & key ) {
const Key oldKey = d->key;
d->key = key;
if ( qstricmp( key.primaryFingerprint(), oldKey.primaryFingerprint() ) != 0 ) {
// different key -> reset
reset();
return;
}
// ### diff them, and signal more fine-grained than this:
if ( key.numUserIDs() > 0 && oldKey.numUserIDs() == key.numUserIDs() ) {
bool identical = true;
for ( unsigned int i = 0, end = key.numUserIDs() ; i != end ; ++i ) {
if ( key.userID( i ).numSignatures() != oldKey.userID( i ).numSignatures() ) {
identical = false;
break;
}
}
if ( identical ) {
emit dataChanged( index( 0, 0 ), index( key.numUserIDs() - 1, NumColumns - 1 ) );
return;
}
}
emit layoutAboutToBeChanged();
emit layoutChanged();
}
-UserID UserIDListModel::userID( const QModelIndex & idx, bool strict ) const {
+UserID UserIDListModel::userID( const QModelIndex & idx ) const {
if ( is_userid_level( idx ) )
return d->key.userID( idx.row() );
- if ( !strict && is_signature_level( idx ) )
+ if ( is_signature_level( idx ) )
return d->key.userID( extract_uid_number( idx ) );
return UserID();
}
-std::vector<UserID> UserIDListModel::userIDs( const QList<QModelIndex> & indexes, bool strict ) const {
+std::vector<UserID> UserIDListModel::userIDs( const QList<QModelIndex> & indexes ) const {
std::vector<UserID> result;
result.reserve( indexes.size() );
std::transform( indexes.begin(), indexes.end(),
std::back_inserter( result ),
- bind( &UserIDListModel::userID, this, _1, strict ) );
+ bind( &UserIDListModel::userID, this, _1 ) );
return result;
}
UserID::Signature UserIDListModel::signature( const QModelIndex & idx ) const {
if ( is_signature_level( idx ) )
return d->key.userID( extract_uid_number( idx ) ).signature( idx.row() );
else
return UserID::Signature();
}
std::vector<UserID::Signature> UserIDListModel::signatures( const QList<QModelIndex> & indexes ) const {
std::vector<UserID::Signature> result;
result.reserve( indexes.size() );
std::transform( indexes.begin(), indexes.end(),
std::back_inserter( result ),
bind( &UserIDListModel::signature, this, _1 ) );
return result;
}
QModelIndex UserIDListModel::index( const UserID & userID, int col ) const {
// O(N), but not sorted, so no better way...
for ( unsigned int row = 0, end = d->key.numUserIDs() ; row != end ; ++row )
if ( qstricmp( userID.id(), d->key.userID( row ).id() ) == 0 )
return createIndex( row, col, -1 );
return QModelIndex();
}
QList<QModelIndex> UserIDListModel::indexes( const std::vector<UserID> & userIDs, int col ) const {
// O(N*M), but who cares...?
QList<QModelIndex> result;
Q_FOREACH( const UserID & uid, userIDs )
result.push_back( index( uid, col ) );
return result;
}
QModelIndex UserIDListModel::index( const UserID::Signature & sig, int col ) const {
const UserID uid = sig.parent();
const QModelIndex pidx = index( uid );
if ( !pidx.isValid() )
return QModelIndex();
const std::vector<UserID::Signature> sigs = uid.signatures();
const std::vector<UserID::Signature>::const_iterator it
= std::find_if( sigs.begin(), sigs.end(),
bind( qstricmp, bind( &UserID::Signature::signerKeyID, _1 ), sig.signerKeyID() ) == 0 );
if ( it == sigs.end() )
return QModelIndex();
return createIndex( std::distance( sigs.begin(), it ), col, pidx.row() );
}
QList<QModelIndex> UserIDListModel::indexes( const std::vector<UserID::Signature> & signatures, int col ) const {
QList<QModelIndex> result;
Q_FOREACH( const UserID::Signature & sig, signatures )
result.push_back( index( sig, col ) );
return result;
}
void UserIDListModel::clear() {
d->key = Key::null;
reset();
}
int UserIDListModel::columnCount( const QModelIndex & ) const {
return NumColumns;
}
int UserIDListModel::rowCount( const QModelIndex & pidx ) const {
if ( !pidx.isValid() )
return d->key.numUserIDs();
if ( is_userid_level( pidx ) )
- return d->key.userID( pidx.row() ).numSignatures();
+ return d->key.userID( extract_uid_number( pidx ) ).numSignatures();
return 0;
}
QModelIndex UserIDListModel::index( int row, int col, const QModelIndex & pidx ) const {
if ( row < 0 || col < 0 || col >= NumColumns )
return QModelIndex();
if ( !pidx.isValid() )
if ( static_cast<unsigned>( row ) < d->key.numUserIDs() )
- return createIndex( row, col, -1 );
- else
return QModelIndex();
+ else
+ return createIndex( row, col, -1 );
if ( !is_userid_level( pidx ) )
return QModelIndex();
const int numSigs = userID( pidx ).numSignatures();
if ( row < numSigs )
return createIndex( row, col, pidx.row() );
return QModelIndex();
}
QModelIndex UserIDListModel::parent( const QModelIndex & idx ) const {
if ( is_signature_level( idx ) )
return createIndex( idx.internalId(), 0, -1 );
else
return QModelIndex();
}
QVariant UserIDListModel::headerData( int section, Qt::Orientation o, int role ) const {
if ( o == Qt::Horizontal )
if ( role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole )
switch ( section ) {
case ID: return i18n( "ID" );
- case PrettyName: return i18n( "Name" );
- case PrettyEMail: return i18n( "EMail" );
+ case PrettyName: return i18n( "Signer Name" );
+ case PrettyEMail: return i18n( "Signer EMail" );
case ValidFrom: return i18n( "Valid From" );
case ValidUntil: return i18n( "Valid Until" );
case Status: return i18n( "Status" );
case NumColumns: ;
}
return QVariant();
}
QVariant UserIDListModel::data( const QModelIndex & idx, int role ) const {
if ( role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::ToolTipRole )
return QVariant();
if ( is_userid_level( idx ) ) {
const UserID uid = this->userID( idx );
if ( uid.isNull() )
return QVariant();
- if ( idx.column() == 0 )
- // we assume that the top-level items are spanned
- return Formatting::prettyUserID( uid );
- else
- return QVariant();
+ switch ( idx.column() ) {
+
+ case ID:
+ return QVariant();
+ case PrettyName:
+ return Formatting::prettyName( uid );
+ case ValidFrom:
+ case ValidUntil:
+ return QVariant();
+ case Status:
+ return Formatting::validityShort( uid );
+#if 0
+ if ( userID.isRevoked() )
+ return i18n("revoked");
+ if ( userID.isExpired() )
+ return i18n("expired");
+ if ( userID.isDisabled() )
+ return i18n("disabled");
+ if ( userID.isInvalid() )
+ return i18n("invalid");
+ return i18n("good");
+#endif
+ }
} else if ( is_signature_level( idx ) ) {
const UserID::Signature signature = this->signature( idx );
if ( signature.isNull() )
return QVariant();
switch ( idx.column() ) {
case ID:
return QString::fromLatin1( signature.signerKeyID() );
- case PrettyName:
- return Formatting::prettyName( signature );
- case PrettyEMail:
- return Formatting::prettyEMail( signature );
case ValidFrom:
if ( role == Qt::EditRole )
return Formatting::creationDate( signature );
else
return Formatting::creationDateString( signature );
case ValidUntil:
if ( role == Qt::EditRole )
return Formatting::expirationDate( signature );
else
return Formatting::expirationDateString( signature );
case Status:
return Formatting::validityShort( signature );
#if 0
if ( userID.isRevoked() )
return i18n("revoked");
if ( userID.isExpired() )
return i18n("expired");
if ( userID.isDisabled() )
return i18n("disabled");
if ( userID.isInvalid() )
return i18n("invalid");
return i18n("good");
#endif
}
}
return QVariant();
}
#include "moc_useridlistmodel.cpp"
diff --git a/models/useridlistmodel.h b/models/useridlistmodel.h
index ae03ce1fb..15c743578 100644
--- a/models/useridlistmodel.h
+++ b/models/useridlistmodel.h
@@ -1,97 +1,97 @@
/* -*- mode: c++; c-basic-offset:4 -*-
models/userIDlistmodel.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_MODELS_USERIDLISTMODEL_H__
#define __KLEOPATRA_MODELS_USERIDLISTMODEL_H__
#include <QAbstractItemModel>
#include <vector>
#include <utils/pimpl_ptr.h>
#include <gpgme++/key.h> // since Signature is nested in UserID...
namespace Kleo {
class UserIDListModel : public QAbstractItemModel {
Q_OBJECT
public:
explicit UserIDListModel( QObject * parent=0 );
~UserIDListModel();
GpgME::Key key() const;
enum Columns {
+ ID,
PrettyName,
PrettyEMail,
ValidFrom,
ValidUntil,
Status,
- ID,
NumColumns,
Icon = PrettyName // which column shall the icon be displayed in?
};
- GpgME::UserID userID( const QModelIndex & idx, bool strict=false ) const;
- std::vector<GpgME::UserID> userIDs( const QList<QModelIndex> & indexes, bool strict=false ) const;
+ GpgME::UserID userID( const QModelIndex & idx ) const;
+ std::vector<GpgME::UserID> userIDs( const QList<QModelIndex> & indexes ) const;
GpgME::UserID::Signature signature( const QModelIndex & idx ) const;
std::vector<GpgME::UserID::Signature> signatures( const QList<QModelIndex> & indexes ) const;
using QAbstractItemModel::index;
QModelIndex index( const GpgME::UserID & userID, int col=0 ) const;
QModelIndex index( const GpgME::UserID::Signature & signature, int col=0 ) const;
QList<QModelIndex> indexes( const std::vector<GpgME::UserID> & userIDs, int col=0 ) const;
QList<QModelIndex> indexes( const std::vector<GpgME::UserID::Signature> & signatures, int col=0 ) const;
public Q_SLOTS:
void setKey( const GpgME::Key & key );
void clear();
public:
/* reimp */ int columnCount( const QModelIndex & pidx=QModelIndex() ) const;
/* reimp */ int rowCount( const QModelIndex & pidx=QModelIndex() ) const;
/* reimp */ QVariant headerData( int section, Qt::Orientation o, int role=Qt::DisplayRole ) const;
/* reimp */ QVariant data( const QModelIndex & index, int role=Qt::DisplayRole ) const;
/* reimp */ QModelIndex index( int row, int col, const QModelIndex & parent=QModelIndex() ) const;
/* reimp */ QModelIndex parent( const QModelIndex & index ) const;
private:
class Private;
kdtools::pimpl_ptr<Private> d;
};
}
#endif /* __KLEOPATRA_MODELS_USERIDLISTMODEL_H__ */
diff --git a/qt-patch-N216530.diff b/qt-patch-N216530.diff
index c33487b20..e69de29bb 100644
--- a/qt-patch-N216530.diff
+++ b/qt-patch-N216530.diff
@@ -1,11 +0,0 @@
---- src/gui/itemviews/qtreeview.cpp~ 2008-04-23 22:39:39.000000000 +0200
-+++ src/gui/itemviews/qtreeview.cpp 2008-06-19 14:59:24.000000000 +0200
-@@ -2598,6 +2598,8 @@
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- const QVector<QTreeViewItem> viewItems = d->viewItems;
- for (int i = 0; i < viewItems.count(); ++i) {
-+ if ( viewItems.at(i).spanning )
-+ continue;
- QModelIndex index = viewItems.at(i).index;
- index = index.sibling(index.row(), column);
- QWidget *editor = d->editorForIndex(index);
diff --git a/selftest/enginecheck.cpp b/selftest/enginecheck.cpp
index f1b2fad26..2ea086a34 100644
--- a/selftest/enginecheck.cpp
+++ b/selftest/enginecheck.cpp
@@ -1,148 +1,147 @@
/* -*- mode: c++; c-basic-offset:4 -*-
selftest/enginecheck.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 "enginecheck.h"
#include "implementation_p.h"
#include <gpgme++/global.h>
#include <gpgme++/engineinfo.h>
#include <gpgme++/error.h>
#include <gpg-error.h>
#include <KLocale>
#include <QFile>
#include <boost/shared_ptr.hpp>
#include <cassert>
using namespace Kleo;
using namespace Kleo::_detail;
using namespace GpgME;
using namespace boost;
static QString engine_name( GpgME::Engine eng ) {
static const char * engines[] = {
"gpg", "gpgsm", "gpgconf"
};
return QString::fromLatin1( engines[eng] );
}
static QString test_name( GpgME::Engine eng ) {
static const char * names[] = {
I18N_NOOP2( "@title", "GPG (OpenPGP Backend) installation" ),
I18N_NOOP2( "@title", "GpgSM (S/MIME Backend) installation" ),
I18N_NOOP2( "@title", "GpgConf (Configuration) installation" ),
};
return i18nc( "@title", names[eng] );
}
namespace {
class EngineCheck : public SelfTestImplementation {
public:
explicit EngineCheck( GpgME::Engine eng )
: SelfTestImplementation( test_name( eng ) )
{
runTest( eng );
}
void runTest( GpgME::Engine eng ) {
const Error err = GpgME::checkEngine( eng );
assert( !err.code() || err.code() == GPG_ERR_INV_ENGINE );
m_passed = !err;
if ( m_passed )
return;
m_explaination = i18nc("@info",
"<para>A problem was detected with the <application>%1</application> backend.</para>",
engine_name( eng ) );
const EngineInfo ei = engineInfo( eng );
if ( ei.isNull() ) {
m_error = i18n("not supported");
m_explaination += i18nc("@info",
"<para>It seems that the <icode>gpgme</icode> library was compiled without "
"support for this backend.</para>");
m_proposedFix += i18nc("@info",
"<para>Replace the <icode>gpgme</icode> library with a version compiled "
- "with <application>%1</application> support.</para>",
+ "with <application>%1</application> support.",
engine_name( eng ) );
} else if ( ei.fileName() && !ei.version() ) {
m_error = i18n("not properly installed");
m_explaination += i18nc("@info",
- "<para>Backend <command>%1</command> is not installed properly.</para>",
- QFile::decodeName( ei.fileName() ) );
+ "<para>Backend <command>%1</command> is not installed properly.</para>" );
m_proposedFix += i18nc( "@info",
"<para>Please check the output of <command>%1 --version</command> manually.</para>",
QFile::decodeName( ei.fileName() ) );
} else if ( ei.fileName() && ei.version() && ei.requiredVersion() ) {
m_error = i18n("too old");
m_explaination += i18nc("@info",
"<para>Backend <command>%1</command> is installed in version %2, "
- "but at least version %3 is required.</para>",
+ "but at least version %3 is required.",
QFile::decodeName( ei.fileName() ),
QString::fromUtf8( ei.version() ),
QString::fromUtf8( ei.requiredVersion() ) );
m_proposedFix += i18nc( "@info",
"<para>Install <application>%1</application> version %2 or higher.</para>",
engine_name( eng ), QString::fromUtf8( ei.requiredVersion() ) );
} else {
m_error = m_explaination = i18n("unknown problem");
m_proposedFix += i18nc( "@info",
"<para>Make sure <application>%1</application> is installed and "
- "in <envar>PATH</envar>.</para>",
+ "in <envvar>PATH</envvar>.",
engine_name( eng ) );
}
}
};
}
shared_ptr<SelfTest> Kleo::makeGpgEngineCheckSelfTest() {
return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgEngine ) );
}
shared_ptr<SelfTest> Kleo::makeGpgSmEngineCheckSelfTest() {
return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgSMEngine ) );
}
shared_ptr<SelfTest> Kleo::makeGpgConfEngineCheckSelfTest() {
return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgConfEngine ) );
}
diff --git a/selftest/gpgconfcheck.cpp b/selftest/gpgconfcheck.cpp
index a0e11ef42..9087e8751 100644
--- a/selftest/gpgconfcheck.cpp
+++ b/selftest/gpgconfcheck.cpp
@@ -1,148 +1,111 @@
/* -*- mode: c++; c-basic-offset:4 -*-
selftest/gpgconfcheck.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 "gpgconfcheck.h"
#include "implementation_p.h"
#include <utils/gnupg-helper.h>
-#include <utils/hex.h>
#include <KLocale>
#include <QProcess>
-#include <QDir>
#include <boost/shared_ptr.hpp>
#include <cassert>
using namespace Kleo;
using namespace Kleo::_detail;
using namespace boost;
namespace {
class GpgConfCheck : public SelfTestImplementation {
- QString m_component;
public:
- explicit GpgConfCheck( const char * component )
- : SelfTestImplementation( i18nc("@title", "%1 Configuration Check", component && *component ? component : "gpgconf" ) ),
- m_component( component )
+ explicit GpgConfCheck()
+ : SelfTestImplementation( i18nc("@title", "GpgConf Configuration Check") )
{
runTest();
}
- QStringList arguments() const {
- if ( m_component.isEmpty() )
- return QStringList() << "--check-config" ;
- else
- return QStringList() << "--check-options" << m_component ;
- }
-
- bool canRun() const {
- if ( !m_component.isEmpty() )
- return true;
- QProcess gpgconf;
- gpgconf.setReadChannel( QProcess::StandardOutput );
- gpgconf.start( gpgConfPath(), QStringList() << "--list-dirs", QIODevice::ReadOnly );
- gpgconf.waitForFinished();
- if ( gpgconf.exitStatus() != QProcess::NormalExit || gpgconf.exitCode() != 0 ) {
- qDebug( "GpgConfCheck: \"gpgconf --list-dirs\" gives error, disabling" );
- return false;
- }
- const QList<QByteArray> lines = gpgconf.readAll().split( '\n' );
- Q_FOREACH( const QByteArray & line, lines )
- if ( line.startsWith( "sysconfdir:" ) )
- try {
- return QDir( QFile::decodeName( hexdecode( line.mid( strlen( "sysconfdir:" ) ) ) ) ).exists( "gpgconf.conf" );
- } catch ( ... ) { return false; }
- qDebug( "GpgConfCheck: \"gpgconf --list-dirs\" has no sysconfdir entry" );
- return false;
- }
-
void runTest() {
- if ( !canRun() ) {
- m_passed = true;
- return;
- }
-
QProcess process;
process.setProcessChannelMode( QProcess::MergedChannels );
-
- process.start( gpgConfPath(), arguments(), QIODevice::ReadOnly );
+ process.start( gpgConfPath(), QStringList() << "--check-config", QIODevice::ReadOnly );
process.waitForFinished();
const QString output = QString::fromUtf8( process.readAll() );
const QString message = process.exitStatus() == QProcess::CrashExit ? i18n( "The process terminated prematurely" ) : process.errorString() ;
if ( process.exitStatus() != QProcess::NormalExit ||
process.error() != QProcess::UnknownError ) {
m_passed = false;
m_error = i18nc("self-test didn't pass", "Failed");
- m_explaination =
- i18n( "There was an error executing the GnuPG configuration self-check for %2:\n"
- " %1\n"
- "You might want to execute \"gpgconf %3\" on the command line.\n",
- message, m_component.isEmpty() ? "GnuPG" : m_component, arguments().join(" ") );
- if ( !output.trimmed().isEmpty() )
- m_explaination += '\n' + i18n("Diagnostics:") + '\n' + output ;
-
+ m_explaination = !output.trimmed().isEmpty()
+ ? i18n( "There was an error executing the GnuPG configuration self-check:\n"
+ " %1\n"
+ "You might want to execute \"gpgconf --check-config\" on the command line.\n"
+ "\n"
+ "Diagnostics:", message ) + '\n' + output
+ : i18n( "There was an error executing \"gpgconf --check-config\":\n"
+ " %1\n"
+ "You might want to execute \"gpgconf --check-config\" on the command line.", message );
m_proposedFix = QString();
} else if ( process.exitCode() ) {
m_passed = false;
m_error = i18nc("self-check didn't pass", "Failed");
m_explaination = !output.trimmed().isEmpty()
? i18nc("Self-test didn't pass",
"The GnuPG configuration self-check failed.\n"
"\n"
"Error code: %1\n"
"Diagnostics:", process.exitCode() ) + '\n' + output
: i18nc("self-check didn't pass",
"The GnuPG configuration self-check failed with error code %1.\n"
"No output was received.", process.exitCode() );
m_proposedFix = QString();
} else {
m_passed = true;
}
}
};
}
-shared_ptr<SelfTest> Kleo::makeGpgConfCheckConfigurationSelfTest( const char * component ) {
- return shared_ptr<SelfTest>( new GpgConfCheck( component ) );
+shared_ptr<SelfTest> Kleo::makeGpgConfCheckConfigurationSelfTest() {
+ return shared_ptr<SelfTest>( new GpgConfCheck );
}
diff --git a/selftest/gpgconfcheck.h b/selftest/gpgconfcheck.h
index affb44b75..63fbe7754 100644
--- a/selftest/gpgconfcheck.h
+++ b/selftest/gpgconfcheck.h
@@ -1,50 +1,50 @@
/* -*- mode: c++; c-basic-offset:4 -*-
selftest/gpgconfcheck.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_SELFTEST_GPGCONFCHECK_H__
#define __KLEOPATRA_SELFTEST_GPGCONFCHECK_H__
#include <selftest/selftest.h>
namespace boost {
template <typename T> class shared_ptr;
}
namespace Kleo {
class SelfTest;
- boost::shared_ptr<SelfTest> makeGpgConfCheckConfigurationSelfTest( const char * component=0 );
+ boost::shared_ptr<SelfTest> makeGpgConfCheckConfigurationSelfTest();
}
#endif /* __KLEOPATRA_SELFTEST_GPGCONFCHECK_H__ */
diff --git a/selftest/uiservercheck.cpp b/selftest/uiservercheck.cpp
index ef55724f7..2fcaae6a0 100644
--- a/selftest/uiservercheck.cpp
+++ b/selftest/uiservercheck.cpp
@@ -1,105 +1,121 @@
/* -*- mode: c++; c-basic-offset:4 -*-
selftest/uiservercheck.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 "uiservercheck.h"
#include "implementation_p.h"
-#include <utils/getpid.h>
-
#include <libkleopatraclient/core/command.h>
#include <QTextDocument> // for Qt::escape
#include <QCoreApplication>
#include <KLocale>
#include <boost/shared_ptr.hpp>
#include <cassert>
+#ifdef Q_OS_WIN32
+# include <process.h>
+#else
+# include <unistd.h>
+#endif
+
using namespace Kleo;
using namespace Kleo::_detail;
using namespace boost;
+static inline qint64 mypid() {
+#if QT_VERSION < 0x040400
+# ifdef Q_OS_WIN32
+ return (qint64)_getpid();
+# else
+ return (qint64)getpid();
+# endif
+#else
+ return QCoreApplication::applicationPid();
+#endif
+}
+
namespace {
class UiServerCheck : public SelfTestImplementation {
public:
explicit UiServerCheck()
: SelfTestImplementation( i18nc("@title", "UiServer Connectivity") )
{
runTest();
}
void runTest() {
KleopatraClientCopy::Command command;
{
QEventLoop loop;
loop.connect( &command, SIGNAL(finished()), SLOT(quit()) );
QMetaObject::invokeMethod( &command, "start", Qt::QueuedConnection );
loop.exec();
}
if ( command.error() ) {
m_passed = false;
m_error = i18n("not reachable");
m_explaination = i18nc("@info",
"Could not connect to UiServer: <message>%1</message>",
Qt::escape( command.errorString() ) );
m_proposedFix = i18nc("@info",
"<para>Check that your firewall is not set to block local connections "
"(allow connections to <resource>localhost</resource> or <resource>127.0.0.1</resource>).</para>");
- } else if ( command.serverPid() != mygetpid() ) {
+ } else if ( command.serverPid() != mypid() ) {
m_passed = false;
m_error = i18n("multiple instances");
m_explaination = i18nc("@info",
"It seems another <application>Kleopatra</application> is running (with process-id %1)",
command.serverPid() );
m_proposedFix = i18nc("@info",
"Quit any other running instances of <application>Kleopatra</application>.");
} else {
m_passed = true;
}
}
};
}
shared_ptr<SelfTest> Kleo::makeUiServerConnectivitySelfTest() {
return shared_ptr<SelfTest>( new UiServerCheck );
}
diff --git a/systemtrayicon.cpp b/systemtrayicon.cpp
index 3441c3468..5449e6011 100644
--- a/systemtrayicon.cpp
+++ b/systemtrayicon.cpp
@@ -1,308 +1,240 @@
/* -*- mode: c++; c-basic-offset:4 -*-
systemtrayicon.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 "systemtrayicon.h"
#include <commands/encryptclipboardcommand.h>
#include <commands/signclipboardcommand.h>
#include <commands/decryptverifyclipboardcommand.h>
-#include <conf/configuredialog.h>
-
#include <KIcon>
#include <KLocale>
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KComponentData>
#include <KWindowSystem>
#include <QMenu>
#include <QAction>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QLabel>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QApplication>
#include <QClipboard>
#include <QProcess>
#include <QPointer>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <cassert>
using namespace boost;
using namespace Kleo::Commands;
-namespace {
- class SignalBlocker {
- public:
- explicit SignalBlocker( QObject * obj ) : object( obj ), previous( object && object->blockSignals( true ) ) {
- assert( object );
- }
-
- ~SignalBlocker() {
- if ( object )
- object->blockSignals( previous );
- }
- private:
- const QPointer<QObject> object;
- const bool previous;
- };
-}
-
class SystemTrayIcon::Private {
friend class ::SystemTrayIcon;
SystemTrayIcon * const q;
public:
explicit Private( SystemTrayIcon * qq );
~Private();
private:
void slotAbout() {
if ( !aboutDialog ) {
aboutDialog = new KAboutApplicationDialog( KGlobal::mainComponent().aboutData() );
aboutDialog->setAttribute( Qt::WA_DeleteOnClose );
}
if ( aboutDialog->isVisible() )
aboutDialog->raise();
else
aboutDialog->show();
}
void slotActivated( ActivationReason reason ) {
if ( reason == QSystemTrayIcon::Trigger )
q->openOrRaiseMainWindow();
}
void slotEnableDisableActions() {
- //work around a Qt bug (seen with Qt 4.4.0, Windows): QClipBoard->mimeData() triggers QClipboard::changed(),
- //triggering slotEnableDisableActions again
- const SignalBlocker block( QApplication::clipboard() );
openCertificateManagerAction.setEnabled( !mainWindow || !mainWindow->isVisible() );
encryptClipboardAction.setEnabled( EncryptClipboardCommand::canEncryptCurrentClipboard() );
openPGPSignClipboardAction.setEnabled( SignClipboardCommand::canSignCurrentClipboard() );
smimeSignClipboardAction.setEnabled( SignClipboardCommand::canSignCurrentClipboard() );
decryptVerifyClipboardAction.setEnabled( DecryptVerifyClipboardCommand::canDecryptVerifyCurrentClipboard() );
}
void slotEncryptClipboard() {
( new EncryptClipboardCommand( 0 ) )->start();
}
void slotOpenPGPSignClipboard() {
( new SignClipboardCommand( GpgME::OpenPGP, 0 ) )->start();
}
void slotSMIMESignClipboard() {
( new SignClipboardCommand( GpgME::CMS, 0 ) )->start();
}
void slotDecryptVerifyClipboard() {
( new DecryptVerifyClipboardCommand( 0 ) )->start();
}
-private:
- void connectConfigureDialog() {
- if ( configureDialog && mainWindow )
- connect( configureDialog, SIGNAL(configCommitted()), mainWindow, SLOT(slotConfigCommitted()) );
- }
- void disconnectConfigureDialog() {
- if ( configureDialog && mainWindow )
- disconnect( configureDialog, SIGNAL(configCommitted()), mainWindow, SLOT(slotConfigCommitted()) );
- }
- void connectMainWindow() {
- if ( mainWindow )
- connect( mainWindow, SIGNAL(configDialogRequested()), q, SLOT(openOrRaiseConfigDialog()) );
- }
- void disconnectMainWindow() {
- if ( mainWindow )
- connect( mainWindow, SIGNAL(configDialogRequested()), q, SLOT(openOrRaiseConfigDialog()) );
- }
private:
QMenu menu;
QAction openCertificateManagerAction;
- QAction configureAction;
QAction aboutAction;
QAction quitAction;
QMenu clipboardMenu;
QAction encryptClipboardAction;
QAction smimeSignClipboardAction;
QAction openPGPSignClipboardAction;
QAction decryptVerifyClipboardAction;
QPointer<KAboutApplicationDialog> aboutDialog;
- QPointer<ConfigureDialog> configureDialog;
QPointer<QWidget> mainWindow;
QRect previousGeometry;
};
SystemTrayIcon::Private::Private( SystemTrayIcon * qq )
: q( qq ),
menu(),
openCertificateManagerAction( i18n("&Open Certificate Manager..."), q ),
- configureAction( i18n("&Configure %1...", KGlobal::mainComponent().aboutData()->programName() ), q ),
aboutAction( i18n("&About %1...", KGlobal::mainComponent().aboutData()->programName() ), q ),
quitAction( i18n("&Shutdown Kleopatra"), q ),
clipboardMenu( i18n("Clipboard" ) ),
encryptClipboardAction( i18n("Encrypt..."), q ),
smimeSignClipboardAction( i18n("S/MIME-Sign..."), q ),
openPGPSignClipboardAction( i18n("OpenPGP-Sign..."), q ),
decryptVerifyClipboardAction( i18n("Decrypt/Verify..."), q ),
aboutDialog(),
mainWindow(),
previousGeometry()
{
KDAB_SET_OBJECT_NAME( menu );
KDAB_SET_OBJECT_NAME( openCertificateManagerAction );
- KDAB_SET_OBJECT_NAME( configureAction );
KDAB_SET_OBJECT_NAME( aboutAction );
KDAB_SET_OBJECT_NAME( quitAction );
KDAB_SET_OBJECT_NAME( clipboardMenu );
KDAB_SET_OBJECT_NAME( encryptClipboardAction );
KDAB_SET_OBJECT_NAME( smimeSignClipboardAction );
KDAB_SET_OBJECT_NAME( openPGPSignClipboardAction );
KDAB_SET_OBJECT_NAME( decryptVerifyClipboardAction );
connect( &openCertificateManagerAction, SIGNAL(triggered()), q, SLOT(openOrRaiseMainWindow()) );
- connect( &configureAction, SIGNAL(triggered()), q, SLOT(openOrRaiseConfigDialog()) );
connect( &aboutAction, SIGNAL(triggered()), q, SLOT(slotAbout()) );
connect( &quitAction, SIGNAL(triggered()), QCoreApplication::instance(), SLOT(quit()) );
connect( &encryptClipboardAction, SIGNAL(triggered()), q, SLOT(slotEncryptClipboard()) );
connect( &smimeSignClipboardAction, SIGNAL(triggered()), q, SLOT(slotSMIMESignClipboard()) );
connect( &openPGPSignClipboardAction, SIGNAL(triggered()), q, SLOT(slotOpenPGPSignClipboard()) );
connect( &decryptVerifyClipboardAction, SIGNAL(triggered()), q, SLOT(slotDecryptVerifyClipboard()) );
connect( QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)),
q, SLOT(slotEnableDisableActions()) );
connect( q, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), q, SLOT(slotActivated(QSystemTrayIcon::ActivationReason)) );
menu.addAction( &openCertificateManagerAction );
- menu.addAction( &configureAction );
menu.addAction( &aboutAction );
menu.addSeparator();
menu.addMenu( &clipboardMenu );
clipboardMenu.addAction( &encryptClipboardAction );
clipboardMenu.addAction( &smimeSignClipboardAction );
clipboardMenu.addAction( &openPGPSignClipboardAction );
clipboardMenu.addAction( &decryptVerifyClipboardAction );
menu.addSeparator();
menu.addAction( &quitAction );
q->setContextMenu( &menu );
slotEnableDisableActions();
}
SystemTrayIcon::Private::~Private() {}
SystemTrayIcon::SystemTrayIcon( QObject * p )
: QSystemTrayIcon( KIcon( "kleopatra" ), p ), d( new Private( this ) )
{
}
SystemTrayIcon::~SystemTrayIcon() {}
void SystemTrayIcon::setMainWindow( QWidget * mw ) {
if ( d->mainWindow )
return;
- d->disconnectConfigureDialog();
- d->disconnectMainWindow();
d->mainWindow = mw;
- d->connectConfigureDialog();
- d->connectMainWindow();
mw->installEventFilter( this );
d->slotEnableDisableActions();
}
-QWidget * SystemTrayIcon::mainWindow() const {
- return d->mainWindow;
-}
-
bool SystemTrayIcon::eventFilter( QObject * o, QEvent * e ) {
if ( o == d->mainWindow )
switch ( e->type() ) {
case QEvent::Close:
d->previousGeometry = static_cast<QWidget*>( o )->geometry();
// fall through:
case QEvent::Show:
case QEvent::DeferredDelete:
QMetaObject::invokeMethod( this, "slotEnableDisableActions", Qt::QueuedConnection );
default: ;
}
return false;
}
void SystemTrayIcon::openOrRaiseMainWindow() {
if ( !d->mainWindow ) {
d->mainWindow = doCreateMainWindow();
assert( d->mainWindow );
if ( d->previousGeometry.isValid() )
d->mainWindow->setGeometry( d->previousGeometry );
d->mainWindow->installEventFilter( this );
- d->connectConfigureDialog();
- d->connectMainWindow();
}
if ( d->mainWindow->isMinimized() ) {
KWindowSystem::unminimizeWindow( d->mainWindow->winId());
d->mainWindow->raise();
} else if ( d->mainWindow->isVisible() ) {
d->mainWindow->raise();
} else {
d->mainWindow->show();
}
}
-void SystemTrayIcon::openOrRaiseConfigDialog() {
- if ( !d->configureDialog ) {
- d->configureDialog = new ConfigureDialog;
- d->configureDialog->setAttribute( Qt::WA_DeleteOnClose );
- d->connectConfigureDialog();
- }
-
- if ( d->configureDialog->isVisible() )
- d->configureDialog->raise();
- else
- d->configureDialog->show();
-}
-
#include "moc_systemtrayicon.cpp"
diff --git a/systemtrayicon.h b/systemtrayicon.h
index 70fc4f916..2eebbd14d 100644
--- a/systemtrayicon.h
+++ b/systemtrayicon.h
@@ -1,80 +1,76 @@
/* -*- mode: c++; c-basic-offset:4 -*-
systemtrayicon.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_SYSTEMTRAYICON_H__
#define __KLEOPATRA_SYSTEMTRAYICON_H__
#include <QSystemTrayIcon>
#include <utils/pimpl_ptr.h>
class SystemTrayIcon : public QSystemTrayIcon {
Q_OBJECT
public:
explicit SystemTrayIcon( QObject * parent=0 );
~SystemTrayIcon();
void setMainWindow( QWidget * w );
- QWidget * mainWindow() const;
public Q_SLOTS:
void openOrRaiseMainWindow();
- void openOrRaiseConfigDialog();
private:
virtual QWidget * doCreateMainWindow() const = 0;
/* reimp */ bool eventFilter( QObject *, QEvent * );
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void slotAbout() )
Q_PRIVATE_SLOT( d, void slotActivated( QSystemTrayIcon::ActivationReason ) )
Q_PRIVATE_SLOT( d, void slotEnableDisableActions() )
Q_PRIVATE_SLOT( d, void slotEncryptClipboard() )
Q_PRIVATE_SLOT( d, void slotOpenPGPSignClipboard() )
Q_PRIVATE_SLOT( d, void slotSMIMESignClipboard() )
Q_PRIVATE_SLOT( d, void slotDecryptVerifyClipboard() )
};
template <typename T_Widget>
class SystemTrayIconFor : public SystemTrayIcon {
public:
explicit SystemTrayIconFor( QObject * parent=0 ) : SystemTrayIcon( parent ) {}
- T_Widget * mainWindow() const { return static_cast<T_Widget*>( SystemTrayIcon::mainWindow() ); }
-
private:
/* reimp */ QWidget * doCreateMainWindow() const { return new T_Widget; }
};
#endif /* __KLEOPATRA_SYSTEMTRAYICON_H__ */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9d983368a..3702ab257 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,73 +1,59 @@
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
include_directories( ${CMAKE_SOURCE_DIR}/kleopatra ${CMAKE_BINARY_DIR}/kleopatra ${CMAKE_SOURCE_DIR}/libkleo ${Boost_INCLUDE_DIR} ${GPGME_INCLUDES} )
########### next target ###############
-if ( PORT_ME_AWAY_FROM_EVENT_LOOPS )
set(test_keylistmodels_SRCS test_keylistmodels.cpp ../models/keylistmodel.cpp ../models/keylistsortfilterproxymodel.cpp ../utils/formatting.cpp ../utils/exception.cpp )
if ( KLEO_MODEL_TEST )
set(test_keylistmodels_SRCS ${test_keylistmodels_SRCS} ../models/modeltest.cpp )
endif ( KLEO_MODEL_TEST )
kde4_add_executable(test_keylistmodels TEST ${test_keylistmodels_SRCS})
target_link_libraries(test_keylistmodels kleo ${KDE4_KDECORE_LIBS} )
########### next target ###############
-set(test_useridlistmodels_SRCS test_useridlistmodels.cpp ../models/useridlistmodel.cpp ../utils/formatting.cpp ../utils/exception.cpp )
-if ( KLEO_MODEL_TEST )
- set(test_useridlistmodels_SRCS ${test_useridlistmodels_SRCS} ../models/modeltest.cpp )
-endif ( KLEO_MODEL_TEST )
-
-kde4_add_executable(test_useridlistmodels TEST ${test_useridlistmodels_SRCS})
-
-target_link_libraries(test_useridlistmodels kleo ${KDE4_KDECORE_LIBS} )
-
-########### next target ###############
-
#set(test_verificationresultdialog_SRCS test_verificationresultdialog.cpp ../uiserver/signaturedisplaywidget.cpp ../utils/formatting.cpp ../certificateinfowidgetimpl.cpp ../uiserver/resultdisplaywidget.cpp)
#kde4_add_ui_files( test_verificationresultdialog_SRCS ../certificateinfowidget.ui)
#kde4_add_executable(test_verificationresultdialog TEST ${test_verificationresultdialog_SRCS})
#
#target_link_libraries(test_verificationresultdialog kleo ${KDE4_KDECORE_LIBS} ${QT_QT3SUPPORT_LIBRARY})
-endif ( PORT_ME_AWAY_FROM_EVENT_LOOPS )
-
########### next target ###############
set(test_verify_SRCS test_verify.cpp)
add_definitions( -DKLEO_TEST_GNUPGHOME=\\"${CMAKE_CURRENT_SOURCE_DIR}/gnupg_home\\" )
add_definitions( -DKLEO_TEST_DATADIR=\\"${CMAKE_CURRENT_SOURCE_DIR}\\" )
kde4_add_unit_test(test_verify TESTNAME kleo-verifytest ${test_verify_SRCS})
target_link_libraries(test_verify kleo ${QT_QTTEST_LIBRARY})
########### next target ###############
if ( USABLE_ASSUAN_FOUND )
# this doesn't yet work on Windows
add_definitions( -DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_2 )
set(test_uiserver_SRCS test_uiserver.cpp ../utils/exception.cpp ../utils/wsastarter.cpp ../utils/hex.cpp )
#FIXME: omitting TEST makes test_uiserver print output again on a Win32 console;
# find a better fix for this issue
if(WIN32)
kde4_add_executable(test_uiserver ${test_uiserver_SRCS})
else(WIN32)
kde4_add_executable(test_uiserver TEST ${test_uiserver_SRCS})
endif(WIN32)
target_link_libraries(test_uiserver ${KDE4_KDECORE_LIBS} )
if(WIN32)
target_link_libraries(test_uiserver ${ASSUAN_VANILLA_LIBRARIES} ${QGPGME_LIBRARIES} ws2_32)
else(WIN32)
target_link_libraries(test_uiserver ${ASSUAN_PTHREAD_LIBRARIES} ${QGPGME_LIBRARIES} )
endif(WIN32)
if (ONLY_KLEO)
install( TARGETS test_uiserver DESTINATION ${BIN_INSTALL_DIR})
endif(ONLY_KLEO)
endif( USABLE_ASSUAN_FOUND )
diff --git a/tests/gnupg_home/dirmngr_ldapservers.conf b/tests/gnupg_home/dirmngr_ldapservers.conf
index 48d0a5e89..e69de29bb 100644
--- a/tests/gnupg_home/dirmngr_ldapservers.conf
+++ b/tests/gnupg_home/dirmngr_ldapservers.conf
@@ -1,8 +0,0 @@
-
-###+++--- GPGConf ---+++###
-ca.intevation.de:389:::o=Intevation GmbH,c=de
-fry.mtgnet.de:389:::c=de
-###+++--- GPGConf ---+++### Thu 24 Apr 2008 03:05:44 PM CEST
-# GPGConf edited this configuration file.
-# It will disable options before this marked block, but it will
-# never change anything below these lines.
diff --git a/tests/gnupg_home/gpg.conf b/tests/gnupg_home/gpg.conf
index 94e00bb2f..e69de29bb 100644
--- a/tests/gnupg_home/gpg.conf
+++ b/tests/gnupg_home/gpg.conf
@@ -1,8 +0,0 @@
-
-###+++--- GPGConf ---+++###
-utf8-strings
-keyserver hkp://keys.gnupg.net
-###+++--- GPGConf ---+++### Sat 24 May 2008 11:04:58 AM CEST
-# GPGConf edited this configuration file.
-# It will disable options before this marked block, but it will
-# never change anything below these lines.
diff --git a/tests/test_useridlistmodels.cpp b/tests/test_useridlistmodels.cpp
index 4d91e3764..e69de29bb 100644
--- a/tests/test_useridlistmodels.cpp
+++ b/tests/test_useridlistmodels.cpp
@@ -1,191 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- test_useridlistmodels.cpp
-
- This file is part of Kleopatra's test suite.
- 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 <models/useridlistmodel.h>
-
-#include <KApplication>
-#include <KCmdLineArgs>
-#include <KAboutData>
-
-#include <QTreeView>
-#include <QtCore>
-
-#ifdef KLEO_MODEL_TEST
-# include <models/modeltest.h>
-#endif
-
-#include <qgpgme/eventloopinteractor.h>
-
-#include <gpgme++/context.h>
-#include <gpgme++/error.h>
-#include <gpgme++/key.h>
-#include <gpgme++/keylistresult.h>
-
-#include <gpg-error.h>
-
-#include <memory>
-#include <stdexcept>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <cassert>
-
-class KeyResolveJob : QObject {
- Q_OBJECT
-public:
- explicit KeyResolveJob( GpgME::Protocol proto=GpgME::OpenPGP, QObject * p=0 )
- : QObject( p ),
- m_ctx( GpgME::Context::createForProtocol( proto ) ),
- m_done( false ),
- m_loop( 0 )
- {
- assert( m_ctx.get() );
- connect( QGpgME::EventLoopInteractor::instance(), SIGNAL(nextKeyEventSignal(GpgME::Context*,GpgME::Key)),
- this, SLOT(slotNextKey(GpgME::Context*,GpgME::Key)) );
- connect( QGpgME::EventLoopInteractor::instance(), SIGNAL(operationDoneEventSignal(GpgME::Context*,GpgME::Error)),
- this, SLOT(slotDone(GpgME::Context*,GpgME::Error)) );
-
- m_ctx->setManagedByEventLoopInteractor( true );
- }
-
- GpgME::Error start( const char * pattern, bool secretOnly=false ) {
- m_ctx->addKeyListMode( GpgME::Signatures|GpgME::SignatureNotations );
- return m_ctx->startKeyListing( pattern, secretOnly );
- }
-
- GpgME::Error waitForDone() {
- if ( m_done )
- return m_error;
- QEventLoop loop;
- m_loop = &loop;
- loop.exec();
- m_loop = 0;
- return m_error;
- }
-
- std::vector<GpgME::Key> keys() const {
- return m_keys;
- }
-
-private Q_SLOTS:
- void slotNextKey( GpgME::Context * ctx, const GpgME::Key & key ) {
- if ( ctx != m_ctx.get() )
- return;
- m_keys.push_back( key );
- }
- void slotDone( GpgME::Context * ctx, const GpgME::Error & err ) {
- if ( ctx != m_ctx.get() )
- return;
- m_error = err;
- m_done = true;
- if ( m_loop )
- m_loop->quit();
- }
-
-private:
- std::auto_ptr<GpgME::Context> m_ctx;
- GpgME::Error m_error;
- bool m_done;
- std::vector<GpgME::Key> m_keys;
- QEventLoop * m_loop;
-};
-
-using namespace GpgME;
-using namespace Kleo;
-
-static void start( const QString & str, Protocol proto ) {
- const QByteArray arg = str.toUtf8();
-
- KeyResolveJob job( proto );
-
- if ( const GpgME::Error err = job.start( arg ) )
- throw std::runtime_error( std::string( "startKeyListing: " ) + gpg_strerror( err.encodedError() ) );
-
- if ( const GpgME::Error err = job.waitForDone() )
- throw std::runtime_error( std::string( "nextKey: " ) + gpg_strerror( err.encodedError() ) );
-
- const Key key = job.keys().front();
-
- if ( key.isNull() )
- throw std::runtime_error( std::string( "key is null" ) );
-
- QTreeView * const tv = new QTreeView;
- tv->setWindowTitle( QString::fromLatin1( "UserIDListModel Test - %1" ).arg( str ) );
-
- UserIDListModel * const model = new UserIDListModel( tv );
-#ifdef KLEO_MODEL_TEST
- new ModelTest( model );
-#endif
- model->setKey( key );
-
- tv->setModel( model );
-
- tv->show();
-}
-
-int main( int argc, char * argv[] ) {
-
- KAboutData aboutData( "test_useridlistmodels", 0, ki18n("UserIDListModel Test"), "0.1" );
- KCmdLineArgs::init( argc, argv, &aboutData );
-
- KCmdLineOptions options;
- options.add( "p <pattern>", ki18n("OpenPGP certificate to look up") );
- options.add( "x <pattern>", ki18n("X.509 certificate to look up") );
-
- KCmdLineArgs::addCmdLineOptions( options );
-
- KApplication app;
-
- KCmdLineArgs * args = KCmdLineArgs::parsedArgs();
-
- if ( args->getOptionList( "p" ).empty() && args->getOptionList( "x" ).empty() )
- return 1;
-
- try {
-
- Q_FOREACH( const QString & arg, args->getOptionList( "p" ) )
- start( arg, OpenPGP );
-
- Q_FOREACH( const QString & arg, args->getOptionList( "x" ) )
- start( arg, CMS );
-
- return app.exec();
-
- } catch ( const std::exception & e ) {
- std::cerr << "Caught exception: " << e.what() << std::endl;
- return 1;
- }
-}
-
-#include "test_useridlistmodel.moc"
diff --git a/uiserver/assuancommand.h b/uiserver/assuancommand.h
index 8033cc029..a21b43d41 100644
--- a/uiserver/assuancommand.h
+++ b/uiserver/assuancommand.h
@@ -1,352 +1,345 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/assuancommand.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_UISERVER_ASSUANCOMMAND_H__
#define __KLEOPATRA_UISERVER_ASSUANCOMMAND_H__
#include <crypto/controller.h>
#include <utils/pimpl_ptr.h>
#include <gpgme++/global.h>
#include <gpgme++/error.h>
#include <kmime/kmime_header_parsing.h>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <string>
#include <map>
#include <vector>
class QVariant;
class QIODevice;
class QObject;
class QStringList;
class QDialog;
class QFile;
struct assuan_context_s;
namespace Kleo {
class Input;
class Output;
class AssuanCommandFactory;
/*!
\brief Base class for GnuPG UI Server commands
\note large parts of this are outdated by now!
<h3>Implementing a new AssuanCommand</h3>
You do not directly inherit AssuanCommand, unless you want to
deal with implementing low-level, repetetive things like name()
in terms of staticName(). Assuming you don't, then you inherit
your command class from AssuanCommandMixin, passing your class
as the template argument to AssuanCommandMixin, like this:
\code
class MyFooCommand : public AssuanCommandMixin<MyFooCommand> {
\endcode
(http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
You then choose a command name, and return that from the static
method staticName(), which is by convention queried by both
AssuanCommandMixin<> and GenericAssuanCommandFactory<>:
\code
static const char * staticName() { return "MYFOO"; }
\endcode
The string should be all-uppercase by convention, but the
UiServer implementation doesn't enforce this.
The next step is to implement start(), the starting point of
command execution:
<h3>Executing the command</h3>
\code
int start( const std::string & line ) {
\endcode
This should set everything up and check the parameters in \a
line and any options this command understands. If there's an
error, choose one the the gpg-error codes and create a
gpg_error_t from it using the protected makeError() function:
\code
return makeError( GPG_ERR_NOT_IMPLEMENTED );
\endcode
But usually, you will want to create a dialog, or call some
GpgME function from here. In case of errors from GpgME, you
shouldn't pipe them through makeError(), but return them
as-is. This will preserve the error source. Error created using
makeError() will have Kleopatra as their error source, so watch
out what you're doing :)
In addition to options and the command line, your command might
require \em{bulk data} input or output. That's what the bulk
input and output channels are for. You can check whether the
client handed you an input channel by checking that
bulkInputDevice() isn't NULL, likewise for bulkOutputDevice().
If everything is ok, you return 0. This indicates to the client
that the command has been accepted and is now in progress.
In this mode (start() returned 0), there are a bunch of options
for your command to do. Some commands may require additional
information from the client. The options passed to start() are
designed to be persistent across commands, and rather limited in
length (there's a strict line length limit in the assuan
protocol with no line continuation mechanism). The same is true
for command line arguments, which, in addition, you have to
parse yourself. Those usually apply only to this command, and
not to following ones.
If you need data that might be larger than the line length
limit, you can either expect it on the bulkInputDevice(), or, if
you have the need for more than one such data channel, or the
data is optional or conditional on some condition that can only
be determined during command execution, you can \em inquire the
missing information from the client.
As an example, a VERIFY command would expect the signed data on
the bulkInputDevice(). But if the input stream doesn't contain
an embedded (opaque) signature, indicating a \em detached
signature, it would go and inquire that data from the
client. Here's how it works:
\code
const int err = inquire( "DETACHED_SIGNATURE",
this, SLOT(slotDetachedSignature(int,QByteArray,QByteArray)) );
if ( err )
done( err );
\endcode
This should be self-explanatory: You give a slot to call when
the data has arrived. The slot's first argument is an error
code. The second the data (if any), and the third is just
repeating what you gave as inquire()'s first argument. As usual,
you can leave argument off of the end, if you are not interested
in them.
You can do as many inquiries as you want, but only one at a
time.
You should peridocally send status updates to the client. You do
that by calling sendStatus().
Once your command has finished executing, call done(). If it's
with an error code, call done(err) like above. \bold{Do not
forget to call done() when done!}. It will close
bulkInputDevice(), bulkOutputDevice(), and send an OK or ERR
message back to the client.
At that point, your command has finished executing, and a new
one can be accepted, or the connection closed.
Apropos connection closed. The only way for the client to cancel
an operation is to shut down the connection. In this case, the
canceled() function will be called. At that point, the
connection to the client will have been broken already, and all
you can do is pack your things and go down gracefully.
If _you_ detect that the user has canceled (your dialog contains
a cancel button, doesn't it?), then you should instead call
done( GPG_ERR_CANCELED ), like for normal operation.
<h3>Registering the command with UiServer</h3>
To register a command, you implement a AssuanCommandFactory for
your AssuanCommand subclass, and register it with the
UiServer. This can be made considerably easier using
GenericAssuanCommandFactory:
\code
UiServer server;
server.registerCommandFactory( shared_ptr<AssuanCommandFactory>( new GenericAssuanCommandFactory<MyFooCommand> ) );
// more registerCommandFactory calls...
server.start();
\endcode
*/
class AssuanCommand : public Crypto::ExecutionContext, public boost::enable_shared_from_this<AssuanCommand> {
// defined in assuanserverconnection.cpp!
public:
AssuanCommand();
virtual ~AssuanCommand();
int start();
void canceled();
virtual const char * name() const = 0;
class Memento {
public:
virtual ~Memento() {}
};
template <typename T>
class TypedMemento : public Memento {
T m_t;
public:
explicit TypedMemento( const T & t ) : m_t( t ) {}
const T & get() const { return m_t; }
T & get() { return m_t; }
};
template <typename T>
static boost::shared_ptr< TypedMemento<T> > make_typed_memento( const T & t ) {
return boost::shared_ptr< TypedMemento<T> >( new TypedMemento<T>( t ) );
}
static int makeError( int code );
// convenience methods:
enum Mode { NoMode, EMail, FileManager };
Mode checkMode() const;
GpgME::Protocol checkProtocol( Mode mode ) const;
/* reimp */ void applyWindowID( QWidget* w ) const {
doApplyWindowID( w );
}
QString heuristicBaseDirectory() const;
- void setNohup( bool on );
bool isNohup() const;
- bool isDone() const;
-
- QString sessionTitle() const;
-
- bool informativeRecipients() const;
- bool informativeSenders() const;
const std::vector<KMime::Types::Mailbox> & recipients() const;
const std::vector<KMime::Types::Mailbox> & senders() const;
bool hasMemento( const QByteArray & tag ) const;
boost::shared_ptr<Memento> memento( const QByteArray & tag ) const;
template <typename T>
boost::shared_ptr<T> mementoAs( const QByteArray & tag ) const {
return boost::dynamic_pointer_cast<T>( this->memento( tag ) );
}
const std::map< QByteArray, boost::shared_ptr<Memento> > & mementos() const;
QByteArray registerMemento( const boost::shared_ptr<Memento> & mem );
QByteArray registerMemento( const QByteArray & tag, const boost::shared_ptr<Memento> & mem );
void removeMemento( const QByteArray & tag );
template <typename T>
T mementoContent( const QByteArray & tag ) const {
if ( boost::shared_ptr< TypedMemento<T> > m = mementoAs< TypedMemento<T> >( tag ) )
return m->get();
else
return T();
}
bool hasOption( const char * opt ) const;
QVariant option( const char * opt ) const;
const std::map<std::string,QVariant> & options() const;
const std::vector< boost::shared_ptr<Input> > & inputs() const;
const std::vector< boost::shared_ptr<Input> > & messages() const;
const std::vector< boost::shared_ptr<Output> > & outputs() const;
QStringList fileNames() const;
std::vector< boost::shared_ptr<QFile> > files() const;
unsigned int numFiles() const;
void sendStatus( const char * keyword, const QString & text );
void sendStatusEncoded( const char * keyword, const std::string & text );
void sendData( const QByteArray & data, bool moreToCome=false );
int inquire( const char * keyword, QObject * receiver, const char * slot, unsigned int maxSize=0 );
void done( const GpgME::Error& err = GpgME::Error() );
void done( const GpgME::Error& err, const QString & details );
void done( int err ) { done( GpgME::Error(err) ); }
void done( int err, const QString & details ) { done( GpgME::Error(err), details ); }
private:
virtual void doCanceled() = 0;
virtual int doStart() = 0;
private:
void doApplyWindowID( QWidget * w ) const;
private:
friend class ::Kleo::AssuanCommandFactory;
class Private;
kdtools::pimpl_ptr<Private> d;
};
class AssuanCommandFactory {
public:
virtual ~AssuanCommandFactory() {}
virtual boost::shared_ptr<AssuanCommand> create() const = 0;
virtual const char * name() const = 0;
typedef int(*_Handler)( assuan_context_s*, char *);
virtual _Handler _handler() const = 0;
protected:
static int _handle( assuan_context_s*, char *, const char * );
};
template <typename Command>
class GenericAssuanCommandFactory : public AssuanCommandFactory {
/* reimp */ AssuanCommandFactory::_Handler _handler() const { return &GenericAssuanCommandFactory::_handle; }
static int _handle( assuan_context_s* _ctx, char * _line ) {
return AssuanCommandFactory::_handle( _ctx, _line, Command::staticName() );
}
/* reimp */ boost::shared_ptr<AssuanCommand> create() const { return make(); }
/* reimp */ const char * name() const { return Command::staticName(); }
public:
static boost::shared_ptr<Command> make() { return boost::shared_ptr<Command>( new Command ); }
};
template <typename Derived, typename Base=AssuanCommand>
class AssuanCommandMixin : public Base {
protected:
/* reimp */ const char * name() const { return Derived::staticName(); }
};
}
#endif /* __KLEOPATRA_UISERVER_ASSUANCOMMAND_H__ */
diff --git a/uiserver/assuanserverconnection.cpp b/uiserver/assuanserverconnection.cpp
index fd5072abf..2efdf960c 100644
--- a/uiserver/assuanserverconnection.cpp
+++ b/uiserver/assuanserverconnection.cpp
@@ -1,1378 +1,1248 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/assuanserverconnection.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.
*/
#ifndef QT_NO_CAST_TO_ASCII
# define QT_NO_CAST_TO_ASCII
#endif
#ifndef QT_NO_CAST_FROM_ASCII
# define QT_NO_CAST_FROM_ASCII
#endif
#include <config-kleopatra.h>
#include "assuanserverconnection.h"
#include "assuancommand.h"
#include <utils/input.h>
#include <utils/output.h>
#include <utils/gnupg-helper.h>
#include <utils/detail_p.h>
#include <utils/hex.h>
#include <utils/log.h>
#include <utils/exception.h>
#include <utils/kleo_assert.h>
-#include <utils/getpid.h>
#include <gpgme++/data.h>
#include <kmime/kmime_header_parsing.h>
#include <KLocalizedString>
#include <KWindowSystem>
#include <QSocketNotifier>
-#include <QTimer>
+#include <QEventLoop>
#include <QVariant>
#include <QPointer>
#include <QFileInfo>
#include <QDebug>
#include <QStringList>
#include <QDialog>
-#include <QRegExp>
#include <kleo-assuan.h>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
-#include <boost/mem_fn.hpp>
#include <boost/mpl/if.hpp>
#include <vector>
#include <map>
#include <string>
#include <memory>
#include <algorithm>
#include <errno.h>
#ifdef __GNUC__
# include <ext/algorithm> // for is_sorted
#endif
#ifdef Q_OS_WIN32
# include <io.h>
# include <process.h>
#else
# include <sys/types.h>
# include <unistd.h>
#endif
#ifdef Q_WS_X11
# include <qx11info_x11.h>
# include <X11/Xlib.h>
#endif
using namespace Kleo;
using namespace boost;
namespace {
struct IOF {
QString fileName;
shared_ptr<QFile> file;
};
+ static inline qint64 mygetpid() {
+#ifdef Q_OS_WIN32
+ return (qint64)_getpid();
+#else
+ return (qint64)getpid();
+#endif
+ }
+
static void close_all( const std::vector<IOF> & ios ) {
Q_FOREACH( const IOF & io, ios )
if ( io.file && io.file->isOpen() )
io.file->close();
}
}
static const unsigned int INIT_SOCKET_FLAGS = 3; // says info assuan...
//static int(*USE_DEFAULT_HANDLER)(assuan_context_t,char*) = 0;
static const int FOR_READING = 0;
static const unsigned int MAX_ACTIVE_FDS = 32;
// shared_ptr for assuan_context_t w/ deleter enforced to assuan_deinit_server:
typedef shared_ptr< remove_pointer<assuan_context_t>::type > AssuanContextBase;
struct AssuanContext : AssuanContextBase {
AssuanContext() : AssuanContextBase() {}
explicit AssuanContext( assuan_context_t ctx ) : AssuanContextBase( ctx, &assuan_deinit_server ) {}
void reset( assuan_context_t ctx=0 ) { AssuanContextBase::reset( ctx, &assuan_deinit_server ); }
};
static inline gpg_error_t assuan_process_done_msg( assuan_context_t ctx, gpg_error_t err, const char * err_msg ) {
return assuan_process_done( ctx, assuan_set_error( ctx, err, err_msg ) );
}
static inline gpg_error_t assuan_process_done_msg( assuan_context_t ctx, gpg_error_t err, const std::string & err_msg ) {
return assuan_process_done_msg( ctx, err, err_msg.c_str() );
}
static inline gpg_error_t assuan_process_done_msg( assuan_context_t ctx, gpg_error_t err, const QString & err_msg ) {
return assuan_process_done_msg( ctx, err, err_msg.toUtf8().constData() );
}
static std::map<std::string,std::string> upcase_option( const char * option, std::map<std::string,std::string> options ) {
std::string value;
bool value_found = false;
std::map<std::string,std::string>::iterator it = options.begin();
while ( it != options.end() )
if ( qstricmp( it->first.c_str(), option ) == 0 ) {
value = it->second;
options.erase( it++ );
value_found = true;
} else {
++it;
}
if ( value_found )
options[option] = value;
return options;
}
static std::map<std::string,std::string> parse_commandline( const char * line ) {
std::map<std::string,std::string> result;
if ( line ) {
const char * begin = line;
const char * lastEQ = 0;
while ( *line ) {
if ( *line == ' ' || *line == '\t' ) {
if ( begin != line ) {
if ( begin[0] == '-' && begin[1] == '-' )
begin += 2; // skip initial "--"
if ( lastEQ && lastEQ > begin )
result[ std::string( begin, lastEQ - begin ) ] = hexdecode( std::string( lastEQ+1, line - (lastEQ+1) ) );
else
result[ std::string( begin, line - begin ) ] = std::string();
}
begin = line + 1;
} else if ( *line == '=' ) {
if ( line == begin )
throw Exception( gpg_error( GPG_ERR_ASS_SYNTAX ),
i18n("No option name given") );
else
lastEQ = line;
}
++line;
}
if ( begin != line ) {
if ( begin[0] == '-' && begin[1] == '-' )
begin += 2; // skip initial "--"
if ( lastEQ && lastEQ > begin )
result[ std::string( begin, lastEQ - begin ) ] = hexdecode( std::string( lastEQ+1, line - (lastEQ+1 ) ) );
else
result[ begin ] = std::string();
}
}
return result;
}
//
//
// AssuanServerConnection:
//
//
class AssuanServerConnection::Private : public QObject {
Q_OBJECT
friend class ::Kleo::AssuanServerConnection;
friend class ::Kleo::AssuanCommandFactory;
friend class ::Kleo::AssuanCommand;
AssuanServerConnection * const q;
public:
Private( assuan_fd_t fd_, const std::vector< shared_ptr<AssuanCommandFactory> > & factories_, AssuanServerConnection * qq );
~Private();
Q_SIGNALS:
void startKeyManager();
public Q_SLOTS:
void slotReadActivity( int ) {
assert( ctx );
if ( const int err = assuan_process_next( ctx.get() ) ) {
//if ( err == -1 || gpg_err_code(err) == GPG_ERR_EOF ) {
topHalfDeletion();
if ( nohupedCommands.empty() )
bottomHalfDeletion();
//} else {
//assuan_process_done( ctx.get(), err );
//return;
//}
}
}
- int startCommandBottomHalf();
-
private:
+ void waitForCryptoCommandsEnabled() {
+ if ( cryptoCommandsEnabled )
+ return;
+ QEventLoop l;
+ loop = &l;
+ l.exec();
+ loop = 0;
+ }
+
void nohupDone( AssuanCommand * cmd ) {
const std::vector< shared_ptr<AssuanCommand> >::iterator it
= std::find_if( nohupedCommands.begin(), nohupedCommands.end(),
bind( &shared_ptr<AssuanCommand>::get, _1 ) == cmd );
assert( it != nohupedCommands.end() );
nohupedCommands.erase( it );
if ( nohupedCommands.empty() && closed )
bottomHalfDeletion();
}
void commandDone( AssuanCommand * cmd ) {
if ( !cmd || cmd != currentCommand.get() )
return;
currentCommand.reset();
}
void topHalfDeletion() {
if ( currentCommand )
currentCommand->canceled();
if ( fd != ASSUAN_INVALID_FD ) {
#ifdef Q_OS_WIN32
CloseHandle( fd );
#else
::close( fd );
#endif
}
notifiers.clear();
closed = true;
}
void bottomHalfDeletion() {
cleanup();
const QPointer<Private> that = this;
emit q->closed( q );
if ( that ) // still there
q->deleteLater();
}
private:
static void reset_handler( assuan_context_t ctx_ ) {
assert( assuan_get_pointer( ctx_ ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
conn.reset();
}
static int option_handler( assuan_context_t ctx_, const char * key, const char * value ) {
assert( assuan_get_pointer( ctx_ ) );
-
+
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
if ( key && key[0] == '-' && key[1] == '-' )
key += 2; // skip "--"
conn.options[key] = QString::fromUtf8( value );
return 0;
//return gpg_error( GPG_ERR_UNKNOWN_OPTION );
}
- static int session_handler( assuan_context_t ctx_, char * line ) {
- assert( assuan_get_pointer( ctx_ ) );
- AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
-
- const QString str = QString::fromUtf8( line );
- QRegExp rx( QLatin1String( "(?:\\d+)(?:\\s+(.*))?" ) );
- if ( !rx.exactMatch( str ) ) {
- static const QString errorString = i18n("Parse error");
- return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_SYNTAX ), errorString );
- }
- if ( !rx.cap( 1 ).isEmpty() )
- conn.sessionTitle = rx.cap( 1 );
- return assuan_process_done( ctx_, 0 );
- }
-
- static int capabilities_handler( assuan_context_t ctx_, char * line ) {
- if ( !QByteArray( line ).trimmed().isEmpty() ) {
- static const QString errorString = i18n("CAPABILITIES doesn't take arguments");
- return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_PARAMETER ), errorString );
- }
- static const char capabilities[] =
- "SENDER=info\n"
- "RECIPIENT=info\n"
- "SESSION\n"
- ;
- return assuan_process_done( ctx_, assuan_send_data( ctx_, capabilities, sizeof capabilities - 1 ) );
- }
-
static int getinfo_handler( assuan_context_t ctx_, char * line ) {
assert( assuan_get_pointer( ctx_ ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
if ( qstrcmp( line, "version" ) == 0 ) {
static const char version[] = "Kleopatra " KLEOPATRA_VERSION_STRING ;
return assuan_process_done( ctx_, assuan_send_data( ctx_, version, sizeof version - 1 ) );
}
QByteArray ba;
if ( qstrcmp( line, "pid" ) == 0 )
ba = QByteArray::number( mygetpid() );
else if ( qstrcmp( line, "options" ) == 0 )
ba = conn.dumpOptions();
else if ( qstrcmp( line, "x-mementos" ) == 0 )
ba = conn.dumpMementos();
else if ( qstrcmp( line, "senders" ) == 0 )
ba = conn.dumpSenders();
else if ( qstrcmp( line, "recipients" ) == 0 )
ba = conn.dumpRecipients();
else if ( qstrcmp( line, "x-files" ) == 0 )
ba = conn.dumpFiles();
else {
static const QString errorString = i18n("Unknown value for WHAT");
return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_PARAMETER ), errorString );
}
return assuan_process_done( ctx_, assuan_send_data( ctx_, ba.constData(), ba.size() ) );
}
static int start_keymanager_handler( assuan_context_t ctx_, char * line ) {
assert( assuan_get_pointer( ctx_ ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
if ( line && *line ) {
static const QString errorString = i18n("START_KEYMANAGER does not take arguments");
return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_PARAMETER ), errorString );
}
emit conn.q->startKeyManagerRequested();
return assuan_process_done( ctx_, 0 );
}
- static int start_confdialog_handler( assuan_context_t ctx_, char * line ) {
- assert( assuan_get_pointer( ctx_ ) );
- AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
-
- if ( line && *line ) {
- static const QString errorString = i18n("START_CONFDIALOG does not take arguments");
- return assuan_process_done_msg( ctx_, gpg_error( GPG_ERR_ASS_PARAMETER ), errorString );
- }
-
- emit conn.q->startConfigDialogRequested();
-
- return assuan_process_done( ctx_, 0 );
- }
-
template <bool in> struct Input_or_Output : mpl::if_c<in,Input,Output> {};
// format: TAG (FD|FD=\d+|FILE=...)
template <bool in, typename T_memptr>
static int IO_handler( assuan_context_t ctx_, char * line_, T_memptr which ) {
assert( assuan_get_pointer( ctx_ ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
try {
/*const*/ std::map<std::string,std::string> options = upcase_option( "FD", upcase_option( "FILE", parse_commandline( line_ ) ) );
if ( options.size() < 1 || options.size() > 2 )
throw gpg_error( GPG_ERR_ASS_SYNTAX );
shared_ptr< typename Input_or_Output<in>::type > io;
if ( options.count( "FD" ) ) {
if ( options.count( "FILE" ) )
throw gpg_error( GPG_ERR_CONFLICT );
assuan_fd_t fd = ASSUAN_INVALID_FD;
const std::string fdstr = options["FD"];
if ( fdstr.empty() ) {
if ( const gpg_error_t err = assuan_receivefd( conn.ctx.get(), &fd ) )
throw err;
} else {
#ifdef Q_OS_WIN32
fd = (assuan_fd_t)lexical_cast<intptr_t>( fdstr );
#else
fd = lexical_cast<assuan_fd_t>( fdstr );
#endif
}
io = Input_or_Output<in>::type::createFromPipeDevice( fd, i18n( "Message #%1", (conn.*which).size() ) );
options.erase( "FD" );
} else if ( options.count( "FILE" ) ) {
-
+
if ( options.count( "FD" ) )
throw gpg_error( GPG_ERR_CONFLICT );
const QString filePath = QFile::decodeName( options["FILE"].c_str() );
if ( filePath.isEmpty() )
throw Exception( gpg_error( GPG_ERR_ASS_SYNTAX ), i18n("Empty file path") );
const QFileInfo fi( filePath );
if ( !fi.isAbsolute() )
throw Exception( gpg_error( GPG_ERR_INV_ARG ), i18n("Only absolute file paths are allowed") );
io = Input_or_Output<in>::type::createFromFile( fi.absoluteFilePath(), true );
options.erase( "FILE" );
} else {
throw gpg_error( GPG_ERR_ASS_PARAMETER );
}
if ( options.size() )
throw gpg_error( GPG_ERR_UNKNOWN_OPTION );
(conn.*which).push_back( io );
qDebug() << "AssuanServerConnection: added" << io->label();
return assuan_process_done( conn.ctx.get(), 0 );
} catch ( const GpgME::Exception & e ) {
return assuan_process_done_msg( conn.ctx.get(), e.error().encodedError(), e.message().c_str() );
} catch ( const std::exception & ) {
return assuan_process_done( conn.ctx.get(), gpg_error( GPG_ERR_ASS_SYNTAX ) );
} catch ( const gpg_error_t e ) {
return assuan_process_done( conn.ctx.get(), e );
} catch ( ... ) {
return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), "unknown exception caught" );
}
}
static int input_handler( assuan_context_t ctx, char * line ) {
return IO_handler<true>( ctx, line, &Private::inputs );
}
static int output_handler( assuan_context_t ctx, char * line ) {
return IO_handler<false>( ctx, line, &Private::outputs );
}
static int message_handler( assuan_context_t ctx, char * line ) {
return IO_handler<true>( ctx, line, &Private::messages );
}
static int file_handler( assuan_context_t ctx_, char * line ) {
assert( assuan_get_pointer( ctx_ ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx_ ) );
try {
const QFileInfo fi( QFile::decodeName( hexdecode( line ).c_str() ) );
if ( !fi.isAbsolute() )
throw Exception( gpg_error( GPG_ERR_INV_ARG ), i18n("Only absolute file paths are allowed") );
if ( fi.exists() && fi.isDir() )
throw Exception( gpg_error( GPG_ERR_NOT_IMPLEMENTED ), i18n("Directory traversal is not yet implemented") );
const QString filePath = fi.absoluteFilePath();
const shared_ptr<QFile> file( new QFile( filePath ) );
if ( !file->open( QIODevice::ReadOnly ) )
throw Exception( gpg_error_from_errno( errno ), i18n("Could not open file \"%1\" for reading", filePath) );
const IOF io = {
filePath, file
};
conn.files.push_back( io );
return assuan_process_done( conn.ctx.get(), 0 );
} catch ( const Exception & e ) {
return assuan_process_done_msg( conn.ctx.get(), e.error().encodedError(), e.message().toUtf8().constData() );
} catch ( ... ) {
return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), i18n("unknown exception caught").toUtf8().constData() );
}
}
- static bool parse_informative( const char * & begin ) {
- if ( qstrnicmp( begin, "--info", strlen("--info") ) != 0 )
- return false;
- const char * pos = begin + strlen("--info");
- if ( *pos == '=' )
- ;
- else if ( *pos == ' ' || *pos == '\t' )
- while ( *pos == ' ' || *pos == '\t' )
- ++pos;
- else
- return false;
- begin = pos;
- return true;
- }
-
- template <typename T_memptr, typename T_memptr2>
- static int recipient_sender_handler( T_memptr mp, T_memptr2 info, assuan_context_t ctx, char * line ) {
+ template <typename T_memptr>
+ static int recipient_sender_handler( T_memptr mp, assuan_context_t ctx, char * line ) {
assert( assuan_get_pointer( ctx ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx ) );
if ( !line || !*line )
return assuan_process_done( conn.ctx.get(), gpg_error( GPG_ERR_INV_ARG ) );
const char * begin = line;
const char * const end = begin + qstrlen( line );
- const bool informative = parse_informative( begin );
- if ( !(conn.*mp).empty() && informative != (conn.*info) )
- return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_CONFLICT ),
- i18n("Cannot mix --info with non-info SENDER or RECIPIENT").toUtf8().constData() );
KMime::Types::Mailbox mb;
if ( !KMime::HeaderParsing::parseMailbox( begin, end, mb ) )
return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_INV_ARG ),
i18n("Argument is not a valid RFC-2822 mailbox").toUtf8().constData() );
if ( begin != end )
return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_INV_ARG ),
i18n("Garbage after valid RFC-2822 mailbox detected").toUtf8().constData() );
- (conn.*info) = informative;
(conn.*mp).push_back( mb );
return assuan_process_done( ctx, 0 );
}
static int recipient_handler( assuan_context_t ctx, char * line ) {
- return recipient_sender_handler( &Private::recipients, &Private::informativeRecipients, ctx, line );
+ return recipient_sender_handler( &Private::recipients, ctx, line );
}
static int sender_handler( assuan_context_t ctx, char * line ) {
- return recipient_sender_handler( &Private::senders, &Private::informativeSenders, ctx, line );
+ return recipient_sender_handler( &Private::senders, ctx, line );
}
QByteArray dumpOptions() const {
QByteArray result;
for ( std::map<std::string,QVariant>::const_iterator it = options.begin(), end = options.end() ; it != end ; ++it )
result += it->first.c_str() + it->second.toString().toUtf8() + '\n';
return result;
}
static QByteArray dumpStringList( const QStringList & sl ) {
return sl.join( QLatin1String( "\n" ) ).toUtf8();
}
template <typename T_container>
static QByteArray dumpStringList( const T_container & c ) {
QStringList sl;
std::copy( c.begin(), c.end(), std::back_inserter( sl ) );
return dumpStringList( sl );
}
template <typename T_container>
static QByteArray dumpMailboxes( const T_container & c ) {
QStringList sl;
std::transform( c.begin(), c.end(),
std::back_inserter( sl ),
bind( &KMime::Types::Mailbox::prettyAddress, _1 ) );
return dumpStringList( sl );
}
QByteArray dumpSenders() const {
return dumpMailboxes( senders );
}
QByteArray dumpRecipients() const {
return dumpMailboxes( recipients );
}
QByteArray dumpMementos() const {
QByteArray result;
for ( std::map< QByteArray, shared_ptr<AssuanCommand::Memento> >::const_iterator it = mementos.begin(), end = mementos.end() ; it != end ; ++it ) {
char buf[2 + 2*sizeof(void*) + 2];
sprintf( buf, "0x%p\n", it->second.get() );
buf[sizeof(buf)-1] = '\0';
result += it->first + QByteArray::fromRawData( buf, sizeof buf );
}
return result;
}
QByteArray dumpFiles() const {
QStringList sl;
std::transform( files.begin(), files.end(), std::back_inserter( sl ),
bind( &IOF::fileName, _1 ) );
return dumpStringList( sl );
}
void cleanup();
void reset() {
options.clear();
senders.clear();
- informativeSenders = false;
recipients.clear();
- informativeRecipients = false;
- sessionTitle.clear();
mementos.clear();
close_all( files );
files.clear();
std::for_each( inputs.begin(), inputs.end(),
bind( &Input::finalize, _1 ) );
inputs.clear();
std::for_each( outputs.begin(), outputs.end(),
bind( &Output::finalize, _1 ) );
outputs.clear();
std::for_each( messages.begin(), messages.end(),
bind( &Input::finalize, _1 ) );
messages.clear();
}
assuan_fd_t fd;
AssuanContext ctx;
bool closed : 1;
bool cryptoCommandsEnabled : 1;
- bool commandWaitingForCryptoCommandsEnabled : 1;
- bool currentCommandIsNohup : 1;
- bool informativeSenders; // address taken, so no : 1
- bool informativeRecipients; // address taken, so no : 1
- QString sessionTitle;
+ QEventLoop * loop;
std::vector< shared_ptr<QSocketNotifier> > notifiers;
std::vector< shared_ptr<AssuanCommandFactory> > factories; // sorted: _detail::ByName<std::less>
shared_ptr<AssuanCommand> currentCommand;
std::vector< shared_ptr<AssuanCommand> > nohupedCommands;
std::map<std::string,QVariant> options;
std::vector<KMime::Types::Mailbox> senders, recipients;
std::vector< shared_ptr<Input> > inputs, messages;
std::vector< shared_ptr<Output> > outputs;
std::vector<IOF> files;
std::map< QByteArray, shared_ptr<AssuanCommand::Memento> > mementos;
};
void AssuanServerConnection::Private::cleanup() {
assert( nohupedCommands.empty() );
reset();
currentCommand.reset();
- currentCommandIsNohup = false;
- commandWaitingForCryptoCommandsEnabled = false;
notifiers.clear();
ctx.reset();
fd = ASSUAN_INVALID_FD;
}
AssuanServerConnection::Private::Private( assuan_fd_t fd_, const std::vector< shared_ptr<AssuanCommandFactory> > & factories_, AssuanServerConnection * qq )
: QObject(),
q( qq ),
fd( fd_ ),
closed( false ),
- cryptoCommandsEnabled( false ),
- commandWaitingForCryptoCommandsEnabled( false ),
- currentCommandIsNohup( false ),
- informativeSenders( false ),
- informativeRecipients( false ),
+ cryptoCommandsEnabled( true ),
+ loop( 0 ),
factories( factories_ )
{
#ifdef __GNUC__
assert( __gnu_cxx::is_sorted( factories_.begin(), factories_.end(), _detail::ByName<std::less>() ) );
#endif
if ( fd == ASSUAN_INVALID_FD )
throw Exception( gpg_error( GPG_ERR_INV_ARG ), "pre-assuan_init_socket_server_ext" );
assuan_context_t naked_ctx = 0;
if ( const gpg_error_t err = assuan_init_socket_server_ext( &naked_ctx, fd, INIT_SOCKET_FLAGS ) )
throw Exception( err, "assuan_init_socket_server_ext" );
-
+
ctx.reset( naked_ctx ); naked_ctx = 0;
// for callbacks, associate the context with this connection:
assuan_set_pointer( ctx.get(), this );
FILE* const logFile = Log::instance()->logFile();
assuan_set_log_stream( ctx.get(), logFile ? logFile : stderr );
-
+
// register FDs with the event loop:
assuan_fd_t fds[MAX_ACTIVE_FDS];
const int numFDs = assuan_get_active_fds( ctx.get(), FOR_READING, fds, MAX_ACTIVE_FDS );
assert( numFDs != -1 ); // == 1
if ( !numFDs || fds[0] != fd ) {
- const shared_ptr<QSocketNotifier> sn( new QSocketNotifier( (int)fd, QSocketNotifier::Read ), mem_fn( &QObject::deleteLater ) );
+ const shared_ptr<QSocketNotifier> sn( new QSocketNotifier( (int)fd, QSocketNotifier::Read ) );
connect( sn.get(), SIGNAL(activated(int)), this, SLOT(slotReadActivity(int)) );
notifiers.push_back( sn );
}
notifiers.reserve( notifiers.size() + numFDs );
for ( int i = 0 ; i < numFDs ; ++i ) {
- const shared_ptr<QSocketNotifier> sn( new QSocketNotifier( (int)fds[i], QSocketNotifier::Read ), mem_fn( &QObject::deleteLater ) );
+ const shared_ptr<QSocketNotifier> sn( new QSocketNotifier( (int)fds[i], QSocketNotifier::Read ) );
connect( sn.get(), SIGNAL(activated(int)), this, SLOT(slotReadActivity(int)) );
notifiers.push_back( sn );
}
// register our INPUT/OUTPUT/MESSGAE/FILE handlers:
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "INPUT", input_handler ) )
throw Exception( err, "register \"INPUT\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "MESSAGE", message_handler ) )
throw Exception( err, "register \"MESSAGE\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "OUTPUT", output_handler ) )
throw Exception( err, "register \"OUTPUT\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "FILE", file_handler ) )
throw Exception( err, "register \"FILE\" handler" );
// register user-defined commands:
Q_FOREACH( shared_ptr<AssuanCommandFactory> fac, factories )
if ( const gpg_error_t err = assuan_register_command( ctx.get(), fac->name(), fac->_handler() ) )
throw Exception( err, std::string( "register \"" ) + fac->name() + "\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "GETINFO", getinfo_handler ) )
throw Exception( err, "register \"GETINFO\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_KEYMANAGER", start_keymanager_handler ) )
throw Exception( err, "register \"START_KEYMANAGER\" handler" );
- if ( const gpg_error_t err = assuan_register_command( ctx.get(), "START_CONFDIALOG", start_confdialog_handler ) )
- throw Exception( err, "register \"START_CONFDIALOG\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "RECIPIENT", recipient_handler ) )
throw Exception( err, "register \"RECIPIENT\" handler" );
if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SENDER", sender_handler ) )
throw Exception( err, "register \"SENDER\" handler" );
- if ( const gpg_error_t err = assuan_register_command( ctx.get(), "SESSION", session_handler ) )
- throw Exception( err, "register \"SESSION\" handler" );
- if ( const gpg_error_t err = assuan_register_command( ctx.get(), "CAPABILITIES", capabilities_handler ) )
- throw Exception( err, "register \"CAPABILITIES\" handler" );
assuan_set_hello_line( ctx.get(), "GPG UI server (Kleopatra/" KLEOPATRA_VERSION_STRING ") ready to serve" );
//assuan_set_hello_line( ctx.get(), GPG UI server (qApp->applicationName() + " v" + kapp->applicationVersion() + "ready to serve" )
// some notifiers we're interested in:
if ( const gpg_error_t err = assuan_register_reset_notify( ctx.get(), reset_handler ) )
throw Exception( err, "register reset notify" );
if ( const gpg_error_t err = assuan_register_option_handler( ctx.get(), option_handler ) )
throw Exception( err, "register option handler" );
// and last, we need to call assuan_accept, which doesn't block
// (d/t INIT_SOCKET_FLAGS), but performs vital connection
// establishing handling:
if ( const gpg_error_t err = assuan_accept( ctx.get() ) )
throw Exception( err, "assuan_accept" );
}
AssuanServerConnection::Private::~Private() {
cleanup();
}
AssuanServerConnection::AssuanServerConnection( assuan_fd_t fd, const std::vector< shared_ptr<AssuanCommandFactory> > & factories, QObject * p )
: QObject( p ), d( new Private( fd, factories, this ) )
{
}
AssuanServerConnection::~AssuanServerConnection() {}
void AssuanServerConnection::enableCryptoCommands( bool on ) {
if ( on == d->cryptoCommandsEnabled )
return;
d->cryptoCommandsEnabled = on;
- if ( d->commandWaitingForCryptoCommandsEnabled )
- QTimer::singleShot( 0, d.get(), SLOT(startCommandBottomHalf()) );
+ if ( d->loop )
+ d->loop->quit();
}
//
//
// AssuanCommand:
//
//
namespace Kleo {
class InquiryHandler : public QObject {
Q_OBJECT
public:
#ifdef HAVE_ASSUAN_INQUIRE_EXT
explicit InquiryHandler( const char * keyword_, QObject * p=0 )
: QObject( p ),
# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
buffer( 0 ),
buflen( 0 ),
# endif
keyword( keyword_ )
{
}
# ifdef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
static int handler( void * cb_data, int rc, unsigned char * buffer, size_t buflen )
{
assert( cb_data );
InquiryHandler * this_ = static_cast<InquiryHandler*>(cb_data);
emit this_->signal( rc, QByteArray::fromRawData( reinterpret_cast<const char*>(buffer), buflen ), this_->keyword );
std::free( buffer );
delete this_;
return 0;
}
# else
static int handler( void * cb_data, int rc )
{
assert( cb_data );
InquiryHandler * this_ = static_cast<InquiryHandler*>(cb_data);
emit this_->signal( rc, QByteArray::fromRawData( reinterpret_cast<const char*>(this_->buffer), this_->buflen ), this_->keyword );
std::free( this_->buffer );
delete this_;
return 0;
}
# endif
private:
# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
friend class ::Kleo::AssuanCommand;
unsigned char * buffer;
size_t buflen;
# endif
const char * keyword;
#endif // HAVE_ASSUAN_INQUIRE_EXT
Q_SIGNALS:
void signal( int rc, const QByteArray & data, const QByteArray & keyword );
};
} // namespace Kleo
class AssuanCommand::Private {
public:
- Private()
- : informativeRecipients( false ),
- informativeSenders( false ),
- done( false ),
- nohup( false )
- {
-
- }
+ Private() : done( false ), nohup( false ) {}
std::map<std::string,QVariant> options;
std::vector< shared_ptr<Input> > inputs, messages;
std::vector< shared_ptr<Output> > outputs;
std::vector<IOF> files;
std::vector<KMime::Types::Mailbox> recipients, senders;
- bool informativeRecipients, informativeSenders;
- QString sessionTitle;
QByteArray utf8ErrorKeepAlive;
AssuanContext ctx;
bool done;
bool nohup;
};
AssuanCommand::AssuanCommand()
: d( new Private )
{
}
AssuanCommand::~AssuanCommand() {
}
int AssuanCommand::start() {
try {
if ( const int err = doStart() )
if ( !d->done )
done( err );
return 0;
} catch ( const Exception & e ) {
if ( !d->done )
done( e.error_code(), e.message() );
return 0;
} catch ( const GpgME::Exception & e ) {
if ( !d->done )
done( e.error(), QString::fromLocal8Bit( e.message().c_str() ) );
return 0;
} catch ( const std::exception & e ) {
if ( !d->done )
done( makeError( GPG_ERR_INTERNAL ), i18n("Caught unexpected exception: %1", QString::fromLocal8Bit( e.what() ) ) );
return 0;
} catch ( ... ) {
if ( !d->done )
done( makeError( GPG_ERR_INTERNAL ), i18n("Caught unknown exception - fix the program!" ) );
return 0;
}
}
void AssuanCommand::canceled() {
d->done = true;
doCanceled();
}
// static
int AssuanCommand::makeError( int code ) {
return makeGnuPGError( code );
}
bool AssuanCommand::hasOption( const char * opt ) const {
return d->options.count( opt );
}
QVariant AssuanCommand::option( const char * opt ) const {
const std::map<std::string,QVariant>::const_iterator it = d->options.find( opt );
if ( it == d->options.end() )
return QVariant();
else
return it->second;
}
const std::map<std::string,QVariant> & AssuanCommand::options() const {
return d->options;
}
namespace {
template <typename U, typename V>
std::vector<U> keys( const std::map<U,V> & map ) {
std::vector<U> result;
result.resize( map.size() );
for ( typename std::map<U,V>::const_iterator it = map.begin(), end = map.end() ; it != end ; ++it )
result.push_back( it->first );
return result;
}
}
const std::map< QByteArray, shared_ptr<AssuanCommand::Memento> > & AssuanCommand::mementos() const {
// oh, hack :(
assert( assuan_get_pointer( d->ctx.get() ) );
const AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( d->ctx.get() ) );
return conn.mementos;
}
bool AssuanCommand::hasMemento( const QByteArray & tag ) const {
return mementos().count( tag );
}
shared_ptr<AssuanCommand::Memento> AssuanCommand::memento( const QByteArray & tag ) const {
const std::map< QByteArray, shared_ptr<Memento> >::const_iterator it = mementos().find( tag );
if ( it == mementos().end() )
return shared_ptr<Memento>();
else
return it->second;
}
QByteArray AssuanCommand::registerMemento( const shared_ptr<Memento> & mem ) {
const QByteArray tag = QByteArray::number( reinterpret_cast<qulonglong>( mem.get() ), 36 );
return registerMemento( tag, mem );
}
QByteArray AssuanCommand::registerMemento( const QByteArray & tag, const shared_ptr<Memento> & mem ) {
// oh, hack :(
assert( assuan_get_pointer( d->ctx.get() ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( d->ctx.get() ) );
-
+
conn.mementos[tag] = mem;
return tag;
}
void AssuanCommand::removeMemento( const QByteArray & tag ) {
// oh, hack :(
assert( assuan_get_pointer( d->ctx.get() ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( d->ctx.get() ) );
-
+
conn.mementos.erase( tag );
}
const std::vector< shared_ptr<Input> > & AssuanCommand::inputs() const {
return d->inputs;
}
const std::vector< shared_ptr<Input> > & AssuanCommand::messages() const {
return d->messages;
}
const std::vector< shared_ptr<Output> > & AssuanCommand::outputs() const {
return d->outputs;
}
QStringList AssuanCommand::fileNames() const {
QStringList result;
Q_FOREACH( const IOF & io, d->files )
result.push_back( io.fileName );
return result;
}
std::vector< shared_ptr<QFile> > AssuanCommand::files() const {
std::vector< shared_ptr<QFile> > result;
Q_FOREACH( const IOF & io, d->files )
result.push_back( io.file );
return result;
}
unsigned int AssuanCommand::numFiles() const {
return d->files.size();
}
#if 0
QString AssuanCommand::bulkInputDeviceFileName( unsigned int idx ) const {
return d->inputs.at( idx ).fileName;
}
shared_ptr<QIODevice> AssuanCommand::bulkInputDevice( unsigned int idx ) const {
return d->inputs.at( idx ).iodev;
}
unsigned int AssuanCommand::numBulkInputDevices() const {
return d->inputs.size();
}
QString AssuanCommand::bulkMessageDeviceFileName( unsigned int idx ) const {
return d->messages.at( idx ).fileName;
}
shared_ptr<QIODevice> AssuanCommand::bulkMessageDevice( unsigned int idx ) const {
return d->messages.at( idx ).iodev;
}
unsigned int AssuanCommand::numBulkMessageDevices() const {
return d->messages.size();
}
QString AssuanCommand::bulkOutputDeviceFileName( unsigned int idx ) const {
return d->outputs.at( idx ).fileName;
}
shared_ptr<QIODevice> AssuanCommand::bulkOutputDevice( unsigned int idx ) const {
return d->outputs.at( idx ).iodev;
}
unsigned int AssuanCommand::numBulkOutputDevices() const {
return d->outputs.size();
}
#endif
void AssuanCommand::sendStatus( const char * keyword, const QString & text ) {
sendStatusEncoded( keyword, text.toUtf8().constData() );
}
void AssuanCommand::sendStatusEncoded( const char * keyword, const std::string & text ) {
if ( d->nohup )
return;
if ( const int err = assuan_write_status( d->ctx.get(), keyword, text.c_str() ) )
throw Exception( err, i18n( "Can't send \"%1\" status", QString::fromLatin1( keyword ) ) );
}
void AssuanCommand::sendData( const QByteArray & data, bool moreToCome ) {
if ( d->nohup )
return;
if ( const gpg_error_t err = assuan_send_data( d->ctx.get(), data.constData(), data.size() ) )
throw Exception( err, i18n( "Can't send data" ) );
if ( !moreToCome )
if ( const gpg_error_t err = assuan_send_data( d->ctx.get(), 0, 0 ) ) // flush
throw Exception( err, i18n( "Can't flush data" ) );
}
int AssuanCommand::inquire( const char * keyword, QObject * receiver, const char * slot, unsigned int maxSize ) {
assert( keyword );
assert( receiver );
assert( slot );
if ( d->nohup )
return makeError( GPG_ERR_INV_OP );
#ifdef HAVE_ASSUAN_INQUIRE_EXT
std::auto_ptr<InquiryHandler> ih( new InquiryHandler( keyword, receiver ) );
receiver->connect( ih.get(), SIGNAL(signal(int,QByteArray,QByteArray)), slot );
if ( const gpg_error_t err = assuan_inquire_ext( d->ctx.get(), keyword,
# ifndef HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT
&ih->buffer, &ih->buflen,
# endif
maxSize, InquiryHandler::handler, ih.get() ) )
return err;
ih.release();
return 0;
#else
return makeError( GPG_ERR_NOT_SUPPORTED ); // libassuan too old
#endif // HAVE_ASSUAN_INQUIRE_EXT
}
void AssuanCommand::done( const GpgME::Error& err, const QString & details ) {
if ( d->ctx && !d->done && !details.isEmpty() ) {
qDebug() << "AssuanCommand::done(): Error: " << details;
d->utf8ErrorKeepAlive = details.toUtf8();
if ( !d->nohup )
assuan_set_error( d->ctx.get(), err.encodedError(), d->utf8ErrorKeepAlive.constData() );
}
done( err );
}
void AssuanCommand::done( const GpgME::Error& err ) {
if ( !d->ctx ) {
qDebug( "AssuanCommand::done( %s ): called with NULL ctx.", err.asString() );
return;
}
if ( d->done ) {
qDebug( "AssuanCommand::done( %s ): called twice!", err.asString() );
return;
}
d->done = true;
std::for_each( d->messages.begin(), d->messages.end(),
bind( &Input::finalize, _1 ) );
std::for_each( d->inputs.begin(), d->inputs.end(),
bind( &Input::finalize, _1 ) );
std::for_each( d->outputs.begin(), d->outputs.end(),
bind( &Output::finalize, _1 ) );
d->messages.clear();
d->inputs.clear();
d->outputs.clear();
close_all( d->files ); // ### ???
// oh, hack :(
assert( assuan_get_pointer( d->ctx.get() ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( d->ctx.get() ) );
if ( d->nohup ) {
conn.nohupDone( this );
return;
}
const gpg_error_t rc = assuan_process_done( d->ctx.get(), err.encodedError() );
if ( gpg_err_code( rc ) != GPG_ERR_NO_ERROR )
qFatal( "AssuanCommand::done: assuan_process_done returned error %d (%s)",
static_cast<int>(rc), gpg_strerror(rc) );
d->utf8ErrorKeepAlive.clear();
conn.commandDone( this );
}
-void AssuanCommand::setNohup( bool nohup ) {
- d->nohup = nohup;
-}
-
bool AssuanCommand::isNohup() const {
return d->nohup;
}
-bool AssuanCommand::isDone() const {
- return d->done;
-}
-
-QString AssuanCommand::sessionTitle() const {
- return d->sessionTitle;
-}
-
-bool AssuanCommand::informativeSenders() const {
- return d->informativeSenders;
-}
-
-bool AssuanCommand::informativeRecipients() const {
- return d->informativeRecipients;
-}
-
const std::vector<KMime::Types::Mailbox> & AssuanCommand::recipients() const {
return d->recipients;
}
const std::vector<KMime::Types::Mailbox> & AssuanCommand::senders() const {
return d->senders;
}
int AssuanCommandFactory::_handle( assuan_context_t ctx, char * line, const char * commandName ) {
assert( assuan_get_pointer( ctx ) );
AssuanServerConnection::Private & conn = *static_cast<AssuanServerConnection::Private*>( assuan_get_pointer( ctx ) );
try {
const std::vector< shared_ptr<AssuanCommandFactory> >::const_iterator it
= std::lower_bound( conn.factories.begin(), conn.factories.end(), commandName, _detail::ByName<std::less>() );
kleo_assert( it != conn.factories.end() );
kleo_assert( *it );
kleo_assert( qstricmp( (*it)->name(), commandName ) == 0 );
const shared_ptr<AssuanCommand> cmd = (*it)->create();
kleo_assert( cmd );
cmd->d->ctx = conn.ctx;
cmd->d->options = conn.options;
cmd->d->inputs.swap( conn.inputs ); kleo_assert( conn.inputs.empty() );
cmd->d->messages.swap( conn.messages ); kleo_assert( conn.messages.empty() );
cmd->d->outputs.swap( conn.outputs ); kleo_assert( conn.outputs.empty() );
cmd->d->files.swap( conn.files ); kleo_assert( conn.files.empty() );
cmd->d->senders.swap( conn.senders ); kleo_assert( conn.senders.empty() );
cmd->d->recipients.swap( conn.recipients ); kleo_assert( conn.recipients.empty() );
- cmd->d->informativeRecipients = conn.informativeRecipients;
- cmd->d->informativeSenders = conn.informativeSenders;
- cmd->d->sessionTitle = conn.sessionTitle;
const std::map<std::string,std::string> cmdline_options = parse_commandline( line );
for ( std::map<std::string,std::string>::const_iterator it = cmdline_options.begin(), end = cmdline_options.end() ; it != end ; ++it )
cmd->d->options[it->first] = QString::fromUtf8( it->second.c_str() );
bool nohup = false;
if ( cmd->d->options.count( "nohup" ) ) {
if ( !cmd->d->options["nohup"].toString().isEmpty() )
return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_ASS_PARAMETER ), "--nohup takes no argument" );
nohup = true;
cmd->d->options.erase( "nohup" );
}
conn.currentCommand = cmd;
- conn.currentCommandIsNohup = nohup;
-
- QTimer::singleShot( 0, &conn, SLOT(startCommandBottomHalf()) );
-
- return 0;
-
- } catch ( const Exception & e ) {
- return assuan_process_done_msg( conn.ctx.get(), e.error_code(), e.message() );
- } catch ( const std::exception & e ) {
- return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), e.what() );
- } catch ( ... ) {
- return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), i18n("Caught unknown exception") );
- }
-}
-
-int AssuanServerConnection::Private::startCommandBottomHalf() {
-
- commandWaitingForCryptoCommandsEnabled = currentCommand && !cryptoCommandsEnabled;
-
- if ( !cryptoCommandsEnabled )
- return 0;
-
- const shared_ptr<AssuanCommand> cmd = currentCommand;
- if ( !cmd )
- return 0;
-
- currentCommand.reset();
-
- const bool nohup = currentCommandIsNohup;
- currentCommandIsNohup = false;
-
- try {
+ conn.waitForCryptoCommandsEnabled();
+ conn.currentCommand.reset();
if ( const int err = cmd->start() )
- if ( cmd->isDone() )
+ if ( cmd->d->done )
return err;
else
- return assuan_process_done( ctx.get(), err );
+ return assuan_process_done( conn.ctx.get(), err );
- if ( cmd->isDone() )
+ if ( cmd->d->done )
return 0;
if ( nohup ) {
- cmd->setNohup( true );
- nohupedCommands.push_back( cmd );
- return assuan_process_done_msg( ctx.get(), 0, "Command put in the background to continue executing after connection end." );
+ cmd->d->nohup = true;
+ conn.nohupedCommands.push_back( cmd );
+ return assuan_process_done_msg( conn.ctx.get(), 0, "Command put in the background to continue executing after connection end." );
} else {
- currentCommand = cmd;
+ conn.currentCommand = cmd;
return 0;
}
} catch ( const Exception & e ) {
- return assuan_process_done_msg( ctx.get(), e.error_code(), e.message() );
+ return assuan_process_done_msg( conn.ctx.get(), e.error_code(), e.message() );
} catch ( const std::exception & e ) {
- return assuan_process_done_msg( ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), e.what() );
+ return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), e.what() );
} catch ( ... ) {
- return assuan_process_done_msg( ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), i18n("Caught unknown exception") );
+ return assuan_process_done_msg( conn.ctx.get(), gpg_error( GPG_ERR_UNEXPECTED ), i18n("Caught unknown exception") );
}
}
//
//
// AssuanCommand convenience methods
//
//
/*!
Checks the \c --mode parameter.
\returns The parameter as an AssuanCommand::Mode enum value.
If no \c --mode was given, or it's value wasn't recognized, throws
an Kleo::Exception.
*/
AssuanCommand::Mode AssuanCommand::checkMode() const {
if ( !hasOption( "mode" ) )
throw Exception( makeError( GPG_ERR_MISSING_VALUE ), i18n( "Required --mode option missing" ) );
const QString modeString = option("mode").toString().toLower();
if ( modeString == QLatin1String( "filemanager" ) )
return FileManager;
if ( modeString == QLatin1String( "email" ) )
return EMail;
throw Exception( makeError( GPG_ERR_INV_ARG ), i18n( "invalid mode: \"%1\"", modeString ) );
}
/*!
Checks the \c --protocol parameter.
\returns The parameter as a GpgME::Protocol enum value.
If \c --protocol was given, but has an invalid value, throws an
Kleo::Exception.
If no \c --protocol was given, in FileManager mode, returns
GpgME::UnknownProtocol, but if \a mode == \c EMail, throws an
Kleo::Exception instead.
*/
GpgME::Protocol AssuanCommand::checkProtocol( Mode mode ) const {
if ( !hasOption("protocol") )
if ( mode == AssuanCommand::EMail )
throw Exception( makeError( GPG_ERR_MISSING_VALUE ), i18n( "Required --protocol option missing" ) );
else
return GpgME::UnknownProtocol;
else
if ( mode == AssuanCommand::FileManager )
throw Exception( makeError( GPG_ERR_INV_FLAG ), i18n("--protocol is not allowed here") );
const QString protocolString = option("protocol").toString().toLower();
if ( protocolString == QLatin1String( "openpgp" ) )
return GpgME::OpenPGP;
if ( protocolString == QLatin1String( "cms" ) )
return GpgME::CMS;
throw Exception( makeError( GPG_ERR_INV_ARG ), i18n( "invalid protocol \"%1\"", protocolString ) );
-}
+}
void AssuanCommand::doApplyWindowID( QWidget * widget ) const {
if ( !widget || !hasOption( "window-id" ) )
return;
const QString winIdStr = option("window-id").toString();
bool ok = false;
#ifdef Q_OS_WIN32
const WId wid = reinterpret_cast<WId>( winIdStr.toULongLong( &ok, 16 ) );
#else
const WId wid = static_cast<WId>( winIdStr.toULongLong( &ok, 16 ) );
#endif
if ( !ok ) {
qDebug() << "window-id value" << wid << "doesn't look like a number";
return;
}
if ( QWidget * pw = QWidget::find( wid ) )
widget->setParent( pw, widget->windowFlags() );
- else {
+ else {
KWindowSystem::setMainWindow( widget, wid );
}
}
static QString commonPrefix( const QString & s1, const QString & s2 ) {
return QString( s1.data(), std::mismatch( s1.data(), s1.data() + std::min( s1.size(), s2.size() ), s2.data() ).first - s1.data() );
}
static QString longestCommonPrefix( const QStringList & sl ) {
if ( sl.empty() )
return QString();
QString result = sl.front();
Q_FOREACH( const QString & s, sl )
result = commonPrefix( s, result );
return result;
}
QString AssuanCommand::heuristicBaseDirectory() const {
const QString candidate = longestCommonPrefix( fileNames() );
const QFileInfo fi( candidate );
if ( fi.isDir() )
return candidate;
else
return fi.absolutePath();
}
#include "assuanserverconnection.moc"
#include "moc_assuanserverconnection.cpp"
diff --git a/uiserver/assuanserverconnection.h b/uiserver/assuanserverconnection.h
index 6ffc9ad17..fa53a841a 100644
--- a/uiserver/assuanserverconnection.h
+++ b/uiserver/assuanserverconnection.h
@@ -1,74 +1,73 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/assuanserverconnection.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_UISERVER_ASSUANSERVERCONNECTION_H__
#define __KLEOPATRA_UISERVER_ASSUANSERVERCONNECTION_H__
#include <QObject>
#include <kleo-assuan.h> // for assuan_fd_t
#include <utils/pimpl_ptr.h>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
namespace Kleo {
class AssuanCommandFactory;
class AssuanServerConnection : public QObject {
Q_OBJECT
public:
AssuanServerConnection( assuan_fd_t fd, const std::vector< boost::shared_ptr<AssuanCommandFactory> > & factories, QObject * parent=0 );
~AssuanServerConnection();
public Q_SLOTS:
void enableCryptoCommands( bool enable=true );
Q_SIGNALS:
void closed( Kleo::AssuanServerConnection * which );
void startKeyManagerRequested();
- void startConfigDialogRequested();
public:
class Private;
private:
kdtools::pimpl_ptr<Private> d;
};
}
#endif /* __KLEOPATRA_UISERVER_ASSUANSERVERCONNECTION_H__ */
diff --git a/uiserver/decryptverifycommandemailbase.cpp b/uiserver/decryptverifycommandemailbase.cpp
index ddc22c7d0..0ba644f5e 100644
--- a/uiserver/decryptverifycommandemailbase.cpp
+++ b/uiserver/decryptverifycommandemailbase.cpp
@@ -1,219 +1,209 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/decryptverifycommandemailbase.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 "decryptverifycommandemailbase.h"
#include <crypto/decryptverifytask.h>
#include <crypto/decryptverifyemailcontroller.h>
#include <utils/formatting.h>
#include <models/keycache.h>
#include <utils/hex.h>
#include <utils/input.h>
#include <utils/output.h>
#include <utils/kleo_assert.h>
#include <utils/exception.h>
#include <kleo/cryptobackendfactory.h>
#include <gpgme++/error.h>
#include <gpgme++/key.h>
#include <gpgme++/verificationresult.h>
#include <KLocalizedString>
#include <gpg-error.h>
#include <cassert>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Formatting;
using namespace GpgME;
using namespace boost;
class DecryptVerifyCommandEMailBase::Private : public QObject {
Q_OBJECT
friend class ::Kleo::DecryptVerifyCommandEMailBase;
DecryptVerifyCommandEMailBase * const q;
public:
explicit Private( DecryptVerifyCommandEMailBase * qq )
: QObject(),
q( qq ),
controller()
{
}
~Private() {
}
void checkForErrors() const;
public Q_SLOTS:
void slotProgress( const QString & what, int current, int total );
void verificationResult( const GpgME::VerificationResult & );
void slotDone() { q->done(); }
void slotError( int err, const QString & details ) { q->done( err, details ); }
-
+
public:
private:
shared_ptr<DecryptVerifyEMailController> controller;
};
DecryptVerifyCommandEMailBase::DecryptVerifyCommandEMailBase()
: AssuanCommandMixin<DecryptVerifyCommandEMailBase>(), d( new Private( this ) )
{
}
DecryptVerifyCommandEMailBase::~DecryptVerifyCommandEMailBase() {}
int DecryptVerifyCommandEMailBase::doStart() {
d->checkForErrors();
d->controller.reset( new DecryptVerifyEMailController( shared_from_this() ) );
-
- const QString st = sessionTitle();
- if ( !st.isNull() ) {
- Q_FOREACH ( const shared_ptr<Input> & i, inputs() )
- i->setLabel( st );
- Q_FOREACH ( const shared_ptr<Output> & i, outputs() )
- i->setLabel( st );
- }
-
+
d->controller->setOperation( operation() );
d->controller->setInputs( inputs() );
d->controller->setSignedData( messages() );
d->controller->setOutputs( outputs() );
d->controller->setWizardShown( !hasOption("silent") );
d->controller->setProtocol( checkProtocol( mode() ) );
QObject::connect( d->controller.get(), SIGNAL(done()),
d.get(), SLOT(slotDone()), Qt::QueuedConnection );
QObject::connect( d->controller.get(), SIGNAL(error(int,QString)),
d.get(), SLOT(slotError(int,QString)), Qt::QueuedConnection );
- QObject::connect( d->controller.get(), SIGNAL(verificationResult(GpgME::VerificationResult)),
+ QObject::connect( d->controller.get(), SIGNAL(verificationResult(GpgME::VerificationResult)),
d.get(), SLOT(verificationResult(GpgME::VerificationResult)), Qt::QueuedConnection );
d->controller->start();
return 0;
}
void DecryptVerifyCommandEMailBase::Private::checkForErrors() const
{
- if ( !q->senders().empty() && !q->informativeSenders() )
+ if ( !q->senders().empty() )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
- i18n("Can't use non-info SENDER") );
+ i18n("Can't use SENDER") );
- if ( !q->recipients().empty() && !q->informativeRecipients() )
+ if ( !q->recipients().empty() )
throw Kleo::Exception( q->makeError( GPG_ERR_CONFLICT ),
- i18n("Can't use non-info RECIPIENT") );
-
- // ### use informative recipients and senders
+ 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 DecryptVerifyOperation op = q->operation();;
const GpgME::Protocol proto = q->checkProtocol( q->mode() );
const unsigned int numFiles = q->numFiles();
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 != Verify )
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() );
}
-
+
void DecryptVerifyCommandEMailBase::doCanceled() {
if ( d->controller )
d->controller->cancel();
}
-
+
void DecryptVerifyCommandEMailBase::Private::slotProgress( const QString& what, int current, int total )
{
// ### FIXME report progress, via sendStatus()
}
void DecryptVerifyCommandEMailBase::Private::verificationResult( const VerificationResult & vResult )
{
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, DecryptVerifyResult::keyForSignature( sig, signers ) );
const char * color = summaryToString( sig.summary() );
q->sendStatusEncoded( "SIGSTATUS",
color + ( ' ' + hexencode( s.toUtf8().constData() ) ) );
}
- } catch ( ... ) {}
+ } catch ( ... ) {}
}
#include "decryptverifycommandemailbase.moc"
diff --git a/uiserver/encryptcommand.cpp b/uiserver/encryptcommand.cpp
index 744af1338..a4b19873c 100644
--- a/uiserver/encryptcommand.cpp
+++ b/uiserver/encryptcommand.cpp
@@ -1,211 +1,202 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/encryptcommand.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 "encryptcommand.h"
#include <crypto/encryptemailcontroller.h>
#include <utils/kleo_assert.h>
#include <utils/exception.h>
-#include <utils/input.h>
-#include <utils/output.h>
#include <KLocale>
#include <QTimer>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace boost;
class EncryptCommand::Private : public QObject {
Q_OBJECT
private:
friend class ::Kleo::EncryptCommand;
EncryptCommand * const q;
public:
explicit Private( EncryptCommand * qq )
: q( qq ),
controller()
{
}
private:
void checkForErrors() const;
private Q_SLOTS:
void slotDone();
void slotError( int, const QString & );
void slotRecipientsResolved();
private:
shared_ptr<EncryptEMailController> controller;
};
EncryptCommand::EncryptCommand()
: AssuanCommandMixin<EncryptCommand>(), d( new Private( this ) )
{
}
EncryptCommand::~EncryptCommand() {}
void EncryptCommand::Private::checkForErrors() const {
if ( q->numFiles() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "ENCRYPT is an email mode command, connection seems to be in filmanager mode" ) );
- if ( !q->senders().empty() && !q->informativeSenders() )
+ if ( !q->senders().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
- i18n( "SENDER may not be given prior to ENCRYPT, except with --info" ) );
+ i18n( "SENDER may not be given prior to ENCRYPT" ) );
if ( q->inputs().empty() )
throw Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
i18n( "At least one INPUT must be present" ) );
if ( q->outputs().empty() )
throw Exception( makeError( GPG_ERR_ASS_NO_OUTPUT ),
i18n( "At least one OUTPUT must be present" ) );
if ( q->outputs().size() != q->inputs().size() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "INPUT/OUTPUT count mismatch" ) );
if ( !q->messages().empty() )
throw Exception( makeError( GPG_ERR_INV_VALUE ),
i18n( "MESSAGE command is not allowed before ENCRYPT" ) );
if ( q->hasMemento( EncryptEMailController::mementoName() ) ) {
const shared_ptr<EncryptEMailController> m = q->mementoContent< shared_ptr<EncryptEMailController> >( EncryptEMailController::mementoName() );
kleo_assert( m );
if ( m->protocol() != q->checkProtocol( EMail ) )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "Protocol given conflicts with protocol determined by PREP_ENCRYPT" ) );
if ( !q->recipients().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "New recipients added after PREP_ENCRYPT command" ) );
if ( !q->senders().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "New senders added after PREP_ENCRYPT command" ) );
} else {
- if ( q->recipients().empty() || q->informativeRecipients() )
+ if ( q->recipients().empty() )
throw Exception( makeError( GPG_ERR_MISSING_VALUE ),
- i18n( "No recipients given, or only with --info" ) );
+ i18n( "No recipients given" ) );
}
}
int EncryptCommand::doStart() {
d->checkForErrors();
const bool hasPreviousMemento = hasMemento( EncryptEMailController::mementoName() );
if ( hasPreviousMemento ) {
d->controller = mementoContent< shared_ptr<EncryptEMailController> >( EncryptEMailController::mementoName() );
removeMemento( EncryptEMailController::mementoName() );
d->controller->setExecutionContext( shared_from_this() );
} else {
d->controller.reset( new EncryptEMailController( shared_from_this(), EncryptEMailController::GpgOLMode ) );
d->controller->setProtocol( checkProtocol( EMail ) );
}
kleo_assert( d->controller );
-
+
QObject::connect( d->controller.get(), SIGNAL(recipientsResolved()), d.get(), SLOT(slotRecipientsResolved()), Qt::QueuedConnection );
QObject::connect( d->controller.get(), SIGNAL(done()), d.get(), SLOT(slotDone()), Qt::QueuedConnection );
QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)), Qt::QueuedConnection );
if ( hasPreviousMemento )
QTimer::singleShot( 0, d.get(), SLOT(slotRecipientsResolved()) );
else
d->controller->startResolveRecipients( recipients() );
return 0;
}
void EncryptCommand::Private::slotRecipientsResolved() {
//hold local shared_ptr to member as q->done() deletes *this
const shared_ptr<EncryptEMailController> cont( controller );
try {
- const QString sessionTitle = q->sessionTitle();
- if ( !sessionTitle.isNull() ) {
- Q_FOREACH ( const shared_ptr<Input> & i, q->inputs() )
- i->setLabel( sessionTitle );
- Q_FOREACH ( const shared_ptr<Output> & i, q->outputs() )
- i->setLabel( sessionTitle );
- }
cont->setInputsAndOutputs( q->inputs(), q->outputs() );
cont->start();
return;
} catch ( const Exception & e ) {
q->done( e.error(), e.message() );
} catch ( const std::exception & e ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unexpected exception in EncryptCommand::Private::slotRecipientsResolved: %1",
QString::fromLocal8Bit( e.what() ) ) );
} catch ( ... ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unknown exception in EncryptCommand::Private::slotRecipientsResolved") );
}
cont->cancel();
}
void EncryptCommand::Private::slotDone() {
q->done();
}
void EncryptCommand::Private::slotError( int err, const QString & details ) {
q->done( err, details );
}
void EncryptCommand::doCanceled() {
if ( d->controller )
d->controller->cancel();
}
#include "encryptcommand.moc"
diff --git a/uiserver/prepencryptcommand.cpp b/uiserver/prepencryptcommand.cpp
index f7d35517c..d4b253560 100644
--- a/uiserver/prepencryptcommand.cpp
+++ b/uiserver/prepencryptcommand.cpp
@@ -1,154 +1,154 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/prepencryptcommand.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 "prepencryptcommand.h"
#include <crypto/encryptemailcontroller.h>
#include <utils/exception.h>
#include <KLocale>
#include <QPointer>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace boost;
class PrepEncryptCommand::Private : public QObject {
Q_OBJECT
private:
friend class ::Kleo::PrepEncryptCommand;
PrepEncryptCommand * const q;
public:
explicit Private( PrepEncryptCommand * qq )
: q( qq ), controller() {}
private:
void checkForErrors() const;
public Q_SLOTS:
void slotRecipientsResolved();
void slotError( int, const QString & );
private:
shared_ptr<EncryptEMailController> controller;
};
PrepEncryptCommand::PrepEncryptCommand()
: AssuanCommandMixin<PrepEncryptCommand>(), d( new Private( this ) )
{
}
PrepEncryptCommand::~PrepEncryptCommand() {}
void PrepEncryptCommand::Private::checkForErrors() const {
if ( !q->inputs().empty() || !q->outputs().empty() || !q->messages().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "INPUT/OUTPUT/MESSAGE may only be given after PREP_ENCRYPT" ) );
if ( q->numFiles() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "PREP_ENCRYPT is an email mode command, connection seems to be in filemanager mode" ) );
- if ( !q->senders().empty() && !q->informativeSenders() )
+ if ( !q->senders().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
- i18n( "SENDER may not be given prior to PREP_ENCRYPT, except with --info" ) );
+ i18n( "SENDER may not be given prior to PREP_ENCRYPT" ) );
- if ( q->recipients().empty() || q->informativeRecipients() )
+ if ( q->recipients().empty() )
throw Exception( makeError( GPG_ERR_MISSING_VALUE ),
- i18n( "No recipients given, or only with --info" ) );
+ i18n( "No recipients given" ) );
}
int PrepEncryptCommand::doStart() {
removeMemento( EncryptEMailController::mementoName() );
d->checkForErrors();
d->controller.reset( new EncryptEMailController( shared_from_this(), EncryptEMailController::GpgOLMode ) );
if ( hasOption( "protocol" ) )
// --protocol is optional for PREP_ENCRYPT
d->controller->setProtocol( checkProtocol( EMail ) );
QObject::connect( d->controller.get(), SIGNAL(recipientsResolved()), d.get(), SLOT(slotRecipientsResolved()) );
QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)) );
d->controller->startResolveRecipients( recipients() );
return 0;
}
void PrepEncryptCommand::Private::slotRecipientsResolved() {
//hold local shared_ptr to member as q->done() deletes *this
const shared_ptr<EncryptEMailController> cont = controller;
QPointer<Private> that( this );
try {
q->sendStatus( "PROTOCOL", controller->protocolAsString() );
q->registerMemento( EncryptEMailController::mementoName(),
make_typed_memento( controller ) );
q->done();
return;
} catch ( const Exception & e ) {
q->done( e.error(), e.message() );
} catch ( const std::exception & e ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unexpected exception in PrepEncryptCommand::Private::slotRecipientsResolved: %1",
QString::fromLocal8Bit( e.what() ) ) );
} catch ( ... ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unknown exception in PrepEncryptCommand::Private::slotRecipientsResolved") );
}
if ( that ) // isn't this always deleted here and thus unnecessary?
q->removeMemento( EncryptEMailController::mementoName() );
cont->cancel();
}
void PrepEncryptCommand::Private::slotError( int err, const QString & details ) {
q->done( err, details );
}
void PrepEncryptCommand::doCanceled() {
if ( d->controller )
d->controller->cancel();
}
#include "prepencryptcommand.moc"
diff --git a/uiserver/signcommand.cpp b/uiserver/signcommand.cpp
index 6520c23c0..63b2fbf8d 100644
--- a/uiserver/signcommand.cpp
+++ b/uiserver/signcommand.cpp
@@ -1,190 +1,181 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/signcommand.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 "signcommand.h"
#include <crypto/signemailcontroller.h>
#include <utils/exception.h>
-#include <utils/input.h>
-#include <utils/output.h>
#include <KLocale>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace boost;
class SignCommand::Private : public QObject {
Q_OBJECT
private:
friend class ::Kleo::SignCommand;
SignCommand * const q;
public:
explicit Private( SignCommand * qq )
: q( qq ), controller()
{
}
-private:
+private:
void checkForErrors() const;
private Q_SLOTS:
void slotSignersResolved();
void slotMicAlgDetermined( const QString & );
void slotDone();
void slotError( int, const QString & );
private:
shared_ptr<SignEMailController> controller;
};
SignCommand::SignCommand()
: AssuanCommandMixin<SignCommand>(), d( new Private( this ) )
{
}
SignCommand::~SignCommand() {}
void SignCommand::Private::checkForErrors() const {
if ( q->numFiles() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
i18n( "SIGN is an email mode command, connection seems to be in filemanager mode" ) );
- if ( !q->recipients().empty() && !q->informativeRecipients() )
+ if ( !q->recipients().empty() )
throw Exception( makeError( GPG_ERR_CONFLICT ),
- i18n( "RECIPIENT may not be given prior to SIGN, except with --info" ) );
+ i18n( "RECIPIENT may not be given prior to SIGN" ) );
if ( q->inputs().empty() )
throw Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
i18n( "At least one INPUT must be present" ) );
if ( q->outputs().size() != q->inputs().size() )
throw Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
i18n( "INPUT/OUTPUT count mismatch" ) );
if ( !q->messages().empty() )
throw Exception( makeError( GPG_ERR_INV_VALUE ),
i18n( "MESSAGE command is not allowed before SIGN" ) );
}
int SignCommand::doStart() {
d->checkForErrors();
d->controller.reset( new SignEMailController( shared_from_this(), SignEMailController::GpgOLMode ) );
d->controller->setProtocol( checkProtocol( EMail ) );
QObject::connect( d->controller.get(), SIGNAL(signersResolved()), d.get(), SLOT(slotSignersResolved() ) );
QObject::connect( d->controller.get(), SIGNAL(reportMicAlg(QString)), d.get(), SLOT(slotMicAlgDetermined(QString)) );
QObject::connect( d->controller.get(), SIGNAL(done()), d.get(), SLOT(slotDone()) );
QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)) );
d->controller->startResolveSigners( senders() );
-
+
return 0;
}
void SignCommand::Private::slotSignersResolved() {
//hold local shared_ptr to member as q->done() deletes *this
const shared_ptr<SignEMailController> cont( controller );
try {
- const QString sessionTitle = q->sessionTitle();
- if ( !sessionTitle.isNull() ) {
- Q_FOREACH ( const shared_ptr<Input> & i, q->inputs() )
- i->setLabel( sessionTitle );
- Q_FOREACH ( const shared_ptr<Output> & i, q->outputs() )
- i->setLabel( sessionTitle );
- }
controller->setDetachedSignature( q->hasOption("detached" ) );
controller->setInputsAndOutputs( q->inputs(), q->outputs() );
controller->start();
return;
} catch ( const Exception & e ) {
q->done( e.error(), e.message() );
} catch ( const std::exception & e ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unexpected exception in SignCommand::Private::slotRecipientsResolved: %1",
QString::fromLocal8Bit( e.what() ) ) );
} catch ( ... ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unknown exception in SignCommand::Private::slotRecipientsResolved") );
}
cont->cancel();
}
void SignCommand::Private::slotMicAlgDetermined( const QString & micalg ) {
//hold local shared_ptr to member as q->done() deletes *this
const shared_ptr<SignEMailController> cont( controller );
try {
q->sendStatus( "MICALG", micalg );
return;
} catch ( const Exception & e ) {
q->done( e.error(), e.message() );
} catch ( const std::exception & e ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unexpected exception in SignCommand::Private::slotMicAlgDetermined: %1",
QString::fromLocal8Bit( e.what() ) ) );
} catch ( ... ) {
q->done( makeError( GPG_ERR_UNEXPECTED ),
i18n("Caught unknown exception in SignCommand::Private::slotMicAlgDetermined") );
}
cont->cancel();
}
void SignCommand::Private::slotDone() {
q->done();
}
void SignCommand::Private::slotError( int err, const QString & details ) {
q->done( err, details );
}
void SignCommand::doCanceled() {
if ( d->controller )
d->controller->cancel();
}
#include "signcommand.moc"
diff --git a/uiserver/uiserver.cpp b/uiserver/uiserver.cpp
index 4c458c753..925ebf20a 100644
--- a/uiserver/uiserver.cpp
+++ b/uiserver/uiserver.cpp
@@ -1,224 +1,217 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/uiserver.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 "uiserver.h"
#include "uiserver_p.h"
#include <utils/detail_p.h>
#include <utils/exception.h>
#include <utils/stl_util.h>
#include <KLocalizedString>
#include <QTcpSocket>
#include <QDir>
#include <QEventLoop>
#include <QTimer>
#include <QFile>
#include <boost/range/empty.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <cassert>
using namespace Kleo;
using namespace boost;
-// static
-void UiServer::setLogStream( FILE * stream ) {
- assuan_set_assuan_log_stream( stream );
-}
-
UiServer::Private::Private( UiServer * qq )
: QTcpServer(),
q( qq ),
tmpDir( tmpDirPrefix() ),
file(),
factories(),
connections(),
suggestedSocketName(),
actualSocketName(),
cryptoCommandsEnabled( false )
{
assuan_set_assuan_err_source( GPG_ERR_SOURCE_DEFAULT );
}
bool UiServer::Private::isStaleAssuanSocket( const QString& fileName )
{
assuan_context_t ctx = 0;
const bool error = assuan_socket_connect_ext( &ctx, QFile::encodeName( fileName ).constData(), -1, 0 );
if ( !error )
assuan_disconnect( ctx );
return error;
}
UiServer::UiServer( const QString & socket, QObject * p )
: QObject( p ), d( new Private( this ) )
{
d->suggestedSocketName = d->makeFileName( socket );
}
UiServer::~UiServer() {
if ( QFile::exists( d->actualSocketName ) )
QFile::remove( d->actualSocketName );
}
bool UiServer::registerCommandFactory( const shared_ptr<AssuanCommandFactory> & cf ) {
if ( cf && empty( std::equal_range( d->factories.begin(), d->factories.end(), cf, _detail::ByName<std::less>() ) ) ) {
d->factories.push_back( cf );
std::inplace_merge( d->factories.begin(), d->factories.end() - 1, d->factories.end(), _detail::ByName<std::less>() );
return true;
} else {
qWarning( "UiServer::registerCommandFactory( %p ): factory NULL or already registered", cf ? cf.get() : 0 );
return false;
}
}
void UiServer::start() {
d->makeListeningSocket();
}
void UiServer::stop() {
d->close();
if ( d->file.exists() )
d->file.remove();
}
void UiServer::enableCryptoCommands( bool on ) {
if ( on == d->cryptoCommandsEnabled )
return;
d->cryptoCommandsEnabled = on;
kdtools::for_each( d->connections,
bind( &AssuanServerConnection::enableCryptoCommands, _1, on ) );
}
QString UiServer::socketName() const {
return d->actualSocketName;
}
bool UiServer::waitForStopped( unsigned int ms ) {
if ( isStopped() )
return true;
QEventLoop loop;
QTimer timer;
timer.setInterval( ms );
timer.setSingleShot( true );
connect( &timer, SIGNAL(timeout()), &loop, SLOT(quit()) );
connect( this, SIGNAL(stopped()), &loop, SLOT(quit()) );
loop.exec();
return !timer.isActive();
}
bool UiServer::isStopped() const {
return d->connections.empty() && !d->isListening() ;
}
bool UiServer::isStopping() const {
return !d->connections.empty() && !d->isListening() ;
}
void UiServer::Private::slotConnectionClosed( Kleo::AssuanServerConnection * conn ) {
qDebug( "UiServer: connection %p closed", conn );
connections.erase( std::remove_if( connections.begin(), connections.end(),
boost::bind( &boost::shared_ptr<AssuanServerConnection>::get, _1 ) == conn ),
connections.end() );
if ( q->isStopped() )
emit q->stopped();
}
void UiServer::Private::incomingConnection( int fd ) {
try {
qDebug( "UiServer: client connect on fd %d", fd );
#ifdef HAVE_ASSUAN_SOCK_GET_NONCE
if ( assuan_sock_check_nonce( (assuan_fd_t)fd, &nonce ) ) {
qDebug( "UiServer: nonce check failed" );
assuan_sock_close( (assuan_fd_t)fd );
return;
}
#endif
const shared_ptr<AssuanServerConnection> c( new AssuanServerConnection( (assuan_fd_t)fd, factories ) );
connect( c.get(), SIGNAL(closed(Kleo::AssuanServerConnection*)),
this, SLOT(slotConnectionClosed(Kleo::AssuanServerConnection*)) );
connect( c.get(), SIGNAL(startKeyManagerRequested()),
q, SIGNAL(startKeyManagerRequested()), Qt::QueuedConnection );
- connect( c.get(), SIGNAL(startConfigDialogRequested()),
- q, SIGNAL(startConfigDialogRequested()), Qt::QueuedConnection );
c->enableCryptoCommands( cryptoCommandsEnabled );
connections.push_back( c );
qDebug( "UiServer: client connection %p established successfully", c.get() );
} catch ( const Exception & e ) {
qDebug( "UiServer: client connection failed: %s", e.what() );
QTcpSocket s;
s.setSocketDescriptor( fd );
QTextStream( &s ) << "ERR " << e.error_code() << " " << e.what() << "\r\n";
s.waitForBytesWritten();
s.close();
} catch ( ... ) {
qDebug( "UiServer: client connection failed: unknown exception caught" );
// this should never happen...
QTcpSocket s;
s.setSocketDescriptor( fd );
QTextStream( &s ) << "ERR 63 unknown exception caught\r\n";
s.waitForBytesWritten();
s.close();
}
}
void UiServer::Private::makeListeningSocket() {
// First, create a file (we do this only for the name, gmpfh)
const QString fileName = suggestedSocketName;
if ( QFile::exists( fileName ) ) {
if ( isStaleAssuanSocket( fileName ) ) {
QFile::remove( fileName );
} else {
throw_<std::runtime_error>( i18n( "Detected another running gnupg UI server listening at %1.", fileName ) );
}
}
doMakeListeningSocket( QFile::encodeName( fileName ) );
actualSocketName = suggestedSocketName;
}
#include "moc_uiserver_p.cpp"
#include "moc_uiserver.cpp"
diff --git a/uiserver/uiserver.h b/uiserver/uiserver.h
index b18b4fb52..28ea9c516 100644
--- a/uiserver/uiserver.h
+++ b/uiserver/uiserver.h
@@ -1,82 +1,79 @@
/* -*- mode: c++; c-basic-offset:4 -*-
uiserver/uiserver.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_UISERVER_UISERVER_H__
#define __KLEOPATRA_UISERVER_UISERVER_H__
#include <QObject>
#include <utils/pimpl_ptr.h>
#include <boost/shared_ptr.hpp>
class QString;
namespace Kleo {
class AssuanCommandFactory;
class UiServer : public QObject {
Q_OBJECT
public:
explicit UiServer( const QString & socket, QObject * parent=0 );
~UiServer();
- static void setLogStream( FILE * file );
-
bool registerCommandFactory( const boost::shared_ptr<AssuanCommandFactory> & cmdFactory );
bool waitForStopped( unsigned int ms=0xFFFFFFFF );
bool isStopped() const;
bool isStopping() const;
QString socketName() const;
public Q_SLOTS:
void start();
void stop();
void enableCryptoCommands( bool enable=true );
Q_SIGNALS:
void stopped();
void startKeyManagerRequested();
- void startConfigDialogRequested();
private:
class Private;
kdtools::pimpl_ptr<Private> d;
};
}
#endif /* __KLEOPATRA_UISERVER_UISERVER_H__ */
diff --git a/utils/classify.cpp b/utils/classify.cpp
index 8a5db0f5f..aa4cd3140 100644
--- a/utils/classify.cpp
+++ b/utils/classify.cpp
@@ -1,280 +1,251 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/classify.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 "classify.h"
#include <QString>
#include <QStringList>
#include <QFile>
#include <QFileInfo>
#include <QtAlgorithms>
#include <QByteArrayMatcher>
#include <boost/range.hpp>
#ifdef __GNUC__
# include <ext/algorithm>
#endif
#include <functional>
using namespace boost;
using namespace Kleo::Class;
namespace {
const unsigned int ExamineContentHint = 0x8000;
static const struct _classification {
char extension[4];
unsigned int classification;
} classifications[] = {
// ordered by extension
{ "asc", OpenPGP| Ascii | OpaqueSignature|DetachedSignature|CipherText|AnyCertStoreType | ExamineContentHint },
{ "crt", CMS | Binary | Certificate },
{ "der", CMS | Binary | Certificate },
{ "gpg", OpenPGP| Binary | OpaqueSignature|CipherText|AnyCertStoreType },
{ "p10", CMS | Ascii | CertificateRequest },
{ "p12", CMS | Binary | ExportedPSM },
{ "p7c", CMS | Binary | Certificate },
{ "p7m", CMS | Binary | CipherText },
{ "p7s", CMS | Binary | AnySignature },
{ "pem", CMS | Ascii | AnyType | ExamineContentHint },
{ "sig", OpenPGP|AnyFormat| DetachedSignature },
};
static const unsigned int defaultClassification = NoClass;
template <template <typename U> class Op>
struct ByExtension {
typedef bool result_type;
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const {
return Op<int>()( qstricmp( lhs.extension, rhs.extension ), 0 );
}
template <typename T>
bool operator()( const T & lhs, const char * rhs ) const {
return Op<int>()( qstricmp( lhs.extension, rhs ), 0 );
}
template <typename T>
bool operator()( const char * lhs, const T & rhs ) const {
return Op<int>()( qstricmp( lhs, rhs.extension ), 0 );
}
bool operator()( const char * lhs, const char * rhs ) const {
return Op<int>()( qstricmp( lhs, rhs ), 0 );
}
};
static const struct _content_classification {
char content[28];
unsigned int classification;
} content_classifications[] = {
- { "CERTIFICATE", Certificate },
{ "MESSAGE", OpaqueSignature|CipherText },
- { "PKCS12", ExportedPSM },
{ "PRIVATE KEY BLOCK", ExportedPSM },
{ "PUBLIC KEY BLOCK", Certificate },
{ "SIGNATURE", DetachedSignature },
{ "SIGNED MESSAGE", ClearsignedMessage },
};
template <template <typename U> class Op>
struct ByContent {
typedef bool result_type;
const unsigned int N;
explicit ByContent( unsigned int n ) : N( n ) {}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const {
return Op<int>()( qstrncmp( lhs.content, rhs.content, N ), 0 );
}
template <typename T>
bool operator()( const T & lhs, const char * rhs ) const {
return Op<int>()( qstrncmp( lhs.content, rhs, N ), 0 );
}
template <typename T>
bool operator()( const char * lhs, const T & rhs ) const {
return Op<int>()( qstrncmp( lhs, rhs.content, N ), 0 );
}
bool operator()( const char * lhs, const char * rhs ) const {
return Op<int>()( qstrncmp( lhs, rhs, N ), 0 );
}
};
}
unsigned int Kleo::classify( const QString & filename ) {
#ifdef __GNUC__
assert( __gnu_cxx::is_sorted( begin( classifications ), end( classifications ), ByExtension<std::less>() ) );
#endif
const QFileInfo fi( filename );
const _classification * const it = qBinaryFind( begin( classifications ), end( classifications ),
fi.suffix().toLatin1().constData(),
ByExtension<std::less>() );
if ( it == end( classifications ) )
return defaultClassification;
if ( !( it->classification & ExamineContentHint ) )
return it->classification;
QFile file( filename );
if ( !file.open( QIODevice::ReadOnly|QIODevice::Text ) )
return it->classification;
- const unsigned int contentClassification = classifyContent( file.read( 4096 ) );
+ const unsigned int contentClassification = classifyContent( file.read( 1024 ) );
if ( contentClassification != defaultClassification )
return contentClassification;
else
return it->classification;
}
unsigned int Kleo::classifyContent( const QByteArray & data ) {
#ifdef __GNUC__
assert( __gnu_cxx::is_sorted( begin( content_classifications ), end( content_classifications ), ByContent<std::less>(100) ) );
#endif
-
+
static const char beginString[] = "-----BEGIN ";
static const QByteArrayMatcher beginMatcher( beginString );
int pos = beginMatcher.indexIn( data );
if ( pos < 0 )
return defaultClassification;
pos += sizeof beginString - 1;
const bool pgp = qstrncmp( data.data() + pos, "PGP ", 4 ) == 0;
if ( pgp )
pos += 4;
const int epos = data.indexOf( "-----\n", pos );
if ( epos < 0 )
return defaultClassification;
const _content_classification * const cit
= qBinaryFind( begin( content_classifications ), end( content_classifications ),
data.data() + pos, ByContent<std::less>( epos - pos ) );
if ( cit == end( content_classifications ) )
return defaultClassification;
else
return cit->classification | ( pgp ? OpenPGP : CMS );
}
-QString Kleo::printableClassification( unsigned int classification ) {
- QStringList parts;
- if ( classification & CMS )
- parts.push_back( "CMS" );
- if ( classification & OpenPGP )
- parts.push_back( "OpenPGP" );
- if ( classification & Binary )
- parts.push_back( "Binary" );
- if ( classification & Ascii )
- parts.push_back( "Ascii" );
- if ( classification & DetachedSignature )
- parts.push_back( "DetachedSignature" );
- if ( classification & OpaqueSignature )
- parts.push_back( "OpaqueSignature" );
- if ( classification & ClearsignedMessage )
- parts.push_back( "ClearsignedMessage" );
- if ( classification & CipherText )
- parts.push_back( "CipherText" );
- if ( classification & Certificate )
- parts.push_back( "Certificate" );
- if ( classification & ExportedPSM )
- parts.push_back( "ExportedPSM" );
- if ( classification & CertificateRequest )
- parts.push_back( "CertificateRequest" );
- return parts.join( ", " );
-}
-
static QString chopped( QString s, unsigned int n ) {
s.chop( n );
return s;
}
/*!
\return the data file that corresponds to the signature file \a
signatureFileName, or QString(), if no such file can be found.
*/
QString Kleo::findSignedData( const QString & signatureFileName ) {
if ( !mayBeDetachedSignature( signatureFileName ) )
return QString();
const QString baseName = chopped( signatureFileName, 4 );
return QFile::exists( baseName ) ? baseName : QString() ;
}
/*!
\return all (existing) candiate signature files for \a signedDataFileName
Note that there can very well be more than one such file, e.g. if
the same data file was signed by both CMS and OpenPGP certificates.
*/
QStringList Kleo::findSignatures( const QString & signedDataFileName ) {
QStringList result;
for ( unsigned int i = 0, end = size( classifications ) ; i < end ; ++i )
if ( classifications[i].classification & DetachedSignature ) {
const QString candiate = signedDataFileName + '.' + classifications[i].extension;
if ( QFile::exists( candiate ) )
result.push_back( candiate );
}
return result;
}
/*!
\return the (likely) output filename for \a inputFileName, or
"inputFileName.out" if none can be determined.
*/
QString Kleo::outputFileName( const QString & inputFileName ) {
const QFileInfo fi( inputFileName );
if ( qBinaryFind( begin( classifications ), end( classifications ),
fi.suffix().toLatin1().constData(),
ByExtension<std::less>() ) == end( classifications ) )
return inputFileName + ".out";
else
return chopped( inputFileName, 4 );
}
/*!
\return the commonly used extension for files of type
\a classification, or NULL if none such exists.
*/
const char * Kleo::outputFileExtension( unsigned int classification ) {
for ( unsigned int i = 0 ; i < sizeof classifications / sizeof *classifications ; ++i )
if ( ( classifications[i].classification & classification ) == classification )
return classifications[i].extension;
return 0;
}
diff --git a/utils/classify.h b/utils/classify.h
index 7fe6a0eef..17a980a0d 100644
--- a/utils/classify.h
+++ b/utils/classify.h
@@ -1,135 +1,133 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/classify.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.
*/
#include <gpgme++/global.h>
#ifndef __KLEOPATRA_UISERVER_CLASSIFY_H__
#define __KLEOPATRA_UISERVER_CLASSIFY_H__
class QString;
class QStringList;
namespace Kleo {
namespace Class {
enum {
NoClass = 0,
// protocol:
CMS = 0x01,
OpenPGP = 0x02,
AnyProtocol = OpenPGP|CMS,
ProtocolMask = AnyProtocol,
// format:
Binary = 0x04,
Ascii = 0x08,
AnyFormat = Binary|Ascii,
FormatMask = AnyFormat,
// type:
DetachedSignature = 0x010,
OpaqueSignature = 0x020,
ClearsignedMessage = 0x040,
AnySignature = DetachedSignature|OpaqueSignature|ClearsignedMessage,
CipherText = 0x080,
AnyMessageType = AnySignature|CipherText,
Certificate = 0x100,
ExportedPSM = 0x200,
AnyCertStoreType = Certificate|ExportedPSM,
CertificateRequest = 0x400,
AnyType = AnyMessageType|AnyCertStoreType|CertificateRequest,
TypeMask = AnyType
};
}
unsigned int classify( const QString & filename );
unsigned int classifyContent( const QByteArray & data );
QString findSignedData( const QString & signatureFileName );
QStringList findSignatures( const QString & signedDataFileName );
QString outputFileName( const QString & input );
const char * outputFileExtension( unsigned int classification );
- QString printableClassification( unsigned int classification );
-
#define make_convenience( What, Mask ) \
inline bool is##What( const QString & filename ) { \
return ( classify( filename ) & Class::Mask ) == Class::What ; \
} \
inline bool is##What( const unsigned int classifcation ) { \
return ( classifcation & Class::Mask ) == Class::What ; \
} \
inline bool mayBe##What( const QString & filename ) { \
return classify( filename ) & Class::What ; \
} \
inline bool mayBe##What( const unsigned int classifcation ) { \
return classifcation & Class::What ; \
}
make_convenience( CMS, ProtocolMask )
make_convenience( OpenPGP, ProtocolMask )
make_convenience( Binary, FormatMask )
make_convenience( Ascii, FormatMask )
make_convenience( DetachedSignature, TypeMask )
make_convenience( OpaqueSignature, TypeMask )
make_convenience( CipherText, TypeMask )
make_convenience( AnyMessageType, TypeMask )
#undef make_convenience
inline GpgME::Protocol findProtocol( const unsigned int classifcation ) {
if ( isOpenPGP( classifcation ) )
return GpgME::OpenPGP;
else if ( isCMS( classifcation ) )
return GpgME::CMS;
else
return GpgME::UnknownProtocol;
}
inline GpgME::Protocol findProtocol( const QString & filename ) {
return findProtocol( classify( filename ) );
}
}
#endif /* __KLEOPATRA_UISERVER_CLASSIFY_H__ */
diff --git a/utils/dragqueen.cpp b/utils/dragqueen.cpp
index a43cfd3d9..e69de29bb 100644
--- a/utils/dragqueen.cpp
+++ b/utils/dragqueen.cpp
@@ -1,198 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- utils/dragqueen.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 "dragqueen.h"
-
-#include <QDrag>
-#include <QMouseEvent>
-#include <QStringList>
-#include <QVariant>
-#include <QApplication>
-#include <QUrl>
-#include <QStyle>
-
-#include <algorithm>
-
-using namespace Kleo;
-
-namespace {
- class MimeDataProxy : public QMimeData {
- Q_OBJECT
- public:
- explicit MimeDataProxy( QMimeData * source )
- : QMimeData(), m_source( source )
- {
-
- }
-
- /* reimp */ QStringList formats() const {
- if ( m_source )
- return m_source->formats();
- else
- return QStringList();
- }
-
- /* reimp */ bool hasFormat( const QString & format ) const {
- return m_source && m_source->hasFormat( format );
- }
-
- protected:
- /* reimp */ QVariant retrieveData( const QString & format, QVariant::Type type ) const {
- if ( !m_source )
- return QVariant();
- // Doesn't work, is protected:
- // return m_source->retrieveData( format, type );
-
- switch ( type ) {
- case QVariant::String:
- if ( format == QLatin1String( "text/plain" ) )
- return m_source->text();
- if ( format == QLatin1String( "text/html" ) )
- return m_source->html();
- break;
- case QVariant::Color:
- if ( format == QLatin1String( "application/x-color" ) )
- return m_source->colorData();
- break;
- case QVariant::Image:
- if ( format == QLatin1String( "application/x-qt-image" ) )
- return m_source->imageData();
- break;
- case QVariant::List:
- case QVariant::Url:
- if ( format == QLatin1String( "text/uri-list" ) ) {
- const QList<QUrl> urls = m_source->urls();
- if ( urls.size() == 1 )
- return urls.front();
- QList<QVariant> result;
- std::copy( urls.begin(), urls.end(),
- std::back_inserter( result ) );
- return result;
- }
- break;
- default:
- break;
- }
-
- QVariant v = m_source->data( format );
- v.convert( type );
- return v;
- }
- private:
- QPointer<QMimeData> m_source;
- };
-}
-
-
-DragQueen::DragQueen( QWidget * p, Qt::WindowFlags f )
- : QLabel( p, f ),
- m_data(),
- m_dragStartPosition()
-{
-
-}
-
-DragQueen::DragQueen( const QString & t, QWidget * p, Qt::WindowFlags f )
- : QLabel( t, p, f ),
- m_data(),
- m_dragStartPosition()
-{
-
-}
-
-DragQueen::~DragQueen() {
- delete m_data;
-}
-
-void DragQueen::setUrl( const QString & url ) {
- QMimeData * data = new QMimeData;
- QList<QUrl> urls;
- urls.push_back( QUrl( url ) );
- data->setUrls( urls );
- setMimeData( data );
-}
-
-QString DragQueen::url() const {
- if ( !m_data || !m_data->hasUrls() )
- return QString();
- const QList<QUrl> urls = m_data->urls();
- if ( urls.empty() )
- return QString();
- return urls.front().toString();
-}
-
-void DragQueen::setMimeData( QMimeData * data ) {
- if ( data == m_data )
- return;
- delete m_data;
- m_data = data;
-}
-
-QMimeData * DragQueen::mimeData() const {
- return m_data;
-}
-
-void DragQueen::mousePressEvent( QMouseEvent * e ) {
- if ( m_data && e->button() == Qt::LeftButton )
- m_dragStartPosition = e->pos();
- QLabel::mousePressEvent( e );
-}
-
-static QPoint calculate_hot_spot( const QPoint & mouse, const QSize & pix, const QLabel * label ) {
- const Qt::Alignment align = label->alignment();
- const int margin = label->margin();
- const QRect cr = label->contentsRect().adjusted( margin, margin, -margin, -margin );
- const QRect rect = QStyle::alignedRect( QApplication::layoutDirection(), align, pix, cr );
- return mouse - rect.topLeft();
-}
-
-void DragQueen::mouseMoveEvent( QMouseEvent * e ) {
- if ( m_data &&
- (e->buttons() & Qt::LeftButton) &&
- ( m_dragStartPosition - e->pos() ).manhattanLength() > QApplication::startDragDistance() ) {
- QDrag * drag = new QDrag( this );
- if ( const QPixmap * const pix = pixmap() ) {
- drag->setPixmap( *pix );
- drag->setHotSpot( calculate_hot_spot( e->pos(), pix->size(), this ) );
- }
- drag->setMimeData( new MimeDataProxy( m_data ) );
- drag->exec();
- } else {
- QLabel::mouseMoveEvent( e );
- }
-}
-
-#include "moc_dragqueen.cpp"
-#include "dragqueen.moc"
diff --git a/utils/dragqueen.h b/utils/dragqueen.h
index 50dee5ddd..e69de29bb 100644
--- a/utils/dragqueen.h
+++ b/utils/dragqueen.h
@@ -1,72 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- utils/dragqueen.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_UTILS_DRAGQUEEN_H__
-#define __KLEOPATRA_UTILS_DRAGQUEEN_H__
-
-#include <QLabel>
-#include <QPointer>
-#include <QPoint>
-#include <QMimeData>
-
-class QUrl;
-
-namespace Kleo {
-
- class DragQueen : public QLabel {
- Q_OBJECT
- Q_PROPERTY( QString url READ url WRITE setUrl )
- public:
- explicit DragQueen( QWidget * p=0, Qt::WindowFlags f=0 );
- explicit DragQueen( const QString & text, QWidget * p=0, Qt::WindowFlags f=0 );
- ~DragQueen();
-
- void setUrl( const QString & url );
- QString url() const;
-
- void setMimeData( QMimeData * md );
- QMimeData * mimeData() const;
-
- protected:
- /* reimp */ void mousePressEvent( QMouseEvent * );
- /* reimp */ void mouseMoveEvent( QMouseEvent * );
-
- private:
- QPointer<QMimeData> m_data;
- QPoint m_dragStartPosition;
- QString m_dataFormat;
- };
-
-}
-
-#endif // __KLEOPATRA_CRYPTO_GUI_DRAGQUEEN_H__
-
diff --git a/utils/formatting.cpp b/utils/formatting.cpp
index 5ef871b28..9c086f823 100644
--- a/utils/formatting.cpp
+++ b/utils/formatting.cpp
@@ -1,586 +1,510 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/formatting.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 "formatting.h"
#include <utils/kleo_assert.h>
#include <kleo/dn.h>
-#include <kmime/kmime_header_parsing.h>
-
#include <gpgme++/key.h>
#include <gpgme++/importresult.h>
#include <KLocale>
#include <KGlobal>
#include <QString>
#include <QStringList>
#include <QDateTime>
#include <QCoreApplication>
#include <QTextDocument> // for Qt::escape
using namespace GpgME;
using namespace Kleo;
-using namespace KMime::Types;
-using namespace KMime::HeaderParsing;
//
// Name
//
QString Formatting::prettyName( int proto, const char * id, const char * name_, const char * comment_ ) {
if ( proto == OpenPGP ) {
const QString name = QString::fromUtf8( name_ );
if ( name.isEmpty() )
return QString();
const QString comment = QString::fromUtf8( comment_ );
if ( comment.isEmpty() )
return name;
return QString::fromLatin1( "%1 (%2)" ).arg( name, comment );
}
if ( proto == CMS ) {
const DN subject( id );
const QString cn = subject["CN"].trimmed();
if ( cn.isEmpty() )
return subject.prettyDN();
return cn;
}
return QString();
}
-QString Formatting::prettyNameAndEMail( int proto, const char * id, const char * name_, const char * email_, const char * comment_ ) {
- return prettyNameAndEMail( proto, QString::fromUtf8( id ), QString::fromUtf8( name_ ), prettyEMail( email_, id ), QString::fromUtf8( comment_ ) );
-}
-
-QString Formatting::prettyNameAndEMail( int proto, const QString & id, const QString & name, const QString & email, const QString & comment ) {
-
- if ( proto == OpenPGP ) {
- if ( name.isEmpty() )
- if ( email.isEmpty() )
- return QString();
- else if ( comment.isEmpty() )
- return QString::fromLatin1( "<%1>" ).arg( email );
- else
- return QString::fromLatin1( "(%2) <%1>" ).arg( email, comment );
- if ( email.isEmpty() )
- if ( comment.isEmpty() )
- return name;
- else
- return QString::fromLatin1( "%1 (%2)" ).arg( name, comment );
- if ( comment.isEmpty() )
- return QString::fromLatin1( "%1 <%2>" ).arg( name, email );
- else
- return QString::fromLatin1( "%1 (%3) <%2>" ).arg( name, email, comment );
- }
-
- if ( proto == CMS ) {
- const DN subject( id );
- const QString cn = subject["CN"].trimmed();
- if ( cn.isEmpty() )
- return subject.prettyDN();
- return cn;
- }
- return QString();
-}
-
-QString Formatting::prettyUserID( const UserID & uid ) {
- if ( uid.parent().protocol() == OpenPGP )
- return prettyNameAndEMail( uid );
- const QByteArray id = QByteArray( uid.id() ).trimmed();
- if ( id.startsWith( '<' ) )
- return prettyEMail( uid.email(), uid.id() );
- if ( id.startsWith( '(' ) )
- // ### parse uri/dns:
- return QString::fromUtf8( uid.id() );
- else
- return DN( uid.id() ).prettyDN();
-}
-
-QString Formatting::prettyKeyID( const char * id ) {
- if ( !id )
- return QString();
- return "0x" + QString::fromLatin1( id ).toUpper();
-}
-
-QString Formatting::prettyNameAndEMail( const UserID & uid ) {
- return prettyNameAndEMail( uid.parent().protocol(), uid.id(), uid.name(), uid.email(), uid.comment() );
-}
-
-QString Formatting::prettyNameAndEMail( const Key & key ) {
- return prettyNameAndEMail( key.userID( 0 ) );
-}
-
QString Formatting::prettyName( const Key & key ) {
return prettyName( key.userID( 0 ) );
}
QString Formatting::prettyName( const UserID & uid ) {
return prettyName( uid.parent().protocol(), uid.id(), uid.name(), uid.comment() );
}
QString Formatting::prettyName( const UserID::Signature & sig ) {
return prettyName( OpenPGP, sig.signerUserID(), sig.signerName(), sig.signerComment() );
}
//
// EMail
//
QString Formatting::prettyEMail( const Key & key ) {
for ( unsigned int i = 0, end = key.numUserIDs() ; i < end ; ++i ) {
const QString email = prettyEMail( key.userID( i ) );
if ( !email.isEmpty() )
return email;
}
return QString();
}
QString Formatting::prettyEMail( const UserID & uid ) {
return prettyEMail( uid.email(), uid.id() );
}
QString Formatting::prettyEMail( const UserID::Signature & sig ) {
return prettyEMail( sig.signerEmail(), sig.signerUserID() );
}
QString Formatting::prettyEMail( const char * email_, const char * id ) {
- Mailbox mailBox;
- if ( email_ && parseMailbox( email_, email_ + strlen( email_ ), mailBox ) )
- return mailBox.addrSpec().asPrettyString();
- else
- return DN( id )["EMAIL"].trimmed();
+ const QString email = QString::fromUtf8( email_ ).trimmed();
+ if ( !email.isEmpty() )
+ if ( email.startsWith( '<' ) && email.endsWith( '>' ) )
+ return email.mid( 1, email.length() - 2 );
+ else
+ return email;
+ return DN( id )["EMAIL"].trimmed();
}
//
// Tooltip
//
namespace {
template <typename T_arg>
QString format_row( const QString & field, const T_arg & arg ) {
return i18n( "<tr><th>%1:</th><td>%2</td></tr>", field, arg );
}
QString format_row( const QString & field, const QString & arg ) {
// ### strings like <foo@bar.com> are only not interpreted as HTML tag if escaped twice
// happened Qt 4.3.3 and Qt 4.4rc1. Change back to one escape() call if you see entities like &lt; in tooltips
return i18n( "<tr><th>%1:</th><td>%2</td></tr>", field, Qt::escape( Qt::escape( arg ) ) );
}
QString format_row( const QString & field, const char * arg ) {
return format_row( field, QString::fromUtf8( arg ) );
}
QString format_keytype( const Key & key ) {
const Subkey subkey = key.subkey( 0 );
if ( key.hasSecret() )
return i18n( "%1-bit %2 (secret key available)", subkey.length(), subkey.publicKeyAlgorithmAsString() );
else
return i18n( "%1-bit %2", subkey.length(), subkey.publicKeyAlgorithmAsString() );
}
QString format_keyusage( const Key & key ) {
QStringList capabilites;
if ( key.canSign() )
if ( key.isQualified() )
capabilites.push_back( i18n( "Signing EMails and Files (Qualified)" ) );
else
capabilites.push_back( i18n( "Signing EMails and Files" ) );
if ( key.canEncrypt() )
capabilites.push_back( i18n( "Encrypting EMails and Files" ) );
if ( key.canCertify() )
capabilites.push_back( i18n( "Certifying other Certificates" ) );
if ( key.canAuthenticate() )
capabilites.push_back( i18n( "Authenticate against Servers" ) );
return capabilites.join( i18n(", ") );
}
static QString time_t2string( time_t t ) {
QDateTime dt;
dt.setTime_t( t );
return KGlobal::locale()->formatDateTime( dt, KLocale::ShortDate );
}
static QString make_red( const QString & txt ) {
return QLatin1String( "<font color=\"red\">" ) + Qt::escape( txt ) + QLatin1String( "</font>" );
}
}
QString Formatting::toolTip( const Key & key, int flags ) {
if ( flags == 0 || key.protocol() != CMS && key.protocol() != OpenPGP )
return QString();
const Subkey subkey = key.subkey( 0 );
QString result;
- if ( flags & Validity )
+ if ( flags & Validity )
if ( key.protocol() == OpenPGP || ( key.keyListMode() & Validate ) )
if ( key.isRevoked() )
result += make_red( i18n( "This certificate has been revoked." ) );
else if ( key.isExpired() )
result += make_red( i18n( "This certificate has expired." ) );
else if ( key.isDisabled() )
result += i18n( "This certificate has been disabled locally." );
else
- result += i18n( "This certificate is currently valid." );
+ result += i18n( "This certificate appears to be valid." );
else
result += i18n( "The validity of this certificate cannot be checked at the moment." );
if ( flags == Validity )
return result;
result += QLatin1String( "<table border=\"0\">" );
if ( key.protocol() == CMS ) {
if ( flags & SerialNumber )
result += format_row( i18n("Serial number"), key.issuerSerial() );
if ( flags & Issuer )
result += format_row( i18n("Issuer"), key.issuerName() );
}
if ( flags & UserIDs ) {
- const std::vector<UserID> uids = key.userIDs();
- if ( !uids.empty() )
- result += format_row( key.protocol() == CMS
- ? i18n("Subject")
- : i18n("User-ID"), prettyUserID( uids.front() ) );
- if ( uids.size() > 1 )
- for ( std::vector<UserID>::const_iterator it = uids.begin() + 1, end = uids.end() ; it != end ; ++it )
- if ( !it->isRevoked() && !it->isInvalid() )
- result += format_row( i18n("a.k.a."), prettyUserID( *it ) );
+ result += format_row( key.protocol() == CMS
+ ? i18n("Subject")
+ : i18n("User-ID"), key.userID( 0 ).id() );
+ for ( unsigned int i = 1, end = key.numUserIDs() ; i < end ; ++i )
+ result += format_row( i18n("a.k.a."), key.userID( i ).id() );
}
if ( flags & ExpiryDates )
result += format_row( i18n("Validity"),
subkey.neverExpires()
? i18n( "from %1 until forever", time_t2string( subkey.creationTime() ) )
: i18n( "from %1 through %2", time_t2string( subkey.creationTime() ), time_t2string( subkey.expirationTime() ) ) );
if ( flags & CertificateType )
result += format_row( i18n("Certificate type"), format_keytype( key ) );
if ( flags & CertificateUsage )
result += format_row( i18n("Certificate usage"), format_keyusage( key ) );
if ( flags & Fingerprint )
result += format_row( i18n("Fingerprint"), key.primaryFingerprint() );
result += QLatin1String( "</table><br>" );
return result;
}
//
// Creation and Expiration
//
namespace {
static QDate time_t2date( time_t t ) {
if ( !t )
return QDate();
QDateTime dt;
dt.setTime_t( t );
return dt.date();
}
static QString date2string( const QDate & date ) {
return KGlobal::locale()->formatDate( date, KLocale::ShortDate );
}
template <typename T>
QString expiration_date_string( const T & tee ) {
return tee.neverExpires() ? QString() : date2string( time_t2date( tee.expirationTime() ) ) ;
}
template <typename T>
QDate creation_date( const T & tee ) {
return time_t2date( tee.creationTime() );
}
template <typename T>
QDate expiration_date( const T & tee ) {
return time_t2date( tee.expirationTime() );
}
}
QString Formatting::expirationDateString( const Key & key ) {
return expiration_date_string( key.subkey( 0 ) );
}
QString Formatting::expirationDateString( const Subkey & subkey ) {
return expiration_date_string( subkey );
}
QString Formatting::expirationDateString( const UserID::Signature & sig ) {
return expiration_date_string( sig );
}
QDate Formatting::expirationDate( const Key & key ) {
return expiration_date( key.subkey( 0 ) );
}
QDate Formatting::expirationDate( const Subkey & subkey ) {
return expiration_date( subkey );
}
QDate Formatting::expirationDate( const UserID::Signature & sig ) {
return expiration_date( sig );
}
QString Formatting::creationDateString( const Key & key ) {
return date2string( creation_date( key.subkey( 0 ) ) );
}
QString Formatting::creationDateString( const Subkey & subkey ) {
return date2string( creation_date( subkey ) );
}
QString Formatting::creationDateString( const UserID::Signature & sig ) {
return date2string( creation_date( sig ) );
}
QDate Formatting::creationDate( const Key & key ) {
return creation_date( key.subkey( 0 ) );
}
QDate Formatting::creationDate( const Subkey & subkey ) {
return creation_date( subkey );
}
QDate Formatting::creationDate( const UserID::Signature & sig ) {
return creation_date( sig );
}
//
// Types
//
QString Formatting::displayName( Protocol p ) {
if ( p == CMS )
return i18nc("X.509/CMS encryption standard", "X.509");
if ( p == OpenPGP )
return i18n("OpenPGP");
return i18nc("Unknown encryption protocol", "Unknown");
}
QString Formatting::type( const Key & key ) {
return displayName( key.protocol() );
}
QString Formatting::type( const Subkey & subkey ) {
return QString::fromUtf8( subkey.publicKeyAlgorithmAsString() );
}
//
// Status / Validity
//
QString Formatting::ownerTrustShort( Key::OwnerTrust trust ) {
switch ( trust ) {
case Key::Unknown: return i18nc("unknown trust level", "unknown");
case Key::Never: return i18n("untrusted");
case Key::Marginal: return i18nc("marginal trust", "marginal");
case Key::Full: return i18nc("full trust", "full");
case Key::Ultimate: return i18nc("ultimate trust", "ultimate");
case Key::Undefined: return i18nc("undefined trust", "undefined");
default:
assert( !"unexpected owner trust value" );
break;
}
return QString();
}
QString Formatting::validityShort( const Subkey & subkey ) {
if ( subkey.isRevoked() )
return i18n("revoked");
if ( subkey.isExpired() )
return i18n("expired");
if ( subkey.isDisabled() )
return i18n("disabled");
if ( subkey.isInvalid() )
return i18n("invalid");
return i18nc("as in good/valid signature", "good");
}
QString Formatting::validityShort( const UserID & uid ) {
if ( uid.isRevoked() )
return i18n("revoked");
if ( uid.isInvalid() )
return i18n("invalid");
switch ( uid.validity() ) {
case UserID::Unknown: return i18nc("unknown trust level", "unknown");
case UserID::Undefined: return i18nc("undefined trust", "undefined");
case UserID::Never: return i18n("untrusted");
case UserID::Marginal: return i18nc("marginal trust", "marginal");
case UserID::Full: return i18nc("full trust", "full");
case UserID::Ultimate: return i18nc("ultimate trust", "ultimate");
}
return QString();
}
QString Formatting::validityShort( const UserID::Signature & sig ) {
switch ( sig.status() ) {
case UserID::Signature::NoError:
if ( !sig.isInvalid() )
if ( sig.certClass() > 0 )
return i18n("class %1", sig.certClass() );
else
return i18nc("good/valid signature", "good");
// fall through:
case UserID::Signature::GeneralError:
return i18n("invalid");
case UserID::Signature::SigExpired: return i18n("expired");
case UserID::Signature::KeyExpired: return i18n("key expired");
case UserID::Signature::BadSignature: return i18nc("fake/invalid signature", "bad");
case UserID::Signature::NoPublicKey: return QString();
}
return QString();
}
QString Formatting::formatKeyLink( const Key & key ) {
if ( key.isNull() )
return QString();
return QString::fromLatin1( "<a href=\"key:%1\">%2</a>" ).arg( key.primaryFingerprint(), Formatting::prettyName( key ) );
}
QString Formatting::formatForComboBox( const GpgME::Key & key ) {
const QString name = prettyName( key );
QString mail = prettyEMail( key );
if ( !mail.isEmpty() )
mail = '<' + mail + '>';
return i18nc( "name, email, key id", "%1 %2 (%3)", name, mail, key.shortKeyID() ).simplified();
}
namespace {
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 );
}
}
const char * Formatting::summaryToString( const Signature::Summary summary )
{
if ( summary & Signature::Red )
return "RED";
if ( summary & Signature::Green )
return "GREEN";
return "YELLOW";
}
QString Formatting::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() ) );
}
//
// ImportResult
//
QString Formatting::importMetaData( const Import & import ) {
if ( import.isNull() )
return QString();
if ( import.error().isCanceled() )
return i18n( "The import of this certificate was canceled." );
if ( import.error() )
return i18n( "An error occurred importing this certificate: %1",
QString::fromLocal8Bit( import.error().asString() ) );
const unsigned int status = import.status();
if ( status & Import::NewKey )
return ( status & Import::ContainedSecretKey )
? i18n( "This certificate was new to your keystore. The secret key is available." )
: i18n( "This certificate is new to your keystore." ) ;
QStringList results;
if ( status & Import::NewUserIDs )
results.push_back( i18n( "New user-ids were added to this certificate by the import." ) );
if ( status & Import::NewSignatures )
results.push_back( i18n( "New signatures were added to this certificate by the import." ) );
if ( status & Import::NewSubkeys )
results.push_back( i18n( "New subkeys were added to this certificate by the import." ) );
return results.empty()
? i18n( "The import contained no new data for this certificate. It is unchanged.")
: results.join( "\n" );
}
-
-//
-// Overview in CertificateDetailsDialog
-//
-
-QString Formatting::formatOverview( const Key & key ) {
- return toolTip( key, AllOptions );
-}
diff --git a/utils/formatting.h b/utils/formatting.h
index c47cb8c20..b19d399a2 100644
--- a/utils/formatting.h
+++ b/utils/formatting.h
@@ -1,123 +1,113 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/formatting.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_UTILS_FORMATTING_H__
#define __KLEOPATRA_UTILS_FORMATTING_H__
#include <gpgme++/key.h>
class QString;
class QDate;
namespace GpgME {
class Import;
}
namespace Kleo {
namespace Formatting {
QString protocolDisplayName( GpgME::Protocol prot );
- QString prettyNameAndEMail( int proto, const char * id, const char * name, const char * email, const char * comment );
- QString prettyNameAndEMail( int proto, const QString & id, const QString & name, const QString & email, const QString & comment );
- QString prettyNameAndEMail( const GpgME::Key & key );
- QString prettyNameAndEMail( const GpgME::UserID & key );
-
- QString prettyUserID( const GpgME::UserID & uid );
- QString prettyKeyID( const char * id );
-
QString prettyName( int proto, const char * id, const char * name, const char * comment );
QString prettyName( const GpgME::Key & key );
QString prettyName( const GpgME::UserID & uid );
QString prettyName( const GpgME::UserID::Signature & sig );
+
QString prettyEMail( const char * email, const char * id );
QString prettyEMail( const GpgME::Key & key );
QString prettyEMail( const GpgME::UserID & uid );
QString prettyEMail( const GpgME::UserID::Signature & sig );
enum ToolTipOption {
Validity=0x1,
SerialNumber=0x2,
Issuer=0x4,
Subject=0x8,
ExpiryDates=0x10,
CertificateType=0x20,
CertificateUsage=0x40,
Fingerprint=0x80,
- UserIDs=0x100,
-
- AllOptions = 0x1ff
+ UserIDs=0x100
};
QString toolTip( const GpgME::Key & key, int opts );
+
QString expirationDateString( const GpgME::Key & key );
QString expirationDateString( const GpgME::Subkey & subkey );
QString expirationDateString( const GpgME::UserID::Signature & sig );
QDate expirationDate( const GpgME::Key & key );
QDate expirationDate( const GpgME::Subkey & subkey );
QDate expirationDate( const GpgME::UserID::Signature & sig );
QString creationDateString( const GpgME::Key & key );
QString creationDateString( const GpgME::Subkey & subkey );
QString creationDateString( const GpgME::UserID::Signature & sig );
QDate creationDate( const GpgME::Key & key );
QDate creationDate( const GpgME::Subkey & subkey );
QDate creationDate( const GpgME::UserID::Signature & sig );
QString displayName( GpgME::Protocol prot );
QString type( const GpgME::Key & key );
QString type( const GpgME::Subkey & subkey );
QString ownerTrustShort( GpgME::Key::OwnerTrust trust );
QString validityShort( const GpgME::Subkey & subkey );
QString validityShort( const GpgME::UserID & uid );
QString validityShort( const GpgME::UserID::Signature & sig );
QString formatForComboBox( const GpgME::Key & key );
QString formatKeyLink( const GpgME::Key & key );
QString signatureToString( const GpgME::Signature & sig, const GpgME::Key & key );
const char * summaryToString( const GpgME::Signature::Summary summary );
QString importMetaData( const GpgME::Import & import );
-
- QString formatOverview( const GpgME::Key & key );
}
}
#endif /* __KLEOPATRA_UTILS_FORMATTING_H__ */
diff --git a/utils/getpid.h b/utils/getpid.h
index b71822dc0..e69de29bb 100644
--- a/utils/getpid.h
+++ b/utils/getpid.h
@@ -1,59 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- utils/getpid.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_UTILS_GETPID_H__
-#define __KLEOPATRA_UTILS_GETPID_H__
-
-#include <qglobal.h>
-
-#ifdef Q_OS_WIN32
-# include <process.h>
-#else
-# include <sys/types.h>
-# include <unistd.h>
-#endif
-
-class QString;
-
-namespace Kleo {
-
- static inline qint64 mygetpid() {
-#ifdef Q_OS_WIN32
- return (qint64)_getpid();
-#else
- return (qint64)getpid();
-#endif
- }
-
-}
-
-#endif /* __KLEOPATRA_UTILS_GETPID_H__ */
diff --git a/utils/gnupg-helper.cpp b/utils/gnupg-helper.cpp
index 339c30566..ab2b60b40 100644
--- a/utils/gnupg-helper.cpp
+++ b/utils/gnupg-helper.cpp
@@ -1,97 +1,84 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/gnupg-helper.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 "gnupg-helper.h"
#include <gpgme++/engineinfo.h>
#include <KStandardDirs>
#include <QDir>
#include <QFile>
#include <QString>
#include <gpg-error.h>
#ifdef Q_OS_WIN
#include "gnupg-registry.h"
#endif // Q_OS_WIN
QString Kleo::gnupgHomeDirectory()
{
#ifdef Q_OS_WIN
return QFile::decodeName( default_homedir() );
#else
const QByteArray gnupgHome = qgetenv( "GNUPGHOME" );
if ( !gnupgHome.isEmpty() )
return QFile::decodeName( gnupgHome );
else
return QDir::homePath() + "/.gnupg";
#endif
}
int Kleo::makeGnuPGError( int code ) {
return gpg_error( static_cast<gpg_err_code_t>( code ) );
}
static QString findGpgExe( GpgME::Engine engine, const char * exe ) {
const GpgME::EngineInfo info = GpgME::engineInfo( engine );
return info.fileName() ? QFile::decodeName( info.fileName() ) : KStandardDirs::findExe( exe ) ;
}
QString Kleo::gpgConfPath() {
return findGpgExe( GpgME::GpgConfEngine, "gpgconf" );
}
QString Kleo::gpgSmPath() {
return findGpgExe( GpgME::GpgSMEngine, "gpgsm" );
}
QString Kleo::gpgPath() {
return findGpgExe( GpgME::GpgEngine, "gpg" );
}
-QStringList Kleo::gnupgFileWatchList() {
- const QString home = Kleo::gnupgHomeDirectory();
- QFileInfo info( home );
- if ( !info.isDir() )
- return QStringList();
- QDir homeDir( home );
- QStringList fileList = homeDir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot );
- fileList.removeAll( "dirmngr-cache.d" );
- QStringList result;
- Q_FOREACH( const QString& i, fileList )
- result.push_back( homeDir.absoluteFilePath( i ) );
- return result;
-}
diff --git a/utils/gnupg-helper.h b/utils/gnupg-helper.h
index e2c5e0c18..d565bcea0 100644
--- a/utils/gnupg-helper.h
+++ b/utils/gnupg-helper.h
@@ -1,52 +1,49 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/gnupg-helper.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_GNUPGHELPER_H__
#define __KLEOPATRA_GNUPGHELPER_H__
class QString;
-class QStringList;
namespace Kleo {
QString gnupgHomeDirectory();
QString gpgConfPath();
QString gpgSmPath();
QString gpgPath();
- QStringList gnupgFileWatchList();
-
int makeGnuPGError( int code );
}
#endif // __KLEOPATRA_GNUPGHELPER_H__
diff --git a/utils/hex.cpp b/utils/hex.cpp
index 9850fd079..401872ed4 100644
--- a/utils/hex.cpp
+++ b/utils/hex.cpp
@@ -1,141 +1,115 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/hex.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 "hex.h"
#include "exception.h"
#include <KLocale>
#include <QString>
-#include <QByteArray>
using namespace Kleo;
static unsigned char unhex( unsigned char ch ) {
if ( ch >= '0' && ch <= '9' )
return ch - '0';
if ( ch >= 'A' && ch <= 'F' )
return ch - 'A' + 10;
if ( ch >= 'a' && ch <= 'f' )
return ch - 'a' + 10;
const char cch = ch;
throw Exception( gpg_error( GPG_ERR_ASS_SYNTAX ),
i18n("Invalid hex char '%1' in input stream.",
QString::fromLatin1( &cch, 1 ) ) );
}
std::string Kleo::hexdecode( const std::string & in ) {
std::string result;
result.reserve( in.size() );
for ( std::string::const_iterator it = in.begin(), end = in.end() ; it != end ; ++it )
if ( *it == '%' ) {
++it;
unsigned char ch = '\0';
if ( it == end )
throw Exception( gpg_error( GPG_ERR_ASS_SYNTAX ),
i18n("Premature end of hex-encoded char in input stream") );
ch |= unhex( *it ) << 4;
++it;
if ( it == end )
throw Exception( gpg_error( GPG_ERR_ASS_SYNTAX ),
i18n("Premature end of hex-encoded char in input stream") );
ch |= unhex( *it );
result.push_back( ch );
} else if ( *it == '+' ) {
result += ' ';
} else {
result.push_back( *it );
}
return result;
}
std::string Kleo::hexencode( const std::string & in ) {
std::string result;
result.reserve( 3 * in.size() );
static const char hex[] = "0123456789ABCDEF";
for ( std::string::const_iterator it = in.begin(), end = in.end() ; it != end ; ++it )
switch ( const unsigned char ch = *it ) {
default:
if ( ch >= '!' && ch <= '~' || ch > 0xA0 ) {
result += ch;
break;
}
// else fall through
case ' ':
result += '+';
break;
case '"':
case '#':
case '$':
case '%':
case '\'':
case '+':
case '=':
result += '%';
result += hex[ (ch & 0xF0) >> 4 ];
result += hex[ (ch & 0x0F) ];
break;
}
return result;
}
-std::string Kleo::hexdecode( const char * in ) {
- if ( !in )
- return std::string();
- return hexdecode( std::string( in ) );
-}
-
-std::string Kleo::hexencode( const char * in ) {
- if ( !in )
- return std::string();
- return hexencode( std::string( in ) );
-}
-
-QByteArray Kleo::hexdecode( const QByteArray & in ) {
- if ( in.isNull() )
- return QByteArray();
- const std::string result = hexdecode( std::string( in.constData() ) );
- return QByteArray( result.data(), result.size() );
-}
-
-QByteArray Kleo::hexencode( const QByteArray & in ) {
- if ( in.isNull() )
- return QByteArray();
- const std::string result = hexencode( std::string( in.constData() ) );
- return QByteArray( result.data(), result.size() );
-}
diff --git a/utils/hex.h b/utils/hex.h
index 69d61f8dd..6b873e2f5 100644
--- a/utils/hex.h
+++ b/utils/hex.h
@@ -1,53 +1,45 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/hex.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_UTILS_HEX_H__
#define __KLEOPATRA_UTILS_HEX_H__
#include <string>
-class QByteArray;
-
namespace Kleo {
- std::string hexencode( const char * s );
- std::string hexdecode( const char * s );
-
std::string hexencode( const std::string & s );
std::string hexdecode( const std::string & s );
- QByteArray hexencode( const QByteArray & s );
- QByteArray hexdecode( const QByteArray & s );
-
}
#endif /* __KLEOPATRA_UTILS_HEX_H__ */
diff --git a/utils/input.cpp b/utils/input.cpp
index e340b6f5e..fb5a982cf 100644
--- a/utils/input.cpp
+++ b/utils/input.cpp
@@ -1,238 +1,231 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/input.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 "input.h"
#include "detail_p.h"
#include "classify.h"
#include "kdpipeiodevice.h"
#include "log.h"
#include "kleo_assert.h"
#include "exception.h"
#include <KLocale>
#include <QFile>
#include <QString>
#include <QClipboard>
#include <QApplication>
#include <QByteArray>
#include <QBuffer>
#include <QFileInfo>
#include <errno.h>
using namespace Kleo;
using namespace boost;
namespace {
class InputImplBase : public Input {
public:
- InputImplBase() : Input(), m_customLabel(), m_defaultLabel() {}
+ InputImplBase() : Input(), m_label() {}
- /* reimp */ QString label() const { return m_customLabel.isEmpty() ? m_defaultLabel : m_customLabel; }
- void setDefaultLabel( const QString & l ) { m_defaultLabel = l; }
- /* reimp */ void setLabel( const QString & l ) { m_customLabel = l; }
+ /* reimp */ QString label() const { return m_label; }
+ void setLabel( const QString & l ) { m_label = l; }
private:
- QString m_customLabel;
- QString m_defaultLabel;
+ QString m_label;
};
class PipeInput : public InputImplBase {
public:
explicit PipeInput( assuan_fd_t fd );
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_io; }
/* reimp */ unsigned int classification() const;
/* reimp */ unsigned long long size() const { return 0; }
private:
shared_ptr<QIODevice> m_io;
};
class FileInput : public InputImplBase {
public:
explicit FileInput( const QString & fileName );
explicit FileInput( const shared_ptr<QFile> & file );
/* reimp */ QString label() const {
return m_io ? QFileInfo( m_fileName ).fileName() : InputImplBase::label();
}
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_io; }
/* reimp */ unsigned int classification() const;
/* reimp */ unsigned long long size() const { return QFileInfo( m_fileName ).size(); }
private:
shared_ptr<QIODevice> m_io;
QString m_fileName;
};
class ClipboardInput : public Input {
public:
explicit ClipboardInput( QClipboard::Mode mode );
- /* reimp */ void setLabel( const QString & label );
/* reimp */ QString label() const;
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_buffer; }
/* reimp */ unsigned int classification() const;
/* reimp */ unsigned long long size() const { return m_buffer ? m_buffer->buffer().size() : 0; }
private:
const QClipboard::Mode m_mode;
shared_ptr<QBuffer> m_buffer;
};
}
shared_ptr<Input> Input::createFromPipeDevice( assuan_fd_t fd, const QString & label ) {
shared_ptr<PipeInput> po( new PipeInput( fd ) );
- po->setDefaultLabel( label );
+ po->setLabel( label );
return po;
}
PipeInput::PipeInput( assuan_fd_t fd )
: InputImplBase(),
m_io()
{
shared_ptr<KDPipeIODevice> kdp( new KDPipeIODevice );
errno = 0;
if ( !kdp->open( fd, QIODevice::ReadOnly ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't open FD %1 for reading",
_detail::assuanFD2int( fd ) ) );
m_io = Log::instance()->createIOLogger( kdp, "pipe-input", Log::Read );
}
unsigned int PipeInput::classification() const {
notImplemented();
return 0;
}
shared_ptr<Input> Input::createFromFile( const QString & fileName, bool ) {
return shared_ptr<Input>( new FileInput( fileName ) );
}
shared_ptr<Input> Input::createFromFile( const shared_ptr<QFile> & file ) {
return shared_ptr<Input>( new FileInput( file ) );
}
FileInput::FileInput( const QString & fileName )
: InputImplBase(),
m_io(), m_fileName( fileName )
{
shared_ptr<QFile> file( new QFile( fileName ) );
-
+
errno = 0;
if ( !file->open( QIODevice::ReadOnly ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't open file \"%1\" for reading", fileName ) );
m_io = Log::instance()->createIOLogger( file, "file-in", Log::Read );
}
FileInput::FileInput( const shared_ptr<QFile> & file )
: InputImplBase(),
m_io(), m_fileName( file->fileName() )
{
kleo_assert( file );
errno = 0;
if ( file->isOpen() && !file->isReadable() )
throw Exception( gpg_error( GPG_ERR_INV_ARG ),
i18n( "File \"%1\" is already open, but not for reading", file->fileName() ) );
if ( !file->isOpen() && !file->open( QIODevice::ReadOnly ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't open file \"%1\" for reading", m_fileName ) );
m_io = Log::instance()->createIOLogger( file, "file-in", Log::Read );
}
unsigned int FileInput::classification() const {
return classify( m_fileName );
}
shared_ptr<Input> Input::createFromClipboard() {
return shared_ptr<Input>( new ClipboardInput( QClipboard::Clipboard ) );
}
static QByteArray dataFromClipboard( QClipboard::Mode mode ) {
if ( QClipboard * const cb = QApplication::clipboard() )
return cb->text().toUtf8();
else
return QByteArray();
}
ClipboardInput::ClipboardInput( QClipboard::Mode mode )
: Input(),
m_mode( mode ),
m_buffer( new QBuffer )
{
m_buffer->setData( dataFromClipboard( mode ) );
if ( !m_buffer->open( QIODevice::ReadOnly ) )
throw Exception( gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't open clipboard for reading" ) );
}
-void ClipboardInput::setLabel( const QString & ) {
- notImplemented();
-}
-
QString ClipboardInput::label() const {
switch ( m_mode ) {
case QClipboard::Clipboard:
return i18n( "Clipboard contents" );
case QClipboard::FindBuffer:
return i18n( "FindBuffer contents" );
case QClipboard::Selection:
return i18n( "Current selection" );
};
return QString();
}
unsigned int ClipboardInput::classification() const {
return classifyContent( m_buffer->data() );
}
Input::~Input() {}
void Input::finalize() {
if ( const shared_ptr<QIODevice> io = ioDevice() )
if ( io->isOpen() )
io->close();
}
diff --git a/utils/input.h b/utils/input.h
index 8c3fc1e76..e2d4bec7d 100644
--- a/utils/input.h
+++ b/utils/input.h
@@ -1,65 +1,64 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/input.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_UTILS_INPUT_H__
#define __KLEOPATRA_UTILS_INPUT_H__
#include <kleo-assuan.h> // for assuan_fd_t
#include <boost/shared_ptr.hpp>
class QIODevice;
class QString;
class QFile;
namespace Kleo {
class Input {
public:
virtual ~Input();
virtual QString label() const = 0;
- virtual void setLabel( const QString & label ) = 0;
virtual boost::shared_ptr<QIODevice> ioDevice() const = 0;
virtual unsigned int classification() const = 0;
virtual unsigned long long size() const = 0;
void finalize(); // equivalent to ioDevice()->close();
static boost::shared_ptr<Input> createFromPipeDevice( assuan_fd_t fd, const QString & label );
static boost::shared_ptr<Input> createFromFile( const QString & filename, bool dummy=false );
static boost::shared_ptr<Input> createFromFile( const boost::shared_ptr<QFile> & file );
static boost::shared_ptr<Input> createFromClipboard();
};
}
#endif /* __KLEOPATRA_UTILS_INPUT_H__ */
diff --git a/utils/output.cpp b/utils/output.cpp
index c5efc9a93..a6f68d919 100644
--- a/utils/output.cpp
+++ b/utils/output.cpp
@@ -1,386 +1,383 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/output.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 "output.h"
#include "detail_p.h"
#include "kleo_assert.h"
#include "exception.h"
#include "kdpipeiodevice.h"
#include "log.h"
#include <KLocale>
#include <KMessageBox>
#include <kdebug.h>
#include <QFileInfo>
#include <QTemporaryFile>
#include <QString>
#include <QClipboard>
#include <QApplication>
#include <QBuffer>
#include <QPointer>
#include <QWidget>
#ifdef Q_OS_WIN
# include <windows.h>
#endif
#include <errno.h>
using namespace Kleo;
using namespace Kleo::_detail;
using namespace boost;
class OverwritePolicy::Private {
public:
Private( QWidget* p, OverwritePolicy::Policy pol ) : policy( pol ), widget( p ) {}
OverwritePolicy::Policy policy;
QWidget* widget;
};
OverwritePolicy::OverwritePolicy( QWidget * parent, Policy initialPolicy ) : d( new Private( parent, initialPolicy ) ) {
}
OverwritePolicy::~OverwritePolicy() {}
OverwritePolicy::Policy OverwritePolicy::policy() const {
return d->policy;
}
void OverwritePolicy::setPolicy( Policy policy ) {
d->policy = policy;
}
QWidget * OverwritePolicy::parentWidget() const {
return d->widget;
}
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();
}
bool openNonInheritable() {
if ( !QTemporaryFile::open() )
return false;
#ifdef Q_OS_WIN
//QTemporaryFile (tested with 4.3.3) creates the file handle as inheritable.
- //The handle is then inherited by gpgsm, which prevents deletion of the temp file
- //in FileOutput::doFinalize()
+ //The handle is then inherited by gpgsm, which prevents deletion of the temp file
+ //in FileOutput::doFinalize()
return SetHandleInformation( (HANDLE)_get_osfhandle( handle() ), HANDLE_FLAG_INHERIT, 0 );
#endif
return true;
}
QString oldFileName() const { return m_oldFileName; }
private:
QString m_oldFileName;
};
template <typename T_IODevice>
struct inhibit_close : T_IODevice {
explicit inhibit_close() : T_IODevice() {}
template <typename T1>
explicit inhibit_close( T1 & t1 ) : T_IODevice( t1 ) {}
/* reimp */ void close() {}
void reallyClose() { T_IODevice::close(); }
};
class OutputImplBase : public Output {
public:
OutputImplBase()
: Output(),
- m_defaultLabel(),
- m_customLabel(),
+ m_label(),
m_isFinalized( false ),
m_isFinalizing( false ),
m_cancelPending( false ),
m_canceled( false )
{
}
- /* reimp */ QString label() const { return m_customLabel.isEmpty() ? m_defaultLabel : m_customLabel; }
- /* reimp */ void setLabel( const QString & label ) { m_customLabel = label; }
- void setDefaultLabel( const QString & l ) { m_defaultLabel = l; }
+ /* reimp */ QString label() const { return m_label; }
+ void setLabel( const QString & l ) { m_label = l; }
/* reimp */ bool isFinalized() const { return m_isFinalized; }
/* reimp */ void finalize() {
kDebug() << this;
if ( m_isFinalized || m_isFinalizing )
return;
m_isFinalizing = true;
try { doFinalize(); } catch ( ... ) { m_isFinalizing = false; throw; }
m_isFinalizing = false;
m_isFinalized = true;
if ( m_cancelPending )
cancel();
}
/* reimp */ void cancel() {
kDebug() << this;
if ( m_isFinalizing ) {
m_cancelPending = true;
} else if ( !m_canceled ) {
m_isFinalizing = true;
try { doCancel(); } catch ( ... ) {}
m_isFinalizing = false;
m_isFinalized = true;
m_canceled = true;
}
}
private:
virtual void doFinalize() = 0;
virtual void doCancel() = 0;
private:
- QString m_defaultLabel;
- QString m_customLabel;
+ QString m_label;
bool m_isFinalized : 1;
bool m_isFinalizing : 1;
bool m_cancelPending : 1;
bool m_canceled : 1;
};
class PipeOutput : public OutputImplBase {
public:
explicit PipeOutput( assuan_fd_t fd );
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_io; }
/* reimp */ void doFinalize() { m_io->reallyClose(); }
/* reimp */ void doCancel() { doFinalize(); }
private:
shared_ptr< inhibit_close<KDPipeIODevice> > m_io;
};
class FileOutput : public OutputImplBase {
public:
explicit FileOutput( const QString & fileName, const shared_ptr<OverwritePolicy> & policy );
~FileOutput() { kDebug() << this; }
/* reimp */ QString label() const { return QFileInfo( m_fileName ).fileName(); }
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_tmpFile; }
/* reimp */ void doFinalize();
/* reimp */ void doCancel() { kDebug() << this; }
private:
bool obtainOverwritePermission();
private:
const QString m_fileName;
shared_ptr< TemporaryFile > m_tmpFile;
const shared_ptr<OverwritePolicy> m_policy;
};
class ClipboardOutput : public OutputImplBase {
public:
explicit ClipboardOutput( QClipboard::Mode mode );
/* reimp */ QString label() const;
/* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_buffer; }
/* reimp */ void doFinalize();
/* reimp */ void doCancel() {}
private:
const QClipboard::Mode m_mode;
shared_ptr<QBuffer> m_buffer;
};
}
shared_ptr<Output> Output::createFromPipeDevice( assuan_fd_t fd, const QString & label ) {
shared_ptr<PipeOutput> po( new PipeOutput( fd ) );
- po->setDefaultLabel( label );
+ po->setLabel( label );
return po;
}
PipeOutput::PipeOutput( assuan_fd_t fd )
: OutputImplBase(),
m_io( new inhibit_close<KDPipeIODevice> )
{
errno = 0;
if ( !m_io->open( fd, QIODevice::WriteOnly ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't open FD %1 for writing",
assuanFD2int( fd ) ) );
}
shared_ptr<Output> Output::createFromFile( const QString & fileName, bool forceOverwrite ) {
return createFromFile( fileName, shared_ptr<OverwritePolicy>( new OverwritePolicy( 0, forceOverwrite ? OverwritePolicy::Allow : OverwritePolicy::Deny ) ) );
-
+
}
shared_ptr<Output> Output::createFromFile( const QString & fileName, const shared_ptr<OverwritePolicy> & policy ) {
shared_ptr<FileOutput> fo( new FileOutput( fileName, policy ) );
kDebug() << fo.get();
return fo;
}
FileOutput::FileOutput( const QString & fileName, const shared_ptr<OverwritePolicy> & policy )
: OutputImplBase(),
m_fileName( fileName ),
m_tmpFile( new TemporaryFile( fileName ) ),
m_policy( policy )
{
assert( m_policy );
errno = 0;
if ( !m_tmpFile->openNonInheritable() )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't create temporary file for output \"%1\"", fileName ) );
}
bool FileOutput::obtainOverwritePermission() {
if ( m_policy->policy() != OverwritePolicy::Ask )
return m_policy->policy() == OverwritePolicy::Allow;
const int sel = KMessageBox::questionYesNoCancel( m_policy->parentWidget(), i18n("The file <b>%1</b> already exists.\n"
"Overwrite?", m_fileName ),
i18n("Overwrite Existing File?"),
KStandardGuiItem::overwrite(),
- KGuiItem( i18n( "Overwrite All" ) ),
+ KGuiItem( i18n( "Overwrite All" ) ),
KStandardGuiItem::cancel() );
if ( sel == KMessageBox::No ) //Overwrite All
m_policy->setPolicy( OverwritePolicy::Allow );
return sel == KMessageBox::Yes || sel == KMessageBox::No;
}
void FileOutput::doFinalize() {
kDebug() << this;
struct Remover {
QString file;
~Remover() { if ( QFile::exists( file ) ) QFile::remove( file ); }
} remover;
kleo_assert( m_tmpFile );
if ( m_tmpFile->isOpen() )
m_tmpFile->close();
const QString tmpFileName = remover.file = m_tmpFile->oldFileName();
m_tmpFile->setAutoRemove( false );
QPointer<QObject> guard = m_tmpFile.get();
m_tmpFile.reset(); // really close the file - needed on Windows for renaming :/
kleo_assert( !guard ); // if this triggers, we need to audit for holder of shared_ptr<QIODevice>s.
kDebug() << this << " renaming " << tmpFileName << "->" << m_fileName ;
if ( QFile::rename( tmpFileName, m_fileName ) ) {
kDebug() << this << "succeeded";
return;
}
kDebug() << this << "failed";
if ( !obtainOverwritePermission() )
throw Exception( gpg_error( GPG_ERR_CANCELED ),
i18n( "Overwriting declined" ) );
kDebug() << this << "going to overwrite" << m_fileName ;
if ( !QFile::remove( m_fileName ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n("Couldn't remove file \"%1\" for overwriting.", m_fileName ) );
kDebug() << this << "succeeded, renaming " << tmpFileName << "->" << m_fileName;
if ( QFile::rename( tmpFileName, m_fileName ) ) {
kDebug() << this << "succeeded";
return;
}
kDebug() << this << "failed";
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't rename file \"%1\" to \"%2\"",
tmpFileName, m_fileName ) );
}
shared_ptr<Output> Output::createFromClipboard() {
return shared_ptr<Output>( new ClipboardOutput( QClipboard::Clipboard ) );
}
ClipboardOutput::ClipboardOutput( QClipboard::Mode mode )
: OutputImplBase(),
m_mode( mode ),
m_buffer( new QBuffer )
{
errno = 0;
if ( !m_buffer->open( QIODevice::WriteOnly ) )
throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't write to clipboard" ) );
}
QString ClipboardOutput::label() const {
switch ( m_mode ) {
case QClipboard::Clipboard:
return i18n( "Clipboard" );
case QClipboard::FindBuffer:
return i18n( "Find buffer" );
case QClipboard::Selection:
return i18n( "Selection" );
}
return QString();
}
void ClipboardOutput::doFinalize() {
if ( m_buffer->isOpen() )
m_buffer->close();
if ( QClipboard * const cb = QApplication::clipboard() )
cb->setText( QString::fromUtf8( m_buffer->data() ) );
else
throw Exception( gpg_error( GPG_ERR_EIO ),
i18n( "Couldn't find clipboard" ) );
}
Output::~Output() {}
diff --git a/utils/output.h b/utils/output.h
index ce93550be..3e6ed1398 100644
--- a/utils/output.h
+++ b/utils/output.h
@@ -1,88 +1,87 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/output.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_UTILS_OUTPUT_H__
#define __KLEOPATRA_UTILS_OUTPUT_H__
#include <kleo-assuan.h> // for assuan_fd_t
#include <utils/pimpl_ptr.h>
#include <boost/shared_ptr.hpp>
class QIODevice;
class QString;
class QWidget;
namespace Kleo {
class OverwritePolicy {
public:
enum Policy {
Allow,
Deny,
Ask
};
explicit OverwritePolicy( QWidget * parent, Policy initialPolicy=Ask );
~OverwritePolicy();
Policy policy() const;
void setPolicy( Policy );
QWidget * parentWidget() const;
private:
class Private;
kdtools::pimpl_ptr<Private> d;
};
class Output {
public:
virtual ~Output();
- virtual void setLabel( const QString & label ) = 0;
virtual QString label() const = 0;
virtual boost::shared_ptr<QIODevice> ioDevice() const = 0;
virtual bool isFinalized() const = 0;
virtual void finalize() = 0;
virtual void cancel() = 0;
static boost::shared_ptr<Output> createFromFile( const QString & fileName, const boost::shared_ptr<OverwritePolicy> & );
static boost::shared_ptr<Output> createFromFile( const QString & fileName, bool forceOverwrite );
static boost::shared_ptr<Output> createFromPipeDevice( assuan_fd_t fd, const QString & label );
static boost::shared_ptr<Output> createFromClipboard();
};
}
#endif /* __KLEOPATRA_UTILS_OUTPUT_H__ */
diff --git a/utils/stl_util.h b/utils/stl_util.h
index 99ef6d6f7..cd15f9ff9 100644
--- a/utils/stl_util.h
+++ b/utils/stl_util.h
@@ -1,277 +1,258 @@
/****************************************************************************
** Copyright (C) 2001-2007 Klarälvdalens Datakonsult AB. All rights reserved.
**
** This file is part of the KD Tools library.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding valid commercial KD Tools licenses may use this file in
** accordance with the KD Tools Commercial License Agreement provided with
** the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Contact info@klaralvdalens-datakonsult.se if any conditions of this
** licensing are not clear to you.
**
**********************************************************************/
#ifndef __KDTOOLSCORE_STL_UTIL_H__
#define __KDTOOLSCORE_STL_UTIL_H__
#include <algorithm>
#include <numeric>
#include <utility>
#include <boost/range.hpp>
#include <boost/iterator/filter_iterator.hpp>
namespace kdtools {
template <typename InputIterator, typename OutputIterator, typename UnaryPredicate>
OutputIterator copy_if( InputIterator first, InputIterator last, OutputIterator dest, UnaryPredicate pred ) {
while ( first != last ) {
if ( pred( *first ) ) {
*dest = *first;
++dest;
}
++first;
}
return dest;
}
template <typename OutputIterator, typename InputIterator, typename UnaryFunction, typename UnaryPredicate>
OutputIterator transform_if( InputIterator first, InputIterator last, OutputIterator dest, UnaryPredicate pred, UnaryFunction filter ) {
return std::transform( boost::make_filter_iterator( filter, first, last ),
boost::make_filter_iterator( filter, last, last ),
dest, pred );
}
template <typename Value, typename InputIterator, typename UnaryPredicate>
Value accumulate_if( InputIterator first, InputIterator last, UnaryPredicate filter, const Value & value=Value() ) {
return std::accumulate( boost::make_filter_iterator( filter, first, last ),
boost::make_filter_iterator( filter, last, last ), value );
}
template <typename InputIterator, typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
std::pair<OutputIterator1,OutputIterator2> separate_if( InputIterator first, InputIterator last, OutputIterator1 dest1, OutputIterator2 dest2, UnaryPredicate pred ) {
while ( first != last ) {
if ( pred( *first ) ) {
*dest1 = *first;
++dest1;
} else {
*dest2 = *first;
++dest2;
}
++first;
}
return std::make_pair( dest1, dest2 );
}
template <typename InputIterator>
bool any( InputIterator first, InputIterator last ) {
while ( first != last )
if ( *first )
return true;
else
++first;
return false;
}
template <typename InputIterator, typename UnaryPredicate>
bool any( InputIterator first, InputIterator last, UnaryPredicate pred ) {
while ( first != last )
if ( pred( *first ) )
return true;
else
++first;
return false;
}
template <typename InputIterator>
bool all( InputIterator first, InputIterator last ) {
while ( first != last )
if ( *first )
++first;
else
return false;
return true;
}
template <typename InputIterator, typename UnaryPredicate>
bool all( InputIterator first, InputIterator last, UnaryPredicate pred ) {
while ( first != last )
if ( pred( *first ) )
++first;
else
return false;
return true;
}
- template <typename InputIterator, typename BinaryOperation>
- BinaryOperation for_each_adjacent_pair( InputIterator first, InputIterator last, BinaryOperation op ) {
- typedef typename std::iterator_traits<InputIterator>::value_type ValueType;
- if ( first == last )
- return op;
- ValueType value = *first;
- while ( ++first != last ) {
- ValueType tmp = *first;
- op( value, tmp );
- value = tmp;
- }
- return op;
- }
-
//@{
/**
Versions of std::set_intersection optimized for ForwardIterator's
*/
template <typename ForwardIterator, typename ForwardIterator2, typename OutputIterator, typename BinaryPredicate>
OutputIterator set_intersection( ForwardIterator first1, ForwardIterator last1, ForwardIterator2 first2, ForwardIterator2 last2, OutputIterator result ) {
while ( first1 != last1 && first2 != last2 ) {
if ( *first1 < *first2 ) {
first1 = std::lower_bound( ++first1, last1, *first2 );
} else if ( *first2 < *first1 ) {
first2 = std::lower_bound( ++first2, last2, *first1 );
} else {
*result = *first1;
++first1;
++first2;
++result;
}
}
return result;
}
template <typename ForwardIterator, typename ForwardIterator2, typename OutputIterator, typename BinaryPredicate>
OutputIterator set_intersection( ForwardIterator first1, ForwardIterator last1, ForwardIterator2 first2, ForwardIterator2 last2, OutputIterator result, BinaryPredicate pred ) {
while ( first1 != last1 && first2 != last2 ) {
if ( pred( *first1, *first2 ) ) {
first1 = std::lower_bound( ++first1, last1, *first2, pred );
} else if ( pred( *first2, *first1 ) ) {
first2 = std::lower_bound( ++first2, last2, *first1, pred );
} else {
*result = *first1;
++first1;
++first2;
++result;
}
}
return result;
}
//@}
template <typename ForwardIterator, typename ForwardIterator2, typename BinaryPredicate>
bool set_intersects( ForwardIterator first1, ForwardIterator last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred )
{
while ( first1 != last1 && first2 != last2 ) {
if ( pred( *first1, *first2 ) ) {
first1 = std::lower_bound( ++first1, last1, *first2, pred );
} else if ( pred( *first2, *first1 ) ) {
first2 = std::lower_bound( ++first2, last2, *first1, pred );
} else {
return true;
}
}
return false;
}
//@{
/*! Versions of std algorithms that take ranges */
template <typename C, typename V>
bool contains( const C & c, const V & v ) {
return std::find( boost::begin( c ), boost::end( c ), v ) != boost::end( c ) ;
}
template <typename C, typename P>
bool contains_if( const C & c, P p ) {
return std::find_if( boost::begin( c ), boost::end( c ), p ) != boost::end( c );
}
template <typename C, typename V>
size_t count( const C & c, const V & v ) {
return std::count( boost::begin( c ), boost::end( c ), v );
}
template <typename C, typename P>
size_t count_if( const C & c, P p ) {
return std::count_if( boost::begin( c ), boost::end( c ), p );
}
template <typename O, typename I, typename P>
O transform( const I & i, P p ) {
O o;
std::transform( boost::begin( i ), boost::end( i ),
std::back_inserter( o ), p );
return o;
}
template <typename O, typename I, typename P, typename F>
O transform_if( const I & i, P p, F f ) {
O o;
transform_if( boost::begin( i ), boost::end( i ),
std::back_inserter( o ), p, f );
return o;
}
template <typename V, typename I, typename F>
V accumulate_if( const I & i, F f, V v=V() ) {
return accumulate_if( boost::begin( i ), boost::end( i ), f, v );
}
template <typename O, typename I>
O copy( const I & i ) {
O o;
std::copy( boost::begin( i ), boost::end( i ), std::back_inserter( o ) );
return o;
}
template <typename O, typename I, typename P>
O copy_if( const I & i, P p ) {
O o;
copy_if( boost::begin( i ), boost::end( i ), std::back_inserter( o ) );
return o;
}
template <typename I, typename P>
P for_each( const I & i, P p ) {
return std::for_each( boost::begin( i ), boost::end( i ), p );
}
//@}
template <typename C>
bool any( const C & c ) {
return any( boost::begin( c ), boost::end( c ) );
}
template <typename C, typename P>
bool any( const C & c, P p ) {
return any( boost::begin( c ), boost::end( c ), p );
}
template <typename C>
bool all( const C & c ) {
return all( boost::begin( c ), boost::end( c ) );
}
template <typename C, typename P>
bool all( const C & c, P p ) {
return all( boost::begin( c ), boost::end( c ), p );
}
- template <typename C, typename B>
- B for_each_adjacent_pair( const C & c, B b ) {
- return for_each_adjacent_pair( boost::begin( c ), boost::end( c ), b );
- }
-
}
#endif /* __KDTOOLSCORE_STL_UTIL_H__ */
diff --git a/view/keylistcontroller.cpp b/view/keylistcontroller.cpp
index c251fe930..d6c3b668d 100644
--- a/view/keylistcontroller.cpp
+++ b/view/keylistcontroller.cpp
@@ -1,449 +1,434 @@
/* -*- mode: c++; c-basic-offset:4 -*-
controllers/keylistcontroller.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 "keylistcontroller.h"
#include "tabwidget.h"
#include <commands/detailscommand.h>
#include <models/keycache.h>
#include <models/keylistmodel.h>
#include <utils/formatting.h>
#include <utils/stl_util.h>
#include "tooltippreferences.h"
#include <gpgme++/key.h>
#include <QAbstractItemView>
#include <QTreeView>
#include <QTableView>
#include <QPointer>
#include <QItemSelectionModel>
#include <QAction>
#include <boost/bind.hpp>
#include <algorithm>
#include <cassert>
using namespace Kleo;
-using namespace Kleo::Commands;
using namespace boost;
using namespace GpgME;
class KeyListController::Private {
friend class ::Kleo::KeyListController;
KeyListController * const q;
public:
explicit Private( KeyListController * qq );
~Private();
void connectView( QAbstractItemView * view );
void connectCommand( Command * cmd );
void connectTabWidget();
void disconnectTabWidget();
void addCommand( Command * cmd ) {
connectCommand( cmd );
commands.insert( std::lower_bound( commands.begin(), commands.end(), cmd ), cmd );
}
void addView( QAbstractItemView * view ) {
connectView( view );
views.insert( std::lower_bound( views.begin(), views.end(), view ), view );
}
void removeView( QAbstractItemView * view ) {
view->disconnect( q );
view->selectionModel()->disconnect( q );
views.erase( std::remove( views.begin(), views.end(), view ), views.end() );
}
public:
void slotDestroyed( QObject * o ) {
qDebug( "KeyListController::Private::slotDestroyed( %p )", o );
views.erase( std::remove( views.begin(), views.end(), o ), views.end() );
commands.erase( std::remove( commands.begin(), commands.end(), o ), commands.end() );
}
void slotDoubleClicked( const QModelIndex & idx );
void slotActivated( const QModelIndex & idx );
void slotSelectionChanged( const QItemSelection & old, const QItemSelection & new_ );
void slotContextMenu( const QPoint & pos );
void slotCommandFinished();
void slotAddKey( const Key & key );
void slotAboutToRemoveKey( const Key & key );
void slotProgress( const QString & what, int current, int total ) {
emit q->progress( current, total );
if ( !what.isEmpty() )
emit q->message( what );
}
void slotActionTriggered();
void slotCurrentViewChanged( QAbstractItemView * view ) {
q->enableDisableActions( view ? view->selectionModel() : 0 );
}
private:
int toolTipOptions() const;
private:
static Command::Restrictions calculateRestrictionsMask( const QItemSelectionModel * sm );
private:
struct action_item {
QPointer<QAction> action;
Command::Restrictions restrictions;
Command * (KeyListController::*createCommand)();
};
std::vector<action_item> actions;
std::vector<QAbstractItemView*> views;
std::vector<Command*> commands;
QPointer<TabWidget> tabWidget;
QPointer<AbstractKeyListModel> flatModel, hierarchicalModel;
};
KeyListController::Private::Private( KeyListController * qq )
: q( qq ),
actions(),
views(),
commands(),
tabWidget(),
flatModel(),
hierarchicalModel()
{
connect( KeyCache::mutableInstance().get(), SIGNAL(added(GpgME::Key)),
q, SLOT(slotAddKey(GpgME::Key)) );
connect( KeyCache::mutableInstance().get(), SIGNAL(aboutToRemove(GpgME::Key)),
q, SLOT(slotAboutToRemoveKey(GpgME::Key)) );
}
KeyListController::Private::~Private() {}
KeyListController::KeyListController( QObject * p )
: QObject( p ), d( new Private( this ) )
{
}
KeyListController::~KeyListController() {}
void KeyListController::Private::slotAddKey( const Key & key ) {
// ### make model act on keycache directly...
if ( flatModel )
flatModel->addKey( key );
if ( hierarchicalModel )
hierarchicalModel->addKey( key );
}
void KeyListController::Private::slotAboutToRemoveKey( const Key & key ) {
// ### make model act on keycache directly...
if ( flatModel )
flatModel->removeKey( key );
if ( hierarchicalModel )
hierarchicalModel->removeKey( key );
}
void KeyListController::addView( QAbstractItemView * view ) {
if ( !view || std::binary_search( d->views.begin(), d->views.end(), view ) )
return;
d->addView( view );
}
void KeyListController::removeView( QAbstractItemView * view ) {
if ( !view || !std::binary_search( d->views.begin(), d->views.end(), view ) )
return;
d->removeView( view );
}
std::vector<QAbstractItemView*> KeyListController::views() const {
return d->views;
}
void KeyListController::setFlatModel( AbstractKeyListModel * model ) {
if ( model == d->flatModel )
return;
d->flatModel = model;
if ( model ) {
model->clear();
model->addKeys( KeyCache::instance()->keys() );
model->setToolTipOptions( d->toolTipOptions() );
}
}
void KeyListController::setHierarchicalModel( AbstractKeyListModel * model ) {
if ( model == d->hierarchicalModel )
return;
d->hierarchicalModel = model;
if ( model ) {
model->clear();
model->addKeys( KeyCache::instance()->keys() );
model->setToolTipOptions( d->toolTipOptions() );
}
}
void KeyListController::setTabWidget( TabWidget * tabWidget ) {
if ( tabWidget == d->tabWidget )
return;
d->disconnectTabWidget();
d->tabWidget = tabWidget;
d->connectTabWidget();
}
static const struct {
const char * signal;
const char * slot;
} tabs2controller[] = {
{ SIGNAL(viewAdded(QAbstractItemView*)), SLOT(addView(QAbstractItemView*)) },
{ SIGNAL(viewAboutToBeRemoved(QAbstractItemView*)), SLOT(removeView(QAbstractItemView*)) },
{ SIGNAL(currentViewChanged(QAbstractItemView*)), SLOT(slotCurrentViewChanged(QAbstractItemView*)) },
};
static const unsigned int numTabs2Controller = sizeof tabs2controller / sizeof *tabs2controller ;
void KeyListController::Private::connectTabWidget() {
if ( !tabWidget )
return;
for ( unsigned int i = 0 ; i < numTabs2Controller ; ++i )
connect( tabWidget, tabs2controller[i].signal, q, tabs2controller[i].slot );
}
void KeyListController::Private::disconnectTabWidget() {
if ( !tabWidget )
return;
for ( unsigned int i = 0 ; i < numTabs2Controller ; ++i )
disconnect( tabWidget, tabs2controller[i].signal, q, tabs2controller[i].slot );
}
AbstractKeyListModel * KeyListController::flatModel() const {
return d->flatModel;
}
AbstractKeyListModel * KeyListController::hierarchicalModel() const {
return d->hierarchicalModel;
}
TabWidget * KeyListController::tabWidget() const {
return d->tabWidget;
}
void KeyListController::registerAction( QAction * action, Command::Restrictions restrictions, Command * (KeyListController::*create)() ) {
if ( !action )
return;
assert( !action->isCheckable() ); // can be added later, for now, disallow
const Private::action_item ai = {
action, restrictions, create
};
connect( action, SIGNAL(triggered()), this, SLOT(slotActionTriggered()) );
d->actions.push_back( ai );
}
void KeyListController::registerCommand( Command * cmd ) {
if ( !cmd || std::binary_search( d->commands.begin(), d->commands.end(), cmd ) )
return;
d->addCommand( cmd );
qDebug( "KeyListController::registerCommand( %p )", cmd );
if ( d->commands.size() == 1 )
emit commandsExecuting( true );
}
bool KeyListController::hasRunningCommands() const {
return !d->commands.empty();
}
-bool KeyListController::shutdownWarningRequired() const {
- return kdtools::any( d->commands, mem_fn( &Command::warnWhenRunningAtShutdown ) );
-}
-
// slot
void KeyListController::cancelCommands() {
std::for_each( d->commands.begin(), d->commands.end(),
bind( &Command::cancel, _1 ) );
}
void KeyListController::Private::connectView( QAbstractItemView * view ) {
connect( view, SIGNAL(destroyed(QObject*)),
q, SLOT(slotDestroyed(QObject*)) );
connect( view, SIGNAL(doubleClicked(QModelIndex)),
q, SLOT(slotDoubleClicked(QModelIndex)) );
connect( view, SIGNAL(activated(QModelIndex)),
q, SLOT(slotActivated(QModelIndex)) );
connect( view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) );
view->setContextMenuPolicy( Qt::CustomContextMenu );
connect( view, SIGNAL(customContextMenuRequested(QPoint)),
q, SLOT(slotContextMenu(QPoint)) );
}
void KeyListController::Private::connectCommand( Command * cmd ) {
if ( !cmd )
return;
connect( cmd, SIGNAL(destroyed(QObject*)), q, SLOT(slotDestroyed(QObject*)) );
connect( cmd, SIGNAL(finished()), q, SLOT(slotCommandFinished()) );
//connect( cmd, SIGNAL(canceled()), q, SLOT(slotCommandCanceled()) );
connect( cmd, SIGNAL(info(QString,int)), q, SIGNAL(message(QString,int)) );
connect( cmd, SIGNAL(progress(QString,int,int)), q, SLOT(slotProgress(QString,int,int)) );
}
void KeyListController::Private::slotDoubleClicked( const QModelIndex & idx ) {
QAbstractItemView * const view = qobject_cast<QAbstractItemView*>( q->sender() );
if ( !view || !std::binary_search( views.begin(), views.end(), view ) )
return;
DetailsCommand * const c = new DetailsCommand( view, q );
c->setIndex( idx );
c->start();
}
void KeyListController::Private::slotActivated( const QModelIndex & idx ) {
QAbstractItemView * const view = qobject_cast<QAbstractItemView*>( q->sender() );
if ( !view || !std::binary_search( views.begin(), views.end(), view ) )
return;
}
void KeyListController::Private::slotSelectionChanged( const QItemSelection & old, const QItemSelection & new_ ) {
const QItemSelectionModel * const sm = qobject_cast<QItemSelectionModel*>( q->sender() );
if ( !sm )
return;
q->enableDisableActions( sm );
}
void KeyListController::Private::slotContextMenu( const QPoint & p ) {
QAbstractItemView * const view = qobject_cast<QAbstractItemView*>( q->sender() );
if ( view && std::binary_search( views.begin(), views.end(), view ) )
emit q->contextMenuRequested( view, view->viewport()->mapToGlobal( p ) );
else
qDebug( "KeyListController::Private::slotContextMenu: sender is not a QAbstractItemView*!" );
}
void KeyListController::Private::slotCommandFinished() {
Command * const cmd = qobject_cast<Command*>( q->sender() );
if ( !cmd || !std::binary_search( commands.begin(), commands.end(), cmd ) )
return;
qDebug( "KeyListController::Private::slotCommandFinished( %p )", cmd );
if ( commands.size() == 1 )
emit q->commandsExecuting( false );
}
void KeyListController::enableDisableActions( const QItemSelectionModel * sm ) const {
const Command::Restrictions restrictionsMask = d->calculateRestrictionsMask( sm );
Q_FOREACH( const Private::action_item & ai, d->actions )
if ( ai.action )
ai.action->setEnabled( ai.restrictions == ( ai.restrictions & restrictionsMask ) );
}
-static bool all_secret_are_not_owner_trust_ultimate( const std::vector<Key> & keys ) {
- Q_FOREACH( const Key & key, keys )
- if ( key.hasSecret() && key.ownerTrust() == Key::Ultimate )
- return false;
- return true;
-}
-
Command::Restrictions KeyListController::Private::calculateRestrictionsMask( const QItemSelectionModel * sm ) {
if ( !sm )
return 0;
const KeyListModelInterface * const m = dynamic_cast<const KeyListModelInterface*>( sm->model() );
if ( !m )
return 0;
const std::vector<Key> keys = m->keys( sm->selectedRows() );
if ( keys.empty() )
return 0;
Command::Restrictions result = Command::NeedSelection;
if ( keys.size() == 1 )
result |= Command::OnlyOneKey;
if ( kdtools::all( keys.begin(), keys.end(), bind( &Key::hasSecret, _1 ) ) )
result |= Command::NeedSecretKey;
else if ( !kdtools::any( keys.begin(), keys.end(), bind( &Key::hasSecret, _1 ) ) )
result |= Command::MustNotBeSecretKey;
if ( kdtools::all( keys.begin(), keys.end(), bind( &Key::protocol, _1 ) == OpenPGP ) )
result |= Command::MustBeOpenPGP;
else if ( kdtools::all( keys.begin(), keys.end(), bind( &Key::protocol, _1 ) == CMS ) )
result |= Command::MustBeCMS;
- if ( all_secret_are_not_owner_trust_ultimate( keys ) )
- result |= Command::MayOnlyBeSecretKeyIfOwnerTrustIsNotYetUltimate;
-
return result;
}
void KeyListController::Private::slotActionTriggered() {
qDebug( "KeyListController::Private::slotActionTriggered: not implemented" );
}
int KeyListController::Private::toolTipOptions() const
{
using namespace Kleo::Formatting;
static const int validityFlags = Validity;
static const int ownerFlags = Subject|Issuer|UserIDs|SerialNumber;
static const int detailsFlags = ExpiryDates|CertificateType|CertificateUsage|Fingerprint;
const TooltipPreferences prefs;
int flags = prefs.showValidity() ? validityFlags : 0;
flags |= prefs.showOwnerInformation() ? ownerFlags : 0;
flags |= prefs.showCertificateDetails() ? detailsFlags : 0;
return flags;
}
void KeyListController::updateConfig()
{
const int opts = d->toolTipOptions();
if ( d->flatModel )
d->flatModel->setToolTipOptions( opts );
if ( d->hierarchicalModel )
d->hierarchicalModel->setToolTipOptions( opts );
}
#include "moc_keylistcontroller.cpp"
diff --git a/view/keylistcontroller.h b/view/keylistcontroller.h
index 5ef369b15..4b936541d 100644
--- a/view/keylistcontroller.h
+++ b/view/keylistcontroller.h
@@ -1,120 +1,119 @@
/* -*- mode: c++; c-basic-offset:4 -*-
controllers/keylistcontroller.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_CONTROLLERS_KEYLISTCONTROLLER_H__
#define __KLEOPATRA_CONTROLLERS_KEYLISTCONTROLLER_H__
#include <QObject>
#include <commands/command.h>
#include <utils/pimpl_ptr.h>
#include <vector>
class QAbstractItemView;
class QAction;
class QPoint;
class QItemSelectionModel;
namespace Kleo {
class AbstractKeyListModel;
class Command;
class TabWidget;
class KeyListController : public QObject {
Q_OBJECT
public:
explicit KeyListController( QObject * parent=0 );
~KeyListController();
std::vector<QAbstractItemView*> views() const;
void setFlatModel( AbstractKeyListModel * model );
AbstractKeyListModel * flatModel() const;
void setHierarchicalModel( AbstractKeyListModel * model );
AbstractKeyListModel * hierarchicalModel() const;
void setTabWidget( TabWidget * tabs );
TabWidget * tabWidget() const;
void registerCommand( Command * cmd );
template <typename T_Command>
void registerActionForCommand( QAction * action ) {
this->registerAction( action, T_Command::restrictions() /*, &KeyListController::create<T_Command>*/ );
}
void enableDisableActions( const QItemSelectionModel * sm ) const;
bool hasRunningCommands() const;
- bool shutdownWarningRequired() const;
private:
void registerAction( QAction * action, Command::Restrictions restrictions , Command * (KeyListController::*create)()=0 );
public Q_SLOTS:
void addView( QAbstractItemView * view );
void removeView( QAbstractItemView * view );
void cancelCommands();
void updateConfig();
Q_SIGNALS:
void progress( int current, int total );
void message( const QString & msg, int timeout=0 );
void commandsExecuting( bool );
void contextMenuRequested( QAbstractItemView * view, const QPoint & p );
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void slotDestroyed(QObject*) )
Q_PRIVATE_SLOT( d, void slotDoubleClicked(QModelIndex) )
Q_PRIVATE_SLOT( d, void slotActivated(QModelIndex) )
Q_PRIVATE_SLOT( d, void slotSelectionChanged(QItemSelection,QItemSelection) )
Q_PRIVATE_SLOT( d, void slotContextMenu(QPoint) )
Q_PRIVATE_SLOT( d, void slotCommandFinished() )
Q_PRIVATE_SLOT( d, void slotAddKey(GpgME::Key) )
Q_PRIVATE_SLOT( d, void slotAboutToRemoveKey(GpgME::Key) )
Q_PRIVATE_SLOT( d, void slotProgress(QString,int,int) )
Q_PRIVATE_SLOT( d, void slotActionTriggered() )
Q_PRIVATE_SLOT( d, void slotCurrentViewChanged(QAbstractItemView*) )
};
}
#endif /* __KLEOPATRA_CONTROLLERS_KEYLISTCONTROLLER_H__ */
diff --git a/view/tabwidget.cpp b/view/tabwidget.cpp
index da3d9f2f9..c44be3197 100644
--- a/view/tabwidget.cpp
+++ b/view/tabwidget.cpp
@@ -1,887 +1,873 @@
/* -*- mode: c++; c-basic-offset:4 -*-
view/tabwidget.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 "tabwidget.h"
#include <models/keylistmodel.h>
#include <models/keylistsortfilterproxymodel.h>
#include <utils/action_data.h>
#include <utils/headerview.h>
#include <utils/stl_util.h>
#include <kleo/keyfilter.h>
#include <kleo/keyfiltermanager.h>
#include <gpgme++/key.h>
#include <KLocale>
#include <KTabWidget>
#include <KConfigGroup>
#include <KConfig>
#include <KAction>
#include <KActionCollection>
#include <QGridLayout>
#include <QTimer>
+#include <QResizeEvent>
+#include <QSortFilterProxyModel>
#include <QTreeView>
#include <QToolButton>
#include <QAction>
#include <QMenu>
#include <QInputDialog>
#include <QItemSelectionModel>
#include <QItemSelection>
-#include <QLayout>
#include <map>
#include <vector>
#include <cassert>
using namespace Kleo;
using namespace boost;
using namespace GpgME;
namespace {
class Page : public QWidget {
Q_OBJECT
Page( const Page & other );
public:
Page( const QString & title, const QString & id, const QString & text, QWidget * parent=0 );
Page( const KConfigGroup & group, QWidget * parent=0 );
~Page();
QTreeView * view() const { return m_view; }
AbstractKeyListModel * model() const {
return m_isHierarchical ? m_hierarchicalModel : m_flatModel ;
}
void setFlatModel( AbstractKeyListModel * model );
void setHierarchicalModel( AbstractKeyListModel * model );
void setTemporary( bool temporary );
bool isTemporary() const { return m_isTemporary; }
void setHierarchical( bool hierarchical );
bool isHierarchical() const { return m_isHierarchical; }
QString stringFilter() const { return m_stringFilter; }
void setStringFilter( const QString & filter );
const shared_ptr<KeyFilter> & keyFilter() const { return m_keyFilter; }
void setKeyFilter( const shared_ptr<KeyFilter> & filter );
QString title() const { return m_title.isEmpty() && m_keyFilter ? m_keyFilter->name() : m_title ; }
void setTitle( const QString & title );
bool canBeClosed() const { return m_canBeClosed; }
bool canBeRenamed() const { return m_canBeRenamed; }
bool canChangeStringFilter() const { return m_canChangeStringFilter; }
bool canChangeKeyFilter() const { return m_canChangeKeyFilter && !m_isTemporary; }
bool canChangeHierarchical() const { return m_canChangeHierarchical; }
void saveTo( KConfigGroup & group ) const;
Page * clone() const { return new Page( *this ); }
void liftAllRestrictions() {
m_canBeClosed = m_canBeRenamed = m_canChangeStringFilter = m_canChangeKeyFilter = m_canChangeHierarchical = true;
}
Q_SIGNALS:
void titleChanged( const QString & title );
void stringFilterChanged( const QString & filter );
void keyFilterChanged( const boost::shared_ptr<Kleo::KeyFilter> & filter );
void hierarchicalChanged( bool on );
+protected:
+ void resizeEvent( QResizeEvent * e ) {
+ QWidget::resizeEvent( e );
+ m_view->resize( e->size() );
+ }
+
private:
void init();
private:
KeyListSortFilterProxyModel m_proxy;
- QVBoxLayout * m_layout;
QTreeView * m_view;
AbstractKeyListModel * m_flatModel;
AbstractKeyListModel * m_hierarchicalModel;
QString m_stringFilter;
shared_ptr<KeyFilter> m_keyFilter;
QString m_title;
bool m_isHierarchical : 1;
bool m_isTemporary : 1;
bool m_canBeClosed : 1;
bool m_canBeRenamed : 1;
bool m_canChangeStringFilter : 1;
bool m_canChangeKeyFilter : 1;
bool m_canChangeHierarchical : 1;
};
} // anon namespace
Page::Page( const Page & other )
: QWidget( 0 ),
m_proxy(),
- m_layout( new QVBoxLayout( this ) ),
m_view( new QTreeView( this ) ),
m_flatModel( other.m_flatModel ),
m_hierarchicalModel( other.m_hierarchicalModel ),
m_stringFilter( other.m_stringFilter ),
m_keyFilter( other.m_keyFilter ),
m_title( other.m_title ),
m_isHierarchical( other.m_isHierarchical ),
m_isTemporary( other.m_isTemporary ),
m_canBeClosed( other.m_canBeClosed ),
m_canBeRenamed( other.m_canBeRenamed ),
m_canChangeStringFilter( other.m_canChangeStringFilter ),
m_canChangeKeyFilter( other.m_canChangeKeyFilter ),
m_canChangeHierarchical( other.m_canChangeHierarchical )
{
init();
}
Page::Page( const QString & title, const QString & id, const QString & text, QWidget * parent )
: QWidget( parent ),
m_proxy(),
- m_layout( new QVBoxLayout( this ) ),
m_view( new QTreeView( this ) ),
m_flatModel( 0 ),
m_hierarchicalModel( 0 ),
m_stringFilter( text ),
m_keyFilter( KeyFilterManager::instance()->keyFilterByID( id ) ),
m_title( title ),
m_isHierarchical( true ),
m_isTemporary( false ),
m_canBeClosed( true ),
m_canBeRenamed( true ),
m_canChangeStringFilter( true ),
m_canChangeKeyFilter( true ),
m_canChangeHierarchical( true )
{
init();
}
static const char TITLE_ENTRY[] = "title";
static const char STRING_FILTER_ENTRY[] = "string-filter";
static const char KEY_FILTER_ENTRY[] = "key-filter";
static const char HIERARCHICAL_VIEW_ENTRY[] = "hierarchical-view";
static const char COLUMN_SIZES[] = "column-sizes";
Page::Page( const KConfigGroup & group, QWidget * parent )
: QWidget( parent ),
m_proxy(),
- m_layout( new QVBoxLayout( this ) ),
m_view( new QTreeView( this ) ),
m_flatModel( 0 ),
m_hierarchicalModel( 0 ),
m_stringFilter( group.readEntry( STRING_FILTER_ENTRY ) ),
m_keyFilter( KeyFilterManager::instance()->keyFilterByID( group.readEntry( KEY_FILTER_ENTRY ) ) ),
m_title( group.readEntry( TITLE_ENTRY ) ),
m_isHierarchical( group.readEntry( HIERARCHICAL_VIEW_ENTRY, true ) ),
m_isTemporary( false ),
m_canBeClosed( !group.isImmutable() ),
m_canBeRenamed( !group.isEntryImmutable( TITLE_ENTRY ) ),
m_canChangeStringFilter( !group.isEntryImmutable( STRING_FILTER_ENTRY ) ),
m_canChangeKeyFilter( !group.isEntryImmutable( KEY_FILTER_ENTRY ) ),
m_canChangeHierarchical( !group.isEntryImmutable( HIERARCHICAL_VIEW_ENTRY ) )
{
init();
assert( m_view );
assert( m_view->header() );
assert( qobject_cast<HeaderView*>( m_view->header() ) == static_cast<HeaderView*>( m_view->header() ) );
if ( HeaderView * const hv = static_cast<HeaderView*>( m_view->header() ) ) {
const QList<int> sizes = group.readEntry( COLUMN_SIZES, QList<int>() );
if ( !sizes.empty() )
hv->setSectionSizes( kdtools::copy< std::vector<int> >( sizes ) );
}
}
static const QHeaderView::ResizeMode resize_modes[AbstractKeyListModel::NumColumns] = {
QHeaderView::Stretch, // Name
QHeaderView::Stretch, // EMail
QHeaderView::Fixed, // Valid From
QHeaderView::Fixed, // Valid Until
QHeaderView::Fixed, // Details
QHeaderView::Fixed, // Fingerprint
};
static void adjust_header( HeaderView * hv ) {
for ( int i = 0, end = AbstractKeyListModel::NumColumns ; i < end ; ++i )
hv->setSectionResizeMode( i, resize_modes[i] );
}
void Page::init() {
KDAB_SET_OBJECT_NAME( m_proxy );
- KDAB_SET_OBJECT_NAME( m_layout );
KDAB_SET_OBJECT_NAME( m_view );
- m_layout->setMargin( 0 );
- m_layout->addWidget( m_view );
-
HeaderView * headerView = new HeaderView( Qt::Horizontal );
KDAB_SET_OBJECT_NAME( headerView );
m_view->setHeader( headerView );
adjust_header( headerView );
m_view->setSelectionBehavior( QAbstractItemView::SelectRows );
m_view->setSelectionMode( QAbstractItemView::ExtendedSelection );
//m_view->setAlternatingRowColors( true );
m_view->setAllColumnsShowFocus( true );
m_view->setSortingEnabled( true );
if ( model() )
m_proxy.setSourceModel( model() );
m_proxy.setFilterFixedString( m_stringFilter );
m_proxy.setKeyFilter( m_keyFilter );
m_view->setModel( &m_proxy );
}
Page::~Page() {}
void Page::saveTo( KConfigGroup & group ) const {
group.writeEntry( TITLE_ENTRY, m_title );
group.writeEntry( STRING_FILTER_ENTRY, m_stringFilter );
group.writeEntry( KEY_FILTER_ENTRY, m_keyFilter ? m_keyFilter->id() : QString() );
group.writeEntry( HIERARCHICAL_VIEW_ENTRY, m_isHierarchical );
if ( const HeaderView * const hv = m_view ? qobject_cast<HeaderView*>( m_view->header() ) : 0 )
group.writeEntry( COLUMN_SIZES, kdtools::copy< QList<int> >( hv->sectionSizes() ) );
}
void Page::setFlatModel( AbstractKeyListModel * model ) {
if ( model == m_flatModel )
return;
m_flatModel = model;
if ( !m_isHierarchical )
m_proxy.setSourceModel( model );
}
void Page::setHierarchicalModel( AbstractKeyListModel * model ) {
if ( model == m_hierarchicalModel )
return;
m_hierarchicalModel = model;
- if ( m_isHierarchical ) {
+ if ( m_isHierarchical )
m_proxy.setSourceModel( model );
- m_view->expandAll();
- }
}
void Page::setStringFilter( const QString & filter ) {
if ( filter == m_stringFilter )
return;
if ( !m_canChangeStringFilter )
return;
m_stringFilter = filter;
m_proxy.setFilterFixedString( filter );
emit stringFilterChanged( filter );
}
void Page::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
if ( filter == m_keyFilter || filter && m_keyFilter && filter->id() == m_keyFilter->id() )
return;
if ( !canChangeKeyFilter() )
return;
const QString oldTitle = title();
m_keyFilter = filter;
m_proxy.setKeyFilter( filter );
const QString newTitle = title();
emit keyFilterChanged( filter );
if ( oldTitle != newTitle )
emit titleChanged( newTitle );
}
void Page::setTitle( const QString & t ) {
if ( t == m_title )
return;
if ( !m_canBeRenamed )
return;
const QString oldTitle = title();
m_title = t;
const QString newTitle = title();
if ( oldTitle != newTitle )
emit titleChanged( newTitle );
}
static QItemSelection itemSelectionFromKeys( const std::vector<Key> & keys, const KeyListSortFilterProxyModel & proxy ) {
QItemSelection result;
Q_FOREACH( const Key & key, keys ) {
const QModelIndex mi = proxy.index( key );
if ( mi.isValid() )
result.merge( QItemSelection( mi, mi ), QItemSelectionModel::Select );
}
return result;
}
void Page::setHierarchical( bool on ) {
if ( on == m_isHierarchical )
return;
if ( !m_canChangeHierarchical )
return;
const std::vector<Key> selectedKeys = m_proxy.keys( m_view->selectionModel()->selectedRows() );
const Key currentKey = m_proxy.key( m_view->currentIndex() );
m_isHierarchical = on;
m_proxy.setSourceModel( model() );
- if ( on )
- m_view->expandAll();
m_view->selectionModel()->select( itemSelectionFromKeys( selectedKeys, m_proxy ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
if ( !currentKey.isNull() ) {
const QModelIndex currentIndex = m_proxy.index( currentKey );
if ( currentIndex.isValid() ) {
m_view->selectionModel()->setCurrentIndex( m_proxy.index( currentKey ), QItemSelectionModel::NoUpdate );
m_view->scrollTo( currentIndex );
}
}
emit hierarchicalChanged( on );
}
void Page::setTemporary( bool on ) {
if ( on == m_isTemporary )
return;
m_isTemporary = on;
if ( on && m_keyFilter ) {
m_keyFilter.reset();
emit keyFilterChanged( shared_ptr<KeyFilter>() );
}
}
//
//
// TabWidget
//
//
class TabWidget::Private {
friend class ::Kleo::TabWidget;
TabWidget * const q;
public:
explicit Private( TabWidget * qq );
~Private() {};
private:
void slotContextMenu( const QPoint & p ) {
slotContextMenu( 0, p );
}
void slotContextMenu( QWidget * w, const QPoint & p );
void currentIndexChanged( int index );
void slotPageTitleChanged( const QString & title );
void slotPageKeyFilterChanged( const shared_ptr<KeyFilter> & filter );
void slotPageStringFilterChanged( const QString & filter );
void slotPageHierarchyChanged( bool on );
void slotRenameCurrentTab() {
renamePage( currentPage() );
}
void slotNewTab();
void slotDuplicateCurrentTab() {
duplicatePage( currentPage() );
}
void slotCloseCurrentTab() {
closePage( currentPage() );
}
void slotMoveCurrentTabLeft() {
movePageLeft( currentPage() );
}
void slotMoveCurrentTabRight() {
movePageRight( currentPage() );
}
void slotToggleHierarchicalView( bool on ) {
toggleHierarchicalView( currentPage(), on );
}
void slotExpandAll() {
expandAll( currentPage() );
}
void slotCollapseAll() {
collapseAll( currentPage() );
}
void renamePage( Page * page );
void duplicatePage( Page * page );
void closePage( Page * page );
void movePageLeft( Page * page );
void movePageRight( Page * page );
void toggleHierarchicalView( Page * page, bool on );
void expandAll( Page * page );
void collapseAll( Page * page );
void enableDisableCurrentPageActions();
void enableDisablePageActions( QAction * actions[], const Page * page );
Page * currentPage() const {
assert( !tabWidget.currentWidget() || qobject_cast<Page*>( tabWidget.currentWidget() ) );
return static_cast<Page*>( tabWidget.currentWidget() );
}
Page * page( unsigned int idx ) const {
assert( !tabWidget.widget( idx ) || qobject_cast<Page*>( tabWidget.widget( idx ) ) );
return static_cast<Page*>( tabWidget.widget( idx ) );
}
Page * senderPage() const {
QObject * const sender = q->sender();
assert( !sender || qobject_cast<Page*>( sender ) );
return static_cast<Page*>( sender );
}
bool isSenderCurrentPage() const {
Page * const sp = senderPage();
return sp && sp == currentPage();
}
QTreeView * addView( Page * page );
void setCornerAction( QAction * action, Qt::Corner corner );
private:
AbstractKeyListModel * flatModel;
AbstractKeyListModel * hierarchicalModel;
KTabWidget tabWidget;
- QVBoxLayout layout;
enum {
Rename,
Duplicate,
Close,
MoveLeft,
MoveRight,
Hierarchical,
ExpandAll,
CollapseAll,
NumPageActions
};
QAction * newAction;
QAction * currentPageActions[NumPageActions];
QAction * otherPageActions[NumPageActions];
};
TabWidget::Private::Private( TabWidget * qq )
: q( qq ),
flatModel( 0 ),
hierarchicalModel( 0 ),
- tabWidget( q ),
- layout( q )
+ tabWidget( q )
{
KDAB_SET_OBJECT_NAME( tabWidget );
- KDAB_SET_OBJECT_NAME( layout );
-
- layout.setMargin( 0 );
- layout.addWidget( &tabWidget );
tabWidget.setTabBarHidden( true );
tabWidget.setTabReorderingEnabled( true );
connect( &tabWidget, SIGNAL(currentChanged(int)),
q, SLOT(currentIndexChanged(int)) );
connect( &tabWidget, SIGNAL(contextMenu(QPoint)),
q, SLOT(slotContextMenu(QPoint)) );
connect( &tabWidget, SIGNAL(contextMenu(QWidget*,QPoint)),
q, SLOT(slotContextMenu(QWidget*,QPoint)) );
const action_data actionDataNew = {
"window_new_tab", i18n("New Tab"), i18n("Open a new tab"),
"tab-new", q, SLOT(slotNewTab()), i18n("CTRL+SHIFT+N"), false, true
};
newAction = make_action_from_data( actionDataNew, q );
struct action_data actionData[NumPageActions] = {
{ "window_rename_tab", i18n("Rename Tab..."), i18n("Rename this tab"),
"edit-rename", q, SLOT(slotRenameCurrentTab()), i18n("CTRL+SHIFT+R"), false, false },
{ "window_duplicate_tab", i18n("Duplicate Current Tab"), i18n("Duplicate the current tab"),
"tab-duplicate", q, SLOT(slotDuplicateCurrentTab()), i18n("CTRL+SHIFT+D"), false, true },
- { "window_close_tab", i18n("Close Tab"), i18n("Close this tab"),
+ { "window_close_tab", i18n("Close Current Tab"), i18n("Close the current tab"),
"tab-close", q, SLOT(slotCloseCurrentTab()), i18n("CTRL+SHIFT+W"), false, false }, // ### CTRL-W when available
{ "window_move_tab_left", i18n("Move Tab Left"), QString(),
0, q, SLOT(slotMoveCurrentTabLeft()), i18n("CTRL+SHIFT+LEFT"), false, false },
{ "window_move_tab_right", i18n("Move Tab Right"), QString(),
0, q, SLOT(slotMoveCurrentTabRight()), i18n("CTRL+SHIFT+RIGHT"), false, false },
{ "window_view_hierarchical", i18n("Hierarchical Certificate List"), QString(),
0, q, SLOT(slotToggleHierarchicalView(bool)), QString(), true, false },
{ "window_expand_all", i18n("Expand All"), QString(),
0, q, SLOT(slotExpandAll()), i18n("CTRL+."), false, false },
{ "window_collapse_all", i18n("Collapse All"), QString(),
0, q, SLOT(slotCollapseAll()), i18n("CTRL+,"), false, false },
};
for ( unsigned int i = 0 ; i < NumPageActions ; ++i )
currentPageActions[i] = make_action_from_data( actionData[i], q );
for ( unsigned int i = 0 ; i < NumPageActions ; ++i ) {
action_data ad = actionData[i];
assert( QString::fromLatin1( ad.name ).startsWith( "window_" ) );
ad.name = ad.name + strlen("window_");
ad.tooltip.clear();
ad.receiver = 0;
ad.shortcut.clear();
otherPageActions[i] = make_action_from_data( ad, q );
}
setCornerAction( newAction, Qt::TopLeftCorner );
setCornerAction( currentPageActions[Close], Qt::TopRightCorner );
}
void TabWidget::Private::slotContextMenu( QWidget * w, const QPoint & p ) {
assert( !w || qobject_cast<Page*>( w ) );
Page * const contextMenuPage = static_cast<Page*>( w );
const Page * const current = currentPage();
QAction ** const actions = contextMenuPage == current ? currentPageActions : otherPageActions ;
if ( contextMenuPage != current )
enableDisablePageActions( actions, contextMenuPage );
QMenu menu;
menu.addAction( actions[Rename] );
menu.addSeparator();
menu.addAction( newAction );
menu.addAction( actions[Duplicate] );
menu.addSeparator();
menu.addAction( actions[MoveLeft] );
menu.addAction( actions[MoveRight] );
menu.addSeparator();
menu.addAction( actions[Close] );
const QAction * const action = menu.exec( p );
if ( contextMenuPage == current || action == newAction )
return; // performed through signal/slot connections...
if ( action == otherPageActions[Rename] )
renamePage( contextMenuPage );
else if ( action == otherPageActions[Duplicate] )
duplicatePage( contextMenuPage );
else if ( action == otherPageActions[Close] )
closePage( contextMenuPage );
else if ( action == otherPageActions[MoveLeft] )
movePageLeft( contextMenuPage );
else if ( action == otherPageActions[MoveRight] )
movePageRight( contextMenuPage );
}
void TabWidget::Private::currentIndexChanged( int index ) {
const Page * const page = this->page( index );
emit q->currentViewChanged( page ? page->view() : 0 );
emit q->keyFilterChanged( page ? page->keyFilter() : shared_ptr<KeyFilter>() );
emit q->stringFilterChanged( page ? page->stringFilter() : QString() );
enableDisableCurrentPageActions();
}
void TabWidget::Private::enableDisableCurrentPageActions() {
const Page * const page = currentPage();
emit q->enableChangeStringFilter( page && page->canChangeStringFilter() );
emit q->enableChangeKeyFilter( page && page->canChangeKeyFilter() );
enableDisablePageActions( currentPageActions, page );
}
void TabWidget::Private::enableDisablePageActions( QAction * actions[], const Page * p ) {
actions[Rename] ->setEnabled( p && p->canBeRenamed() );
actions[Duplicate] ->setEnabled( p );
actions[Close] ->setEnabled( p && p->canBeClosed() && tabWidget.count() > 1 );
actions[MoveLeft] ->setEnabled( p && tabWidget.indexOf( const_cast<Page*>(p) ) != 0 );
actions[MoveRight] ->setEnabled( p && tabWidget.indexOf( const_cast<Page*>(p) ) != tabWidget.count()-1 );
actions[Hierarchical]->setEnabled( p && p->canChangeHierarchical() );
actions[Hierarchical]->setChecked( p && p->isHierarchical() );
actions[ExpandAll] ->setEnabled( p && p->isHierarchical() );
actions[CollapseAll] ->setEnabled( p && p->isHierarchical() );
}
void TabWidget::Private::slotPageTitleChanged( const QString & ) {
if ( Page * const page = senderPage() )
tabWidget.setTabText( tabWidget.indexOf( page ), page->title() );
}
void TabWidget::Private::slotPageKeyFilterChanged( const shared_ptr<KeyFilter> & kf ) {
if ( isSenderCurrentPage() )
emit q->keyFilterChanged( kf );
}
void TabWidget::Private::slotPageStringFilterChanged( const QString & filter ) {
if ( isSenderCurrentPage() )
emit q->stringFilterChanged( filter );
}
void TabWidget::Private::slotPageHierarchyChanged( bool ) {
enableDisableCurrentPageActions();
}
void TabWidget::Private::slotNewTab() {
- q->addView( QString(), "all-certificates" );
+ q->addView( QString(), "my-certificates" );
tabWidget.setCurrentIndex( tabWidget.count()-1 );
}
void TabWidget::Private::renamePage( Page * page ) {
if ( !page )
return;
bool ok = false;
const QString text = QInputDialog::getText( q, i18n("Rename Tab"), i18n("New tab title:"), QLineEdit::Normal, page->title(), &ok );
if ( !ok )
return;
page->setTitle( text );
}
void TabWidget::Private::duplicatePage( Page * page ) {
if ( !page )
return;
Page * const clone = page->clone();
assert( clone );
clone->liftAllRestrictions();
addView( clone );
}
void TabWidget::Private::closePage( Page * page) {
if ( !page || !page->canBeClosed() || tabWidget.count() <= 1 )
return;
emit q->viewAboutToBeRemoved( page->view() );
tabWidget.removeTab( tabWidget.indexOf( page ) );
enableDisableCurrentPageActions();
}
void TabWidget::Private::movePageLeft( Page * page ) {
if ( !page )
return;
const int idx = tabWidget.indexOf( page );
if ( idx <= 0 )
return;
tabWidget.moveTab( idx, idx-1 );
enableDisableCurrentPageActions();
}
void TabWidget::Private::movePageRight( Page * page ) {
if ( !page )
return;
const int idx = tabWidget.indexOf( page );
if ( idx < 0 || idx >= tabWidget.count()-1 )
return;
tabWidget.moveTab( idx, idx+1 );
enableDisableCurrentPageActions();
}
void TabWidget::Private::toggleHierarchicalView( Page * page, bool on ) {
if ( !page )
return;
page->setHierarchical( on );
}
void TabWidget::Private::expandAll( Page * page ) {
if ( !page || !page->view() )
return;
page->view()->expandAll();
}
void TabWidget::Private::collapseAll( Page * page ) {
if ( !page || !page->view() )
return;
page->view()->collapseAll();
}
TabWidget::TabWidget( QWidget * p, Qt::WindowFlags f )
: QWidget( p, f ), d( new Private( this ) )
{
}
TabWidget::~TabWidget() {}
void TabWidget::setFlatModel( AbstractKeyListModel * model ) {
if ( model == d->flatModel )
return;
d->flatModel = model;
for ( unsigned int i = 0, end = count() ; i != end ; ++i )
if ( Page * const page = d->page( i ) )
page->setFlatModel( model );
}
AbstractKeyListModel * TabWidget::flatModel() const {
return d->flatModel;
}
void TabWidget::setHierarchicalModel( AbstractKeyListModel * model ) {
if ( model == d->hierarchicalModel )
return;
d->hierarchicalModel = model;
for ( unsigned int i = 0, end = count() ; i != end ; ++i )
if ( Page * const page = d->page( i ) )
page->setHierarchicalModel( model );
}
AbstractKeyListModel * TabWidget::hierarchicalModel() const {
return d->hierarchicalModel;
}
void TabWidget::Private::setCornerAction( QAction * action, Qt::Corner corner ) {
if ( !action )
return;
QToolButton * b = new QToolButton;
b->setDefaultAction( action );
tabWidget.setCornerWidget( b, corner );
}
void TabWidget::setStringFilter( const QString & filter ) {
if ( Page * const page = d->currentPage() )
page->setStringFilter( filter );
}
void TabWidget::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
if ( Page * const page = d->currentPage() )
page->setKeyFilter( filter );
}
QAbstractItemView * TabWidget::currentView() const {
if ( Page * const page = d->currentPage() )
return page->view();
else
return 0;
}
unsigned int TabWidget::count() const {
return d->tabWidget.count();
}
void TabWidget::setMultiSelection( bool on ) {
for ( unsigned int i = 0, end = count() ; i != end ; ++i )
if ( const Page * const p = d->page( i ) )
if ( QTreeView * const view = p->view() )
view->setSelectionMode( on ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection );
}
void TabWidget::createActions( KActionCollection * coll ) {
if ( !coll )
return;
coll->addAction( d->newAction->objectName(), d->newAction );
for ( unsigned int i = 0 ; i < Private::NumPageActions ; ++i ) {
QAction * a = d->currentPageActions[i];
coll->addAction( a->objectName(), a );
}
}
+void TabWidget::resizeEvent( QResizeEvent * e ) {
+ QWidget::resizeEvent( e );
+ d->tabWidget.resize( e->size() );
+}
+
QAbstractItemView * TabWidget::addView( const QString & title, const QString & id, const QString & text ) {
return d->addView( new Page( title, id, text ) );
}
QAbstractItemView * TabWidget::addView( const KConfigGroup & group ) {
return d->addView( new Page( group ) );
}
QAbstractItemView * TabWidget::addTemporaryView( const QString & title ) {
Page * const page = new Page( title, QString(), QString() );
page->setTemporary( true );
QAbstractItemView * v = d->addView( page );
d->tabWidget.setCurrentIndex( d->tabWidget.count()-1 );
return v;
}
QTreeView * TabWidget::Private::addView( Page * page ) {
if ( !page )
return 0;
page->setFlatModel( flatModel );
page->setHierarchicalModel( hierarchicalModel );
connect( page, SIGNAL(titleChanged(QString)),
q, SLOT(slotPageTitleChanged(QString)) );
connect( page, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
q, SLOT(slotPageKeyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)) );
connect( page, SIGNAL(stringFilterChanged(QString)),
q, SLOT(slotPageStringFilterChanged(QString)) );
connect( page, SIGNAL(hierarchicalChanged(bool)),
q, SLOT(slotPageHierarchyChanged(bool)) );
QAbstractItemView * const previous = q->currentView();
tabWidget.addTab( page, page->title() );
tabWidget.setTabBarHidden( tabWidget.count() < 2 );
// work around a bug in QTabWidget (tested with 4.3.2) not emitting currentChanged() when the first widget is inserted
QAbstractItemView * const current = q->currentView();
if ( previous != current )
currentIndexChanged( tabWidget.currentIndex() );
enableDisableCurrentPageActions();
QTreeView * view = page->view();
emit q->viewAdded( view );
return view;
}
static QStringList extractViewGroups( const KConfig * config ) {
return config ? config->groupList().filter( QRegExp( "^View #\\d+$" ) ) : QStringList() ;
}
-// work around deleteGroup() not deleting groups out of groupList():
-static const bool KCONFIG_DELETEGROUP_BROKEN = true;
-
void TabWidget::loadViews( const KConfig * config ) {
if ( config )
- Q_FOREACH( const QString & group, extractViewGroups( config ) ) {
- const KConfigGroup kcg( config, group );
- if ( !KCONFIG_DELETEGROUP_BROKEN || kcg.readEntry( "magic", 0U ) == 0xFA1AFE1U )
- addView( kcg );
- }
+ Q_FOREACH( const QString & group, extractViewGroups( config ) )
+ addView( KConfigGroup( config, group ) );
if ( !count() ) {
// add default views:
addView( QString(), "my-certificates" );
addView( QString(), "trusted-certificates" );
addView( QString(), "other-certificates" );
}
}
void TabWidget::saveViews( KConfig * config ) const {
if ( !config )
return;
Q_FOREACH( QString group, extractViewGroups( config ) )
config->deleteGroup( group );
unsigned int vg = 0;
for ( unsigned int i = 0, end = count() ; i != end ; ++i ) {
if ( const Page * const p = d->page( i ) ) {
if ( p->isTemporary() )
continue;
KConfigGroup group( config, QString().sprintf( "View #%u", vg++ ) );
p->saveTo( group );
- if ( KCONFIG_DELETEGROUP_BROKEN )
- group.writeEntry( "magic", 0xFA1AFE1U );
}
}
}
static void xconnect( const QObject * o1, const char * signal, const QObject * o2, const char * slot ) {
QObject::connect( o1, signal, o2, slot );
QObject::connect( o2, signal, o1, slot );
}
void TabWidget::connectSearchBar( QObject * sb ) {
xconnect( sb, SIGNAL(stringFilterChanged(QString)),
this, SLOT(setStringFilter(QString)) );
xconnect( sb, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
this, SLOT(setKeyFilter(boost::shared_ptr<Kleo::KeyFilter>)) );
connect( this, SIGNAL(enableChangeStringFilter(bool)),
sb, SLOT(setChangeStringFilterEnabled(bool)) );
connect( this, SIGNAL(enableChangeKeyFilter(bool)),
sb, SLOT(setChangeKeyFilterEnabled(bool)) );
}
#include "moc_tabwidget.cpp"
#include "tabwidget.moc"
diff --git a/view/tabwidget.h b/view/tabwidget.h
index f8f8aaf9b..7cdb58d04 100644
--- a/view/tabwidget.h
+++ b/view/tabwidget.h
@@ -1,119 +1,122 @@
/* -*- mode: c++; c-basic-offset:4 -*-
view/tabwidget.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_VIEW_TABWIDGET_H__
#define __KLEOPATRA_VIEW_TABWIDGET_H__
#include <QWidget>
#include <utils/pimpl_ptr.h>
#include <boost/shared_ptr.hpp>
class QAbstractItemView;
class KConfigGroup;
class KActionCollection;
class KConfig;
namespace Kleo {
class AbstractKeyListModel;
class KeyFilter;
class TabWidget : public QWidget {
Q_OBJECT
public:
explicit TabWidget( QWidget * parent=0, Qt::WindowFlags f=0 );
~TabWidget();
void setFlatModel( AbstractKeyListModel * model );
AbstractKeyListModel * flatModel() const;
void setHierarchicalModel( AbstractKeyListModel * model );
AbstractKeyListModel * hierarchicalModel() const;
QAbstractItemView * addView( const QString & title=QString(), const QString & keyFilterID=QString(), const QString & searchString=QString() );
QAbstractItemView * addView( const KConfigGroup & group );
QAbstractItemView * addTemporaryView( const QString & title=QString() );
void loadViews( const KConfig * cfg );
void saveViews( KConfig * cfg ) const;
QAbstractItemView * currentView() const;
unsigned int count() const;
void createActions( KActionCollection * collection );
void connectSearchBar( QObject * sb );
void setMultiSelection( bool on );
public Q_SLOTS:
void setKeyFilter( const boost::shared_ptr<Kleo::KeyFilter> & filter );
void setStringFilter( const QString & filter );
Q_SIGNALS:
void viewAdded( QAbstractItemView * view );
void viewAboutToBeRemoved( QAbstractItemView * view );
void currentViewChanged( QAbstractItemView * view );
void stringFilterChanged( const QString & filter );
void keyFilterChanged( const boost::shared_ptr<Kleo::KeyFilter> & filter );
void enableChangeStringFilter( bool enable );
void enableChangeKeyFilter( bool enable );
+ protected:
+ void resizeEvent( QResizeEvent * );
+
private:
class Private;
kdtools::pimpl_ptr<Private> d;
Q_PRIVATE_SLOT( d, void slotContextMenu( QWidget *, const QPoint & ) )
Q_PRIVATE_SLOT( d, void slotContextMenu( const QPoint & ) )
Q_PRIVATE_SLOT( d, void currentIndexChanged( int ) )
Q_PRIVATE_SLOT( d, void slotPageTitleChanged( const QString & ) )
Q_PRIVATE_SLOT( d, void slotPageKeyFilterChanged( const boost::shared_ptr<Kleo::KeyFilter> & ) )
Q_PRIVATE_SLOT( d, void slotPageStringFilterChanged( const QString & ) )
Q_PRIVATE_SLOT( d, void slotPageHierarchyChanged( bool ) )
Q_PRIVATE_SLOT( d, void slotRenameCurrentTab() )
Q_PRIVATE_SLOT( d, void slotNewTab() )
Q_PRIVATE_SLOT( d, void slotDuplicateCurrentTab() )
Q_PRIVATE_SLOT( d, void slotCloseCurrentTab() )
Q_PRIVATE_SLOT( d, void slotMoveCurrentTabLeft() )
Q_PRIVATE_SLOT( d, void slotMoveCurrentTabRight() )
Q_PRIVATE_SLOT( d, void slotToggleHierarchicalView( bool ) )
Q_PRIVATE_SLOT( d, void slotExpandAll() )
Q_PRIVATE_SLOT( d, void slotCollapseAll() )
};
}
#endif /* __KLEOPATRA_VIEW_TABWIDGET_H__ */

File Metadata

Mime Type
text/x-diff
Expires
Thu, Dec 11, 12:48 AM (11 h, 13 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d7/df/ce549b924cacd609bfa2464db23f

Event Timeline