Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F36622970
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
91 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment