Page MenuHome GnuPG

No OneTemporary

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 36041e791..f11662766 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,646 +1,646 @@
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(icons)
add_subdirectory(mimetypes)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
if (NOT DISABLE_KWATCHGNUPG)
add_subdirectory(kwatchgnupg)
endif()
add_subdirectory(libkleopatraclient)
add_subdirectory(conf)
if(WIN32)
set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp)
set(_kleopatra_extra_SRCS
pics/gpg4win.qrc
selftest/registrycheck.cpp selftest/registrycheck.h
utils/gnupg-registry.c
utils/userinfo_win.cpp
utils/winapi-helpers.cpp utils/winapi-helpers.h
utils/windowsprocessdevice.cpp utils/windowsprocessdevice.h
versioninfo.rc kleopatra.w32-manifest
)
else()
set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp)
set(_kleopatra_extra_SRCS)
endif()
set(_kleopatra_uiserver_SRCS
${_kleopatra_extra_uiserver_SRCS}
selftest/uiservercheck.cpp selftest/uiservercheck.h
uiserver/assuanserverconnection.cpp uiserver/assuanserverconnection.h
uiserver/createchecksumscommand.cpp uiserver/createchecksumscommand.h
uiserver/decryptverifycommandemailbase.cpp uiserver/decryptverifycommandemailbase.h
uiserver/decryptverifycommandfilesbase.cpp uiserver/decryptverifycommandfilesbase.h
uiserver/echocommand.cpp uiserver/echocommand.h
uiserver/encryptcommand.cpp uiserver/encryptcommand.h
uiserver/importfilescommand.cpp uiserver/importfilescommand.h
uiserver/prepencryptcommand.cpp uiserver/prepencryptcommand.h
uiserver/prepsigncommand.cpp uiserver/prepsigncommand.h
uiserver/selectcertificatecommand.cpp
uiserver/sessiondata.cpp uiserver/sessiondata.h
uiserver/signcommand.cpp uiserver/signcommand.h
uiserver/signencryptfilescommand.cpp
uiserver/uiserver.cpp
uiserver/verifychecksumscommand.cpp uiserver/verifychecksumscommand.h
)
set(_kleopatra_uiserver_extra_libs LibAssuan::LibAssuan LibGpgError::LibGpgError)
if(HAVE_GPG_ERR_SOURCE_KLEO)
add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
else()
add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
endif()
if(KPim6IdentityManagementCore_FOUND AND KPim6MailTransport_FOUND AND KPim6AkonadiMime_FOUND)
set(_kleopatra_mail_libs
KPim6::IdentityManagementCore # Export OpenPGP keys using WKS
KPim6::MailTransport
KPim6::AkonadiMime
)
add_definitions(-DMAILAKONADI_ENABLED)
endif()
ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui)
set(_kleopatra_SRCS
${_kleopatra_extra_SRCS}
accessibility/accessiblelink.cpp
accessibility/accessiblelink_p.h
accessibility/accessiblerichtextlabel.cpp
accessibility/accessiblerichtextlabel_p.h
accessibility/accessiblevaluelabel.cpp
accessibility/accessiblevaluelabel_p.h
accessibility/accessiblewidgetfactory.cpp
accessibility/accessiblewidgetfactory.h
commands/addadskcommand.cpp
commands/addadskcommand.h
commands/addsubkeycommand.cpp
commands/addsubkeycommand.h
commands/adduseridcommand.cpp
commands/adduseridcommand.h
commands/authenticatepivcardapplicationcommand.cpp
commands/authenticatepivcardapplicationcommand.h
commands/cardcommand.cpp
commands/cardcommand.h
commands/certificatetocardcommand.cpp
commands/certificatetocardcommand.h
commands/certificatetopivcardcommand.cpp
commands/certificatetopivcardcommand.h
commands/certifycertificatecommand.cpp
commands/certifycertificatecommand.h
commands/certifygroupcommand.cpp
commands/certifygroupcommand.h
commands/changeexpirycommand.cpp
commands/changeexpirycommand.h
commands/changeownertrustcommand.cpp
commands/changeownertrustcommand.h
commands/changepassphrasecommand.cpp
commands/changepassphrasecommand.h
commands/changepincommand.cpp
commands/changepincommand.h
commands/changeroottrustcommand.cpp
commands/changeroottrustcommand.h
commands/checksumcreatefilescommand.cpp
commands/checksumcreatefilescommand.h
commands/checksumverifyfilescommand.cpp
commands/checksumverifyfilescommand.h
commands/clearcrlcachecommand.cpp
commands/clearcrlcachecommand.h
commands/command.cpp
commands/command.h
commands/createcsrforcardkeycommand.cpp
commands/createcsrforcardkeycommand.h
commands/creategroupcommand.cpp
commands/creategroupcommand.h
commands/createopenpgpkeyfromcardkeyscommand.cpp
commands/createopenpgpkeyfromcardkeyscommand.h
commands/decryptverifyclipboardcommand.cpp
commands/decryptverifyclipboardcommand.h
commands/decryptverifyfilescommand.cpp
commands/decryptverifyfilescommand.h
commands/deletecertificatescommand.cpp
commands/deletecertificatescommand.h
commands/detailscommand.cpp
commands/detailscommand.h
commands/dumpcertificatecommand.cpp
commands/dumpcertificatecommand.h
commands/dumpcrlcachecommand.cpp
commands/dumpcrlcachecommand.h
commands/encryptclipboardcommand.cpp
commands/encryptclipboardcommand.h
commands/exportcertificatecommand.cpp
commands/exportcertificatecommand.h
commands/exportgroupscommand.cpp
commands/exportgroupscommand.h
commands/exportopenpgpcertstoservercommand.cpp
commands/exportopenpgpcertstoservercommand.h
commands/exportopenpgpcerttoprovidercommand.cpp
commands/exportopenpgpcerttoprovidercommand.h
commands/exportpaperkeycommand.cpp
commands/exportpaperkeycommand.h
commands/exportsecretkeycommand.cpp
commands/exportsecretkeycommand.h
commands/exportsecretsubkeycommand.cpp
commands/exportsecretsubkeycommand.h
commands/generateopenpgpcardkeysandcertificatecommand.cpp
commands/generateopenpgpcardkeysandcertificatecommand.h
commands/genrevokecommand.cpp
commands/genrevokecommand.h
commands/gnupgprocesscommand.cpp
commands/gnupgprocesscommand.h
commands/importcertificatefromclipboardcommand.cpp
commands/importcertificatefromclipboardcommand.h
commands/importcertificatefromdatacommand.cpp
commands/importcertificatefromdatacommand.h
commands/importcertificatefromfilecommand.cpp
commands/importcertificatefromfilecommand.h
commands/importcertificatefromkeyservercommand.cpp
commands/importcertificatefromkeyservercommand.h
commands/importcertificatefrompivcardcommand.cpp
commands/importcertificatefrompivcardcommand.h
commands/importcertificatescommand.cpp
commands/importcertificatescommand.h
commands/importcrlcommand.cpp
commands/importcrlcommand.h
commands/importpaperkeycommand.cpp
commands/importpaperkeycommand.h
commands/keytocardcommand.cpp
commands/keytocardcommand.h
commands/lookupcertificatescommand.cpp
commands/lookupcertificatescommand.h
commands/newcertificatesigningrequestcommand.cpp
commands/newcertificatesigningrequestcommand.h
commands/newopenpgpcertificatecommand.cpp
commands/newopenpgpcertificatecommand.h
commands/openpgpgeneratecardkeycommand.cpp
commands/openpgpgeneratecardkeycommand.h
commands/pivgeneratecardkeycommand.cpp
commands/pivgeneratecardkeycommand.h
commands/refreshcertificatescommand.cpp
commands/refreshcertificatescommand.h
commands/refreshopenpgpcertscommand.cpp
commands/refreshopenpgpcertscommand.h
commands/refreshx509certscommand.cpp
commands/refreshx509certscommand.h
commands/reloadkeyscommand.cpp
commands/reloadkeyscommand.h
commands/revokecertificationcommand.cpp
commands/revokecertificationcommand.h
commands/revokekeycommand.cpp
commands/revokekeycommand.h
commands/revokeuseridcommand.cpp
commands/revokeuseridcommand.h
commands/selftestcommand.cpp
commands/selftestcommand.h
commands/setinitialpincommand.cpp
commands/setinitialpincommand.h
commands/setpivcardapplicationadministrationkeycommand.cpp
commands/setpivcardapplicationadministrationkeycommand.h
commands/setprimaryuseridcommand.cpp
commands/setprimaryuseridcommand.h
commands/signclipboardcommand.cpp
commands/signclipboardcommand.h
commands/signencryptfilescommand.cpp
commands/signencryptfilescommand.h
commands/signencryptfoldercommand.cpp
commands/signencryptfoldercommand.h
commands/togglecertificateenabledcommand.cpp
commands/togglecertificateenabledcommand.h
commands/viewemailfilescommand.cpp
commands/viewemailfilescommand.h
conf/configuredialog.cpp
conf/configuredialog.h
conf/groupsconfigdialog.cpp
conf/groupsconfigdialog.h
conf/groupsconfigwidget.cpp
conf/groupsconfigwidget.h
crypto/autodecryptverifyfilescontroller.cpp
crypto/autodecryptverifyfilescontroller.h
crypto/certificateresolver.cpp
crypto/certificateresolver.h
crypto/checksumsutils_p.cpp
crypto/checksumsutils_p.h
crypto/controller.cpp
crypto/controller.h
crypto/createchecksumscontroller.cpp
crypto/createchecksumscontroller.h
crypto/decryptverifyemailcontroller.cpp
crypto/decryptverifyemailcontroller.h
crypto/decryptverifyfilescontroller.cpp
crypto/decryptverifyfilescontroller.h
crypto/decryptverifytask.cpp
crypto/decryptverifytask.h
crypto/encryptemailcontroller.cpp
crypto/encryptemailcontroller.h
crypto/encryptemailtask.cpp
crypto/encryptemailtask.h
crypto/gui/certificatelineedit.cpp
crypto/gui/certificatelineedit.h
crypto/gui/certificateselectionline.cpp
crypto/gui/certificateselectionline.h
crypto/gui/decryptverifyfilesdialog.cpp
crypto/gui/decryptverifyfilesdialog.h
crypto/gui/decryptverifyfileswizard.cpp
crypto/gui/decryptverifyfileswizard.h
crypto/gui/decryptverifyoperationwidget.cpp
crypto/gui/decryptverifyoperationwidget.h
crypto/gui/encryptemailwizard.cpp
crypto/gui/encryptemailwizard.h
crypto/gui/newresultpage.cpp
crypto/gui/newresultpage.h
crypto/gui/objectspage.cpp
crypto/gui/objectspage.h
crypto/gui/resolverecipientspage.cpp
crypto/gui/resolverecipientspage.h
crypto/gui/resultitemwidget.cpp
crypto/gui/resultitemwidget.h
crypto/gui/resultlistwidget.cpp
crypto/gui/resultlistwidget.h
crypto/gui/resultpage.cpp
crypto/gui/resultpage.h
crypto/gui/signemailwizard.cpp
crypto/gui/signemailwizard.h
crypto/gui/signencryptemailconflictdialog.cpp
crypto/gui/signencryptemailconflictdialog.h
- crypto/gui/signencryptfileswizard.cpp
- crypto/gui/signencryptfileswizard.h
+ crypto/gui/signencryptfilesdialog.cpp
+ crypto/gui/signencryptfilesdialog.h
crypto/gui/signencryptwidget.cpp
crypto/gui/signencryptwidget.h
crypto/gui/signencryptwizard.cpp
crypto/gui/signencryptwizard.h
crypto/gui/signerresolvepage.cpp
crypto/gui/signerresolvepage.h
crypto/gui/signingcertificateselectiondialog.cpp
crypto/gui/signingcertificateselectiondialog.h
crypto/gui/signingcertificateselectionwidget.cpp
crypto/gui/signingcertificateselectionwidget.h
crypto/gui/unknownrecipientwidget.cpp
crypto/gui/unknownrecipientwidget.h
crypto/gui/verifychecksumsdialog.cpp
crypto/gui/verifychecksumsdialog.h
crypto/gui/wizard.cpp
crypto/gui/wizard.h
crypto/gui/wizardpage.cpp
crypto/gui/wizardpage.h
crypto/newsignencryptemailcontroller.cpp
crypto/newsignencryptemailcontroller.h
crypto/recipient.cpp
crypto/recipient.h
crypto/sender.cpp
crypto/sender.h
crypto/signemailcontroller.cpp
crypto/signemailcontroller.h
crypto/signemailtask.cpp
crypto/signemailtask.h
crypto/signencryptfilescontroller.cpp
crypto/signencryptfilescontroller.h
crypto/signencrypttask.cpp
crypto/signencrypttask.h
crypto/task.cpp
crypto/task.h
crypto/taskcollection.cpp
crypto/taskcollection.h
crypto/verifychecksumscontroller.cpp
crypto/verifychecksumscontroller.h
dialogs/addsubkeydialog.cpp
dialogs/addsubkeydialog.h
dialogs/adduseriddialog.cpp
dialogs/adduseriddialog.h
dialogs/animatedexpander.cpp
dialogs/animatedexpander.h
dialogs/certificatedetailsdialog.cpp
dialogs/certificatedetailsdialog.h
dialogs/certificatedetailsinputwidget.cpp
dialogs/certificatedetailsinputwidget.h
dialogs/certificatedetailswidget.cpp
dialogs/certificatedetailswidget.h
dialogs/certificatedumpwidget.cpp
dialogs/certificatedumpwidget.h
dialogs/certificateselectiondialog.cpp
dialogs/certificateselectiondialog.h
dialogs/certifycertificatedialog.cpp
dialogs/certifycertificatedialog.h
dialogs/certifywidget.cpp
dialogs/certifywidget.h
dialogs/createcsrforcardkeydialog.cpp
dialogs/createcsrforcardkeydialog.h
dialogs/copytosmartcarddialog.cpp
dialogs/copytosmartcarddialog.h
dialogs/debugdialog.cpp
dialogs/debugdialog.h
dialogs/deletecertificatesdialog.cpp
dialogs/deletecertificatesdialog.h
dialogs/editgroupdialog.cpp
dialogs/editgroupdialog.h
dialogs/expirydialog.cpp
dialogs/expirydialog.h
dialogs/exportdialog.cpp
dialogs/exportdialog.h
dialogs/gencardkeydialog.cpp
dialogs/gencardkeydialog.h
dialogs/groupdetailsdialog.cpp
dialogs/groupdetailsdialog.h
dialogs/lookupcertificatesdialog.cpp
dialogs/lookupcertificatesdialog.h
dialogs/pivcardapplicationadministrationkeyinputdialog.cpp
dialogs/pivcardapplicationadministrationkeyinputdialog.h
dialogs/revokekeydialog.cpp
dialogs/revokekeydialog.h
dialogs/revokerswidget.cpp
dialogs/revokerswidget.h
dialogs/selftestdialog.cpp
dialogs/selftestdialog.h
dialogs/setinitialpindialog.cpp
dialogs/setinitialpindialog.h
dialogs/smartcardwindow.cpp
dialogs/smartcardwindow.h
dialogs/subkeyswidget.cpp
dialogs/subkeyswidget.h
dialogs/trustchainwidget.cpp
dialogs/trustchainwidget.h
dialogs/updatenotification.cpp
dialogs/updatenotification.h
dialogs/useridswidget.cpp
dialogs/useridswidget.h
dialogs/weboftrustwidget.cpp
dialogs/weboftrustwidget.h
interfaces/anchorprovider.h
interfaces/focusfirstchild.h
newcertificatewizard/advancedsettingsdialog.cpp
newcertificatewizard/advancedsettingsdialog_p.h
newcertificatewizard/enterdetailspage.cpp
newcertificatewizard/enterdetailspage_p.h
newcertificatewizard/keycreationpage.cpp
newcertificatewizard/keycreationpage_p.h
newcertificatewizard/listwidget.cpp
newcertificatewizard/listwidget.h
newcertificatewizard/newcertificatewizard.cpp
newcertificatewizard/newcertificatewizard.h
newcertificatewizard/resultpage.cpp
newcertificatewizard/resultpage_p.h
newcertificatewizard/wizardpage.cpp
newcertificatewizard/wizardpage_p.h
selftest/compliancecheck.cpp
selftest/compliancecheck.h
selftest/enginecheck.cpp
selftest/enginecheck.h
selftest/gpgagentcheck.cpp
selftest/gpgagentcheck.h
selftest/gpgconfcheck.cpp
selftest/gpgconfcheck.h
selftest/libkleopatrarccheck.cpp
selftest/libkleopatrarccheck.h
selftest/selftest.cpp
selftest/selftest.h
smartcard/algorithminfo.h
smartcard/card.cpp
smartcard/card.h
smartcard/deviceinfowatcher.cpp
smartcard/deviceinfowatcher.h
smartcard/keypairinfo.cpp
smartcard/keypairinfo.h
smartcard/netkeycard.cpp
smartcard/netkeycard.h
smartcard/openpgpcard.cpp
smartcard/openpgpcard.h
smartcard/p15card.cpp
smartcard/p15card.h
smartcard/pivcard.cpp
smartcard/pivcard.h
smartcard/readerstatus.cpp
smartcard/readerstatus.h
smartcard/utils.cpp
smartcard/utils.h
utils/accessibility.cpp
utils/accessibility.h
utils/action_data.cpp
utils/action_data.h
utils/applicationstate.cpp
utils/applicationstate.h
utils/archivedefinition.cpp
utils/archivedefinition.h
utils/certificatepair.h
utils/clipboardmenu.cpp
utils/clipboardmenu.h
utils/debug-helpers.cpp
utils/debug-helpers.h
utils/dragqueen.cpp
utils/dragqueen.h
utils/email.cpp
utils/email.h
utils/emptypassphraseprovider.cpp
utils/emptypassphraseprovider.h
utils/filedialog.cpp
utils/filedialog.h
utils/fileutils.cpp
utils/fileutils.h
utils/gui-helper.cpp
utils/gui-helper.h
utils/headerview.cpp
utils/headerview.h
utils/input.cpp
utils/input.h
utils/iodevicelogger.cpp
utils/iodevicelogger.h
utils/kdpipeiodevice.cpp
utils/kdpipeiodevice.h
utils/keyexportdraghandler.cpp
utils/keyexportdraghandler.h
utils/kuniqueservice.cpp
utils/kuniqueservice.h
utils/log.cpp
utils/log.h
utils/memory-helpers.h
utils/migration.cpp
utils/migration.h
utils/output.cpp
utils/output.h
utils/overwritedialog.cpp
utils/overwritedialog.h
utils/path-helper.cpp
utils/path-helper.h
utils/scrollarea.cpp
utils/scrollarea.h
utils/statusmessage.cpp
utils/statusmessage.h
utils/systemtrayicon.cpp
utils/systemtrayicon.h
utils/tags.cpp
utils/tags.h
utils/types.cpp
utils/types.h
utils/userinfo.cpp
utils/userinfo.h
utils/writecertassuantransaction.cpp
utils/writecertassuantransaction.h
utils/wsastarter.cpp
utils/wsastarter.h
view/anchorcache.cpp
view/anchorcache_p.h
view/cardkeysview.cpp
view/cardkeysview.h
view/htmllabel.cpp
view/htmllabel.h
view/infofield.cpp
view/infofield.h
view/keycacheoverlay.cpp
view/keycacheoverlay.h
view/keylistcontroller.cpp
view/keylistcontroller.h
view/keytreeview.cpp
view/keytreeview.h
view/netkeywidget.cpp
view/netkeywidget.h
view/overlaywidget.cpp
view/overlaywidget.h
view/p15cardwidget.cpp
view/p15cardwidget.h
view/padwidget.cpp
view/padwidget.h
view/pgpcardwidget.cpp
view/pgpcardwidget.h
view/pivcardwidget.cpp
view/pivcardwidget.h
view/progressoverlay.cpp
view/progressoverlay.h
view/searchbar.cpp
view/searchbar.h
view/smartcardactions.cpp
view/smartcardactions.h
view/smartcardswidget.cpp
view/smartcardswidget.h
view/smartcardwidget.cpp
view/smartcardwidget.h
view/tabwidget.cpp
view/tabwidget.h
view/textoverlay.cpp
view/textoverlay.h
view/urllabel.cpp
view/urllabel.h
view/waitwidget.cpp
view/waitwidget.h
view/welcomewidget.cpp
view/welcomewidget.h
aboutdata.cpp
aboutdata.h
kleopatra.qrc
kleopatraapplication.cpp
kleopatraapplication.h
main.cpp
mainwindow.cpp
mainwindow.h
systrayicon.cpp
systrayicon.h
kleopatra_options.h
)
if(WIN32)
configure_file (versioninfo.rc.in versioninfo.rc)
configure_file (kleopatra.w32-manifest.in kleopatra.w32-manifest)
set(_kleopatra_SRCS
${CMAKE_CURRENT_BINARY_DIR}/kleopatra.w32-manifest
${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc
conf/kmessageboxdontaskagainstorage.cpp
conf/kmessageboxdontaskagainstorage.h
${_kleopatra_SRCS}
)
endif()
set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp conf/kleopageconfigdialog.h ${_kleopatra_SRCS})
ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra
DESCRIPTION "kleopatra (kleopatra)"
OLD_CATEGORY_NAMES log_kleopatra
EXPORT KLEOPATRA
)
if(KLEO_MODEL_TEST)
add_definitions(-DKLEO_MODEL_TEST)
set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp)
endif()
ki18n_wrap_ui(_kleopatra_SRCS
dialogs/setinitialpindialog.ui
newcertificatewizard/listwidget.ui
)
kconfig_add_kcfg_files(_kleopatra_SRCS
kcfg/emailoperationspreferences.kcfgc
kcfg/fileoperationspreferences.kcfgc
kcfg/settings.kcfgc
kcfg/smimevalidationpreferences.kcfgc
kcfg/tooltippreferences.kcfgc
)
file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png")
ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS})
add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS})
# For the ConfigureDialog & KCMs
target_link_libraries(kleopatra_bin kcm_kleopatra_static)
#if (COMPILE_WITH_UNITY_CMAKE_SUPPORT)
# set_target_properties(kleopatra_bin PROPERTIES UNITY_BUILD ON)
#endif()
set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
if (WIN32)
set(_kleopatra_platform_libs "secur32")
endif ()
target_link_libraries(kleopatra_bin
Gpgmepp
KPim6::Libkleo
KPim6::Mime
KPim6::MimeTreeParserWidgets
KF6::Codecs
KF6::CoreAddons
KF6::Crash
KF6::I18n
KF6::IconThemes
KF6::ItemModels
KF6::KIOCore
KF6::KIOWidgets
KF6::WindowSystem
KF6::XmlGui
Qt::Network
Qt::PrintSupport # Printing secret keys
kleopatraclientcore
${_kleopatra_extra_libs}
${_kleopatra_mail_libs}
${_kleopatra_uiserver_extra_libs}
${_kleopatra_dbusaddons_libs}
${_kleopatra_platform_libs}
)
target_link_libraries(kleopatra_bin QGpgmeQt6)
install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(
PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop
DESTINATION ${KDE_INSTALL_APPDIR}
)
install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
install(FILES data/kleopatra-mime.xml DESTINATION ${KDE_INSTALL_MIMEDIR})
install(
PROGRAMS data/kleopatra_signencryptfiles.desktop
data/kleopatra_signencryptfolders.desktop
data/kleopatra_decryptverifyfiles.desktop
data/kleopatra_decryptverifyfolders.desktop
DESTINATION ${KDE_INSTALL_DATADIR}/kio/servicemenus
)
install(FILES kleopatradebugcommandsrc DESTINATION ${KDE_INSTALL_CONFDIR})
diff --git a/src/crypto/gui/signencryptfileswizard.cpp b/src/crypto/gui/signencryptfilesdialog.cpp
similarity index 73%
rename from src/crypto/gui/signencryptfileswizard.cpp
rename to src/crypto/gui/signencryptfilesdialog.cpp
index 891933ba4..da70f19b6 100644
--- a/src/crypto/gui/signencryptfileswizard.cpp
+++ b/src/crypto/gui/signencryptfilesdialog.cpp
@@ -1,702 +1,685 @@
/* crypto/gui/signencryptfileswizard.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "kleopatra_debug.h"
-#include "signencryptfileswizard.h"
+#include "signencryptfilesdialog.h"
#include "signencryptwidget.h"
-#include "newresultpage.h"
+#include "resultpage.h"
#include "utils/scrollarea.h"
#include <fileoperationspreferences.h>
#include <settings.h>
#include <KColorScheme>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KMessageBox>
#include <KMessageWidget>
#include <KSeparator>
#include <KSharedConfig>
+#include <KTitleWidget>
#include <Libkleo/Compliance>
#include <Libkleo/FileNameRequester>
#include <Libkleo/Formatting>
#include <Libkleo/GnuPG>
#include <Libkleo/SystemInfo>
#include <QCheckBox>
#include <QGroupBox>
#include <QIcon>
#include <QLabel>
#include <QPushButton>
#include <QStyle>
#include <QVBoxLayout>
#include <QWindow>
-#include <QWizardPage>
#include <gpgme++/key.h>
#include <array>
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Crypto::Gui;
-enum Page {
- SigEncPageId,
- ResultPageId,
-
- NumPages
-};
-
class FileNameRequesterWithIcon : public QWidget
{
Q_OBJECT
public:
explicit FileNameRequesterWithIcon(QDir::Filters filter, QWidget *parent = nullptr)
: QWidget(parent)
{
auto layout = new QHBoxLayout{this};
layout->setContentsMargins(0, 0, 0, 0);
mIconLabel = new QLabel{this};
mRequester = new FileNameRequester{filter, this};
mRequester->setExistingOnly(false);
layout->addWidget(mIconLabel);
layout->addWidget(mRequester);
setFocusPolicy(mRequester->focusPolicy());
setFocusProxy(mRequester);
connect(mRequester, &FileNameRequester::fileNameChanged, this, &FileNameRequesterWithIcon::fileNameChanged);
}
void setIcon(const QIcon &icon)
{
mIconLabel->setPixmap(icon.pixmap(32, 32));
}
void setFileName(const QString &name)
{
mRequester->setFileName(name);
}
QString fileName() const
{
return mRequester->fileName();
}
void setNameFilter(const QString &nameFilter)
{
mRequester->setNameFilter(nameFilter);
}
QString nameFilter() const
{
return mRequester->nameFilter();
}
FileNameRequester *requester()
{
return mRequester;
}
Q_SIGNALS:
void fileNameChanged(const QString &filename);
protected:
bool event(QEvent *e) override
{
if (e->type() == QEvent::ToolTipChange) {
mRequester->setToolTip(toolTip());
}
return QWidget::event(e);
}
private:
QLabel *mIconLabel;
FileNameRequester *mRequester;
};
-class SigEncPage : public QWizardPage
+class SigEncPage : public QWidget
{
Q_OBJECT
public:
explicit SigEncPage(QWidget *parent = nullptr)
- : QWizardPage(parent)
- , mParent((SignEncryptFilesWizard *)parent)
+ : QWidget(parent)
, mWidget(new SignEncryptWidget)
, mOutLayout(new QVBoxLayout)
, mOutputLabel{nullptr}
, mArchive(false)
, mUseOutputDir(false)
, mSingleFile{true}
{
- setTitle(i18nc("@title", "Sign / Encrypt Files"));
-
auto mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins({});
auto scrollArea = new Kleo::ScrollArea;
mainLayout->addWidget(scrollArea);
auto wrapper = new QWidget;
scrollArea->setWidget(wrapper);
+
+ scrollArea->setFrameStyle(0);
auto vLay = new QVBoxLayout(wrapper);
vLay->setContentsMargins({});
if (!Settings{}.cmsEnabled()) {
mWidget->setProtocol(GpgME::OpenPGP);
}
mWidget->setSignAsText(i18nc("@option:check on SignEncryptPage", "&Sign as:"));
mWidget->setEncryptForMeText(i18nc("@option:check on SignEncryptPage", "Encrypt for &me:"));
mWidget->setEncryptForOthersText(i18nc("@label on SignEncryptPage", "Encrypt for &others:"));
mWidget->setEncryptWithPasswordText(i18nc("@option:check on SignEncryptPage", "Encrypt with &password:"));
vLay->addWidget(mWidget);
- connect(mWidget, &SignEncryptWidget::operationChanged, this, &SigEncPage::updateCommitButton);
+ connect(mWidget, &SignEncryptWidget::operationChanged, this, &SigEncPage::checkReady);
connect(mWidget, &SignEncryptWidget::keysChanged, this, &SigEncPage::updateFileWidgets);
vLay->addSpacing(style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) * 3);
vLay->addLayout(mOutLayout);
mPlaceholderWidget = new QLabel(i18nc("@label:textbox", "Please select an action."));
mOutLayout->addWidget(mPlaceholderWidget);
mOutputLabel = new QLabel(i18nc("@label on SignEncryptPage", "Output &files/folder:"));
auto font = mOutputLabel->font();
font.setWeight(QFont::DemiBold);
mOutputLabel->setFont(font);
mOutLayout->addWidget(mOutputLabel);
createRequesters(mOutLayout);
mUseOutputDirChk = new QCheckBox(i18nc("@option:check on SignEncryptPage", "Encrypt / Sign &each file separately."));
mUseOutputDirChk->setToolTip(i18nc("@info:tooltip", "Keep each file separate instead of creating an archive for all."));
mOutLayout->addWidget(mUseOutputDirChk);
connect(mUseOutputDirChk, &QCheckBox::toggled, this, [this](bool state) {
mUseOutputDir = state;
mArchive = !mUseOutputDir && !mSingleFile;
updateFileWidgets();
});
auto messageWidget = new KMessageWidget;
messageWidget->setMessageType(KMessageWidget::Error);
messageWidget->setIcon(style()->standardIcon(QStyle::SP_MessageBoxCritical, nullptr, this));
messageWidget->setText(i18n("Invalid compliance settings for signing and encrypting files."));
messageWidget->setToolTip(xi18nc("@info %1 is a placeholder for the name of a compliance mode. E.g. NATO RESTRICTED compliant or VS-NfD compliant",
"<para>You cannot use <application>Kleopatra</application> for signing or encrypting files "
"because the <application>GnuPG</application> system used by <application>Kleopatra</application> is not %1.</para>",
DeVSCompliance::name(true)));
messageWidget->setCloseButtonVisible(false);
messageWidget->setVisible(DeVSCompliance::isActive() && !DeVSCompliance::isCompliant());
vLay->addWidget(messageWidget);
setMinimumHeight(300);
vLay->addStretch();
}
void setEncryptionPreset(bool value)
{
mWidget->setEncryptionChecked(value);
}
void setSigningPreset(bool value)
{
mWidget->setSigningChecked(value);
}
- bool isComplete() const override
- {
- if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) {
- return false;
- }
- return mWidget->isComplete();
- }
-
- int nextId() const override
- {
- return ResultPageId;
- }
-
- void initializePage() override
- {
- setCommitPage(true);
- updateCommitButton(mWidget->currentOp());
- }
-
void setArchiveForced(bool archive)
{
mArchive = archive;
setArchiveMutable(!archive);
}
void setArchiveMutable(bool archive)
{
mUseOutputDirChk->setVisible(archive);
if (archive) {
- const KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard"));
+ const KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesDialog"));
mUseOutputDirChk->setChecked(archCfg.readEntry("LastUseOutputDir", false));
} else {
mUseOutputDirChk->setChecked(false);
}
}
void setSingleFile(bool singleFile)
{
mSingleFile = singleFile;
mArchive = !mUseOutputDir && !mSingleFile;
}
- bool validatePage() override
+ bool validatePage()
{
if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) {
- KMessageBox::error(topLevelWidget(),
- xi18nc("@info %1 is a placeholder for the name of a compliance mode. E.g. NATO RESTRICTED compliant or VS-NfD compliant",
- "<para>Sorry! You cannot use <application>Kleopatra</application> for signing or encrypting files "
- "because the <application>GnuPG</application> system used by <application>Kleopatra</application> is not %1.</para>",
- DeVSCompliance::name(true)));
return false;
}
- bool sign = !mWidget->signUserId().isNull();
- bool encrypt = !mWidget->selfUserId().isNull() || !mWidget->recipients().empty();
- if (!mWidget->validate()) {
- return false;
+
+ return mWidget->isComplete();
+ }
+
+ std::vector<Key> recipients() const
+ {
+ return mWidget->recipients();
+ }
+
+ /* In the future we might find a usecase for multiple
+ * signers */
+ std::vector<Key> signers() const
+ {
+ const Key k = mWidget->signUserId().parent();
+ if (!k.isNull()) {
+ return {k};
}
+ return {};
+ }
+
+ void done()
+ {
mWidget->saveOwnKeys();
if (mUseOutputDirChk->isVisible()) {
- KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesWizard"));
+ KConfigGroup archCfg(KSharedConfig::openConfig(), QStringLiteral("SignEncryptFilesDialog"));
archCfg.writeEntry("LastUseOutputDir", mUseOutputDir);
}
- if (sign && !encrypt && mArchive) {
- return KMessageBox::warningContinueCancel(
- this,
- xi18nc("@info",
- "<para>Archiving in combination with sign-only currently requires what are known as opaque signatures - "
- "unlike detached ones, these embed the content in the signature.</para>"
- "<para>This format is rather unusual. You might want to archive the files separately, "
- "and then sign the archive as one file with Kleopatra.</para>"
- "<para>Future versions of Kleopatra are expected to also support detached signatures in this case.</para>"),
- i18nc("@title:window", "Unusual Signature Warning"),
- KStandardGuiItem::cont(),
- KStandardGuiItem::cancel(),
- QStringLiteral("signencryptfileswizard-archive+sign-only-warning"))
- == KMessageBox::Continue;
- } else if (sign && !encrypt) {
- return true;
+ auto sign = !mWidget->signUserId().isNull();
+ auto encrypt = !mWidget->selfUserId().isNull() || !mWidget->recipients().empty();
+ if (!mWidget->validate()) {
+ return;
+ }
+ if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) {
+ KMessageBox::error(topLevelWidget(),
+ xi18nc("@info %1 is a placeholder for the name of a compliance mode. E.g. NATO RESTRICTED compliant or VS-NfD compliant",
+ "<para>Sorry! You cannot use <application>Kleopatra</application> for signing or encrypting files "
+ "because the <application>GnuPG</application> system used by <application>Kleopatra</application> is not %1.</para>",
+ DeVSCompliance::name(true)));
+ return;
}
- if (!mWidget->selfUserId().isNull() || mWidget->encryptSymmetric()) {
- return true;
+ if (sign && !encrypt && mArchive) {
+ auto status = KMessageBox::warningContinueCancel(
+ this,
+ xi18nc("@info",
+ "<para>Archiving in combination with sign-only currently requires what are known as opaque signatures - "
+ "unlike detached ones, these embed the content in the signature.</para>"
+ "<para>This format is rather unusual. You might want to archive the files separately, "
+ "and then sign the archive as one file with Kleopatra.</para>"
+ "<para>Future versions of Kleopatra are expected to also support detached signatures in this case.</para>"),
+ i18nc("@title:window", "Unusual Signature Warning"),
+ KStandardGuiItem::cont(),
+ KStandardGuiItem::cancel(),
+ QStringLiteral("signencryptfileswizard-archive+sign-only-warning"));
+ if (status != KMessageBox::Continue) {
+ return;
+ }
}
- const auto recipientKeys = recipients();
- const bool hasSecret = std::any_of(std::begin(recipientKeys), std::end(recipientKeys), [](const auto &k) {
- return k.hasSecret();
- });
- if (!hasSecret) {
+
+ if (encrypt && !mWidget->encryptSymmetric() && std::ranges::none_of(recipients(), [](const auto &k) {
+ return k.hasSecret();
+ })) {
if (KMessageBox::warningContinueCancel(this,
xi18nc("@info",
"<para>None of the recipients you are encrypting to seems to be your own.</para>"
"<para>This means that you will not be able to decrypt the data anymore, once encrypted.</para>"
"<para>Do you want to continue, or cancel to change the recipient selection?</para>"),
i18nc("@title:window", "Encrypt-To-Self Warning"),
KStandardGuiItem::cont(),
KStandardGuiItem::cancel(),
QStringLiteral("warn-encrypt-to-non-self"),
KMessageBox::Notify | KMessageBox::Dangerous)
== KMessageBox::Cancel) {
- return false;
+ return;
}
}
- return true;
- }
-
- std::vector<Key> recipients() const
- {
- return mWidget->recipients();
+ Q_EMIT finished();
}
- /* In the future we might find a usecase for multiple
- * signers */
- std::vector<Key> signers() const
+ bool isDeVsAndValid() const
{
- const Key k = mWidget->signUserId().parent();
- if (!k.isNull()) {
- return {k};
- }
- return {};
+ return mWidget->isDeVsAndValid();
}
private:
struct RequesterInfo {
- SignEncryptFilesWizard::KindNames id;
+ SignEncryptFilesDialog::KindNames id;
QString icon;
QString toolTip;
QString accessibleName;
QString nameFilterBinary;
QString nameFilterAscii;
};
void createRequesters(QBoxLayout *lay)
{
static const std::array<RequesterInfo, 6> requestersInfo = {{
{
- SignEncryptFilesWizard::SignatureCMS,
+ SignEncryptFilesDialog::SignatureCMS,
QStringLiteral("document-sign"),
i18nc("@info:tooltip", "This is the filename of the S/MIME signature."),
i18nc("Lineedit accessible name", "S/MIME signature file"),
i18nc("Name filter binary", "S/MIME Signatures (*.p7s)"),
i18nc("Name filter ASCII", "S/MIME Signatures (*.p7s *.pem)"),
},
{
- SignEncryptFilesWizard::SignaturePGP,
+ SignEncryptFilesDialog::SignaturePGP,
QStringLiteral("document-sign"),
i18nc("@info:tooltip", "This is the filename of the detached OpenPGP signature."),
i18nc("Lineedit accessible name", "OpenPGP signature file"),
i18nc("Name filter binary", "OpenPGP Signatures (*.sig *.pgp)"),
i18nc("Name filter ASCII", "OpenPGP Signatures (*.asc *.sig)"),
},
{
- SignEncryptFilesWizard::CombinedPGP,
+ SignEncryptFilesDialog::CombinedPGP,
QStringLiteral("document-edit-sign-encrypt"),
i18nc("@info:tooltip", "This is the filename of the OpenPGP-signed and encrypted file."),
i18nc("Lineedit accessible name", "OpenPGP signed and encrypted file"),
i18nc("Name filter binary", "OpenPGP Files (*.gpg *.pgp)"),
i18nc("Name filter ASCII", "OpenPGP Files (*.asc)"),
},
{
- SignEncryptFilesWizard::EncryptedPGP,
+ SignEncryptFilesDialog::EncryptedPGP,
QStringLiteral("document-encrypt"),
i18nc("@info:tooltip", "This is the filename of the OpenPGP encrypted file."),
i18nc("Lineedit accessible name", "OpenPGP encrypted file"),
i18nc("Name filter binary", "OpenPGP Files (*.gpg *.pgp)"),
i18nc("Name filter ASCII", "OpenPGP Files (*.asc)"),
},
{
- SignEncryptFilesWizard::EncryptedCMS,
+ SignEncryptFilesDialog::EncryptedCMS,
QStringLiteral("document-encrypt"),
i18nc("@info:tooltip", "This is the filename of the S/MIME encrypted file."),
i18nc("Lineedit accessible name", "S/MIME encrypted file"),
i18nc("Name filter binary", "S/MIME Files (*.p7m)"),
i18nc("Name filter ASCII", "S/MIME Files (*.p7m *.pem)"),
},
{
- SignEncryptFilesWizard::Directory,
+ SignEncryptFilesDialog::Directory,
QStringLiteral("folder"),
i18nc("@info:tooltip", "The resulting files are written to this directory."),
i18nc("Lineedit accessible name", "Output directory"),
{},
{},
},
}};
if (!mRequesters.empty()) {
return;
}
const bool isAscii = FileOperationsPreferences().addASCIIArmor();
for (const auto &requester : requestersInfo) {
const auto id = requester.id;
- auto requesterWithIcon = new FileNameRequesterWithIcon{id == SignEncryptFilesWizard::Directory ? QDir::Dirs : QDir::Files, this};
+ auto requesterWithIcon = new FileNameRequesterWithIcon{id == SignEncryptFilesDialog::Directory ? QDir::Dirs : QDir::Files, this};
requesterWithIcon->setIcon(QIcon::fromTheme(requester.icon));
requesterWithIcon->setToolTip(requester.toolTip);
requesterWithIcon->requester()->setAccessibleNameOfLineEdit(requester.accessibleName);
requesterWithIcon->setNameFilter(isAscii ? requester.nameFilterAscii : requester.nameFilterBinary);
lay->addWidget(requesterWithIcon);
connect(requesterWithIcon, &FileNameRequesterWithIcon::fileNameChanged, this, [this, id](const QString &newName) {
mOutNames[id] = newName;
});
mRequesters.insert(id, requesterWithIcon);
}
}
public:
void setOutputNames(const QMap<int, QString> &names)
{
Q_ASSERT(mOutNames.isEmpty());
for (auto it = std::begin(names); it != std::end(names); ++it) {
mRequesters.value(it.key())->setFileName(it.value());
}
mOutNames = names;
updateFileWidgets();
}
QMap<int, QString> outputNames() const
{
if (!mUseOutputDir) {
auto ret = mOutNames;
- ret.remove(SignEncryptFilesWizard::Directory);
+ ret.remove(SignEncryptFilesDialog::Directory);
return ret;
}
return mOutNames;
}
bool encryptSymmetric() const
{
return mWidget->encryptSymmetric();
}
private Q_SLOTS:
- void updateCommitButton(const SignEncryptWidget::Operations op)
- {
- if (mParent->currentPage() != this) {
- return;
- }
- QString label;
- switch (op) {
- case SignEncryptWidget::Sign:
- label = i18nc("@action:button", "Sign");
- break;
- case SignEncryptWidget::Encrypt:
- label = i18nc("@action:button", "Encrypt");
- break;
- case SignEncryptWidget::SignAndEncrypt:
- label = i18nc("@action:button", "Sign / Encrypt");
- break;
- default:;
- };
- auto btn = qobject_cast<QPushButton *>(mParent->button(QWizard::CommitButton));
- if (!label.isEmpty()) {
- mParent->setButtonText(QWizard::CommitButton, label);
- if (DeVSCompliance::isActive()) {
- const bool de_vs = DeVSCompliance::isCompliant() && mWidget->isDeVsAndValid();
- DeVSCompliance::decorate(btn, de_vs);
- mParent->setLabelText(DeVSCompliance::name(de_vs));
- }
- } else {
- mParent->setButtonText(QWizard::CommitButton, i18n("Next"));
- btn->setIcon(QIcon());
- btn->setStyleSheet(QString());
- }
- Q_EMIT completeChanged();
- }
-
void updateFileWidgets()
{
if (mRequesters.isEmpty()) {
return;
}
const std::vector<Key> recipients = mWidget->recipients();
const Key sigKey = mWidget->signUserId().parent();
const bool pgp = mWidget->encryptSymmetric() || std::any_of(std::cbegin(recipients), std::cend(recipients), [](const auto &k) {
return k.protocol() == Protocol::OpenPGP;
});
const bool cms = std::any_of(std::cbegin(recipients), std::cend(recipients), [](const auto &k) {
return k.protocol() == Protocol::CMS;
});
mOutLayout->setEnabled(false);
if (cms || pgp || !sigKey.isNull()) {
mPlaceholderWidget->setVisible(false);
mOutputLabel->setVisible(true);
- mRequesters[SignEncryptFilesWizard::SignatureCMS]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::CMS);
- mRequesters[SignEncryptFilesWizard::EncryptedCMS]->setVisible(!mUseOutputDir && cms);
- mRequesters[SignEncryptFilesWizard::CombinedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && pgp);
- mRequesters[SignEncryptFilesWizard::EncryptedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() != Protocol::OpenPGP && pgp);
- mRequesters[SignEncryptFilesWizard::SignaturePGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && !pgp);
- mRequesters[SignEncryptFilesWizard::Directory]->setVisible(mUseOutputDir);
+ mRequesters[SignEncryptFilesDialog::SignatureCMS]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::CMS);
+ mRequesters[SignEncryptFilesDialog::EncryptedCMS]->setVisible(!mUseOutputDir && cms);
+ mRequesters[SignEncryptFilesDialog::CombinedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && pgp);
+ mRequesters[SignEncryptFilesDialog::EncryptedPGP]->setVisible(!mUseOutputDir && sigKey.protocol() != Protocol::OpenPGP && pgp);
+ mRequesters[SignEncryptFilesDialog::SignaturePGP]->setVisible(!mUseOutputDir && sigKey.protocol() == Protocol::OpenPGP && !pgp);
+ mRequesters[SignEncryptFilesDialog::Directory]->setVisible(mUseOutputDir);
auto firstNotHidden = std::find_if(std::cbegin(mRequesters), std::cend(mRequesters), [](auto w) {
return !w->isHidden();
});
mOutputLabel->setBuddy(*firstNotHidden);
} else {
mPlaceholderWidget->setVisible(true);
mOutputLabel->setVisible(false);
std::for_each(std::cbegin(mRequesters), std::cend(mRequesters), [](auto w) {
w->setVisible(false);
});
mOutputLabel->setBuddy(nullptr);
}
mOutLayout->setEnabled(true);
+ Q_EMIT checkReady(mWidget->currentOp());
}
+Q_SIGNALS:
+ void finished();
+ void checkReady(SignEncryptWidget::Operations op);
+
private:
- SignEncryptFilesWizard *mParent;
SignEncryptWidget *mWidget;
QMap<int, QString> mOutNames;
QMap<int, FileNameRequesterWithIcon *> mRequesters;
QVBoxLayout *mOutLayout;
QWidget *mPlaceholderWidget;
QCheckBox *mUseOutputDirChk;
QLabel *mOutputLabel;
bool mArchive;
bool mUseOutputDir;
bool mSingleFile;
};
-class ResultPage : public NewResultPage
+class SignEncryptResultPage : public Kleo::Crypto::Gui::ResultPage
{
Q_OBJECT
public:
- explicit ResultPage(QWidget *parent = nullptr)
- : NewResultPage(parent)
- , mParent((SignEncryptFilesWizard *)parent)
+ explicit SignEncryptResultPage(QWidget *parent = nullptr)
+ : ResultPage(parent)
{
setTitle(i18nc("@title", "Results"));
setSubTitle(i18nc("@title", "Status and progress of the crypto operations is shown here."));
}
-
- void initializePage() override
- {
- mParent->setLabelText(QString());
- }
-
-private:
- SignEncryptFilesWizard *mParent;
};
-SignEncryptFilesWizard::SignEncryptFilesWizard(QWidget *parent, Qt::WindowFlags f)
- : QWizard(parent, f)
+SignEncryptFilesDialog::SignEncryptFilesDialog(QWidget *parent, Qt::WindowFlags f)
+ : QDialog(parent, f)
{
readConfig();
- const bool de_vs = DeVSCompliance::isActive();
-#ifdef Q_OS_WIN
- // Enforce modern style to avoid vista style ugliness.
- setWizardStyle(QWizard::ModernStyle);
-#endif
- mSigEncPage = new SigEncPage(this);
- mResultPage = new ResultPage(this);
-
- connect(this, &QWizard::currentIdChanged, this, &SignEncryptFilesWizard::slotCurrentIdChanged);
- setPage(SigEncPageId, mSigEncPage);
- setPage(ResultPageId, mResultPage);
- setOptions(QWizard::IndependentPages | //
- (de_vs ? QWizard::HaveCustomButton1 : QWizard::WizardOption(0)) | //
- QWizard::NoBackButtonOnLastPage | //
- QWizard::NoBackButtonOnStartPage);
-
- if (de_vs) {
+ setWindowTitle(i18nc("@title", "Sign / Encrypt Files"));
+
+ mSigEncPage = new SigEncPage;
+ mResultPage = new SignEncryptResultPage(this);
+ mResultPage->setVisible(false);
+ auto layout = new QVBoxLayout(this);
+
+ auto title = new KTitleWidget;
+ title->setText(i18nc("@title:dialog", "Sign / Encrypt Files"));
+ layout->addWidget(title);
+ layout->addWidget(mSigEncPage);
+ layout->addWidget(mResultPage);
+
+ auto buttons = new QDialogButtonBox;
+
+ QPushButton *labelButton = nullptr;
+
+ if (DeVSCompliance::isActive()) {
/* We use a custom button to display a label next to the
- buttons. */
- auto btn = button(QWizard::CustomButton1);
+ buttons. */
+ labelButton = buttons->addButton(QString(), QDialogButtonBox::ActionRole);
/* We style the button so that it looks and acts like a
label. */
- btn->setStyleSheet(QStringLiteral("border: none"));
- btn->setFocusPolicy(Qt::NoFocus);
- }
-}
+ labelButton->setStyleSheet(QStringLiteral("border: none"));
+ labelButton->setFocusPolicy(Qt::NoFocus);
+ }
+
+ auto okButton = buttons->addButton(i18nc("@action:button", "Continue"), QDialogButtonBox::ActionRole);
+ auto cancelButton = buttons->addButton(QDialogButtonBox::Cancel);
+ connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject);
+ connect(okButton, &QPushButton::clicked, this, [this]() {
+ mSigEncPage->done();
+ });
+ connect(mSigEncPage, &SigEncPage::finished, this, [this, title, okButton]() {
+ if (mSigEncPage->isVisible()) {
+ mSigEncPage->setVisible(false);
+ Q_EMIT operationPrepared();
+ mResultPage->setVisible(true);
+ title->setText(i18nc("@title:dialog", "Results"));
+ okButton->setText(i18nc("@action:button", "Finished"));
+ } else {
+ accept();
+ }
+ });
-void SignEncryptFilesWizard::setLabelText(const QString &label)
-{
- button(QWizard::CommitButton)->setToolTip(label);
- setButtonText(QWizard::CustomButton1, label);
-}
+ connect(mSigEncPage, &SigEncPage::checkReady, this, [this, okButton, labelButton](const auto op) {
+ QString label;
+ switch (op) {
+ case SignEncryptWidget::Sign:
+ label = i18nc("@action:button", "Sign");
+ break;
+ case SignEncryptWidget::Encrypt:
+ label = i18nc("@action:button", "Encrypt");
+ break;
+ case SignEncryptWidget::SignAndEncrypt:
+ label = i18nc("@action:button", "Sign / Encrypt");
+ break;
+ default:;
+ };
+ if (!label.isEmpty()) {
+ okButton->setText(label);
+ if (DeVSCompliance::isActive()) {
+ const bool de_vs = DeVSCompliance::isCompliant() && mSigEncPage->isDeVsAndValid();
+ DeVSCompliance::decorate(okButton, de_vs);
-void SignEncryptFilesWizard::slotCurrentIdChanged(int id)
-{
- if (id == ResultPageId) {
- Q_EMIT operationPrepared();
- }
+ okButton->setToolTip(DeVSCompliance::name(de_vs));
+ labelButton->setText(DeVSCompliance::name(de_vs));
+ }
+ } else {
+ okButton->setText(i18nc("@action:button", "Next"));
+ okButton->setIcon(QIcon());
+ okButton->setStyleSheet(QString());
+ }
+ okButton->setEnabled(mSigEncPage->validatePage());
+ });
+
+ layout->addWidget(buttons);
}
-SignEncryptFilesWizard::~SignEncryptFilesWizard()
+SignEncryptFilesDialog::~SignEncryptFilesDialog()
{
qCDebug(KLEOPATRA_LOG) << this << __func__;
writeConfig();
}
-void SignEncryptFilesWizard::setSigningPreset(bool preset)
+void SignEncryptFilesDialog::setSigningPreset(bool preset)
{
mSigEncPage->setSigningPreset(preset);
}
-void SignEncryptFilesWizard::setSigningUserMutable(bool mut)
+void SignEncryptFilesDialog::setSigningUserMutable(bool mut)
{
if (mut == mSigningUserMutable) {
return;
}
mSigningUserMutable = mut;
}
-void SignEncryptFilesWizard::setEncryptionPreset(bool preset)
+void SignEncryptFilesDialog::setEncryptionPreset(bool preset)
{
mSigEncPage->setEncryptionPreset(preset);
}
-void SignEncryptFilesWizard::setEncryptionUserMutable(bool mut)
+void SignEncryptFilesDialog::setEncryptionUserMutable(bool mut)
{
if (mut == mEncryptionUserMutable) {
return;
}
mEncryptionUserMutable = mut;
}
-void SignEncryptFilesWizard::setArchiveForced(bool archive)
+void SignEncryptFilesDialog::setArchiveForced(bool archive)
{
mSigEncPage->setArchiveForced(archive);
}
-void SignEncryptFilesWizard::setArchiveMutable(bool archive)
+void SignEncryptFilesDialog::setArchiveMutable(bool archive)
{
mSigEncPage->setArchiveMutable(archive);
}
-void SignEncryptFilesWizard::setSingleFile(bool singleFile)
+void SignEncryptFilesDialog::setSingleFile(bool singleFile)
{
mSigEncPage->setSingleFile(singleFile);
}
-std::vector<Key> SignEncryptFilesWizard::resolvedRecipients() const
+std::vector<Key> SignEncryptFilesDialog::resolvedRecipients() const
{
return mSigEncPage->recipients();
}
-std::vector<Key> SignEncryptFilesWizard::resolvedSigners() const
+std::vector<Key> SignEncryptFilesDialog::resolvedSigners() const
{
return mSigEncPage->signers();
}
-void SignEncryptFilesWizard::setTaskCollection(const std::shared_ptr<Kleo::Crypto::TaskCollection> &coll)
+void SignEncryptFilesDialog::setTaskCollection(const std::shared_ptr<Kleo::Crypto::TaskCollection> &coll)
{
mResultPage->setTaskCollection(coll);
}
-void SignEncryptFilesWizard::setOutputNames(const QMap<int, QString> &map) const
+void SignEncryptFilesDialog::setOutputNames(const QMap<int, QString> &map) const
{
mSigEncPage->setOutputNames(map);
}
-QMap<int, QString> SignEncryptFilesWizard::outputNames() const
+QMap<int, QString> SignEncryptFilesDialog::outputNames() const
{
return mSigEncPage->outputNames();
}
-bool SignEncryptFilesWizard::encryptSymmetric() const
+bool SignEncryptFilesDialog::encryptSymmetric() const
{
return mSigEncPage->encryptSymmetric();
}
-void SignEncryptFilesWizard::readConfig()
+void SignEncryptFilesDialog::readConfig()
{
- KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("SignEncryptFilesWizard"));
+ KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("SignEncryptFilesDialog"));
const QSize size = dialog.readEntry("Size", QSize(640, 480));
if (size.isValid()) {
resize(size);
}
}
-void SignEncryptFilesWizard::writeConfig()
+void SignEncryptFilesDialog::writeConfig()
{
- KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("SignEncryptFilesWizard"));
+ KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("SignEncryptFilesDialog"));
dialog.writeEntry("Size", size());
dialog.sync();
}
-#include "signencryptfileswizard.moc"
+#include "signencryptfilesdialog.moc"
-#include "moc_signencryptfileswizard.cpp"
+#include "moc_signencryptfilesdialog.cpp"
diff --git a/src/crypto/gui/signencryptfileswizard.h b/src/crypto/gui/signencryptfilesdialog.h
similarity index 83%
rename from src/crypto/gui/signencryptfileswizard.h
rename to src/crypto/gui/signencryptfilesdialog.h
index 5fb5aa656..2a3789f50 100644
--- a/src/crypto/gui/signencryptfileswizard.h
+++ b/src/crypto/gui/signencryptfilesdialog.h
@@ -1,99 +1,96 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/signencryptfileswizard.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <gpgme++/global.h>
-#include <QWizard>
+#include <QDialog>
#include <QMap>
#include <memory>
+class QDialogButtonBox;
+
namespace GpgME
{
class Key;
}
namespace Kleo
{
namespace Crypto
{
class TaskCollection;
}
}
-class ResultPage;
+class SignEncryptResultPage;
class SigEncPage;
namespace Kleo
{
-class SignEncryptFilesWizard : public QWizard
+class SignEncryptFilesDialog : public QDialog
{
Q_OBJECT
public:
enum KindNames {
SignatureCMS,
SignaturePGP,
CombinedPGP,
EncryptedPGP,
EncryptedCMS,
Directory,
};
- explicit SignEncryptFilesWizard(QWidget *parent = nullptr, Qt::WindowFlags f = {});
- ~SignEncryptFilesWizard() override;
+ explicit SignEncryptFilesDialog(QWidget *parent = nullptr, Qt::WindowFlags f = {});
+ ~SignEncryptFilesDialog() override;
// Inputs
void setSigningPreset(bool preset);
void setSigningUserMutable(bool mut);
void setEncryptionPreset(bool preset);
void setEncryptionUserMutable(bool mut);
void setArchiveForced(bool archive);
void setArchiveMutable(bool archive);
void setSingleFile(bool singleFile);
void setOutputNames(const QMap<int, QString> &nameMap) const;
QMap<int, QString> outputNames() const;
void setTaskCollection(const std::shared_ptr<Kleo::Crypto::TaskCollection> &coll);
// Outputs
std::vector<GpgME::Key> resolvedRecipients() const;
std::vector<GpgME::Key> resolvedSigners() const;
bool encryptSymmetric() const;
- void setLabelText(const QString &label);
-
protected:
void readConfig();
void writeConfig();
Q_SIGNALS:
void operationPrepared();
-private Q_SLOTS:
- void slotCurrentIdChanged(int);
-
private:
SigEncPage *mSigEncPage = nullptr;
- ResultPage *mResultPage = nullptr;
+ SignEncryptResultPage *mResultPage = nullptr;
bool mSigningUserMutable = true;
bool mEncryptionUserMutable = true;
};
}
diff --git a/src/crypto/signencryptfilescontroller.cpp b/src/crypto/signencryptfilescontroller.cpp
index fc7abfb1f..cdecc1acc 100644
--- a/src/crypto/signencryptfilescontroller.cpp
+++ b/src/crypto/signencryptfilescontroller.cpp
@@ -1,814 +1,814 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/signencryptfilescontroller.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "signencryptfilescontroller.h"
#include "signencrypttask.h"
-#include "crypto/gui/signencryptfileswizard.h"
+#include "crypto/gui/signencryptfilesdialog.h"
#include "crypto/taskcollection.h"
#include "fileoperationspreferences.h"
#include "utils/archivedefinition.h"
#include "utils/input.h"
#include "utils/kleo_assert.h"
#include "utils/output.h"
#include "utils/path-helper.h"
#include <Libkleo/Classify>
#include <Libkleo/KleoException>
#include "kleopatra_debug.h"
#include <KLocalizedString>
#include <QGpgME/SignEncryptArchiveJob>
#include <QDir>
#include <QFileInfo>
#include <QPointer>
#include <QTimer>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace GpgME;
class SignEncryptFilesController::Private
{
friend class ::Kleo::Crypto::SignEncryptFilesController;
SignEncryptFilesController *const q;
public:
explicit Private(SignEncryptFilesController *qq);
~Private();
private:
void slotWizardOperationPrepared();
void slotWizardCanceled();
private:
void ensureWizardCreated();
void ensureWizardVisible();
void updateWizardMode();
void cancelAllTasks();
void reportError(int err, const QString &details)
{
q->setLastError(err, details);
q->emitDoneOrError();
}
void schedule();
std::shared_ptr<SignEncryptTask> takeRunnable(GpgME::Protocol proto);
static void assertValidOperation(unsigned int);
static QString titleForOperation(unsigned int op);
private:
std::vector<std::shared_ptr<SignEncryptTask>> runnable, completed;
std::shared_ptr<SignEncryptTask> cms, openpgp;
- QPointer<SignEncryptFilesWizard> wizard;
+ QPointer<SignEncryptFilesDialog> wizard;
QStringList files;
unsigned int operation;
Protocol protocol;
};
SignEncryptFilesController::Private::Private(SignEncryptFilesController *qq)
: q(qq)
, runnable()
, cms()
, openpgp()
, wizard()
, files()
, operation(SignAllowed | EncryptAllowed | ArchiveAllowed)
, protocol(UnknownProtocol)
{
}
SignEncryptFilesController::Private::~Private()
{
qCDebug(KLEOPATRA_LOG) << q << __func__;
}
QString SignEncryptFilesController::Private::titleForOperation(unsigned int op)
{
const bool signDisallowed = (op & SignMask) == SignDisallowed;
const bool encryptDisallowed = (op & EncryptMask) == EncryptDisallowed;
const bool archiveSelected = (op & ArchiveMask) == ArchiveForced;
kleo_assert(!signDisallowed || !encryptDisallowed);
if (!signDisallowed && encryptDisallowed) {
if (archiveSelected) {
return i18n("Archive and Sign Files");
} else {
return i18n("Sign Files");
}
}
if (signDisallowed && !encryptDisallowed) {
if (archiveSelected) {
return i18n("Archive and Encrypt Files");
} else {
return i18n("Encrypt Files");
}
}
if (archiveSelected) {
return i18n("Archive and Sign/Encrypt Files");
} else {
return i18n("Sign/Encrypt Files");
}
}
SignEncryptFilesController::SignEncryptFilesController(QObject *p)
: Controller(p)
, d(new Private(this))
{
}
SignEncryptFilesController::SignEncryptFilesController(const std::shared_ptr<const ExecutionContext> &ctx, QObject *p)
: Controller(ctx, p)
, d(new Private(this))
{
}
SignEncryptFilesController::~SignEncryptFilesController()
{
qCDebug(KLEOPATRA_LOG) << this << __func__;
if (d->wizard && !d->wizard->isVisible()) {
delete d->wizard;
}
// d->wizard->close(); ### ?
}
void SignEncryptFilesController::setProtocol(Protocol proto)
{
kleo_assert(d->protocol == UnknownProtocol || d->protocol == proto);
d->protocol = proto;
d->ensureWizardCreated();
}
Protocol SignEncryptFilesController::protocol() const
{
return d->protocol;
}
// static
void SignEncryptFilesController::Private::assertValidOperation(unsigned int op)
{
kleo_assert((op & SignMask) == SignDisallowed || //
(op & SignMask) == SignAllowed || //
(op & SignMask) == SignSelected);
kleo_assert((op & EncryptMask) == EncryptDisallowed || //
(op & EncryptMask) == EncryptAllowed || //
(op & EncryptMask) == EncryptSelected);
kleo_assert((op & ArchiveMask) == ArchiveDisallowed || //
(op & ArchiveMask) == ArchiveAllowed || //
(op & ArchiveMask) == ArchiveForced);
kleo_assert((op & ~(SignMask | EncryptMask | ArchiveMask)) == 0);
}
void SignEncryptFilesController::setOperationMode(unsigned int mode)
{
Private::assertValidOperation(mode);
d->operation = mode;
d->updateWizardMode();
}
void SignEncryptFilesController::Private::updateWizardMode()
{
if (!wizard) {
return;
}
wizard->setWindowTitle(titleForOperation(operation));
const unsigned int signOp = (operation & SignMask);
const unsigned int encrOp = (operation & EncryptMask);
const unsigned int archOp = (operation & ArchiveMask);
if (signOp == SignDisallowed) {
wizard->setSigningUserMutable(false);
wizard->setSigningPreset(false);
} else {
wizard->setSigningUserMutable(true);
wizard->setSigningPreset(signOp == SignSelected);
}
if (encrOp == EncryptDisallowed) {
wizard->setEncryptionPreset(false);
wizard->setEncryptionUserMutable(false);
} else {
wizard->setEncryptionUserMutable(true);
wizard->setEncryptionPreset(encrOp == EncryptSelected);
}
wizard->setArchiveForced(archOp == ArchiveForced);
wizard->setArchiveMutable(archOp == ArchiveAllowed);
}
unsigned int SignEncryptFilesController::operationMode() const
{
return d->operation;
}
static QString extension(bool pgp, bool sign, bool encrypt, bool ascii, bool detached)
{
unsigned int cls = pgp ? Class::OpenPGP : Class::CMS;
if (encrypt) {
cls |= Class::CipherText;
} else if (sign) {
cls |= detached ? Class::DetachedSignature : Class::OpaqueSignature;
}
cls |= ascii ? Class::Ascii : Class::Binary;
const bool usePGPFileExt = FileOperationsPreferences().usePGPFileExt();
const auto ext = outputFileExtension(cls, usePGPFileExt);
if (!ext.isEmpty()) {
return ext;
} else {
return QStringLiteral("out");
}
}
static std::shared_ptr<ArchiveDefinition> getDefaultAd()
{
const std::vector<std::shared_ptr<ArchiveDefinition>> ads = ArchiveDefinition::getArchiveDefinitions();
Q_ASSERT(!ads.empty());
std::shared_ptr<ArchiveDefinition> ad = ads.front();
const FileOperationsPreferences prefs;
const QString archiveCmd = prefs.archiveCommand();
auto it = std::find_if(ads.cbegin(), ads.cend(), [&archiveCmd](const std::shared_ptr<ArchiveDefinition> &toCheck) {
return toCheck->id() == archiveCmd;
});
if (it != ads.cend()) {
ad = *it;
}
return ad;
}
static QMap<int, QString> buildOutputNames(const QStringList &files, const bool archive)
{
QMap<int, QString> nameMap;
// Build the default names for the wizard.
QString baseNameCms;
QString baseNamePgp;
const QFileInfo firstFile(files.first());
if (archive) {
QString baseName = files.size() > 1 ? i18nc("base name of an archive file, e.g. archive.zip or archive.tar.gz", "archive") : firstFile.baseName();
baseName = QDir(heuristicBaseDirectory(files)).absoluteFilePath(baseName);
const auto ad = getDefaultAd();
baseNamePgp = baseName + QLatin1Char('.') + ad->extensions(GpgME::OpenPGP).first() + QLatin1Char('.');
baseNameCms = baseName + QLatin1Char('.') + ad->extensions(GpgME::CMS).first() + QLatin1Char('.');
} else {
baseNameCms = baseNamePgp = files.first() + QLatin1Char('.');
}
const FileOperationsPreferences prefs;
const bool ascii = prefs.addASCIIArmor();
- nameMap.insert(SignEncryptFilesWizard::SignatureCMS, baseNameCms + extension(false, true, false, ascii, true));
- nameMap.insert(SignEncryptFilesWizard::EncryptedCMS, baseNameCms + extension(false, false, true, ascii, false));
- nameMap.insert(SignEncryptFilesWizard::CombinedPGP, baseNamePgp + extension(true, true, true, ascii, false));
- nameMap.insert(SignEncryptFilesWizard::EncryptedPGP, baseNamePgp + extension(true, false, true, ascii, false));
- nameMap.insert(SignEncryptFilesWizard::SignaturePGP, baseNamePgp + extension(true, true, false, ascii, true));
- nameMap.insert(SignEncryptFilesWizard::Directory, heuristicBaseDirectory(files));
+ nameMap.insert(SignEncryptFilesDialog::SignatureCMS, baseNameCms + extension(false, true, false, ascii, true));
+ nameMap.insert(SignEncryptFilesDialog::EncryptedCMS, baseNameCms + extension(false, false, true, ascii, false));
+ nameMap.insert(SignEncryptFilesDialog::CombinedPGP, baseNamePgp + extension(true, true, true, ascii, false));
+ nameMap.insert(SignEncryptFilesDialog::EncryptedPGP, baseNamePgp + extension(true, false, true, ascii, false));
+ nameMap.insert(SignEncryptFilesDialog::SignaturePGP, baseNamePgp + extension(true, true, false, ascii, true));
+ nameMap.insert(SignEncryptFilesDialog::Directory, heuristicBaseDirectory(files));
return nameMap;
}
static QMap<int, QString> buildOutputNamesForDir(const QString &file, const QMap<int, QString> &orig)
{
QMap<int, QString> ret;
- const QString dir = orig.value(SignEncryptFilesWizard::Directory);
+ const QString dir = orig.value(SignEncryptFilesDialog::Directory);
if (dir.isEmpty()) {
return orig;
}
// Build the default names for the wizard.
const QFileInfo fi(file);
const QString baseName = dir + QLatin1Char('/') + fi.fileName() + QLatin1Char('.');
const FileOperationsPreferences prefs;
const bool ascii = prefs.addASCIIArmor();
- ret.insert(SignEncryptFilesWizard::SignatureCMS, baseName + extension(false, true, false, ascii, true));
- ret.insert(SignEncryptFilesWizard::EncryptedCMS, baseName + extension(false, false, true, ascii, false));
- ret.insert(SignEncryptFilesWizard::CombinedPGP, baseName + extension(true, true, true, ascii, false));
- ret.insert(SignEncryptFilesWizard::EncryptedPGP, baseName + extension(true, false, true, ascii, false));
- ret.insert(SignEncryptFilesWizard::SignaturePGP, baseName + extension(true, true, false, ascii, true));
+ ret.insert(SignEncryptFilesDialog::SignatureCMS, baseName + extension(false, true, false, ascii, true));
+ ret.insert(SignEncryptFilesDialog::EncryptedCMS, baseName + extension(false, false, true, ascii, false));
+ ret.insert(SignEncryptFilesDialog::CombinedPGP, baseName + extension(true, true, true, ascii, false));
+ ret.insert(SignEncryptFilesDialog::EncryptedPGP, baseName + extension(true, false, true, ascii, false));
+ ret.insert(SignEncryptFilesDialog::SignaturePGP, baseName + extension(true, true, false, ascii, true));
return ret;
}
// strips all trailing slashes from the filename, but keeps filename "/"
static QString stripTrailingSlashes(const QString &fileName)
{
if (fileName.size() < 2 || !fileName.endsWith(QLatin1Char('/'))) {
return fileName;
}
auto tmp = QStringView{fileName}.chopped(1);
while (tmp.size() > 1 && tmp.endsWith(QLatin1Char('/'))) {
tmp.chop(1);
}
return tmp.toString();
}
static QStringList stripTrailingSlashesForAll(const QStringList &fileNames)
{
QStringList result;
result.reserve(fileNames.size());
std::transform(fileNames.begin(), fileNames.end(), std::back_inserter(result), &stripTrailingSlashes);
return result;
}
void SignEncryptFilesController::setFiles(const QStringList &files)
{
kleo_assert(!files.empty());
d->files = stripTrailingSlashesForAll(files);
bool archive = false;
if (d->files.size() > 1) {
setOperationMode((operationMode() & ~ArchiveMask) | ArchiveAllowed);
archive = true;
}
for (const auto &file : std::as_const(d->files)) {
if (QFileInfo(file).isDir()) {
setOperationMode((operationMode() & ~ArchiveMask) | ArchiveForced);
archive = true;
break;
}
}
d->ensureWizardCreated();
d->wizard->setSingleFile(!archive);
d->wizard->setOutputNames(buildOutputNames(d->files, archive));
}
void SignEncryptFilesController::Private::slotWizardCanceled()
{
qCDebug(KLEOPATRA_LOG) << q << __func__;
q->cancel();
reportError(gpg_error(GPG_ERR_CANCELED), i18n("User cancel"));
}
void SignEncryptFilesController::start()
{
d->ensureWizardVisible();
}
static std::shared_ptr<SignEncryptTask> createSignEncryptTaskForFileInfo(const QFileInfo &fi,
bool ascii,
const std::vector<Key> &recipients,
const std::vector<Key> &signers,
const QString &outputName,
bool symmetric)
{
const std::shared_ptr<SignEncryptTask> task(new SignEncryptTask);
Q_ASSERT(!signers.empty() || !recipients.empty() || symmetric);
task->setAsciiArmor(ascii);
if (!signers.empty()) {
task->setSign(true);
task->setSigners(signers);
task->setDetachedSignature(true);
} else {
task->setSign(false);
}
if (!recipients.empty()) {
task->setEncrypt(true);
task->setRecipients(recipients);
task->setDetachedSignature(false);
} else {
task->setEncrypt(false);
}
task->setEncryptSymmetric(symmetric);
const QString input = fi.absoluteFilePath();
task->setInputFileName(input);
#if QGPGME_FILE_JOBS_SUPPORT_DIRECT_FILE_IO
if (task->protocol() != GpgME::OpenPGP) {
task->setInput(Input::createFromFile(input));
}
#else
task->setInput(Input::createFromFile(input));
#endif
task->setOutputFileName(outputName);
return task;
}
static bool archiveJobsCanBeUsed([[maybe_unused]] GpgME::Protocol protocol)
{
return (protocol == GpgME::OpenPGP) && QGpgME::SignEncryptArchiveJob::isSupported();
}
static std::shared_ptr<SignEncryptTask> createArchiveSignEncryptTaskForFiles(const QStringList &files,
const std::shared_ptr<ArchiveDefinition> &ad,
bool pgp,
bool ascii,
const std::vector<Key> &recipients,
const std::vector<Key> &signers,
const QString &outputName,
bool symmetric)
{
const std::shared_ptr<SignEncryptTask> task(new SignEncryptTask);
task->setCreateArchive(true);
task->setEncryptSymmetric(symmetric);
Q_ASSERT(!signers.empty() || !recipients.empty() || symmetric);
task->setAsciiArmor(ascii);
if (!signers.empty()) {
task->setSign(true);
task->setSigners(signers);
task->setDetachedSignature(false);
} else {
task->setSign(false);
}
if (!recipients.empty()) {
task->setEncrypt(true);
task->setRecipients(recipients);
} else {
task->setEncrypt(false);
}
const Protocol proto = pgp ? OpenPGP : CMS;
task->setInputFileNames(files);
if (!archiveJobsCanBeUsed(proto)) {
// use legacy archive creation
kleo_assert(ad);
task->setInput(ad->createInputFromPackCommand(proto, files));
}
task->setOutputFileName(outputName);
return task;
}
static std::vector<std::shared_ptr<SignEncryptTask>> createSignEncryptTasksForFileInfo(const QFileInfo &fi,
bool ascii,
const std::vector<Key> &pgpRecipients,
const std::vector<Key> &pgpSigners,
const std::vector<Key> &cmsRecipients,
const std::vector<Key> &cmsSigners,
const QMap<int, QString> &outputNames,
bool symmetric)
{
std::vector<std::shared_ptr<SignEncryptTask>> result;
const bool pgp = !pgpSigners.empty() || !pgpRecipients.empty();
const bool cms = !cmsSigners.empty() || !cmsRecipients.empty();
result.reserve(pgp + cms);
if (pgp || symmetric) {
// Symmetric encryption is only supported for PGP
int outKind = 0;
if ((!pgpRecipients.empty() || symmetric) && !pgpSigners.empty()) {
- outKind = SignEncryptFilesWizard::CombinedPGP;
+ outKind = SignEncryptFilesDialog::CombinedPGP;
} else if (!pgpRecipients.empty() || symmetric) {
- outKind = SignEncryptFilesWizard::EncryptedPGP;
+ outKind = SignEncryptFilesDialog::EncryptedPGP;
} else {
- outKind = SignEncryptFilesWizard::SignaturePGP;
+ outKind = SignEncryptFilesDialog::SignaturePGP;
}
result.push_back(createSignEncryptTaskForFileInfo(fi, ascii, pgpRecipients, pgpSigners, outputNames[outKind], symmetric));
}
if (cms) {
// There is no combined sign / encrypt in gpgsm so we create one sign task
// and one encrypt task. Which leaves us with the age old dilemma, encrypt
// then sign, or sign then encrypt. Ugly.
if (!cmsSigners.empty()) {
result.push_back(
- createSignEncryptTaskForFileInfo(fi, ascii, std::vector<Key>(), cmsSigners, outputNames[SignEncryptFilesWizard::SignatureCMS], false));
+ createSignEncryptTaskForFileInfo(fi, ascii, std::vector<Key>(), cmsSigners, outputNames[SignEncryptFilesDialog::SignatureCMS], false));
}
if (!cmsRecipients.empty()) {
result.push_back(
- createSignEncryptTaskForFileInfo(fi, ascii, cmsRecipients, std::vector<Key>(), outputNames[SignEncryptFilesWizard::EncryptedCMS], false));
+ createSignEncryptTaskForFileInfo(fi, ascii, cmsRecipients, std::vector<Key>(), outputNames[SignEncryptFilesDialog::EncryptedCMS], false));
}
}
return result;
}
static std::vector<std::shared_ptr<SignEncryptTask>> createArchiveSignEncryptTasksForFiles(const QStringList &files,
const std::shared_ptr<ArchiveDefinition> &ad,
bool ascii,
const std::vector<Key> &pgpRecipients,
const std::vector<Key> &pgpSigners,
const std::vector<Key> &cmsRecipients,
const std::vector<Key> &cmsSigners,
const QMap<int, QString> &outputNames,
bool symmetric)
{
std::vector<std::shared_ptr<SignEncryptTask>> result;
const bool pgp = !pgpSigners.empty() || !pgpRecipients.empty();
const bool cms = !cmsSigners.empty() || !cmsRecipients.empty();
result.reserve(pgp + cms);
if (pgp || symmetric) {
int outKind = 0;
if ((!pgpRecipients.empty() || symmetric) && !pgpSigners.empty()) {
- outKind = SignEncryptFilesWizard::CombinedPGP;
+ outKind = SignEncryptFilesDialog::CombinedPGP;
} else if (!pgpRecipients.empty() || symmetric) {
- outKind = SignEncryptFilesWizard::EncryptedPGP;
+ outKind = SignEncryptFilesDialog::EncryptedPGP;
} else {
- outKind = SignEncryptFilesWizard::SignaturePGP;
+ outKind = SignEncryptFilesDialog::SignaturePGP;
}
result.push_back(createArchiveSignEncryptTaskForFiles(files, ad, true, ascii, pgpRecipients, pgpSigners, outputNames[outKind], symmetric));
}
if (cms) {
if (!cmsSigners.empty()) {
result.push_back(createArchiveSignEncryptTaskForFiles(files,
ad,
false,
ascii,
std::vector<Key>(),
cmsSigners,
- outputNames[SignEncryptFilesWizard::SignatureCMS],
+ outputNames[SignEncryptFilesDialog::SignatureCMS],
false));
}
if (!cmsRecipients.empty()) {
result.push_back(createArchiveSignEncryptTaskForFiles(files,
ad,
false,
ascii,
cmsRecipients,
std::vector<Key>(),
- outputNames[SignEncryptFilesWizard::EncryptedCMS],
+ outputNames[SignEncryptFilesDialog::EncryptedCMS],
false));
}
}
return result;
}
namespace
{
static bool isDetachedOpenPGPSignature(const QString &fileName)
{
const auto classification = Kleo::classify(fileName);
return Kleo::isOpenPGP(classification) && Kleo::isDetachedSignature(classification);
}
static auto resolveFileNameConflicts(const std::vector<std::shared_ptr<SignEncryptTask>> &tasks, QWidget *parent)
{
std::vector<std::shared_ptr<SignEncryptTask>> resolvedTasks;
OverwritePolicy overwritePolicy{parent, tasks.size() > 1 ? OverwritePolicy::MultipleFiles : OverwritePolicy::Options{}};
for (auto &task : tasks) {
// by default, do not overwrite existing files
task->setOverwritePolicy(std::make_shared<OverwritePolicy>(OverwritePolicy::Skip));
const auto outputFileName = task->outputFileName();
if (QFile::exists(outputFileName)) {
const auto isDetachedOpenPGPSigningTask = (task->protocol() == GpgME::OpenPGP) && task->detachedSignatureEnabled();
const auto extraOptions = (isDetachedOpenPGPSigningTask && isDetachedOpenPGPSignature(outputFileName) //
? OverwritePolicy::AllowAppend //
: OverwritePolicy::Options{});
const auto policyAndFileName = overwritePolicy.obtainOverwritePermission(outputFileName, extraOptions);
if (policyAndFileName.policy == OverwritePolicy::Cancel) {
resolvedTasks.clear();
break;
}
switch (policyAndFileName.policy) {
case OverwritePolicy::Skip:
// do not add task to the final task list
continue;
case OverwritePolicy::Rename: {
task->setOutputFileName(policyAndFileName.fileName);
break;
}
case OverwritePolicy::Append: {
task->setOverwritePolicy(std::make_shared<OverwritePolicy>(OverwritePolicy::Append));
break;
}
case OverwritePolicy::Overwrite: {
task->setOverwritePolicy(std::make_shared<OverwritePolicy>(OverwritePolicy::Overwrite));
break;
}
case OverwritePolicy::Cancel:
// already handled outside of switch
break;
case OverwritePolicy::None:
case OverwritePolicy::Ask:
qCDebug(KLEOPATRA_LOG) << "Unexpected OverwritePolicy result" << policyAndFileName.policy << "for" << outputFileName;
};
}
resolvedTasks.push_back(task);
}
return resolvedTasks;
}
}
void SignEncryptFilesController::Private::slotWizardOperationPrepared()
{
try {
kleo_assert(wizard);
kleo_assert(!files.empty());
- const bool archive = ((wizard->outputNames().value(SignEncryptFilesWizard::Directory).isNull() && files.size() > 1) //
+ const bool archive = ((wizard->outputNames().value(SignEncryptFilesDialog::Directory).isNull() && files.size() > 1) //
|| ((operation & ArchiveMask) == ArchiveForced));
const std::vector<Key> recipients = wizard->resolvedRecipients();
const std::vector<Key> signers = wizard->resolvedSigners();
const FileOperationsPreferences prefs;
const bool ascii = prefs.addASCIIArmor();
std::vector<Key> pgpRecipients, cmsRecipients, pgpSigners, cmsSigners;
for (const Key &k : recipients) {
if (k.protocol() == GpgME::OpenPGP) {
pgpRecipients.push_back(k);
} else {
cmsRecipients.push_back(k);
}
}
for (const Key &k : signers) {
if (k.protocol() == GpgME::OpenPGP) {
pgpSigners.push_back(k);
} else {
cmsSigners.push_back(k);
}
}
std::vector<std::shared_ptr<SignEncryptTask>> tasks;
if (!archive) {
tasks.reserve(files.size());
}
if (archive) {
tasks = createArchiveSignEncryptTasksForFiles(files,
getDefaultAd(),
ascii,
pgpRecipients,
pgpSigners,
cmsRecipients,
cmsSigners,
wizard->outputNames(),
wizard->encryptSymmetric());
} else {
for (const QString &file : std::as_const(files)) {
const std::vector<std::shared_ptr<SignEncryptTask>> created =
createSignEncryptTasksForFileInfo(QFileInfo(file),
ascii,
pgpRecipients,
pgpSigners,
cmsRecipients,
cmsSigners,
buildOutputNamesForDir(file, wizard->outputNames()),
wizard->encryptSymmetric());
tasks.insert(tasks.end(), created.begin(), created.end());
}
}
tasks = resolveFileNameConflicts(tasks, wizard);
if (tasks.empty()) {
q->cancel();
return;
}
kleo_assert(runnable.empty());
runnable.swap(tasks);
for (const auto &task : std::as_const(runnable)) {
q->connectTask(task);
}
std::shared_ptr<TaskCollection> coll(new TaskCollection);
std::vector<std::shared_ptr<Task>> tmp;
std::copy(runnable.begin(), runnable.end(), std::back_inserter(tmp));
coll->setTasks(tmp);
wizard->setTaskCollection(coll);
QTimer::singleShot(0, q, SLOT(schedule()));
} catch (const Kleo::Exception &e) {
reportError(e.error().encodedError(), e.message());
} catch (const std::exception &e) {
reportError(
gpg_error(GPG_ERR_UNEXPECTED),
i18n("Caught unexpected exception in SignEncryptFilesController::Private::slotWizardOperationPrepared: %1", QString::fromLocal8Bit(e.what())));
} catch (...) {
reportError(gpg_error(GPG_ERR_UNEXPECTED), i18n("Caught unknown exception in SignEncryptFilesController::Private::slotWizardOperationPrepared"));
}
}
void SignEncryptFilesController::Private::schedule()
{
if (!cms)
if (const std::shared_ptr<SignEncryptTask> t = takeRunnable(CMS)) {
t->start();
cms = t;
}
if (!openpgp)
if (const std::shared_ptr<SignEncryptTask> t = takeRunnable(OpenPGP)) {
t->start();
openpgp = t;
}
if (!cms && !openpgp) {
kleo_assert(runnable.empty());
q->emitDoneOrError();
}
}
std::shared_ptr<SignEncryptTask> SignEncryptFilesController::Private::takeRunnable(GpgME::Protocol proto)
{
const auto it = std::find_if(runnable.begin(), runnable.end(), [proto](const std::shared_ptr<Task> &task) {
return task->protocol() == proto;
});
if (it == runnable.end()) {
return std::shared_ptr<SignEncryptTask>();
}
const std::shared_ptr<SignEncryptTask> result = *it;
runnable.erase(it);
return result;
}
void SignEncryptFilesController::doTaskDone(const Task *task, const std::shared_ptr<const Task::Result> &result)
{
Q_UNUSED(result)
Q_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->cms.get()) {
d->completed.push_back(d->cms);
d->cms.reset();
} else if (task == d->openpgp.get()) {
d->completed.push_back(d->openpgp);
d->openpgp.reset();
}
QTimer::singleShot(0, this, SLOT(schedule()));
}
void SignEncryptFilesController::cancel()
{
qCDebug(KLEOPATRA_LOG) << this << __func__;
try {
if (d->wizard) {
d->wizard->close();
}
d->cancelAllTasks();
} catch (const std::exception &e) {
qCDebug(KLEOPATRA_LOG) << "Caught exception: " << e.what();
}
}
void SignEncryptFilesController::Private::cancelAllTasks()
{
// we just kill all runnable tasks - this will not result in
// signal emissions.
runnable.clear();
// a cancel() will result in a call to
if (cms) {
cms->cancel();
}
if (openpgp) {
openpgp->cancel();
}
}
void SignEncryptFilesController::Private::ensureWizardCreated()
{
if (wizard) {
return;
}
- std::unique_ptr<SignEncryptFilesWizard> w(new SignEncryptFilesWizard);
+ std::unique_ptr<SignEncryptFilesDialog> w(new SignEncryptFilesDialog);
w->setAttribute(Qt::WA_DeleteOnClose);
connect(w.get(), SIGNAL(operationPrepared()), q, SLOT(slotWizardOperationPrepared()), Qt::QueuedConnection);
connect(w.get(), SIGNAL(rejected()), q, SLOT(slotWizardCanceled()), Qt::QueuedConnection);
wizard = w.release();
updateWizardMode();
}
void SignEncryptFilesController::Private::ensureWizardVisible()
{
ensureWizardCreated();
q->bringToForeground(wizard);
}
#include "moc_signencryptfilescontroller.cpp"

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:27 PM (14 h, 39 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a6/ae/590da8521633689b974a4aa7fc21

Event Timeline