Page MenuHome GnuPG

No OneTemporary

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7b444b140..150959441 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,644 +1,644 @@
# 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/signencryptclipboardcommand.cpp
+ commands/signencryptclipboardcommand.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/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/signencryptclipboarddialog.cpp
+ dialogs/signencryptclipboarddialog.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/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/commands/signclipboardcommand.h b/src/commands/signclipboardcommand.h
deleted file mode 100644
index d33035176..000000000
--- a/src/commands/signclipboardcommand.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/signclipboardcommand.h
-
- This file is part of Kleopatra, the KDE keymanager
- SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
-
- SPDX-License-Identifier: GPL-2.0-or-later
-*/
-
-#pragma once
-
-#include <commands/command.h>
-
-#ifndef QT_NO_CLIPBOARD
-
-#include <utils/types.h>
-
-#include <gpgme++/global.h>
-
-namespace Kleo
-{
-namespace Commands
-{
-
-class SignClipboardCommand : public Command
-{
- Q_OBJECT
-public:
- explicit SignClipboardCommand(GpgME::Protocol protocol, QAbstractItemView *view, KeyListController *parent);
- explicit SignClipboardCommand(GpgME::Protocol protocol, KeyListController *parent);
- ~SignClipboardCommand() override;
-
- static bool canSignCurrentClipboard();
-
-private:
- void doStart() override;
- void doCancel() override;
-
-private:
- class Private;
- inline Private *d_func();
- inline const Private *d_func() const;
-};
-
-}
-}
-
-#endif // QT_NO_CLIPBOARD
diff --git a/src/commands/signencryptclipboardcommand.cpp b/src/commands/signencryptclipboardcommand.cpp
new file mode 100644
index 000000000..2a6d38380
--- /dev/null
+++ b/src/commands/signencryptclipboardcommand.cpp
@@ -0,0 +1,108 @@
+/*
+ This file is part of Kleopatra, the KDE keymanager
+ SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
+ SPDX-FileCopyrightText: 2025 g10 Code GmbH
+ SPDX-FileContributor: Tobias Fella <tobias.fella@gnupg.com>
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include <config-kleopatra.h>
+
+#include "signencryptclipboardcommand.h"
+
+#ifndef QT_NO_CLIPBOARD
+
+#include "dialogs/signencryptclipboarddialog.h"
+
+#include "command_p.h"
+
+#include "kleopatra_debug.h"
+#include <KLocalizedString>
+
+using namespace Kleo;
+using namespace Kleo::Commands;
+
+class SignEncryptClipboardCommand::Private : public Command::Private
+{
+ friend class ::Kleo::Commands::SignEncryptClipboardCommand;
+ SignEncryptClipboardCommand *q_func() const
+ {
+ return static_cast<SignEncryptClipboardCommand *>(q);
+ }
+
+public:
+ explicit Private(SignEncryptClipboardCommand *qq);
+ ~Private() override;
+
+ void slotDialogRejected();
+ void slotDialogAccepted();
+
+private:
+ QPointer<SignEncryptClipboardDialog> dialog;
+ SignEncryptClipboardCommand::Mode mode = SignEncryptClipboardCommand::Mode::SignEncrypt;
+};
+
+SignEncryptClipboardCommand::Private *SignEncryptClipboardCommand::d_func()
+{
+ return static_cast<Private *>(d.get());
+}
+const SignEncryptClipboardCommand::Private *SignEncryptClipboardCommand::d_func() const
+{
+ return static_cast<const Private *>(d.get());
+}
+
+#define d d_func()
+#define q q_func()
+
+SignEncryptClipboardCommand::Private::Private(SignEncryptClipboardCommand *qq)
+ : Command::Private(qq)
+{
+}
+
+SignEncryptClipboardCommand::Private::~Private()
+{
+ qCDebug(KLEOPATRA_LOG);
+ delete dialog;
+}
+
+void SignEncryptClipboardCommand::Private::slotDialogRejected()
+{
+ canceled();
+}
+
+void SignEncryptClipboardCommand::Private::slotDialogAccepted()
+{
+ finished();
+}
+
+SignEncryptClipboardCommand::SignEncryptClipboardCommand(Mode mode)
+ : Command(new Private(this))
+{
+ d->mode = mode;
+}
+
+void SignEncryptClipboardCommand::doStart()
+{
+ d->dialog = new SignEncryptClipboardDialog(d->mode);
+ d->dialog->show();
+ connect(d->dialog.get(), &QDialog::rejected, this, [this]() {
+ d->slotDialogRejected();
+ });
+
+ connect(d->dialog.get(), &QDialog::accepted, this, [this]() {
+ d->slotDialogAccepted();
+ });
+}
+
+void SignEncryptClipboardCommand::doCancel()
+{
+ qCDebug(KLEOPATRA_LOG);
+}
+
+#undef d
+#undef q
+
+#include "moc_signencryptclipboardcommand.cpp"
+
+#endif // QT_NO_CLIPBOARD
diff --git a/src/commands/encryptclipboardcommand.h b/src/commands/signencryptclipboardcommand.h
similarity index 56%
rename from src/commands/encryptclipboardcommand.h
rename to src/commands/signencryptclipboardcommand.h
index 935d79a7f..9e42d0061 100644
--- a/src/commands/encryptclipboardcommand.h
+++ b/src/commands/signencryptclipboardcommand.h
@@ -1,46 +1,45 @@
-/* -*- mode: c++; c-basic-offset:4 -*-
- commands/encryptclipboardcommand.h
-
+/*
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
+ SPDX-FileCopyrightText: 2025 g10 Code GmbH
+ SPDX-FileContributor: Tobias Fella <tobias.fella@gnupg.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
-
#pragma once
#include <commands/command.h>
#ifndef QT_NO_CLIPBOARD
-#include <utils/types.h>
-
namespace Kleo
{
namespace Commands
{
-class EncryptClipboardCommand : public Command
+class SignEncryptClipboardCommand : public Command
{
Q_OBJECT
-public:
- explicit EncryptClipboardCommand(QAbstractItemView *view, KeyListController *parent);
- explicit EncryptClipboardCommand(KeyListController *parent);
- ~EncryptClipboardCommand() override;
- static bool canEncryptCurrentClipboard();
+public:
+ enum class Mode {
+ SignEncrypt,
+ Sign,
+ Encrypt,
+ };
+ explicit SignEncryptClipboardCommand(SignEncryptClipboardCommand::Mode mode = SignEncryptClipboardCommand::Mode::SignEncrypt);
private:
void doStart() override;
void doCancel() override;
private:
class Private;
inline Private *d_func();
inline const Private *d_func() const;
};
}
}
#endif // QT_NO_CLIPBOARD
diff --git a/src/crypto/gui/resultpage.cpp b/src/crypto/gui/resultpage.cpp
index bdfc0cefe..0755be179 100644
--- a/src/crypto/gui/resultpage.cpp
+++ b/src/crypto/gui/resultpage.cpp
@@ -1,177 +1,172 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/gui/resultpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "resultitemwidget.h"
#include "resultlistwidget.h"
#include "resultpage.h"
#include <crypto/taskcollection.h>
#include <KLocalizedString>
#include <QCheckBox>
#include <QHash>
#include <QLabel>
#include <QProgressBar>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
class ResultPage::Private
{
ResultPage *const q;
public:
explicit Private(ResultPage *qq);
void progress(int progress, int total);
void result(const std::shared_ptr<const Task::Result> &result);
void started(const std::shared_ptr<Task> &result);
void allDone();
QLabel *labelForTag(const QString &tag);
std::shared_ptr<TaskCollection> m_tasks;
QProgressBar *m_progressBar;
QHash<QString, QLabel *> m_progressLabelByTag;
QVBoxLayout *m_progressLabelLayout;
int m_lastErrorItemIndex = 0;
ResultListWidget *m_resultList;
QCheckBox *m_keepOpenCB;
};
ResultPage::Private::Private(ResultPage *qq)
: q(qq)
{
QBoxLayout *const layout = new QVBoxLayout(q);
auto const labels = new QWidget;
m_progressLabelLayout = new QVBoxLayout(labels);
layout->addWidget(labels);
m_progressBar = new QProgressBar;
layout->addWidget(m_progressBar);
m_resultList = new ResultListWidget;
layout->addWidget(m_resultList);
m_keepOpenCB = new QCheckBox;
m_keepOpenCB->setText(i18n("Keep open after operation completed"));
m_keepOpenCB->setChecked(true);
layout->addWidget(m_keepOpenCB);
}
void ResultPage::Private::progress(int progress, int total)
{
Q_ASSERT(progress >= 0);
Q_ASSERT(total >= 0);
m_progressBar->setRange(0, total);
m_progressBar->setValue(progress);
}
void ResultPage::Private::allDone()
{
Q_ASSERT(m_tasks);
q->setAutoAdvance(!m_keepOpenCB->isChecked() && !m_tasks->errorOccurred());
- m_progressBar->setRange(0, 100);
- m_progressBar->setValue(100);
+ m_progressBar->setVisible(false);
m_tasks.reset();
const auto progressLabelByTagKeys{m_progressLabelByTag.keys()};
for (const QString &i : progressLabelByTagKeys) {
- if (!i.isEmpty()) {
- m_progressLabelByTag.value(i)->setText(i18n("%1: All operations completed.", i));
- } else {
- m_progressLabelByTag.value(i)->setText(i18n("All operations completed."));
- }
+ m_progressLabelByTag.value(i)->clear();
}
Q_EMIT q->completeChanged();
}
void ResultPage::Private::result(const std::shared_ptr<const Task::Result> &)
{
}
void ResultPage::Private::started(const std::shared_ptr<Task> &task)
{
Q_ASSERT(task);
const QString tag = task->tag();
QLabel *const label = labelForTag(tag);
Q_ASSERT(label);
if (tag.isEmpty()) {
label->setText(i18nc("number, operation description", "Operation %1: %2", m_tasks->numberOfCompletedTasks() + 1, task->label()));
} else {
label->setText(i18nc(R"(tag( "OpenPGP" or "CMS"), operation description)", "%1: %2", tag, task->label()));
}
}
ResultPage::ResultPage(QWidget *parent, Qt::WindowFlags flags)
: WizardPage(parent, flags)
, d(new Private(this))
{
setTitle(i18n("<b>Results</b>"));
}
ResultPage::~ResultPage()
{
}
bool ResultPage::keepOpenWhenDone() const
{
return d->m_keepOpenCB->isChecked();
}
void ResultPage::setKeepOpenWhenDone(bool keep)
{
d->m_keepOpenCB->setChecked(keep);
}
void ResultPage::setTaskCollection(const std::shared_ptr<TaskCollection> &coll)
{
Q_ASSERT(!d->m_tasks);
if (d->m_tasks == coll) {
return;
}
d->m_tasks = coll;
Q_ASSERT(d->m_tasks);
d->m_resultList->setTaskCollection(coll);
connect(d->m_tasks.get(), &TaskCollection::progress, this, [this](int current, int total) {
d->progress(current, total);
});
connect(d->m_tasks.get(), SIGNAL(done()), this, SLOT(allDone()));
connect(d->m_tasks.get(),
SIGNAL(result(std::shared_ptr<const Kleo::Crypto::Task::Result>)),
this,
SLOT(result(std::shared_ptr<const Kleo::Crypto::Task::Result>)));
connect(d->m_tasks.get(), SIGNAL(started(std::shared_ptr<Kleo::Crypto::Task>)), this, SLOT(started(std::shared_ptr<Kleo::Crypto::Task>)));
for (const std::shared_ptr<Task> &i : d->m_tasks->tasks()) { // create labels for all tags in collection
Q_ASSERT(i && d->labelForTag(i->tag()));
Q_UNUSED(i)
}
Q_EMIT completeChanged();
}
QLabel *ResultPage::Private::labelForTag(const QString &tag)
{
if (QLabel *const label = m_progressLabelByTag.value(tag)) {
return label;
}
auto label = new QLabel;
label->setTextFormat(Qt::RichText);
label->setWordWrap(true);
m_progressLabelLayout->addWidget(label);
m_progressLabelByTag.insert(tag, label);
return label;
}
bool ResultPage::isComplete() const
{
return d->m_tasks ? d->m_tasks->allTasksCompleted() : true;
}
#include "moc_resultpage.cpp"
diff --git a/src/crypto/signencrypttask.cpp b/src/crypto/signencrypttask.cpp
index 1ff1e2413..dc3fd786a 100644
--- a/src/crypto/signencrypttask.cpp
+++ b/src/crypto/signencrypttask.cpp
@@ -1,1040 +1,1058 @@
/* -*- mode: c++; c-basic-offset:4 -*-
crypto/signencrypttask.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "signencrypttask.h"
#include <utils/input.h>
#include <utils/kleo_assert.h>
#include <utils/output.h>
#include <utils/path-helper.h>
#include <Libkleo/AuditLogEntry>
#include <Libkleo/Formatting>
#include <Libkleo/KleoException>
#include <Libkleo/Stl_Util>
#include <QGpgME/Debug>
#include <QGpgME/EncryptArchiveJob>
#include <QGpgME/EncryptJob>
#include <QGpgME/Protocol>
#include <QGpgME/SignArchiveJob>
#include <QGpgME/SignEncryptArchiveJob>
#include <QGpgME/SignEncryptJob>
#include <QGpgME/SignJob>
#include <gpgme++/encryptionresult.h>
#include <gpgme++/key.h>
#include <gpgme++/signingresult.h>
#include <KLocalizedString>
#include "kleopatra_debug.h"
#include <QFileInfo>
#include <QPointer>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace GpgME;
namespace
{
class ErrorResult : public Task::Result
{
public:
ErrorResult(bool sign, bool encrypt, const Error &err, const QString &errStr, const QString &input, const QString &output, const AuditLogEntry &auditLog)
: Task::Result()
, m_sign(sign)
, m_encrypt(encrypt)
, m_error(err)
, m_errString(errStr)
, m_inputLabel(input)
, m_outputLabel(output)
, m_auditLog(auditLog)
{
}
QString overview() const override;
QString details() const override;
GpgME::Error error() const override
{
return m_error;
}
QString errorString() const override
{
return m_errString;
}
AuditLogEntry auditLog() const override
{
return m_auditLog;
}
private:
const bool m_sign;
const bool m_encrypt;
const Error m_error;
const QString m_errString;
const QString m_inputLabel;
const QString m_outputLabel;
const AuditLogEntry m_auditLog;
};
namespace
{
struct LabelAndError {
QString label;
QString errorString;
QStringList fileNames;
};
}
class SignEncryptFilesResult : public Task::Result
{
public:
SignEncryptFilesResult(const SigningResult &sr,
const EncryptionResult &er,
const LabelAndError &input,
const LabelAndError &output,
const AuditLogEntry &auditLog)
: Task::Result()
, m_sresult(sr)
, m_eresult(er)
, m_input{input}
, m_output{output}
, m_auditLog(auditLog)
{
qCDebug(KLEOPATRA_LOG) << "\ninputError :" << m_input.errorString << "\noutputError:" << m_output.errorString;
Q_ASSERT(!m_sresult.isNull() || !m_eresult.isNull());
}
QString overview() const override;
QString details() const override;
GpgME::Error error() const override;
QString errorString() const override;
AuditLogEntry auditLog() const override;
private:
const SigningResult m_sresult;
const EncryptionResult m_eresult;
const LabelAndError m_input;
const LabelAndError m_output;
const AuditLogEntry m_auditLog;
};
QString formatResultLine(const QStringList &inputs,
const QString &output,
bool sign,
bool encrypt,
bool signingFailed,
bool encryptionFailed,
const GpgME::Error &error)
{
Q_ASSERT(inputs.size() > 0);
Q_ASSERT(sign || encrypt);
if (error.isCanceled()) {
if (sign && encrypt) {
return i18nc("@info", "Signing and encryption canceled.");
}
if (sign) {
return i18nc("@info", "Signing canceled.");
}
return i18nc("@info", "Encryption canceled.");
}
if (signingFailed && encryptionFailed) {
if (inputs.size() == 1) {
return xi18nc("@info Failed to sign and encrypt <file>: <reason>",
"Failed to sign and encrypt <filename>%1</filename>: <emphasis strong='true'>%2</emphasis>",
inputs[0],
Formatting::errorAsString(error));
}
if (inputs.size() == 2) {
return xi18nc("@info Failed to sign and encrypt <file> and <file>: <reason>",
"Failed to sign and encrypt <filename>%1</filename> and <filename>%2</filename>: <emphasis strong='true'>%3</emphasis>",
inputs[0],
inputs[1],
Formatting::errorAsString(error));
}
return xi18ncp("@info Failed to sign and encrypt <file> and <n> other(s): <reason>",
"Failed to sign and encrypt <filename>%2</filename> and %1 other: <emphasis strong='true'>%3</emphasis>",
"Failed to sign and encrypt <filename>%2</filename> and %1 others: <emphasis strong='true'>%3</emphasis>",
inputs.size() - 1,
inputs[0],
Formatting::errorAsString(error));
}
if (signingFailed) {
if (inputs.size() == 1) {
return xi18nc("@info Failed to sign <file>: <reason>",
"Failed to sign <filename>%1</filename>: <emphasis strong='true'>%2</emphasis>",
inputs[0],
Formatting::errorAsString(error));
}
if (inputs.size() == 2) {
return xi18nc("@info Failed to sign <file> and <file>: <reason>",
"Failed to sign <filename>%1</filename> and <filename>%2</filename>: <emphasis strong='true'>%3</emphasis>",
inputs[0],
inputs[1],
Formatting::errorAsString(error));
}
return xi18ncp("@info Failed to sign <file> and <n> other(s): <reason>",
"Failed to sign <filename>%2</filename> and %1 other: <emphasis strong='true'>%3</emphasis>",
"Failed to sign <filename>%2</filename> and %1 others: <emphasis strong='true'>%3</emphasis>",
inputs.size() - 1,
inputs[0],
Formatting::errorAsString(error));
}
if (encryptionFailed) {
if (inputs.size() == 1) {
return xi18nc("@info Failed to encrypt <file>: <reason>",
"Failed to encrypt <filename>%1</filename>: <emphasis strong='true'>%2</emphasis>",
inputs[0],
Formatting::errorAsString(error));
}
if (inputs.size() == 2) {
return xi18nc("@info Failed to encrypt <file> and <file>: <reason>",
"Failed to encrypt <filename>%1</filename> and <filename>%2</filename>: <emphasis strong='true'>%3</emphasis>",
inputs[0],
inputs[1],
Formatting::errorAsString(error));
}
return xi18ncp("@info Failed to encrypt <file> and <n> other(s): <reason>",
"Failed to encrypt <filename>%2</filename> and %1 other: <emphasis strong='true'>%3</emphasis>",
"Failed to encrypt <filename>%2</filename> and %1 others: <emphasis strong='true'>%3</emphasis>",
inputs.size() - 1,
inputs[0],
Formatting::errorAsString(error));
}
if (sign && encrypt) {
if (inputs.size() == 1) {
return xi18nc("@info Successfully signed and encrypted <file> and saved it as <file>.",
"Successfully signed and encrypted <filename>%1</filename> and saved it as <filename>%2</filename>.",
inputs[0],
output);
}
if (inputs.size() == 2) {
return xi18nc("@info Successfully signed and encrypted <file> and <file> and saved it as <file>.",
"Successfully signed and encrypted <filename>%1</filename> and <filename>%2</filename> and saved it as <filename>%3</filename>.",
inputs[0],
inputs[1],
output);
}
return xi18ncp("@info Successfully signed and encrypted <file> and <n> other(s) as <file>.",
"Successfully signed and encrypted <filename>%2</filename> and %1 other and saved it as <filename>%3</filename>.",
"Successfully signed and encrypted <filename>%2</filename> and %1 others and saved it as <filename>%3</filename>.",
inputs.size() - 1,
inputs[0],
output);
}
if (sign) {
if (inputs.size() == 1) {
return xi18nc("@info Successfully signed <file> and saved the signature in <file>.",
"Successfully signed <filename>%1</filename> and saved the signature in <filename>%2</filename>.",
inputs[0],
output);
}
if (inputs.size() == 2) {
return xi18nc("@info Successfully signed <file> and <file> and saved the signature in <file>.",
"Successfully signed <filename>%1</filename> and <filename>%2</filename> and saved the signature in <filename>%3</filename>.",
inputs[0],
inputs[1],
output);
}
return xi18ncp("@info Successfully signed <file> and <n> other(s) and saved the signature in <file>.",
"Successfully signed <filename>%2</filename> and %1 other and saved the signature in <filename>%3</filename>.",
"Successfully signed <filename>%2</filename> and %1 others and saved the signature in <filename>%3</filename>.",
inputs.size() - 1,
inputs[0],
output);
}
if (inputs.size() == 1) {
return xi18nc("@info Successfully encrypted <file> and saved it as <file>.",
"Successfully encrypted <filename>%1</filename> and saved it as <filename>%2</filename>.",
inputs[0],
output);
}
if (inputs.size() == 2) {
return xi18nc("@info Successfully encrypted <file> and <file> and saved it as <file>.",
"Successfully encrypted <filename>%1</filename> and <filename>%2</filename> and saved it as <filename>%3</filename>.",
inputs[0],
inputs[1],
output);
}
return xi18ncp("@info Successfully encrypted <file> and <n> other(s) and saved it as <file>.",
"Successfully encrypted <filename>%2</filename> and %1 other and saved it as <filename>%3</filename>.",
"Successfully encrypted <filename>%2</filename> and %1 others and saved it as <filename>%3</filename>.",
inputs.size() - 1,
inputs[0],
output);
}
static QString escape(QString s)
{
s = s.toHtmlEscaped();
s.replace(QLatin1Char('\n'), QStringLiteral("<br>"));
return s;
}
static QString makeResultDetails(const SigningResult &result, const QString &inputError, const QString &outputError)
{
const Error err = result.error();
if (err.code() == GPG_ERR_EIO) {
if (!inputError.isEmpty()) {
return i18n("Input error: %1", escape(inputError));
} else if (!outputError.isEmpty()) {
return i18n("Output error: %1", escape(outputError));
}
}
if (err || err.isCanceled()) {
return Formatting::errorAsString(err).toHtmlEscaped();
}
return QString();
}
static QString makeResultDetails(const EncryptionResult &result, const QString &inputError, const QString &outputError)
{
const Error err = result.error();
if (err.code() == GPG_ERR_EIO) {
if (!inputError.isEmpty()) {
return i18n("Input error: %1", escape(inputError));
} else if (!outputError.isEmpty()) {
return i18n("Output error: %1", escape(outputError));
}
}
if (err || err.isCanceled()) {
return Formatting::errorAsString(err).toHtmlEscaped();
}
return {};
}
}
QString ErrorResult::overview() const
{
Q_ASSERT(m_error || m_error.isCanceled());
Q_ASSERT(m_sign || m_encrypt);
return formatResultLine({m_inputLabel}, m_outputLabel, m_sign, m_encrypt, true, true, m_error);
}
QString ErrorResult::details() const
{
return m_errString;
}
class SignEncryptTask::Private
{
friend class ::Kleo::Crypto::SignEncryptTask;
SignEncryptTask *const q;
public:
explicit Private(SignEncryptTask *qq);
private:
QString inputLabel() const;
QString outputLabel() const;
bool removeExistingOutputFile();
void startSignEncryptJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::SignJob> createSignJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::SignEncryptJob> createSignEncryptJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::EncryptJob> createEncryptJob(GpgME::Protocol proto);
void startSignEncryptArchiveJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::SignArchiveJob> createSignArchiveJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::SignEncryptArchiveJob> createSignEncryptArchiveJob(GpgME::Protocol proto);
std::unique_ptr<QGpgME::EncryptArchiveJob> createEncryptArchiveJob(GpgME::Protocol proto);
std::shared_ptr<const Task::Result> makeErrorResult(const Error &err, const QString &errStr, const AuditLogEntry &auditLog);
private:
void slotResult(const SigningResult &);
void slotResult(const SigningResult &, const EncryptionResult &);
void slotResult(const EncryptionResult &);
void slotResult(const QGpgME::Job *, const SigningResult &, const EncryptionResult &);
private:
std::shared_ptr<Input> input;
std::shared_ptr<Output> output;
QStringList inputFileNames;
QString outputFileName;
std::vector<Key> signers;
std::vector<Key> recipients;
SignEncryptTask::DataSource dataSource = SignEncryptTask::DataSource::Files;
bool sign : 1;
bool encrypt : 1;
bool detached : 1;
bool symmetric : 1;
bool clearsign : 1;
bool archive : 1;
QPointer<QGpgME::Job> job;
QString labelText;
std::shared_ptr<OverwritePolicy> m_overwritePolicy;
};
SignEncryptTask::Private::Private(SignEncryptTask *qq)
: q{qq}
, sign{true}
, encrypt{true}
, detached{false}
, clearsign{false}
, archive{false}
, m_overwritePolicy{new OverwritePolicy{OverwritePolicy::Ask}}
{
q->setAsciiArmor(true);
}
std::shared_ptr<const Task::Result> SignEncryptTask::Private::makeErrorResult(const Error &err, const QString &errStr, const AuditLogEntry &auditLog)
{
return std::shared_ptr<const ErrorResult>(new ErrorResult(sign, encrypt, err, errStr, inputLabel(), outputLabel(), auditLog));
}
SignEncryptTask::SignEncryptTask(QObject *p)
: Task(p)
, d(new Private(this))
{
}
SignEncryptTask::~SignEncryptTask()
{
}
void SignEncryptTask::setInputFileName(const QString &fileName)
{
kleo_assert(!d->job);
kleo_assert(!fileName.isEmpty());
d->inputFileNames = QStringList(fileName);
}
void SignEncryptTask::setInputFileNames(const QStringList &fileNames)
{
kleo_assert(!d->job);
kleo_assert(!fileNames.empty());
d->inputFileNames = fileNames;
}
void SignEncryptTask::setInput(const std::shared_ptr<Input> &input)
{
kleo_assert(!d->job);
kleo_assert(input);
d->input = input;
}
void SignEncryptTask::setOutput(const std::shared_ptr<Output> &output)
{
kleo_assert(!d->job);
kleo_assert(output);
d->output = output;
}
void SignEncryptTask::setOutputFileName(const QString &fileName)
{
kleo_assert(!d->job);
kleo_assert(!fileName.isEmpty());
d->outputFileName = fileName;
}
QString SignEncryptTask::outputFileName() const
{
return d->outputFileName;
}
void SignEncryptTask::setSigners(const std::vector<Key> &signers)
{
kleo_assert(!d->job);
d->signers = signers;
}
void SignEncryptTask::setRecipients(const std::vector<Key> &recipients)
{
kleo_assert(!d->job);
d->recipients = recipients;
}
void SignEncryptTask::setOverwritePolicy(const std::shared_ptr<OverwritePolicy> &policy)
{
kleo_assert(!d->job);
d->m_overwritePolicy = policy;
}
void SignEncryptTask::setSign(bool sign)
{
kleo_assert(!d->job);
d->sign = sign;
}
void SignEncryptTask::setEncrypt(bool encrypt)
{
kleo_assert(!d->job);
d->encrypt = encrypt;
}
void SignEncryptTask::setDetachedSignature(bool detached)
{
kleo_assert(!d->job);
d->detached = detached;
}
bool SignEncryptTask::detachedSignatureEnabled() const
{
return d->detached;
}
void SignEncryptTask::setEncryptSymmetric(bool symmetric)
{
kleo_assert(!d->job);
d->symmetric = symmetric;
}
void SignEncryptTask::setClearsign(bool clearsign)
{
kleo_assert(!d->job);
d->clearsign = clearsign;
}
void SignEncryptTask::setCreateArchive(bool archive)
{
kleo_assert(!d->job);
d->archive = archive;
}
Protocol SignEncryptTask::protocol() const
{
if (d->sign && !d->signers.empty()) {
return d->signers.front().protocol();
}
if (d->encrypt || d->symmetric) {
if (!d->recipients.empty()) {
return d->recipients.front().protocol();
} else {
return GpgME::OpenPGP; // symmetric OpenPGP encryption
}
}
throw Kleo::Exception(gpg_error(GPG_ERR_INTERNAL), i18n("Cannot determine protocol for task"));
}
QString SignEncryptTask::label() const
{
if (!d->labelText.isEmpty()) {
return d->labelText;
}
return d->inputLabel();
}
QString SignEncryptTask::tag() const
{
return Formatting::displayName(protocol());
}
unsigned long long SignEncryptTask::inputSize() const
{
return d->input ? d->input->size() : 0U;
}
static bool archiveJobsCanBeUsed(GpgME::Protocol protocol)
{
return (protocol == GpgME::OpenPGP) && QGpgME::SignEncryptArchiveJob::isSupported();
}
void SignEncryptTask::doStart()
{
kleo_assert(!d->job);
if (d->sign) {
kleo_assert(!d->signers.empty());
if (d->archive) {
kleo_assert(!d->detached && !d->clearsign);
}
}
const auto proto = protocol();
if (d->archive && archiveJobsCanBeUsed(proto)) {
d->startSignEncryptArchiveJob(proto);
} else {
d->startSignEncryptJob(proto);
}
}
QString SignEncryptTask::Private::inputLabel() const
{
if (input) {
return input->label();
}
if (!inputFileNames.empty()) {
const auto firstFile = QFileInfo{inputFileNames.front()}.fileName();
return inputFileNames.size() == 1 ? firstFile : i18nc("<name of first file>, ...", "%1, ...", firstFile);
}
return {};
}
QString SignEncryptTask::Private::outputLabel() const
{
return output ? output->label() : QFileInfo{outputFileName}.fileName();
}
bool SignEncryptTask::Private::removeExistingOutputFile()
{
if (QFile::exists(outputFileName)) {
bool fileRemoved = false;
// we should already have asked the user for overwrite permission
if (m_overwritePolicy && (m_overwritePolicy->policy() == OverwritePolicy::Overwrite)) {
qCDebug(KLEOPATRA_LOG) << __func__ << "going to remove file for overwriting" << outputFileName;
fileRemoved = QFile::remove(outputFileName);
if (!fileRemoved) {
qCDebug(KLEOPATRA_LOG) << __func__ << "removing file to overwrite failed";
}
} else {
qCDebug(KLEOPATRA_LOG) << __func__ << "we have no permission to overwrite" << outputFileName;
}
if (!fileRemoved) {
QMetaObject::invokeMethod(
q,
[this]() {
slotResult(nullptr, SigningResult{}, EncryptionResult{Error::fromCode(GPG_ERR_EEXIST)});
},
Qt::QueuedConnection);
return false;
}
}
return true;
}
void SignEncryptTask::Private::startSignEncryptJob(GpgME::Protocol proto)
{
#if QGPGME_FILE_JOBS_SUPPORT_DIRECT_FILE_IO
if (proto == GpgME::OpenPGP) {
// either input and output are both set (e.g. when encrypting the notepad),
// or they are both unset (when encrypting files)
kleo_assert((!input && !output) || (input && output));
} else {
kleo_assert(input);
if (!output) {
output = Output::createFromFile(outputFileName, m_overwritePolicy);
}
}
#else
kleo_assert(input);
if (!output) {
output = Output::createFromFile(outputFileName, m_overwritePolicy);
}
#endif
if (encrypt || symmetric) {
Context::EncryptionFlags flags{Context::None};
if (proto == GpgME::OpenPGP) {
flags = static_cast<Context::EncryptionFlags>(flags | Context::AlwaysTrust);
}
if (symmetric) {
flags = static_cast<Context::EncryptionFlags>(flags | Context::Symmetric);
qCDebug(KLEOPATRA_LOG) << "Adding symmetric flag";
}
if (sign) {
std::unique_ptr<QGpgME::SignEncryptJob> job = createSignEncryptJob(proto);
kleo_assert(job.get());
#if QGPGME_FILE_JOBS_SUPPORT_DIRECT_FILE_IO
if (proto == GpgME::OpenPGP && !input && !output) {
kleo_assert(inputFileNames.size() == 1);
job->setSigners(signers);
job->setRecipients(recipients);
job->setInputFile(inputFileNames.front());
job->setOutputFile(outputFileName);
job->setEncryptionFlags(flags);
if (!removeExistingOutputFile()) {
return;
}
job->startIt();
} else {
if (inputFileNames.size() == 1) {
job->setFileName(inputFileNames.front());
}
job->start(signers, recipients, input->ioDevice(), output->ioDevice(), flags);
}
#else
if (inputFileNames.size() == 1) {
job->setFileName(inputFileNames.front());
}
job->start(signers, recipients, input->ioDevice(), output->ioDevice(), flags);
#endif
this->job = job.release();
} else {
std::unique_ptr<QGpgME::EncryptJob> job = createEncryptJob(proto);
kleo_assert(job.get());
#if QGPGME_FILE_JOBS_SUPPORT_DIRECT_FILE_IO
if (proto == GpgME::OpenPGP && !input && !output) {
kleo_assert(inputFileNames.size() == 1);
job->setRecipients(recipients);
job->setInputFile(inputFileNames.front());
job->setOutputFile(outputFileName);
job->setEncryptionFlags(flags);
if (!removeExistingOutputFile()) {
return;
}
job->startIt();
} else {
if (inputFileNames.size() == 1) {
job->setFileName(inputFileNames.front());
}
job->start(recipients, input->ioDevice(), output->ioDevice(), flags);
}
#else
if (inputFileNames.size() == 1) {
job->setFileName(inputFileNames.front());
}
job->start(recipients, input->ioDevice(), output->ioDevice(), flags);
#endif
this->job = job.release();
}
} else if (sign) {
std::unique_ptr<QGpgME::SignJob> job = createSignJob(proto);
kleo_assert(job.get());
kleo_assert(!(detached && clearsign));
const GpgME::SignatureMode sigMode = detached ? GpgME::Detached : clearsign ? GpgME::Clearsigned : GpgME::NormalSignatureMode;
#if QGPGME_FILE_JOBS_SUPPORT_DIRECT_FILE_IO
if (proto == GpgME::OpenPGP && !input && !output) {
kleo_assert(inputFileNames.size() == 1);
job->setSigners(signers);
job->setInputFile(inputFileNames.front());
job->setOutputFile(outputFileName);
job->setSigningFlags(sigMode);
if (QFile::exists(outputFileName) && m_overwritePolicy && (m_overwritePolicy->policy() == OverwritePolicy::Append)) {
job->setAppendSignature(true);
} else if (!removeExistingOutputFile()) {
return;
}
job->startIt();
} else {
job->start(signers, input->ioDevice(), output->ioDevice(), sigMode);
}
#else
job->start(signers, input->ioDevice(), output->ioDevice(), sigMode);
#endif
this->job = job.release();
} else {
kleo_assert(!"Either 'sign' or 'encrypt' or 'symmetric' must be set!");
}
}
void SignEncryptTask::cancel()
{
qCDebug(KLEOPATRA_LOG) << this << __func__;
if (d->job) {
d->job->slotCancel();
}
}
std::unique_ptr<QGpgME::SignJob> SignEncryptTask::Private::createSignJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::SignJob> signJob(backend->signJob(q->asciiArmor(), /*textmode=*/false));
kleo_assert(signJob.get());
connect(signJob.get(), &QGpgME::Job::jobProgress, q, &SignEncryptTask::setProgress);
connect(signJob.get(), &QGpgME::SignJob::result, q, [this](const GpgME::SigningResult &signingResult, const QByteArray &) {
slotResult(signingResult);
});
return signJob;
}
std::unique_ptr<QGpgME::SignEncryptJob> SignEncryptTask::Private::createSignEncryptJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::SignEncryptJob> signEncryptJob(backend->signEncryptJob(q->asciiArmor(), /*textmode=*/false));
kleo_assert(signEncryptJob.get());
connect(signEncryptJob.get(), &QGpgME::Job::jobProgress, q, &SignEncryptTask::setProgress);
connect(signEncryptJob.get(),
&QGpgME::SignEncryptJob::result,
q,
[this](const GpgME::SigningResult &signingResult, const GpgME::EncryptionResult &encryptionResult) {
slotResult(signingResult, encryptionResult);
});
return signEncryptJob;
}
std::unique_ptr<QGpgME::EncryptJob> SignEncryptTask::Private::createEncryptJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::EncryptJob> encryptJob(backend->encryptJob(q->asciiArmor(), /*textmode=*/false));
kleo_assert(encryptJob.get());
connect(encryptJob.get(), &QGpgME::Job::jobProgress, q, &SignEncryptTask::setProgress);
connect(encryptJob.get(), &QGpgME::EncryptJob::result, q, [this](const GpgME::EncryptionResult &encryptionResult) {
slotResult(encryptionResult);
});
return encryptJob;
}
void SignEncryptTask::Private::startSignEncryptArchiveJob(GpgME::Protocol proto)
{
kleo_assert(!input);
kleo_assert(!output);
const auto baseDirectory = heuristicBaseDirectory(inputFileNames);
if (baseDirectory.isEmpty()) {
throw Kleo::Exception(GPG_ERR_CONFLICT, i18n("Cannot find common base directory for these files:\n%1", inputFileNames.join(QLatin1Char('\n'))));
}
qCDebug(KLEOPATRA_LOG) << "heuristicBaseDirectory(" << inputFileNames << ") ->" << baseDirectory;
const auto tempPaths = makeRelativeTo(baseDirectory, inputFileNames);
const auto relativePaths = std::vector<QString>{tempPaths.begin(), tempPaths.end()};
qCDebug(KLEOPATRA_LOG) << "relative paths:" << relativePaths;
if (encrypt || symmetric) {
Context::EncryptionFlags flags{Context::None};
if (proto == GpgME::OpenPGP) {
flags = static_cast<Context::EncryptionFlags>(flags | Context::AlwaysTrust);
}
if (symmetric) {
flags = static_cast<Context::EncryptionFlags>(flags | Context::Symmetric);
qCDebug(KLEOPATRA_LOG) << "Adding symmetric flag";
}
if (sign) {
labelText = i18nc("@info", "Creating signed and encrypted archive ...");
std::unique_ptr<QGpgME::SignEncryptArchiveJob> job = createSignEncryptArchiveJob(proto);
kleo_assert(job.get());
job->setBaseDirectory(baseDirectory);
job->setSigners(signers);
job->setRecipients(recipients);
job->setInputPaths(relativePaths);
job->setOutputFile(outputFileName);
job->setEncryptionFlags(flags);
if (!removeExistingOutputFile()) {
return;
}
job->startIt();
this->job = job.release();
} else {
labelText = i18nc("@info", "Creating encrypted archive ...");
std::unique_ptr<QGpgME::EncryptArchiveJob> job = createEncryptArchiveJob(proto);
kleo_assert(job.get());
job->setBaseDirectory(baseDirectory);
job->setRecipients(recipients);
job->setInputPaths(relativePaths);
job->setOutputFile(outputFileName);
job->setEncryptionFlags(flags);
if (!removeExistingOutputFile()) {
return;
}
job->startIt();
this->job = job.release();
}
} else if (sign) {
labelText = i18nc("@info", "Creating signed archive ...");
std::unique_ptr<QGpgME::SignArchiveJob> job = createSignArchiveJob(proto);
kleo_assert(job.get());
job->setBaseDirectory(baseDirectory);
job->setSigners(signers);
job->setInputPaths(relativePaths);
job->setOutputFile(outputFileName);
if (!removeExistingOutputFile()) {
return;
}
job->startIt();
this->job = job.release();
} else {
kleo_assert(!"Either 'sign' or 'encrypt' or 'symmetric' must be set!");
}
}
std::unique_ptr<QGpgME::SignArchiveJob> SignEncryptTask::Private::createSignArchiveJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::SignArchiveJob> signJob(backend->signArchiveJob(q->asciiArmor()));
auto job = signJob.get();
kleo_assert(job);
connect(job, &QGpgME::SignArchiveJob::dataProgress, q, &SignEncryptTask::setProgress);
connect(job, &QGpgME::SignArchiveJob::result, q, [this, job](const GpgME::SigningResult &signResult) {
slotResult(job, signResult, EncryptionResult{});
});
return signJob;
}
std::unique_ptr<QGpgME::SignEncryptArchiveJob> SignEncryptTask::Private::createSignEncryptArchiveJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::SignEncryptArchiveJob> signEncryptJob(backend->signEncryptArchiveJob(q->asciiArmor()));
auto job = signEncryptJob.get();
kleo_assert(job);
connect(job, &QGpgME::SignEncryptArchiveJob::dataProgress, q, &SignEncryptTask::setProgress);
connect(job, &QGpgME::SignEncryptArchiveJob::result, q, [this, job](const GpgME::SigningResult &signResult, const GpgME::EncryptionResult &encryptResult) {
slotResult(job, signResult, encryptResult);
});
return signEncryptJob;
}
std::unique_ptr<QGpgME::EncryptArchiveJob> SignEncryptTask::Private::createEncryptArchiveJob(GpgME::Protocol proto)
{
const QGpgME::Protocol *const backend = (proto == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
kleo_assert(backend);
std::unique_ptr<QGpgME::EncryptArchiveJob> encryptJob(backend->encryptArchiveJob(q->asciiArmor()));
auto job = encryptJob.get();
kleo_assert(job);
connect(job, &QGpgME::EncryptArchiveJob::dataProgress, q, &SignEncryptTask::setProgress);
connect(job, &QGpgME::EncryptArchiveJob::result, q, [this, job](const GpgME::EncryptionResult &encryptResult) {
slotResult(job, SigningResult{}, encryptResult);
});
return encryptJob;
}
void SignEncryptTask::Private::slotResult(const SigningResult &result)
{
slotResult(qobject_cast<const QGpgME::Job *>(q->sender()), result, EncryptionResult{});
}
void SignEncryptTask::Private::slotResult(const SigningResult &sresult, const EncryptionResult &eresult)
{
slotResult(qobject_cast<const QGpgME::Job *>(q->sender()), sresult, eresult);
}
void SignEncryptTask::Private::slotResult(const EncryptionResult &result)
{
slotResult(qobject_cast<const QGpgME::Job *>(q->sender()), SigningResult{}, result);
}
void SignEncryptTask::Private::slotResult(const QGpgME::Job *job, const SigningResult &sresult, const EncryptionResult &eresult)
{
qCDebug(KLEOPATRA_LOG) << q << __func__ << "job:" << job << "signing result:" << QGpgME::toLogString(sresult)
<< "encryption result:" << QGpgME::toLogString(eresult);
const AuditLogEntry auditLog = AuditLogEntry::fromJob(job);
if (input && input->failed()) {
if (output) {
output->cancel();
}
q->emitResult(makeErrorResult(Error::fromCode(GPG_ERR_EIO), i18n("Input error: %1", escape(input->errorString())), auditLog));
return;
} else if (sresult.error().code() || eresult.error().code()) {
if (output) {
output->cancel();
}
if (!outputFileName.isEmpty() && eresult.error().code() != GPG_ERR_EEXIST) {
// ensure that the output file is removed if the task was canceled or an error occurred;
// unless a "file exists" error occurred because this means that the file with the name
// of outputFileName wasn't created as result of this task
if (QFile::exists(outputFileName)) {
qCDebug(KLEOPATRA_LOG) << __func__ << "Removing output file" << outputFileName << "after error or cancel";
if (!QFile::remove(outputFileName)) {
qCDebug(KLEOPATRA_LOG) << __func__ << "Removing output file" << outputFileName << "failed";
}
}
}
} else {
try {
kleo_assert(!sresult.isNull() || !eresult.isNull());
if (output) {
output->finalize();
}
if (input) {
input->finalize();
}
} catch (const GpgME::Exception &e) {
q->emitResult(makeErrorResult(e.error(), QString::fromLocal8Bit(e.what()), auditLog));
return;
}
}
const LabelAndError inputInfo{inputLabel(), input ? input->errorString() : QString{}, inputFileNames};
const LabelAndError outputInfo{outputLabel(), output ? output->errorString() : QString{}, {}};
auto result = std::shared_ptr<Result>(new SignEncryptFilesResult(sresult, eresult, inputInfo, outputInfo, auditLog));
result->setDataSource(dataSource);
q->emitResult(result);
}
QString SignEncryptFilesResult::overview() const
{
if (dataSource() == Task::Notepad) {
if (!m_sresult.isNull() && m_sresult.error()) {
return i18nc("@info", "Failed to sign the notepad: %1", Formatting::errorAsString(m_sresult.error()));
}
if (!m_eresult.isNull() && m_eresult.error()) {
return i18nc("@info", "Failed to encrypt the notepad: %1", Formatting::errorAsString(m_eresult.error()));
}
if (!m_sresult.isNull() && !m_eresult.isNull()) {
return i18nc("@info", "Successfully encrypted and signed the notepad");
} else if (!m_eresult.isNull()) {
return i18nc("@info", "Successfully encrypted the notepad");
} else {
return i18nc("@info", "Successfully signed the notepad");
}
return {};
}
+ if (dataSource() == Task::Clipboard) {
+ if (!m_sresult.isNull() && m_sresult.error()) {
+ return i18nc("@info", "Failed to sign the clipboard: %1", Formatting::errorAsString(m_sresult.error()));
+ }
+ if (!m_eresult.isNull() && m_eresult.error()) {
+ return i18nc("@info", "Failed to encrypt the clipboard: %1", Formatting::errorAsString(m_eresult.error()));
+ }
+
+ if (!m_sresult.isNull() && !m_eresult.isNull()) {
+ return i18nc("@info", "Successfully encrypted and signed the clipboard");
+ } else if (!m_eresult.isNull()) {
+ return i18nc("@info", "Successfully encrypted the clipboard");
+ } else {
+ return i18nc("@info", "Successfully signed the clipboard");
+ }
+ return {};
+ }
+
return formatResultLine(m_input.fileNames,
m_output.label,
!m_sresult.isNull(),
!m_eresult.isNull(),
m_sresult.error(),
m_eresult.error(),
m_sresult.error().code() ? m_sresult.error() : m_eresult.error());
}
QString SignEncryptFilesResult::details() const
{
return errorString();
}
GpgME::Error SignEncryptFilesResult::error() const
{
if (m_sresult.error().code()) {
return m_sresult.error();
}
if (m_eresult.error().code()) {
return m_eresult.error();
}
return {};
}
QString SignEncryptFilesResult::errorString() const
{
const bool sign = !m_sresult.isNull();
const bool encrypt = !m_eresult.isNull();
kleo_assert(sign || encrypt);
if (sign && encrypt) {
return m_sresult.error().code() ? makeResultDetails(m_sresult, m_input.errorString, m_output.errorString)
: m_eresult.error().code() ? makeResultDetails(m_eresult, m_input.errorString, m_output.errorString)
: QString();
}
return sign ? makeResultDetails(m_sresult, m_input.errorString, m_output.errorString) //
: makeResultDetails(m_eresult, m_input.errorString, m_output.errorString);
}
AuditLogEntry SignEncryptFilesResult::auditLog() const
{
return m_auditLog;
}
void SignEncryptTask::setDataSource(Task::DataSource dataSource)
{
d->dataSource = dataSource;
}
#include "moc_signencrypttask.cpp"
diff --git a/src/dialogs/signencryptclipboarddialog.cpp b/src/dialogs/signencryptclipboarddialog.cpp
new file mode 100644
index 000000000..b167ac8e5
--- /dev/null
+++ b/src/dialogs/signencryptclipboarddialog.cpp
@@ -0,0 +1,232 @@
+// SPDX-FileCopyrightText: 2024 g10 Code GmbH
+// SPDX-FileContributor: Tobias Fella <tobias.fella@gnupg.com>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "signencryptclipboarddialog.h"
+
+#include "crypto/gui/resultpage.h"
+#include "crypto/gui/signencryptwidget.h"
+#include "crypto/signencrypttask.h"
+#include "crypto/taskcollection.h"
+#include "utils/input.h"
+#include "utils/output.h"
+
+#include <Libkleo/Compliance>
+
+#include <gpgme++/key.h>
+
+#include <KAdjustingScrollArea>
+#include <KLocalizedString>
+#include <KMessageBox>
+#include <KTitleWidget>
+
+#include <QApplication>
+#include <QClipboard>
+#include <QDialogButtonBox>
+#include <QMimeData>
+#include <QPushButton>
+#include <QStackedLayout>
+#include <QVBoxLayout>
+
+using namespace Kleo;
+using namespace Kleo::Crypto;
+using namespace Kleo::Commands;
+
+using namespace Qt::Literals::StringLiterals;
+
+class SignEncryptPage : public QWidget
+{
+public:
+ explicit SignEncryptPage(Kleo::Commands::SignEncryptClipboardCommand::Mode mode, QWidget *parent = nullptr)
+ : QWidget(parent)
+ {
+ auto mainLayout = new QVBoxLayout(this);
+ mainLayout->setContentsMargins({});
+ auto scrollArea = new KAdjustingScrollArea;
+ mainLayout->addWidget(scrollArea);
+
+ auto wrapper = new QWidget;
+ scrollArea->setWidget(wrapper);
+
+ scrollArea->setFrameStyle(0);
+ auto vLay = new QVBoxLayout(wrapper);
+ vLay->setContentsMargins({});
+ m_widget = new SignEncryptWidget(this, true);
+ m_widget->setSigningChecked(mode == SignEncryptClipboardCommand::Mode::Sign || mode == SignEncryptClipboardCommand::Mode::SignEncrypt);
+ m_widget->setEncryptionChecked(mode == SignEncryptClipboardCommand::Mode::Encrypt || mode == SignEncryptClipboardCommand::Mode::SignEncrypt);
+ vLay->addWidget(m_widget);
+ }
+
+ std::vector<GpgME::Key> recipients() const
+ {
+ return m_widget->recipients();
+ }
+
+ GpgME::Key signer() const
+ {
+ const auto key = m_widget->signUserId().parent();
+ if (!key.isNull()) {
+ return key;
+ }
+ return {};
+ }
+
+ SignEncryptWidget *signEncryptWidget() const
+ {
+ return m_widget;
+ }
+
+ bool isDeVsAndValid() const
+ {
+ return m_widget->isDeVsAndValid();
+ }
+
+ bool validatePage()
+ {
+ if (DeVSCompliance::isActive() && !DeVSCompliance::isCompliant()) {
+ return false;
+ }
+
+ return m_widget->isComplete();
+ }
+
+private:
+ SignEncryptWidget *m_widget;
+};
+
+SignEncryptClipboardDialog::SignEncryptClipboardDialog(Kleo::Commands::SignEncryptClipboardCommand::Mode mode)
+ : QDialog(nullptr)
+{
+ setWindowTitle(i18nc("@title:dialog", "Sign/Encrypt Clipboard"));
+ auto layout = new QVBoxLayout(this);
+
+ auto title = new KTitleWidget;
+ title->setText(i18nc("@title", "Sign/Encrypt Clipboard"));
+ layout->addWidget(title);
+
+ auto stackedLayout = new QStackedLayout;
+
+ auto signEncryptPage = new SignEncryptPage(mode, this);
+
+ stackedLayout->addWidget(signEncryptPage);
+
+ auto resultPage = new Kleo::Crypto::Gui::ResultPage;
+ stackedLayout->addWidget(resultPage);
+
+ layout->addLayout(stackedLayout);
+
+ auto buttons = new QDialogButtonBox;
+
+ QPushButton *labelButton = nullptr;
+
+ if (DeVSCompliance::isActive()) {
+ /* We use a custom button to display a label next to the
+ buttons. */
+ labelButton = buttons->addButton(QString(), QDialogButtonBox::ActionRole);
+ /* We style the button so that it looks and acts like a
+ label. */
+ 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, [this]() {
+ reject();
+ });
+
+ layout->addWidget(buttons);
+
+ connect(signEncryptPage->signEncryptWidget(), &SignEncryptWidget::operationChanged, this, [okButton, signEncryptPage, 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() && signEncryptPage->isDeVsAndValid();
+ DeVSCompliance::decorate(okButton, de_vs);
+
+ 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(signEncryptPage->validatePage());
+ });
+
+ connect(okButton, &QPushButton::clicked, this, [this, signEncryptPage, stackedLayout, resultPage, okButton, title]() {
+ if (stackedLayout->currentIndex() == 0) {
+ m_task = std::make_shared<SignEncryptTask>();
+ m_task->setDataSource(Task::Clipboard);
+ auto output = Output::createFromClipboard();
+ m_task->setInput(m_input);
+ m_task->setOutput(output);
+ title->setText(i18nc("@title", "Results"));
+
+ auto recipients = signEncryptPage->recipients();
+ auto signer = signEncryptPage->signer();
+
+ m_task->setRecipients(recipients);
+ m_task->setEncrypt(!recipients.empty());
+ m_task->setSigners({signer});
+ m_task->setSign(!signer.isNull());
+ m_task->setClearsign(!signer.isNull() && recipients.empty() && signer.protocol() == GpgME::OpenPGP);
+ m_task->setEncryptSymmetric(signEncryptPage->signEncryptWidget()->encryptSymmetric());
+ m_task->setAsciiArmor(true);
+
+ stackedLayout->setCurrentIndex(1);
+ okButton->setText(i18nc("@action:button", "Finish"));
+
+ std::shared_ptr<TaskCollection> coll(new TaskCollection);
+ coll->setTasks({m_task});
+ resultPage->setTaskCollection(coll);
+ m_task->start();
+ } else {
+ accept();
+ }
+ });
+
+ auto onClipboardAvailable = [this]() {
+ const auto mimeData = qApp->clipboard()->mimeData();
+ if (!mimeData->hasFormat("text/plain"_L1)) {
+ KMessageBox::information(this, i18nc("@info", "The clipboard does not contain text."));
+ QMetaObject::invokeMethod(this, &QDialog::reject, Qt::QueuedConnection);
+ } else {
+ m_input = Input::createFromClipboard();
+ }
+ };
+
+ if (qApp->platformName() != "wayland"_L1) {
+ onClipboardAvailable();
+ } else {
+ connect(
+ qApp->clipboard(),
+ &QClipboard::dataChanged,
+ this,
+ [onClipboardAvailable]() {
+ onClipboardAvailable();
+ },
+ Qt::SingleShotConnection);
+ }
+}
+
+SignEncryptClipboardDialog::~SignEncryptClipboardDialog()
+{
+ if (m_task) {
+ m_task->cancel();
+ }
+}
diff --git a/src/dialogs/signencryptclipboarddialog.h b/src/dialogs/signencryptclipboarddialog.h
new file mode 100644
index 000000000..e6786e655
--- /dev/null
+++ b/src/dialogs/signencryptclipboarddialog.h
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: 2024 g10 Code GmbH
+// SPDX-FileContributor: Tobias Fella <tobias.fella@gnupg.com>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "commands/signencryptclipboardcommand.h"
+
+#include <QDialog>
+
+namespace Kleo
+{
+class Input;
+namespace Crypto
+{
+class SignEncryptTask;
+}
+}
+
+class SignEncryptClipboardDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SignEncryptClipboardDialog(Kleo::Commands::SignEncryptClipboardCommand::Mode mode);
+ ~SignEncryptClipboardDialog() override;
+
+private:
+ std::shared_ptr<Kleo::Crypto::SignEncryptTask> m_task;
+ std::shared_ptr<Kleo::Input> m_input;
+};
diff --git a/src/systrayicon.cpp b/src/systrayicon.cpp
index 4317a0ce9..e92dc3cac 100644
--- a/src/systrayicon.cpp
+++ b/src/systrayicon.cpp
@@ -1,225 +1,221 @@
/* -*- mode: c++; c-basic-offset:4 -*-
systemtrayicon.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "systrayicon.h"
#ifndef QT_NO_SYSTEMTRAYICON
#include "kleopatraapplication.h"
#include "mainwindow.h"
#include <smartcard/readerstatus.h>
#include <utils/clipboardmenu.h>
-#include <commands/decryptverifyclipboardcommand.h>
-#include <commands/encryptclipboardcommand.h>
-#include <commands/importcertificatefromclipboardcommand.h>
#include <commands/setinitialpincommand.h>
-#include <commands/signclipboardcommand.h>
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KActionMenu>
#include <KLocalizedString>
#include <QEventLoopLocker>
#include <QIcon>
#include <QAction>
#include <QApplication>
#include <QMenu>
#include <QPointer>
#include <QSignalBlocker>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::SmartCard;
class SysTrayIcon::Private
{
friend class ::SysTrayIcon;
SysTrayIcon *const q;
public:
explicit Private(SysTrayIcon *qq);
~Private();
private:
void slotAbout()
{
if (!aboutDialog) {
aboutDialog = new KAboutApplicationDialog(KAboutData::applicationData());
aboutDialog->setAttribute(Qt::WA_DeleteOnClose);
}
if (aboutDialog->isVisible()) {
aboutDialog->raise();
} else {
aboutDialog->show();
}
}
void enableDisableActions()
{
openCertificateManagerAction.setEnabled(!q->mainWindow() || !q->mainWindow()->isVisible());
setInitialPinAction.setEnabled(!firstCardWithNullPin.empty());
q->setAttentionWanted(!firstCardWithNullPin.empty() && !q->attentionWindow());
}
void slotSetInitialPin()
{
if (!firstCardWithNullPin.empty()) {
auto cmd = new SetInitialPinCommand(firstCardWithNullPin);
q->setAttentionWindow(cmd->dialog());
startCommand(cmd);
}
}
void startCommand(Command *cmd)
{
Q_ASSERT(cmd);
cmd->setParent(q->mainWindow());
cmd->start();
}
private:
std::string firstCardWithNullPin;
QMenu menu;
QAction openCertificateManagerAction;
QAction configureAction;
QAction aboutAction;
QAction quitAction;
ClipboardMenu clipboardMenu;
QMenu cardMenu;
QAction updateCardStatusAction;
QAction setInitialPinAction;
QPointer<KAboutApplicationDialog> aboutDialog;
};
SysTrayIcon::Private::Private(SysTrayIcon *qq)
: q(qq)
, menu()
, openCertificateManagerAction(i18nc("@action:inmenu", "&Open Certificate Manager..."), q)
, configureAction(QIcon::fromTheme(QStringLiteral("configure")),
xi18nc("@action:inmenu", "&Configure <application>%1</application>...", KAboutData::applicationData().displayName()),
q)
, aboutAction(QIcon::fromTheme(QStringLiteral("kleopatra")),
xi18nc("@action:inmenu", "&About <application>%1</application>...", KAboutData::applicationData().displayName()),
q)
, quitAction(QIcon::fromTheme(QStringLiteral("application-exit")),
xi18nc("@action:inmenu", "&Shutdown <application>%1</application>", KAboutData::applicationData().displayName()),
q)
, clipboardMenu(q)
, cardMenu(i18nc("@title:menu", "SmartCard"))
, updateCardStatusAction(i18nc("@action:inmenu", "Update Card Status"), q)
, setInitialPinAction(i18nc("@action:inmenu", "Set NetKey v3 Initial PIN..."), q)
, aboutDialog()
{
#ifdef Q_OS_WIN
q->setNormalIcon(QIcon::fromTheme(QStringLiteral("kleopatra")));
#else
q->setNormalIcon(QIcon::fromTheme(QStringLiteral("kleopatra-symbolic")));
#endif
q->setAttentionIcon(QIcon::fromTheme(QStringLiteral("auth-sim-locked")));
Q_SET_OBJECT_NAME(menu);
Q_SET_OBJECT_NAME(openCertificateManagerAction);
Q_SET_OBJECT_NAME(configureAction);
Q_SET_OBJECT_NAME(aboutAction);
Q_SET_OBJECT_NAME(quitAction);
Q_SET_OBJECT_NAME(clipboardMenu);
Q_SET_OBJECT_NAME(cardMenu);
Q_SET_OBJECT_NAME(setInitialPinAction);
connect(&openCertificateManagerAction, SIGNAL(triggered()), qApp, SLOT(openOrRaiseMainWindow()));
connect(&configureAction, SIGNAL(triggered()), qApp, SLOT(openOrRaiseConfigDialog()));
connect(&aboutAction, SIGNAL(triggered()), q, SLOT(slotAbout()));
connect(&quitAction, &QAction::triggered, QCoreApplication::instance(), &QCoreApplication::quit);
connect(&updateCardStatusAction, &QAction::triggered, ReaderStatus::instance(), &ReaderStatus::updateStatus);
connect(&setInitialPinAction, SIGNAL(triggered()), q, SLOT(slotSetInitialPin()));
menu.addAction(&openCertificateManagerAction);
menu.addAction(&configureAction);
menu.addAction(&aboutAction);
menu.addSeparator();
menu.addMenu(clipboardMenu.clipboardMenu()->menu());
menu.addSeparator();
menu.addMenu(&cardMenu);
cardMenu.addAction(&updateCardStatusAction);
cardMenu.addAction(&setInitialPinAction);
menu.addSeparator();
menu.addAction(&quitAction);
q->setContextMenu(&menu);
clipboardMenu.setMainWindow(q->mainWindow());
}
SysTrayIcon::Private::~Private()
{
}
SysTrayIcon::SysTrayIcon(QObject *p)
: SystemTrayIcon(p)
, d(new Private(this))
{
slotEnableDisableActions();
}
SysTrayIcon::~SysTrayIcon()
{
}
MainWindow *SysTrayIcon::mainWindow() const
{
return static_cast<MainWindow *>(SystemTrayIcon::mainWindow());
}
QDialog *SysTrayIcon::attentionWindow() const
{
return static_cast<QDialog *>(SystemTrayIcon::attentionWindow());
}
void SysTrayIcon::doActivated()
{
if (const QWidget *const aw = attentionWindow())
if (aw->isVisible()) {
return; // ignore clicks while an attention window is open.
}
if (!d->firstCardWithNullPin.empty()) {
d->slotSetInitialPin();
} else {
// Toggle visibility of MainWindow
KleopatraApplication::instance()->toggleMainWindowVisibility();
}
}
void SysTrayIcon::setFirstCardWithNullPin(const std::string &serialNumber)
{
if (d->firstCardWithNullPin == serialNumber) {
return;
}
d->firstCardWithNullPin = serialNumber;
slotEnableDisableActions();
}
void SysTrayIcon::slotEnableDisableActions()
{
d->enableDisableActions();
}
#include "moc_systrayicon.cpp"
#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/utils/clipboardmenu.cpp b/src/utils/clipboardmenu.cpp
index 371ce0db9..4d9b614e7 100644
--- a/src/utils/clipboardmenu.cpp
+++ b/src/utils/clipboardmenu.cpp
@@ -1,146 +1,111 @@
/*
SPDX-FileCopyrightText: 2014-2021 Laurent Montel <montel@kde.org>
SPDX-License-Identifier: GPL-2.0-only
*/
#include <config-kleopatra.h>
#include "clipboardmenu.h"
#include "kdtoolsglobal.h"
#include "mainwindow.h"
#include <settings.h>
#include <commands/decryptverifyclipboardcommand.h>
-#include <commands/encryptclipboardcommand.h>
#include <commands/importcertificatefromclipboardcommand.h>
-#include <commands/signclipboardcommand.h>
+#include <commands/signencryptclipboardcommand.h>
#include <Libkleo/Algorithm>
#include <Libkleo/Compat>
#include <Libkleo/KeyCache>
#include <KActionMenu>
#include <KLocalizedString>
#include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QSignalBlocker>
#include <gpgme++/key.h>
using namespace Kleo;
using namespace Kleo::Commands;
ClipboardMenu::ClipboardMenu(QObject *parent)
: QObject{parent}
{
mClipboardMenu = new KActionMenu(i18n("Clipboard"), this);
mImportClipboardAction = new QAction(i18nc("@action", "Certificate Import"), this);
mEncryptClipboardAction = new QAction(i18nc("@action", "Encrypt..."), this);
- const Kleo::Settings settings{};
- if (settings.cmsEnabled() && settings.cmsSigningAllowed()) {
- mSmimeSignClipboardAction = new QAction(i18nc("@action", "S/MIME-Sign..."), this);
- Q_SET_OBJECT_NAME(mSmimeSignClipboardAction);
- }
- mOpenPGPSignClipboardAction = new QAction(i18nc("@action", "OpenPGP-Sign..."), this);
+ mSignEncryptClipboardAction = new QAction(i18nc("@action", "Sign/Encrypt..."), this);
+ mSignClipboardAction = new QAction(i18nc("@action", "Sign..."), this);
mDecryptVerifyClipboardAction = new QAction(i18nc("@action", "Decrypt/Verify..."), this);
Q_SET_OBJECT_NAME(mClipboardMenu);
Q_SET_OBJECT_NAME(mImportClipboardAction);
Q_SET_OBJECT_NAME(mEncryptClipboardAction);
- Q_SET_OBJECT_NAME(mOpenPGPSignClipboardAction);
+ Q_SET_OBJECT_NAME(mSignClipboardAction);
+ Q_SET_OBJECT_NAME(mSignEncryptClipboardAction);
Q_SET_OBJECT_NAME(mDecryptVerifyClipboardAction);
connect(mImportClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotImportClipboard);
connect(mEncryptClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotEncryptClipboard);
- if (mSmimeSignClipboardAction) {
- connect(mSmimeSignClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotSMIMESignClipboard);
- }
- connect(mOpenPGPSignClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotOpenPGPSignClipboard);
+ connect(mSignClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotSignClipboard);
+ connect(mSignEncryptClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotSignEncryptClipboard);
connect(mDecryptVerifyClipboardAction, &QAction::triggered, this, &ClipboardMenu::slotDecryptVerifyClipboard);
mClipboardMenu->addAction(mImportClipboardAction);
mClipboardMenu->addAction(mEncryptClipboardAction);
- if (mSmimeSignClipboardAction) {
- mClipboardMenu->addAction(mSmimeSignClipboardAction);
- }
- mClipboardMenu->addAction(mOpenPGPSignClipboardAction);
+ mClipboardMenu->addAction(mSignClipboardAction);
+ mClipboardMenu->addAction(mSignEncryptClipboardAction);
mClipboardMenu->addAction(mDecryptVerifyClipboardAction);
- connect(QApplication::clipboard(), &QClipboard::changed, this, &ClipboardMenu::slotEnableDisableActions);
- connect(KeyCache::instance().get(), &KeyCache::keyListingDone, this, &ClipboardMenu::slotEnableDisableActions);
- slotEnableDisableActions();
}
ClipboardMenu::~ClipboardMenu() = default;
void ClipboardMenu::setMainWindow(MainWindow *window)
{
mWindow = window;
}
KActionMenu *ClipboardMenu::clipboardMenu() const
{
return mClipboardMenu;
}
void ClipboardMenu::startCommand(Command *cmd)
{
Q_ASSERT(cmd);
cmd->setParent(mWindow);
cmd->start();
}
void ClipboardMenu::slotImportClipboard()
{
startCommand(new ImportCertificateFromClipboardCommand(nullptr));
}
void ClipboardMenu::slotEncryptClipboard()
{
- startCommand(new EncryptClipboardCommand(nullptr));
+ startCommand(new SignEncryptClipboardCommand(SignEncryptClipboardCommand::Mode::Encrypt));
}
-void ClipboardMenu::slotOpenPGPSignClipboard()
+void ClipboardMenu::slotSignClipboard()
{
- startCommand(new SignClipboardCommand(GpgME::OpenPGP, nullptr));
+ startCommand(new SignEncryptClipboardCommand(SignEncryptClipboardCommand::Mode::Sign));
}
-void ClipboardMenu::slotSMIMESignClipboard()
+void ClipboardMenu::slotSignEncryptClipboard()
{
- startCommand(new SignClipboardCommand(GpgME::CMS, nullptr));
+ startCommand(new SignEncryptClipboardCommand(SignEncryptClipboardCommand::Mode::SignEncrypt));
}
void ClipboardMenu::slotDecryptVerifyClipboard()
{
startCommand(new DecryptVerifyClipboardCommand(nullptr));
}
-namespace
-{
-
-bool hasSigningKeys(GpgME::Protocol protocol)
-{
- if (!KeyCache::instance()->initialized()) {
- return false;
- }
- return std::ranges::any_of(KeyCache::instance()->keys(), [protocol](const auto &k) {
- return k.hasSecret() && Kleo::keyHasSign(k) && (k.protocol() == protocol);
- });
-}
-
-}
-
-void ClipboardMenu::slotEnableDisableActions()
-{
- mOpenPGPSignClipboardAction->setEnabled(hasSigningKeys(GpgME::OpenPGP));
- if (mSmimeSignClipboardAction) {
- Settings settings;
- mSmimeSignClipboardAction->setEnabled(settings.cmsEnabled() && settings.cmsSigningAllowed() && hasSigningKeys(GpgME::CMS));
- }
-}
-
#include "moc_clipboardmenu.cpp"
diff --git a/src/utils/clipboardmenu.h b/src/utils/clipboardmenu.h
index 1e0cfd51f..692a12451 100644
--- a/src/utils/clipboardmenu.h
+++ b/src/utils/clipboardmenu.h
@@ -1,50 +1,49 @@
/*
SPDX-FileCopyrightText: 2014-2021 Laurent Montel <montel@kde.org>
SPDX-License-Identifier: GPL-2.0-only
*/
#pragma once
#include <QObject>
#include <QPointer>
class KActionMenu;
class QAction;
class MainWindow;
namespace Kleo
{
class Command;
}
class ClipboardMenu : public QObject
{
Q_OBJECT
public:
explicit ClipboardMenu(QObject *parent = nullptr);
~ClipboardMenu() override;
void setMainWindow(MainWindow *window);
KActionMenu *clipboardMenu() const;
private Q_SLOTS:
void slotImportClipboard();
+ void slotSignEncryptClipboard();
+ void slotSignClipboard();
void slotEncryptClipboard();
- void slotOpenPGPSignClipboard();
- void slotSMIMESignClipboard();
void slotDecryptVerifyClipboard();
- void slotEnableDisableActions();
private:
void startCommand(Kleo::Command *cmd);
QPointer<KActionMenu> mClipboardMenu;
QPointer<QAction> mImportClipboardAction;
+ QPointer<QAction> mSignClipboardAction;
QPointer<QAction> mEncryptClipboardAction;
- QPointer<QAction> mSmimeSignClipboardAction;
- QPointer<QAction> mOpenPGPSignClipboardAction;
+ QPointer<QAction> mSignEncryptClipboardAction;
QPointer<QAction> mDecryptVerifyClipboardAction;
QPointer<MainWindow> mWindow;
};

File Metadata

Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:38 PM (1 d, 9 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
8c/c0/e3dee5267948a784b1d43d89fa5b

Event Timeline