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