diff --git a/autotests/newkeyapprovaldialogtest.cpp b/autotests/newkeyapprovaldialogtest.cpp
index 48e9fa11..7dbe670e 100644
--- a/autotests/newkeyapprovaldialogtest.cpp
+++ b/autotests/newkeyapprovaldialogtest.cpp
@@ -1,1116 +1,1129 @@
 /*
     autotests/newkeyapprovaldialogtest.cpp
 
     This file is part of libkleopatra's test suite.
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <Libkleo/Compliance>
 #include <Libkleo/Formatting>
 #include <Libkleo/KeyCache>
 #include <Libkleo/KeySelectionCombo>
 #include <Libkleo/NewKeyApprovalDialog>
 #include <Libkleo/Predicates>
 #include <Libkleo/Test>
 
 #include <QCheckBox>
 #include <QGroupBox>
 #include <QLabel>
 #include <QObject>
 #include <QPushButton>
 #include <QRadioButton>
 #include <QSignalSpy>
 #include <QTest>
 
 #include <gpgme++/key.h>
 
 #include <gpgme.h>
 
 #include <memory>
 #include <set>
 
+#include <gpgme++/gpgmepp_version.h>
+#if GPGMEPP_VERSION >= 0x11700 // 1.23.0
+#define GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE 1
+#else
+#define GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE 0
+#endif
+
 using namespace Kleo;
 
 namespace QTest
 {
 template<>
 inline char *toString(const bool &t)
 {
     return t ? qstrdup("true") : qstrdup("false");
 }
 
 template<>
 inline bool qCompare(bool const &t1, bool const &t2, const char *actual, const char *expected, const char *file, int line)
 {
     return compare_helper(t1 == t2, "Compared values are not the same", toString(t1), toString(t2), actual, expected, file, line);
 }
 
 template<>
 inline char *toString(const GpgME::Protocol &t)
 {
     return qstrdup(Formatting::displayName(t).toLocal8Bit().constData());
 }
 
 template<>
 inline bool qCompare(GpgME::Protocol const &t1, GpgME::Protocol const &t2, const char *actual, const char *expected, const char *file, int line)
 {
     return compare_helper(t1 == t2, "Compared values are not the same", toString(t1), toString(t2), actual, expected, file, line);
 }
 }
 
 namespace
 {
 
 // copied from NewKeyApprovalDialog::Private
 enum Action {
     Unset,
     GenerateKey,
     IgnoreKey,
 };
 
 auto mapValidity(GpgME::UserID::Validity validity)
 {
     switch (validity) {
     default:
     case GpgME::UserID::Unknown:
         return GPGME_VALIDITY_UNKNOWN;
     case GpgME::UserID::Undefined:
         return GPGME_VALIDITY_UNDEFINED;
     case GpgME::UserID::Never:
         return GPGME_VALIDITY_NEVER;
     case GpgME::UserID::Marginal:
         return GPGME_VALIDITY_MARGINAL;
     case GpgME::UserID::Full:
         return GPGME_VALIDITY_FULL;
     case GpgME::UserID::Ultimate:
         return GPGME_VALIDITY_ULTIMATE;
     }
 }
 
 // copied from gpgme; slightly modified
 void _gpgme_key_add_subkey(gpgme_key_t key, gpgme_subkey_t *r_subkey)
 {
     gpgme_subkey_t subkey;
 
     subkey = static_cast<gpgme_subkey_t>(calloc(1, sizeof *subkey));
     Q_ASSERT(subkey);
     subkey->keyid = subkey->_keyid;
     subkey->_keyid[16] = '\0';
 
     if (!key->subkeys) {
         key->subkeys = subkey;
     }
     if (key->_last_subkey) {
         key->_last_subkey->next = subkey;
     }
     key->_last_subkey = subkey;
 
     *r_subkey = subkey;
 }
 
 GpgME::Key createTestKey(const char *uid,
                          GpgME::Protocol protocol = GpgME::UnknownProtocol,
                          KeyCache::KeyUsage usage = KeyCache::KeyUsage::AnyUsage,
                          GpgME::UserID::Validity validity = GpgME::UserID::Full)
 {
     static int count = 0;
     count++;
 
     gpgme_key_t key;
     gpgme_key_from_uid(&key, uid);
     Q_ASSERT(key);
     Q_ASSERT(key->uids);
     if (protocol != GpgME::UnknownProtocol) {
         key->protocol = protocol == GpgME::OpenPGP ? GPGME_PROTOCOL_OpenPGP : GPGME_PROTOCOL_CMS;
     }
     const QByteArray fingerprint = QByteArray::number(count, 16).rightJustified(40, '0');
     key->fpr = strdup(fingerprint.constData());
     key->revoked = 0;
     key->expired = 0;
     key->disabled = 0;
     key->can_encrypt = int(usage == KeyCache::KeyUsage::AnyUsage || usage == KeyCache::KeyUsage::Encrypt);
     key->can_sign = int(usage == KeyCache::KeyUsage::AnyUsage || usage == KeyCache::KeyUsage::Sign);
+#if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
+    key->has_encrypt = int(usage == KeyCache::KeyUsage::AnyUsage || usage == KeyCache::KeyUsage::Encrypt);
+    key->has_sign = int(usage == KeyCache::KeyUsage::AnyUsage || usage == KeyCache::KeyUsage::Sign);
+#endif
     key->secret = 1;
     key->uids->validity = mapValidity(validity);
     key->keylist_mode = GPGME_KEYLIST_MODE_VALIDATE;
 
     // add a usable VS-NfD-compliant subkey
     gpgme_subkey_t subkey;
     _gpgme_key_add_subkey(key, &subkey);
     subkey->is_de_vs = 1;
+    subkey->can_encrypt = key->can_encrypt;
+    subkey->can_sign = key->can_sign;
 
     return GpgME::Key(key, false);
 }
 
 auto testKey(const char *address, GpgME::Protocol protocol = GpgME::UnknownProtocol)
 {
     const auto email = GpgME::UserID::addrSpecFromString(address);
     const auto keys = KeyCache::instance()->findByEMailAddress(email);
     for (const auto &key : keys) {
         if (protocol == GpgME::UnknownProtocol || key.protocol() == protocol) {
             return key;
         }
     }
     return GpgME::Key();
 }
 
 void waitForKeySelectionCombosBeingInitialized(const QDialog *dialog)
 {
     QVERIFY(dialog);
     auto combo = dialog->findChild<KeySelectionCombo *>();
     QVERIFY(combo);
 
     const auto spy = std::make_unique<QSignalSpy>(combo, &KeySelectionCombo::keyListingFinished);
     QVERIFY(spy->isValid());
     QVERIFY(spy->wait(10));
 }
 
 template<typename T>
 struct Widgets {
     std::vector<T *> visible;
     std::vector<T *> hidden;
 };
 
 template<typename T>
 Widgets<T> visibleAndHiddenWidgets(const QList<T *> &widgets)
 {
     Widgets<T> result;
     std::partition_copy(std::begin(widgets),
                         std::end(widgets),
                         std::back_inserter(result.visible),
                         std::back_inserter(result.hidden),
                         std::mem_fn(&QWidget::isVisible));
     return result;
 }
 
 enum Visibility {
     IsHidden,
     IsVisible,
 };
 
 enum CheckedState {
     IsUnchecked,
     IsChecked,
 };
 
 template<typename T>
 void verifyProtocolButton(const T *button, Visibility expectedVisibility, CheckedState expectedCheckedState)
 {
     QVERIFY(button);
     QCOMPARE(button->isVisible(), expectedVisibility == IsVisible);
     QCOMPARE(button->isChecked(), expectedCheckedState == IsChecked);
 }
 
 template<typename T>
 void verifyWidgetVisibility(const T *widget, Visibility expectedVisibility)
 {
     QVERIFY(widget);
     QCOMPARE(widget->isVisible(), expectedVisibility == IsVisible);
 }
 
 template<typename T>
 void verifyWidgetsVisibility(const QList<T> &widgets, Visibility expectedVisibility)
 {
     for (auto w : widgets) {
         verifyWidgetVisibility(w, expectedVisibility);
     }
 }
 
 void verifyProtocolLabels(const QList<QLabel *> &labels, int expectedNumber, Visibility expectedVisibility)
 {
     QCOMPARE(labels.size(), expectedNumber);
     verifyWidgetsVisibility(labels, expectedVisibility);
 }
 
 bool listsOfKeysAreEqual(const std::vector<GpgME::Key> &l1, const std::vector<GpgME::Key> &l2)
 {
     return std::equal(std::begin(l1), std::end(l1), std::begin(l2), std::end(l2), ByFingerprint<std::equal_to>());
 }
 
 void verifySolution(const KeyResolver::Solution &actual, const KeyResolver::Solution &expected)
 {
     QCOMPARE(actual.protocol, expected.protocol);
 
     QVERIFY(listsOfKeysAreEqual(actual.signingKeys, expected.signingKeys));
 
     QVERIFY(std::equal(actual.encryptionKeys.constKeyValueBegin(),
                        actual.encryptionKeys.constKeyValueEnd(),
                        expected.encryptionKeys.constKeyValueBegin(),
                        expected.encryptionKeys.constKeyValueEnd(),
                        [](const auto &kv1, const auto &kv2) {
                            return kv1.first == kv2.first && listsOfKeysAreEqual(kv1.second, kv2.second);
                        }));
 }
 
 void switchKeySelectionCombosFromGenerateKeyToIgnoreKey(const QList<KeySelectionCombo *> &combos)
 {
     for (auto combo : combos) {
         if (combo->currentData(Qt::UserRole).toInt() == GenerateKey) {
             const auto ignoreIndex = combo->findData(IgnoreKey);
             QVERIFY(ignoreIndex != -1);
             combo->setCurrentIndex(ignoreIndex);
         }
     }
 }
 
 }
 
 class NewKeyApprovalDialogTest : public QObject
 {
     Q_OBJECT
 
 private Q_SLOTS:
     void init()
     {
         // hold a reference to the key cache to avoid rebuilding while the test is running
         mKeyCache = KeyCache::instance();
 
         KeyCache::mutableInstance()->setKeys({
             createTestKey("sender@example.net", GpgME::OpenPGP, KeyCache::KeyCache::KeyUsage::AnyUsage),
             createTestKey("sender@example.net", GpgME::CMS, KeyCache::KeyCache::KeyUsage::AnyUsage),
             createTestKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP, KeyCache::KeyCache::KeyUsage::Encrypt),
             createTestKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS, KeyCache::KeyCache::KeyUsage::Encrypt),
             createTestKey("Marginal Validity <marginal-openpgp@example.net>", GpgME::OpenPGP, KeyCache::KeyCache::KeyUsage::Encrypt, GpgME::UserID::Marginal),
         });
     }
 
     void cleanup()
     {
         // verify that nobody else holds a reference to the key cache
         QVERIFY(mKeyCache.use_count() == 1);
         mKeyCache.reset();
     }
 
     void test__verify_test_keys()
     {
         QVERIFY(!testKey("sender@example.net", GpgME::OpenPGP).isNull());
         QVERIFY(!testKey("sender@example.net", GpgME::CMS).isNull());
         QVERIFY(!testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP).isNull());
         QVERIFY(!testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS).isNull());
         QVERIFY(!testKey("Marginal Validity <marginal-openpgp@example.net>", GpgME::OpenPGP).isNull());
     }
 
     void test__both_protocols_allowed__mixed_not_allowed__openpgp_preferred()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {
             GpgME::CMS,
             {testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::CMS)}},
             },
         };
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("openpgp button")), IsVisible, IsChecked);
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("smime button")), IsVisible, IsUnchecked);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 1);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.signingKeys[0].primaryFingerprint());
         QCOMPARE(signingKeyWidgets.hidden[0]->defaultKey(GpgME::CMS), alternativeSolution.signingKeys[0].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 3);
 
         // encryption key widgets for sender come first (visible for OpenPGP, hidden for S/MIME)
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.hidden[0]->defaultKey(GpgME::CMS), alternativeSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
 
         // encryption key widgets for other recipients follow (visible for OpenPGP, hidden for S/MIME)
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::OpenPGP),
                  preferredSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[1]->property("address").toString(), "prefer-openpgp@example.net");
         QVERIFY(encryptionKeyWidgets.hidden[1]->defaultKey(GpgME::CMS).isEmpty());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-smime@example.net");
         QVERIFY(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::OpenPGP).isEmpty());
         QCOMPARE(encryptionKeyWidgets.hidden[2]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.hidden[2]->defaultKey(GpgME::CMS),
                  alternativeSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
     }
 
     void test__both_protocols_allowed__mixed_not_allowed__smime_preferred()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::CMS,
             {testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
             },
         };
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("openpgp button")), IsVisible, IsUnchecked);
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("smime button")), IsVisible, IsChecked);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 1);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.signingKeys[0].primaryFingerprint());
         QCOMPARE(signingKeyWidgets.hidden[0]->defaultKey(GpgME::OpenPGP), alternativeSolution.signingKeys[0].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 3);
 
         // encryption key widgets for sender come first (visible for S/MIME, hidden for OpenPGP)
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.hidden[0]->defaultKey(GpgME::OpenPGP), alternativeSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
 
         // encryption key widgets for other recipients follow (visible for OpenPGP, hidden for S/MIME)
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-openpgp@example.net");
         QVERIFY(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::CMS).isEmpty());
         QCOMPARE(encryptionKeyWidgets.hidden[1]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.hidden[1]->defaultKey(GpgME::OpenPGP),
                  alternativeSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::CMS),
                  preferredSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[2]->property("address").toString(), "prefer-smime@example.net");
         QVERIFY(encryptionKeyWidgets.hidden[2]->defaultKey(GpgME::OpenPGP).isEmpty());
     }
 
     void test__openpgp_only()
     {
         const GpgME::Protocol forcedProtocol = GpgME::OpenPGP;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("openpgp button")), IsHidden, IsChecked);
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("smime button")), IsHidden, IsUnchecked);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 0);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.signingKeys[0].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 0);
 
         // encryption key widget for sender comes first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::OpenPGP),
                  preferredSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-smime@example.net");
         QVERIFY(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::OpenPGP).isEmpty());
     }
 
     void test__smime_only()
     {
         const GpgME::Protocol forcedProtocol = GpgME::CMS;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::CMS,
             {testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("openpgp button")), IsHidden, IsUnchecked);
         verifyProtocolButton(dialog->findChild<QRadioButton *>(QStringLiteral("smime button")), IsHidden, IsChecked);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 0);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.signingKeys[0].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 0);
 
         // encryption key widget for sender comes first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-openpgp@example.net");
         QVERIFY(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::CMS).isEmpty());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::CMS),
                  preferredSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
     }
 
     void test__both_protocols_allowed__mixed_allowed()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("openpgp button")), IsVisible, IsChecked);
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("smime button")), IsVisible, IsChecked);
         verifyProtocolLabels(dialog->findChildren<QLabel *>(QStringLiteral("protocol label")), 4, IsVisible);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 2);
         QCOMPARE(signingKeyWidgets.hidden.size(), 0);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.signingKeys[0].primaryFingerprint());
         QCOMPARE(signingKeyWidgets.visible[1]->defaultKey(GpgME::CMS), preferredSolution.signingKeys[1].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 5);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 0);
 
         // encryption key widgets for sender come first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::CMS), preferredSolution.encryptionKeys.value(sender)[1].primaryFingerprint());
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[3]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[3]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[4]->property("address").toString(), "unknown@example.net");
         QVERIFY(encryptionKeyWidgets.visible[4]->defaultKey(GpgME::UnknownProtocol).isEmpty());
     }
 
     void test__both_protocols_allowed__mixed_allowed__openpgp_only_preferred_solution()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("openpgp button")), IsVisible, IsChecked);
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("smime button")), IsVisible, IsUnchecked);
         verifyProtocolLabels(dialog->findChildren<QLabel *>(QStringLiteral("protocol label")), 4, IsHidden);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 1);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.signingKeys[0].primaryFingerprint());
         QCOMPARE(signingKeyWidgets.hidden[0]->defaultKey(GpgME::CMS), preferredSolution.signingKeys[1].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 1);
 
         // encryption key widgets for sender come first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::OpenPGP), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.hidden[0]->defaultKey(GpgME::CMS), preferredSolution.encryptionKeys.value(sender)[1].primaryFingerprint());
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "unknown@example.net");
         QVERIFY(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::UnknownProtocol).isEmpty());
     }
 
     void test__both_protocols_allowed__mixed_allowed__smime_only_preferred_solution()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::CMS,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("openpgp button")), IsVisible, IsUnchecked);
         verifyProtocolButton(dialog->findChild<QCheckBox *>(QStringLiteral("smime button")), IsVisible, IsChecked);
         verifyProtocolLabels(dialog->findChildren<QLabel *>(QStringLiteral("protocol label")), 4, IsHidden);
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 1);
         QCOMPARE(signingKeyWidgets.hidden.size(), 1);
         QCOMPARE(signingKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.signingKeys[1].primaryFingerprint());
         QCOMPARE(signingKeyWidgets.hidden[0]->defaultKey(GpgME::OpenPGP), preferredSolution.signingKeys[0].primaryFingerprint());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 3);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 1);
 
         // encryption key widgets for sender come first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[0]->defaultKey(GpgME::CMS), preferredSolution.encryptionKeys.value(sender)[1].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.hidden[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.hidden[0]->defaultKey(GpgME::OpenPGP), preferredSolution.encryptionKeys.value(sender)[0].primaryFingerprint());
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[1]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "unknown@example.net");
         QVERIFY(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::UnknownProtocol).isEmpty());
     }
 
     void test__both_protocols_allowed__mixed_allowed__no_sender_keys()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 2);
         QCOMPARE(signingKeyWidgets.hidden.size(), 0);
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 5);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 0);
 
         // encryption key widgets for sender come first
         QCOMPARE(encryptionKeyWidgets.visible[0]->property("address").toString(), sender);
         QCOMPARE(encryptionKeyWidgets.visible[1]->property("address").toString(), sender);
 
         // encryption key widgets for other recipients follow
         QCOMPARE(encryptionKeyWidgets.visible[2]->property("address").toString(), "prefer-openpgp@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[2]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-openpgp@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[3]->property("address").toString(), "prefer-smime@example.net");
         QCOMPARE(encryptionKeyWidgets.visible[3]->defaultKey(GpgME::UnknownProtocol),
                  preferredSolution.encryptionKeys.value("prefer-smime@example.net")[0].primaryFingerprint());
         QCOMPARE(encryptionKeyWidgets.visible[4]->property("address").toString(), "unknown@example.net");
         QVERIFY(encryptionKeyWidgets.visible[4]->defaultKey(GpgME::UnknownProtocol).isEmpty());
     }
 
     void test__both_protocols_allowed__mixed_allowed__encrypt_only()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, false, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         const auto signingKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("signing key")));
         QCOMPARE(signingKeyWidgets.visible.size(), 0);
         QCOMPARE(signingKeyWidgets.hidden.size(), 0);
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         QCOMPARE(encryptionKeyWidgets.visible.size(), 5);
         QCOMPARE(encryptionKeyWidgets.hidden.size(), 0);
     }
 
     void test__ok_button_shows_generate_if_generate_is_selected()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {}, // no signing keys to get "Generate key" choice in OpenPGP combo
             {{QStringLiteral("sender@example.net"), {}}} // no encryption keys to get "Generate key" choice in OpenPGP combo
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto okButton = dialog->findChild<QPushButton *>("ok button");
         QVERIFY(okButton);
         QVERIFY(okButton->text() != "Generate");
 
         {
             // get the first signing key combo which is the OpenPGP one
             const auto signingKeyCombo = dialog->findChild<KeySelectionCombo *>("signing key");
             verifyWidgetVisibility(signingKeyCombo, IsVisible);
             const auto originalIndex = signingKeyCombo->currentIndex();
             const auto generateIndex = signingKeyCombo->findData(GenerateKey);
             QVERIFY(generateIndex != -1);
             signingKeyCombo->setCurrentIndex(generateIndex);
             QCOMPARE(okButton->text(), "Generate");
             signingKeyCombo->setCurrentIndex(originalIndex);
             QVERIFY(okButton->text() != "Generate");
         }
         {
             // get the first encryption key combo which is the OpenPGP one for the sender
             const auto encryptionKeyCombo = dialog->findChild<KeySelectionCombo *>("encryption key");
             verifyWidgetVisibility(encryptionKeyCombo, IsVisible);
             const auto originalIndex = encryptionKeyCombo->currentIndex();
             const auto generateIndex = encryptionKeyCombo->findData(GenerateKey);
             QVERIFY(generateIndex != -1);
             encryptionKeyCombo->setCurrentIndex(generateIndex);
             QCOMPARE(okButton->text(), QStringLiteral("Generate"));
             encryptionKeyCombo->setCurrentIndex(originalIndex);
             QVERIFY(okButton->text() != QStringLiteral("Generate"));
         }
     }
 
     void test__ok_button_does_not_show_generate_if_generate_is_selected_in_hidden_combos()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::CMS, // enables S/MIME as default protocol, hides OpenPGP combos
             {}, // no signing keys to get "Generate key" choice in OpenPGP combo
             {{QStringLiteral("sender@example.net"), {}}} // no encryption keys to get "Generate key" choice in OpenPGP combo
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto okButton = dialog->findChild<QPushButton *>("ok button");
         QVERIFY(okButton);
         QVERIFY(okButton->text() != "Generate");
 
         {
             // get the first signing key combo which is the OpenPGP one
             const auto signingKeyCombo = dialog->findChild<KeySelectionCombo *>("signing key");
             verifyWidgetVisibility(signingKeyCombo, IsHidden);
             const auto originalIndex = signingKeyCombo->currentIndex();
             const auto generateIndex = signingKeyCombo->findData(GenerateKey);
             QVERIFY(generateIndex != -1);
             signingKeyCombo->setCurrentIndex(generateIndex);
             QVERIFY(okButton->text() != QStringLiteral("Generate"));
             signingKeyCombo->setCurrentIndex(originalIndex);
             QVERIFY(okButton->text() != QStringLiteral("Generate"));
         }
         {
             // get the first encryption key combo which is the OpenPGP one for the sender
             const auto encryptionKeyCombo = dialog->findChild<KeySelectionCombo *>("encryption key");
             verifyWidgetVisibility(encryptionKeyCombo, IsHidden);
             const auto originalIndex = encryptionKeyCombo->currentIndex();
             const auto generateIndex = encryptionKeyCombo->findData(GenerateKey);
             QVERIFY(generateIndex != -1);
             encryptionKeyCombo->setCurrentIndex(generateIndex);
             QVERIFY(okButton->text() != QStringLiteral("Generate"));
             encryptionKeyCombo->setCurrentIndex(originalIndex);
             QVERIFY(okButton->text() != QStringLiteral("Generate"));
         }
     }
 
     void test__ok_button_is_disabled_if_ignore_is_selected_in_all_visible_encryption_combos()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {}, // no signing keys to get "Generate key" choice in OpenPGP combo
             {{QStringLiteral("sender@example.net"), {}}} // no encryption keys to get "Generate key" choice in OpenPGP combo
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto okButton = dialog->findChild<QPushButton *>(QStringLiteral("ok button"));
         QVERIFY(okButton);
         QVERIFY(okButton->isEnabled());
 
         const auto encryptionKeyWidgets = visibleAndHiddenWidgets(dialog->findChildren<KeySelectionCombo *>(QStringLiteral("encryption key")));
         for (auto combo : encryptionKeyWidgets.visible) {
             const auto ignoreIndex = combo->findData(IgnoreKey);
             QVERIFY(ignoreIndex != -1);
             combo->setCurrentIndex(ignoreIndex);
         }
         QVERIFY(!okButton->isEnabled());
     }
 
     void test__vs_de_compliance__all_keys_fully_valid()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         Tests::FakeCryptoConfigStringValue fakeCompliance{"gpg", "compliance", QStringLiteral("de-vs")};
         Tests::FakeCryptoConfigIntValue fakeDeVsCompliance{"gpg", "compliance_de_vs", 1};
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto complianceLabel = dialog->findChild<QLabel *>(QStringLiteral("compliance label"));
         verifyWidgetVisibility(complianceLabel, IsVisible);
         QVERIFY(!complianceLabel->text().contains(DeVSCompliance::name(false)));
     }
 
     void test__vs_de_compliance__not_all_keys_fully_valid()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("marginal-openpgp@example.net"), {testKey("Marginal Validity <marginal-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         Tests::FakeCryptoConfigStringValue fakeCompliance{"gpg", "compliance", QStringLiteral("de-vs")};
         Tests::FakeCryptoConfigIntValue fakeDeVsCompliance{"gpg", "compliance_de_vs", 1};
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto complianceLabel = dialog->findChild<QLabel *>(QStringLiteral("compliance label"));
         verifyWidgetVisibility(complianceLabel, IsVisible);
         QVERIFY(complianceLabel->text().contains(DeVSCompliance::name(false)));
     }
 
     void test__vs_de_compliance__null_keys_are_ignored()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("unknown@example.net"), {}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         Tests::FakeCryptoConfigStringValue fakeCompliance{"gpg", "compliance", QStringLiteral("de-vs")};
         Tests::FakeCryptoConfigIntValue fakeDeVsCompliance{"gpg", "compliance_de_vs", 1};
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
 
         const auto complianceLabel = dialog->findChild<QLabel *>(QStringLiteral("compliance label"));
         verifyWidgetVisibility(complianceLabel, IsVisible);
         QVERIFY(!complianceLabel->text().contains(DeVSCompliance::name(false)));
     }
 
     void test__sign_and_encrypt_to_self_only()
     {
         const GpgME::Protocol forcedProtocol = GpgME::OpenPGP;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP)},
             {
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         QVERIFY(!dialog->findChild<QGroupBox *>(QStringLiteral("encrypt-to-others box")));
     }
 
     void test__sign_and_encrypt_to_self_and_others()
     {
         const GpgME::Protocol forcedProtocol = GpgME::OpenPGP;
         const bool allowMixed = false;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::OpenPGP,
             {testKey("sender@example.net", GpgME::OpenPGP)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
 
         QVERIFY(dialog->findChild<QGroupBox *>(QStringLiteral("encrypt-to-others box")));
     }
 
     void test__result_does_not_include_null_keys()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("unknown@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("unknown@example.net"), {}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
         switchKeySelectionCombosFromGenerateKeyToIgnoreKey(dialog->findChildren<KeySelectionCombo *>());
 
         const QSignalSpy dialogAcceptedSpy{dialog.get(), &QDialog::accepted};
         QVERIFY(dialogAcceptedSpy.isValid());
 
         const auto okButton = dialog->findChild<QPushButton *>(QStringLiteral("ok button"));
         QVERIFY(okButton);
         QVERIFY(okButton->isEnabled());
         okButton->click();
 
         QCOMPARE(dialogAcceptedSpy.count(), 1);
         verifySolution(dialog->result(),
                        {GpgME::UnknownProtocol,
                         {},
                         {
                             {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                             {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                         }});
     }
 
     void test__result_has_keys_for_both_protocols_if_both_are_needed()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
         switchKeySelectionCombosFromGenerateKeyToIgnoreKey(dialog->findChildren<KeySelectionCombo *>());
 
         const QSignalSpy dialogAcceptedSpy{dialog.get(), &QDialog::accepted};
         QVERIFY(dialogAcceptedSpy.isValid());
 
         const auto okButton = dialog->findChild<QPushButton *>(QStringLiteral("ok button"));
         QVERIFY(okButton);
         QVERIFY(okButton->isEnabled());
         okButton->click();
 
         QCOMPARE(dialogAcceptedSpy.count(), 1);
         verifySolution(dialog->result(), preferredSolution);
     }
 
     void test__result_has_only_openpgp_keys_if_openpgp_protocol_selected()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
         switchKeySelectionCombosFromGenerateKeyToIgnoreKey(dialog->findChildren<KeySelectionCombo *>());
 
         const auto smimeButton = dialog->findChild<QCheckBox *>(QStringLiteral("smime button"));
         QVERIFY(smimeButton);
         smimeButton->click();
         QVERIFY(!smimeButton->isChecked());
 
         const QSignalSpy dialogAcceptedSpy{dialog.get(), &QDialog::accepted};
         QVERIFY(dialogAcceptedSpy.isValid());
 
         const auto okButton = dialog->findChild<QPushButton *>(QStringLiteral("ok button"));
         QVERIFY(okButton);
         QVERIFY(okButton->isEnabled());
         okButton->click();
 
         QCOMPARE(dialogAcceptedSpy.count(), 1);
         verifySolution(dialog->result(),
                        {GpgME::OpenPGP,
                         {testKey("sender@example.net", GpgME::OpenPGP)},
                         {
                             {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                             {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP)}},
                         }});
     }
 
     void test__result_has_only_smime_keys_if_smime_protocol_selected()
     {
         const GpgME::Protocol forcedProtocol = GpgME::UnknownProtocol;
         const bool allowMixed = true;
         const QString sender = QStringLiteral("sender@example.net");
         const KeyResolver::Solution preferredSolution = {
             GpgME::UnknownProtocol,
             {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)},
             {
                 {QStringLiteral("prefer-openpgp@example.net"), {testKey("Full Trust <prefer-openpgp@example.net>", GpgME::OpenPGP)}},
                 {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                 {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::OpenPGP), testKey("sender@example.net", GpgME::CMS)}},
             },
         };
         const KeyResolver::Solution alternativeSolution = {};
 
         const auto dialog = std::make_unique<NewKeyApprovalDialog>(true, true, sender, preferredSolution, alternativeSolution, allowMixed, forcedProtocol);
         dialog->show();
         waitForKeySelectionCombosBeingInitialized(dialog.get());
         switchKeySelectionCombosFromGenerateKeyToIgnoreKey(dialog->findChildren<KeySelectionCombo *>());
 
         const auto openPGPButton = dialog->findChild<QCheckBox *>(QStringLiteral("openpgp button"));
         QVERIFY(openPGPButton);
         openPGPButton->click();
         QVERIFY(!openPGPButton->isChecked());
 
         const QSignalSpy dialogAcceptedSpy{dialog.get(), &QDialog::accepted};
         QVERIFY(dialogAcceptedSpy.isValid());
 
         const auto okButton = dialog->findChild<QPushButton *>(QStringLiteral("ok button"));
         QVERIFY(okButton);
         QVERIFY(okButton->isEnabled());
         okButton->click();
 
         QCOMPARE(dialogAcceptedSpy.count(), 1);
         verifySolution(dialog->result(),
                        {GpgME::CMS,
                         {testKey("sender@example.net", GpgME::CMS)},
                         {
                             {QStringLiteral("prefer-smime@example.net"), {testKey("Trusted S/MIME <prefer-smime@example.net>", GpgME::CMS)}},
                             {QStringLiteral("sender@example.net"), {testKey("sender@example.net", GpgME::CMS)}},
                         }});
     }
 
 private:
     std::shared_ptr<const KeyCache> mKeyCache;
 };
 
 QTEST_MAIN(NewKeyApprovalDialogTest)
 #include "newkeyapprovaldialogtest.moc"
diff --git a/src/ui/newkeyapprovaldialog.cpp b/src/ui/newkeyapprovaldialog.cpp
index 0f345d3e..bba05275 100644
--- a/src/ui/newkeyapprovaldialog.cpp
+++ b/src/ui/newkeyapprovaldialog.cpp
@@ -1,904 +1,904 @@
 /*  -*- c++ -*-
     newkeyapprovaldialog.cpp
 
     This file is part of libkleopatra, the KDE keymanagement library
     SPDX-FileCopyrightText: 2018 Intevation GmbH
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <config-libkleo.h>
 
 #include "newkeyapprovaldialog.h"
 
 #include "keyselectioncombo.h"
 #include "progressdialog.h"
 
 #include <libkleo/compliance.h>
 #include <libkleo/debug.h>
 #include <libkleo/defaultkeyfilter.h>
 #include <libkleo/formatting.h>
 #include <libkleo/gnupg.h>
 #include <libkleo/keyhelpers.h>
 #include <libkleo/systeminfo.h>
 
 #include <libkleo_debug.h>
 
 #include <KColorScheme>
 #include <KLocalizedString>
 #include <KMessageBox>
 
 #include <QGpgME/DefaultKeyGenerationJob>
 #include <QGpgME/Job>
 
 #include <QButtonGroup>
 #include <QCheckBox>
 #include <QDialogButtonBox>
 #include <QGroupBox>
 #include <QHBoxLayout>
 #include <QLabel>
 #include <QMap>
 #include <QPushButton>
 #include <QRadioButton>
 #include <QScreen>
 #include <QScrollArea>
 #include <QToolTip>
 #include <QVBoxLayout>
 
 #include <gpgme++/key.h>
 #include <gpgme++/keygenerationresult.h>
 
 using namespace Kleo;
 using namespace GpgME;
 
 namespace
 {
 class EncryptFilter : public DefaultKeyFilter
 {
 public:
     EncryptFilter()
         : DefaultKeyFilter()
     {
-        setCanEncrypt(DefaultKeyFilter::Set);
+        setHasEncrypt(DefaultKeyFilter::Set);
     }
 };
 static std::shared_ptr<KeyFilter> s_encryptFilter = std::shared_ptr<KeyFilter>(new EncryptFilter);
 
 class OpenPGPFilter : public DefaultKeyFilter
 {
 public:
     OpenPGPFilter()
         : DefaultKeyFilter()
     {
         setIsOpenPGP(DefaultKeyFilter::Set);
-        setCanEncrypt(DefaultKeyFilter::Set);
+        setHasEncrypt(DefaultKeyFilter::Set);
     }
 };
 static std::shared_ptr<KeyFilter> s_pgpEncryptFilter = std::shared_ptr<KeyFilter>(new OpenPGPFilter);
 
 class OpenPGPSignFilter : public DefaultKeyFilter
 {
 public:
     OpenPGPSignFilter()
         : DefaultKeyFilter()
     {
         /* Also list unusable keys to make it transparent why they are unusable */
         setDisabled(DefaultKeyFilter::NotSet);
         setRevoked(DefaultKeyFilter::NotSet);
         setExpired(DefaultKeyFilter::NotSet);
         setCanSign(DefaultKeyFilter::Set);
         setHasSecret(DefaultKeyFilter::Set);
         setIsOpenPGP(DefaultKeyFilter::Set);
     }
 };
 static std::shared_ptr<KeyFilter> s_pgpSignFilter = std::shared_ptr<KeyFilter>(new OpenPGPSignFilter);
 
 class SMIMEFilter : public DefaultKeyFilter
 {
 public:
     SMIMEFilter()
         : DefaultKeyFilter()
     {
         setIsOpenPGP(DefaultKeyFilter::NotSet);
-        setCanEncrypt(DefaultKeyFilter::Set);
+        setHasEncrypt(DefaultKeyFilter::Set);
     }
 };
 static std::shared_ptr<KeyFilter> s_smimeEncryptFilter = std::shared_ptr<KeyFilter>(new SMIMEFilter);
 
 class SMIMESignFilter : public DefaultKeyFilter
 {
 public:
     SMIMESignFilter()
         : DefaultKeyFilter()
     {
         setDisabled(DefaultKeyFilter::NotSet);
         setRevoked(DefaultKeyFilter::NotSet);
         setExpired(DefaultKeyFilter::NotSet);
         setCanSign(DefaultKeyFilter::Set);
         setIsOpenPGP(DefaultKeyFilter::NotSet);
         setHasSecret(DefaultKeyFilter::Set);
     }
 };
 static std::shared_ptr<KeyFilter> s_smimeSignFilter = std::shared_ptr<KeyFilter>(new SMIMESignFilter);
 
 /* Some decoration and a button to remove the filter for a keyselectioncombo */
 class ComboWidget : public QWidget
 {
     Q_OBJECT
 public:
     explicit ComboWidget(KeySelectionCombo *combo)
         : mCombo(combo)
         , mFilterBtn(new QPushButton)
     {
         auto hLay = new QHBoxLayout(this);
         auto infoBtn = new QPushButton;
         infoBtn->setIcon(QIcon::fromTheme(QStringLiteral("help-contextual")));
         infoBtn->setIconSize(QSize(22, 22));
         infoBtn->setFlat(true);
         infoBtn->setAccessibleName(i18nc("@action:button", "Show Details"));
         hLay->addWidget(infoBtn);
         hLay->addWidget(combo, 1);
         hLay->addWidget(mFilterBtn, 0);
 
         connect(infoBtn, &QPushButton::clicked, this, [this, infoBtn]() {
             QToolTip::showText(infoBtn->mapToGlobal(QPoint()) + QPoint(infoBtn->width(), 0),
                                mCombo->currentData(Qt::ToolTipRole).toString(),
                                infoBtn,
                                QRect(),
                                30000);
         });
 
         // FIXME: This is ugly to enforce but otherwise the
         // icon is broken.
         combo->setMinimumHeight(22);
         mFilterBtn->setMinimumHeight(23);
 
         updateFilterButton();
 
         connect(mFilterBtn, &QPushButton::clicked, this, [this]() {
             const QString curFilter = mCombo->idFilter();
             if (curFilter.isEmpty()) {
                 setIdFilter(mLastIdFilter);
                 mLastIdFilter = QString();
             } else {
                 setIdFilter(QString());
                 mLastIdFilter = curFilter;
             }
         });
     }
 
     void setIdFilter(const QString &id)
     {
         mCombo->setIdFilter(id);
         updateFilterButton();
     }
 
     void updateFilterButton()
     {
         if (mCombo->idFilter().isEmpty()) {
             mFilterBtn->setIcon(QIcon::fromTheme(QStringLiteral("kt-add-filters")));
             mFilterBtn->setAccessibleName(i18nc("@action:button", "Show Matching Keys"));
             mFilterBtn->setToolTip(i18n("Show keys matching the email address"));
         } else {
             mFilterBtn->setIcon(QIcon::fromTheme(QStringLiteral("kt-remove-filters")));
             mFilterBtn->setAccessibleName(i18nc("@action:button short for 'Show all keys'", "Show All"));
             mFilterBtn->setToolTip(i18n("Show all keys"));
         }
     }
 
     KeySelectionCombo *combo()
     {
         return mCombo;
     }
 
     GpgME::Protocol fixedProtocol() const
     {
         return mFixedProtocol;
     }
 
     void setFixedProtocol(GpgME::Protocol proto)
     {
         mFixedProtocol = proto;
     }
 
 private:
     KeySelectionCombo *mCombo;
     QPushButton *mFilterBtn;
     QString mLastIdFilter;
     GpgME::Protocol mFixedProtocol = GpgME::UnknownProtocol;
 };
 
 static bool key_has_addr(const GpgME::Key &key, const QString &addr)
 {
     for (const auto &uid : key.userIDs()) {
         if (QString::fromStdString(uid.addrSpec()).toLower() == addr.toLower()) {
             return true;
         }
     }
     return false;
 }
 
 Key findfirstKeyOfType(const std::vector<Key> &keys, GpgME::Protocol protocol)
 {
     const auto it = std::find_if(std::begin(keys), std::end(keys), [protocol](const auto &key) {
         return key.protocol() == protocol;
     });
     return it != std::end(keys) ? *it : Key();
 }
 
 } // namespace
 
 class NewKeyApprovalDialog::Private
 {
 private:
     enum Action {
         Unset,
         GenerateKey,
         IgnoreKey,
     };
 
 public:
     enum {
         OpenPGPButtonId = 1,
         SMIMEButtonId = 2,
     };
 
     Private(NewKeyApprovalDialog *qq,
             bool encrypt,
             bool sign,
             GpgME::Protocol forcedProtocol,
             GpgME::Protocol presetProtocol,
             const QString &sender,
             bool allowMixed)
         : mForcedProtocol{forcedProtocol}
         , mSender{sender}
         , mSign{sign}
         , mEncrypt{encrypt}
         , mAllowMixed{allowMixed}
         , q{qq}
     {
         Q_ASSERT(forcedProtocol == GpgME::UnknownProtocol || presetProtocol == GpgME::UnknownProtocol || presetProtocol == forcedProtocol);
         Q_ASSERT(!allowMixed || (allowMixed && forcedProtocol == GpgME::UnknownProtocol));
         Q_ASSERT(!(!allowMixed && presetProtocol == GpgME::UnknownProtocol));
 
         // We do the translation here to avoid having the same string multiple times.
         mGenerateTooltip = i18nc(
             "@info:tooltip for a 'Generate new key pair' action "
             "in a combobox when a user does not yet have an OpenPGP or S/MIME key.",
             "Generate a new key using your E-Mail address.<br/><br/>"
             "The key is necessary to decrypt and sign E-Mails. "
             "You will be asked for a passphrase to protect this key and the protected key "
             "will be stored in your home directory.");
         mMainLay = new QVBoxLayout;
 
         QDialogButtonBox *btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
         mOkButton = btnBox->button(QDialogButtonBox::Ok);
 #ifndef NDEBUG
         mOkButton->setObjectName(QStringLiteral("ok button"));
 #endif
         QObject::connect(btnBox, &QDialogButtonBox::accepted, q, [this]() {
             accepted();
         });
         QObject::connect(btnBox, &QDialogButtonBox::rejected, q, &QDialog::reject);
 
         mScrollArea = new QScrollArea;
         mScrollArea->setWidget(new QWidget);
         mScrollLayout = new QVBoxLayout;
         mScrollArea->widget()->setLayout(mScrollLayout);
         mScrollArea->setWidgetResizable(true);
         mScrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
         mScrollArea->setFrameStyle(QFrame::NoFrame);
         mScrollLayout->setContentsMargins(0, 0, 0, 0);
 
         q->setWindowTitle(i18nc("@title:window", "Security approval"));
 
         auto fmtLayout = new QHBoxLayout;
         mFormatBtns = new QButtonGroup(qq);
         QAbstractButton *pgpBtn;
         QAbstractButton *smimeBtn;
         if (mAllowMixed) {
             pgpBtn = new QCheckBox(i18n("OpenPGP"));
             smimeBtn = new QCheckBox(i18n("S/MIME"));
         } else {
             pgpBtn = new QRadioButton(i18n("OpenPGP"));
             smimeBtn = new QRadioButton(i18n("S/MIME"));
         }
 #ifndef NDEBUG
         pgpBtn->setObjectName(QStringLiteral("openpgp button"));
         smimeBtn->setObjectName(QStringLiteral("smime button"));
 #endif
         mFormatBtns->addButton(pgpBtn, OpenPGPButtonId);
         mFormatBtns->addButton(smimeBtn, SMIMEButtonId);
         mFormatBtns->setExclusive(!mAllowMixed);
 
         connect(mFormatBtns, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), q, [this]() {
             updateOkButton();
         });
 
         fmtLayout->addStretch(-1);
         fmtLayout->addWidget(pgpBtn);
         fmtLayout->addWidget(smimeBtn);
         mMainLay->addLayout(fmtLayout);
 
         if (mForcedProtocol != GpgME::UnknownProtocol) {
             pgpBtn->setChecked(mForcedProtocol == GpgME::OpenPGP);
             smimeBtn->setChecked(mForcedProtocol == GpgME::CMS);
             pgpBtn->setVisible(false);
             smimeBtn->setVisible(false);
         } else {
             pgpBtn->setChecked(presetProtocol == GpgME::OpenPGP || presetProtocol == GpgME::UnknownProtocol);
             smimeBtn->setChecked(presetProtocol == GpgME::CMS || presetProtocol == GpgME::UnknownProtocol);
         }
 
         QObject::connect(mFormatBtns, &QButtonGroup::idClicked, q, [this](int buttonId) {
             // ensure that at least one protocol button is checked
             if (mAllowMixed && !mFormatBtns->button(OpenPGPButtonId)->isChecked() && !mFormatBtns->button(SMIMEButtonId)->isChecked()) {
                 mFormatBtns->button(buttonId == OpenPGPButtonId ? SMIMEButtonId : OpenPGPButtonId)->setChecked(true);
             }
             updateWidgets();
         });
 
         mMainLay->addWidget(mScrollArea);
 
         mComplianceLbl = new QLabel;
         mComplianceLbl->setVisible(false);
 #ifndef NDEBUG
         mComplianceLbl->setObjectName(QStringLiteral("compliance label"));
 #endif
 
         auto btnLayout = new QHBoxLayout;
         btnLayout->addWidget(mComplianceLbl);
         btnLayout->addWidget(btnBox);
         mMainLay->addLayout(btnLayout);
 
         q->setLayout(mMainLay);
     }
 
     ~Private() = default;
 
     GpgME::Protocol currentProtocol()
     {
         const bool openPGPButtonChecked = mFormatBtns->button(OpenPGPButtonId)->isChecked();
         const bool smimeButtonChecked = mFormatBtns->button(SMIMEButtonId)->isChecked();
         if (mAllowMixed) {
             if (openPGPButtonChecked && !smimeButtonChecked) {
                 return GpgME::OpenPGP;
             }
             if (!openPGPButtonChecked && smimeButtonChecked) {
                 return GpgME::CMS;
             }
         } else if (openPGPButtonChecked) {
             return GpgME::OpenPGP;
         } else if (smimeButtonChecked) {
             return GpgME::CMS;
         }
         return GpgME::UnknownProtocol;
     }
 
     auto findVisibleKeySelectionComboWithGenerateKey()
     {
         const auto it = std::find_if(std::begin(mAllCombos), std::end(mAllCombos), [](auto combo) {
             return combo->isVisible() && combo->currentData(Qt::UserRole).toInt() == GenerateKey;
         });
         return it != std::end(mAllCombos) ? *it : nullptr;
     }
 
     void generateKey(KeySelectionCombo *combo)
     {
         const auto &addr = combo->property("address").toString();
         auto job = new QGpgME::DefaultKeyGenerationJob(q);
         auto progress =
             new Kleo::ProgressDialog(job, i18n("Generating key for '%1'...", addr) + QStringLiteral("\n\n") + i18n("This can take several minutes."), q);
         progress->setWindowFlags(progress->windowFlags() & ~Qt::WindowContextHelpButtonHint);
         progress->setWindowTitle(i18nc("@title:window", "Key generation"));
         progress->setModal(true);
         progress->setAutoClose(true);
         progress->setMinimumDuration(0);
         progress->setValue(0);
 
         mRunningJobs << job;
         connect(job, &QGpgME::DefaultKeyGenerationJob::result, q, [this, job, combo](const GpgME::KeyGenerationResult &result) {
             handleKeyGenResult(result, job, combo);
         });
         job->start(addr, QString());
         return;
     }
 
     void handleKeyGenResult(const GpgME::KeyGenerationResult &result, QGpgME::Job *job, KeySelectionCombo *combo)
     {
         mLastError = result.error();
         if (!mLastError || mLastError.isCanceled()) {
             combo->setDefaultKey(QString::fromLatin1(result.fingerprint()), GpgME::OpenPGP);
             connect(combo, &KeySelectionCombo::keyListingFinished, q, [this, job]() {
                 mRunningJobs.removeAll(job);
             });
             combo->refreshKeys();
         } else {
             mRunningJobs.removeAll(job);
         }
     }
 
     void checkAccepted()
     {
         if (mLastError || mLastError.isCanceled()) {
             KMessageBox::error(q, Formatting::errorAsString(mLastError), i18n("Operation Failed"));
             mRunningJobs.clear();
             return;
         }
 
         if (!mRunningJobs.empty()) {
             return;
         }
 
         /* Save the keys */
         mAcceptedResult.protocol = currentProtocol();
         for (const auto combo : std::as_const(mEncCombos)) {
             const auto addr = combo->property("address").toString();
             const auto key = combo->currentKey();
             if (!combo->isVisible() || key.isNull()) {
                 continue;
             }
             mAcceptedResult.encryptionKeys[addr].push_back(key);
         }
         for (const auto combo : std::as_const(mSigningCombos)) {
             const auto key = combo->currentKey();
             if (!combo->isVisible() || key.isNull()) {
                 continue;
             }
             mAcceptedResult.signingKeys.push_back(key);
         }
 
         q->accept();
     }
 
     void accepted()
     {
         // We can assume everything was validly resolved, otherwise
         // the OK button would have been disabled.
         // Handle custom items now.
         if (auto combo = findVisibleKeySelectionComboWithGenerateKey()) {
             generateKey(combo);
             return;
         }
         checkAccepted();
     }
 
     auto encryptionKeyFilter(GpgME::Protocol protocol)
     {
         switch (protocol) {
         case OpenPGP:
             return s_pgpEncryptFilter;
         case CMS:
             return s_smimeEncryptFilter;
         default:
             return s_encryptFilter;
         }
     }
 
     void updateWidgets()
     {
         const GpgME::Protocol protocol = currentProtocol();
         const auto encryptionFilter = encryptionKeyFilter(protocol);
 
         for (auto combo : std::as_const(mSigningCombos)) {
             auto widget = qobject_cast<ComboWidget *>(combo->parentWidget());
             if (!widget) {
                 qCDebug(LIBKLEO_LOG) << "Failed to find signature combo widget";
                 continue;
             }
             widget->setVisible(protocol == GpgME::UnknownProtocol || widget->fixedProtocol() == GpgME::UnknownProtocol || widget->fixedProtocol() == protocol);
         }
         for (auto combo : std::as_const(mEncCombos)) {
             auto widget = qobject_cast<ComboWidget *>(combo->parentWidget());
             if (!widget) {
                 qCDebug(LIBKLEO_LOG) << "Failed to find combo widget";
                 continue;
             }
             widget->setVisible(protocol == GpgME::UnknownProtocol || widget->fixedProtocol() == GpgME::UnknownProtocol || widget->fixedProtocol() == protocol);
             if (widget->isVisible() && combo->property("address") != mSender) {
                 combo->setKeyFilter(encryptionFilter);
             }
         }
         // hide the labels indicating the protocol of the sender's keys if only a single protocol is active
         const auto protocolLabels = q->findChildren<QLabel *>(QStringLiteral("protocol label"));
         for (auto label : protocolLabels) {
             label->setVisible(protocol == GpgME::UnknownProtocol);
         }
     }
 
     auto createProtocolLabel(GpgME::Protocol protocol)
     {
         auto label = new QLabel(Formatting::displayName(protocol));
         label->setObjectName(QStringLiteral("protocol label"));
         return label;
     }
 
     ComboWidget *createSigningCombo(const QString &addr, const GpgME::Key &key, GpgME::Protocol protocol = GpgME::UnknownProtocol)
     {
         Q_ASSERT(!key.isNull() || protocol != UnknownProtocol);
         protocol = !key.isNull() ? key.protocol() : protocol;
 
         auto combo = new KeySelectionCombo();
         auto comboWidget = new ComboWidget(combo);
 #ifndef NDEBUG
         combo->setObjectName(QStringLiteral("signing key"));
 #endif
         if (protocol == GpgME::OpenPGP) {
             combo->setKeyFilter(s_pgpSignFilter);
         } else if (protocol == GpgME::CMS) {
             combo->setKeyFilter(s_smimeSignFilter);
         }
         if (key.isNull() || key_has_addr(key, mSender)) {
             comboWidget->setIdFilter(mSender);
         }
         comboWidget->setFixedProtocol(protocol);
         if (!key.isNull()) {
             combo->setDefaultKey(QString::fromLatin1(key.primaryFingerprint()), protocol);
         }
         if (key.isNull() && protocol == OpenPGP) {
             combo->appendCustomItem(QIcon::fromTheme(QStringLiteral("document-new")), i18n("Generate a new key pair"), GenerateKey, mGenerateTooltip);
         }
         combo->appendCustomItem(QIcon::fromTheme(QStringLiteral("emblem-unavailable")),
                                 i18n("Don't confirm identity and integrity"),
                                 IgnoreKey,
                                 i18nc("@info:tooltip for not selecting a key for signing.", "The E-Mail will not be cryptographically signed."));
 
         mSigningCombos << combo;
         mAllCombos << combo;
         combo->setProperty("address", addr);
 
         connect(combo, &KeySelectionCombo::currentKeyChanged, q, [this]() {
             updateOkButton();
         });
         connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), q, [this]() {
             updateOkButton();
         });
 
         return comboWidget;
     }
 
     void setSigningKeys(const std::vector<GpgME::Key> &preferredKeys, const std::vector<GpgME::Key> &alternativeKeys)
     {
         auto group = new QGroupBox(i18nc("Caption for signing key selection", "Confirm identity '%1' as:", mSender));
         group->setAlignment(Qt::AlignLeft);
         auto sigLayout = new QVBoxLayout(group);
 
         const bool mayNeedOpenPGP = mForcedProtocol != CMS;
         const bool mayNeedCMS = mForcedProtocol != OpenPGP;
         if (mayNeedOpenPGP) {
             if (mAllowMixed) {
                 sigLayout->addWidget(createProtocolLabel(OpenPGP));
             }
             const Key preferredKey = findfirstKeyOfType(preferredKeys, OpenPGP);
             const Key alternativeKey = findfirstKeyOfType(alternativeKeys, OpenPGP);
             if (!preferredKey.isNull()) {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for" << preferredKey;
                 auto comboWidget = createSigningCombo(mSender, preferredKey);
                 sigLayout->addWidget(comboWidget);
             } else if (!alternativeKey.isNull()) {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for" << alternativeKey;
                 auto comboWidget = createSigningCombo(mSender, alternativeKey);
                 sigLayout->addWidget(comboWidget);
             } else {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for OpenPGP key";
                 auto comboWidget = createSigningCombo(mSender, Key(), OpenPGP);
                 sigLayout->addWidget(comboWidget);
             }
         }
         if (mayNeedCMS) {
             if (mAllowMixed) {
                 sigLayout->addWidget(createProtocolLabel(CMS));
             }
             const Key preferredKey = findfirstKeyOfType(preferredKeys, CMS);
             const Key alternativeKey = findfirstKeyOfType(alternativeKeys, CMS);
             if (!preferredKey.isNull()) {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for" << preferredKey;
                 auto comboWidget = createSigningCombo(mSender, preferredKey);
                 sigLayout->addWidget(comboWidget);
             } else if (!alternativeKey.isNull()) {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for" << alternativeKey;
                 auto comboWidget = createSigningCombo(mSender, alternativeKey);
                 sigLayout->addWidget(comboWidget);
             } else {
                 qCDebug(LIBKLEO_LOG) << "setSigningKeys - creating signing combo for S/MIME key";
                 auto comboWidget = createSigningCombo(mSender, Key(), CMS);
                 sigLayout->addWidget(comboWidget);
             }
         }
 
         mScrollLayout->addWidget(group);
     }
 
     ComboWidget *createEncryptionCombo(const QString &addr, const GpgME::Key &key, GpgME::Protocol fixedProtocol)
     {
         auto combo = new KeySelectionCombo(false);
         auto comboWidget = new ComboWidget(combo);
 #ifndef NDEBUG
         combo->setObjectName(QStringLiteral("encryption key"));
 #endif
         if (fixedProtocol == GpgME::OpenPGP) {
             combo->setKeyFilter(s_pgpEncryptFilter);
         } else if (fixedProtocol == GpgME::CMS) {
             combo->setKeyFilter(s_smimeEncryptFilter);
         } else {
             combo->setKeyFilter(s_encryptFilter);
         }
         if (key.isNull() || key_has_addr(key, addr)) {
             comboWidget->setIdFilter(addr);
         }
         comboWidget->setFixedProtocol(fixedProtocol);
         if (!key.isNull()) {
             combo->setDefaultKey(QString::fromLatin1(key.primaryFingerprint()), fixedProtocol);
         }
 
         if (addr == mSender && key.isNull() && fixedProtocol == OpenPGP) {
             combo->appendCustomItem(QIcon::fromTheme(QStringLiteral("document-new")), i18n("Generate a new key pair"), GenerateKey, mGenerateTooltip);
         }
 
         combo->appendCustomItem(QIcon::fromTheme(QStringLiteral("emblem-unavailable")),
                                 i18n("No key. Recipient will be unable to decrypt."),
                                 IgnoreKey,
                                 i18nc("@info:tooltip for No Key selected for a specific recipient.",
                                       "Do not select a key for this recipient.<br/><br/>"
                                       "The recipient will receive the encrypted E-Mail, but it can only "
                                       "be decrypted with the other keys selected in this dialog."));
 
         connect(combo, &KeySelectionCombo::currentKeyChanged, q, [this]() {
             updateOkButton();
         });
         connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), q, [this]() {
             updateOkButton();
         });
 
         mEncCombos << combo;
         mAllCombos << combo;
         combo->setProperty("address", addr);
         return comboWidget;
     }
 
     void addEncryptionAddr(const QString &addr,
                            GpgME::Protocol preferredKeysProtocol,
                            const std::vector<GpgME::Key> &preferredKeys,
                            GpgME::Protocol alternativeKeysProtocol,
                            const std::vector<GpgME::Key> &alternativeKeys,
                            QGridLayout *encGrid)
     {
         if (addr == mSender) {
             const bool mayNeedOpenPGP = mForcedProtocol != CMS;
             const bool mayNeedCMS = mForcedProtocol != OpenPGP;
             if (mayNeedOpenPGP) {
                 if (mAllowMixed) {
                     encGrid->addWidget(createProtocolLabel(OpenPGP), encGrid->rowCount(), 0);
                 }
                 for (const auto &key : preferredKeys) {
                     if (key.protocol() == OpenPGP) {
                         qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                         auto comboWidget = createEncryptionCombo(addr, key, OpenPGP);
                         encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                     }
                 }
                 for (const auto &key : alternativeKeys) {
                     if (key.protocol() == OpenPGP) {
                         qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                         auto comboWidget = createEncryptionCombo(addr, key, OpenPGP);
                         encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                     }
                 }
                 if (!anyKeyHasProtocol(preferredKeys, OpenPGP) && !anyKeyHasProtocol(alternativeKeys, OpenPGP)) {
                     qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for OpenPGP key";
                     auto comboWidget = createEncryptionCombo(addr, GpgME::Key(), OpenPGP);
                     encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                 }
             }
             if (mayNeedCMS) {
                 if (mAllowMixed) {
                     encGrid->addWidget(createProtocolLabel(CMS), encGrid->rowCount(), 0);
                 }
                 for (const auto &key : preferredKeys) {
                     if (key.protocol() == CMS) {
                         qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                         auto comboWidget = createEncryptionCombo(addr, key, CMS);
                         encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                     }
                 }
                 for (const auto &key : alternativeKeys) {
                     if (key.protocol() == CMS) {
                         qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                         auto comboWidget = createEncryptionCombo(addr, key, CMS);
                         encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                     }
                 }
                 if (!anyKeyHasProtocol(preferredKeys, CMS) && !anyKeyHasProtocol(alternativeKeys, CMS)) {
                     qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for S/MIME key";
                     auto comboWidget = createEncryptionCombo(addr, GpgME::Key(), CMS);
                     encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                 }
             }
         } else {
             encGrid->addWidget(new QLabel(addr), encGrid->rowCount(), 0);
 
             for (const auto &key : preferredKeys) {
                 qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                 auto comboWidget = createEncryptionCombo(addr, key, preferredKeysProtocol);
                 encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
             }
             for (const auto &key : alternativeKeys) {
                 qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << key;
                 auto comboWidget = createEncryptionCombo(addr, key, alternativeKeysProtocol);
                 encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
             }
             if (!mAllowMixed) {
                 if (preferredKeys.empty()) {
                     qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for" << Formatting::displayName(preferredKeysProtocol)
                                          << "key";
                     auto comboWidget = createEncryptionCombo(addr, GpgME::Key(), preferredKeysProtocol);
                     encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                 }
                 if (alternativeKeys.empty() && alternativeKeysProtocol != UnknownProtocol) {
                     qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for"
                                          << Formatting::displayName(alternativeKeysProtocol) << "key";
                     auto comboWidget = createEncryptionCombo(addr, GpgME::Key(), alternativeKeysProtocol);
                     encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                 }
             } else {
                 if (preferredKeys.empty() && alternativeKeys.empty()) {
                     qCDebug(LIBKLEO_LOG) << "setEncryptionKeys -" << addr << "- creating encryption combo for any key";
                     auto comboWidget = createEncryptionCombo(addr, GpgME::Key(), UnknownProtocol);
                     encGrid->addWidget(comboWidget, encGrid->rowCount(), 0, 1, 2);
                 }
             }
         }
     }
 
     void setEncryptionKeys(GpgME::Protocol preferredKeysProtocol,
                            const QMap<QString, std::vector<GpgME::Key>> &preferredKeys,
                            GpgME::Protocol alternativeKeysProtocol,
                            const QMap<QString, std::vector<GpgME::Key>> &alternativeKeys)
     {
         {
             auto group = new QGroupBox(i18nc("Encrypt to self (email address):", "Encrypt to self (%1):", mSender));
 #ifndef NDEBUG
             group->setObjectName(QStringLiteral("encrypt-to-self box"));
 #endif
             group->setAlignment(Qt::AlignLeft);
             auto encGrid = new QGridLayout(group);
 
             addEncryptionAddr(mSender, preferredKeysProtocol, preferredKeys.value(mSender), alternativeKeysProtocol, alternativeKeys.value(mSender), encGrid);
 
             encGrid->setColumnStretch(1, -1);
             mScrollLayout->addWidget(group);
         }
 
         const bool hasOtherRecipients = std::any_of(preferredKeys.keyBegin(), preferredKeys.keyEnd(), [this](const auto &recipient) {
             return recipient != mSender;
         });
         if (hasOtherRecipients) {
             auto group = new QGroupBox(i18n("Encrypt to others:"));
 #ifndef NDEBUG
             group->setObjectName(QStringLiteral("encrypt-to-others box"));
 #endif
             group->setAlignment(Qt::AlignLeft);
             auto encGrid = new QGridLayout{group};
 
             for (auto it = std::begin(preferredKeys); it != std::end(preferredKeys); ++it) {
                 const auto &address = it.key();
                 const auto &keys = it.value();
                 if (address != mSender) {
                     addEncryptionAddr(address, preferredKeysProtocol, keys, alternativeKeysProtocol, alternativeKeys.value(address), encGrid);
                 }
             }
 
             encGrid->setColumnStretch(1, -1);
             mScrollLayout->addWidget(group);
         }
 
         mScrollLayout->addStretch(-1);
     }
 
     void updateOkButton()
     {
         static QString origOkText = mOkButton->text();
         const bool isGenerate = bool(findVisibleKeySelectionComboWithGenerateKey());
         const bool allVisibleEncryptionKeysAreIgnored = std::all_of(std::begin(mEncCombos), std::end(mEncCombos), [](auto combo) {
             return !combo->isVisible() || combo->currentData(Qt::UserRole).toInt() == IgnoreKey;
         });
 
         // If we don't encrypt the ok button is always enabled. But otherwise
         // we only enable it if we encrypt to at least one recipient.
         mOkButton->setEnabled(!mEncrypt || !allVisibleEncryptionKeysAreIgnored);
 
         mOkButton->setText(isGenerate ? i18n("Generate") : origOkText);
 
         if (!DeVSCompliance::isActive()) {
             return;
         }
 
         // Handle compliance
         bool de_vs = DeVSCompliance::isCompliant();
 
         if (de_vs) {
             const GpgME::Protocol protocol = currentProtocol();
 
             for (const auto combo : std::as_const(mAllCombos)) {
                 if (!combo->isVisible()) {
                     continue;
                 }
                 const auto key = combo->currentKey();
                 if (key.isNull()) {
                     continue;
                 }
                 if (protocol != GpgME::UnknownProtocol && key.protocol() != protocol) {
                     continue;
                 }
                 if (!DeVSCompliance::keyIsCompliant(key)) {
                     de_vs = false;
                     break;
                 }
             }
         }
 
         DeVSCompliance::decorate(mOkButton, de_vs);
         mComplianceLbl->setText(DeVSCompliance::name(de_vs));
         mComplianceLbl->setVisible(true);
     }
 
     GpgME::Protocol mForcedProtocol;
     QList<KeySelectionCombo *> mSigningCombos;
     QList<KeySelectionCombo *> mEncCombos;
     QList<KeySelectionCombo *> mAllCombos;
     QScrollArea *mScrollArea;
     QVBoxLayout *mScrollLayout;
     QPushButton *mOkButton;
     QVBoxLayout *mMainLay;
     QButtonGroup *mFormatBtns;
     QString mSender;
     bool mSign;
     bool mEncrypt;
     bool mAllowMixed;
     NewKeyApprovalDialog *q;
     QList<QGpgME::Job *> mRunningJobs;
     GpgME::Error mLastError;
     QLabel *mComplianceLbl;
     KeyResolver::Solution mAcceptedResult;
     QString mGenerateTooltip;
 };
 
 NewKeyApprovalDialog::NewKeyApprovalDialog(bool encrypt,
                                            bool sign,
                                            const QString &sender,
                                            KeyResolver::Solution preferredSolution,
                                            KeyResolver::Solution alternativeSolution,
                                            bool allowMixed,
                                            GpgME::Protocol forcedProtocol,
                                            QWidget *parent,
                                            Qt::WindowFlags f)
     : QDialog(parent, f)
     , d{std::make_unique<Private>(this, encrypt, sign, forcedProtocol, preferredSolution.protocol, sender, allowMixed)}
 {
     if (sign) {
         d->setSigningKeys(std::move(preferredSolution.signingKeys), std::move(alternativeSolution.signingKeys));
     }
     if (encrypt) {
         d->setEncryptionKeys(allowMixed ? UnknownProtocol : preferredSolution.protocol,
                              std::move(preferredSolution.encryptionKeys),
                              allowMixed ? UnknownProtocol : alternativeSolution.protocol,
                              std::move(alternativeSolution.encryptionKeys));
     }
     d->updateWidgets();
     d->updateOkButton();
 
     const auto size = sizeHint();
     const auto desk = screen()->size();
     resize(QSize(desk.width() / 3, qMin(size.height(), desk.height() / 2)));
 }
 
 Kleo::NewKeyApprovalDialog::~NewKeyApprovalDialog() = default;
 
 KeyResolver::Solution NewKeyApprovalDialog::result()
 {
     return d->mAcceptedResult;
 }
 
 #include "newkeyapprovaldialog.moc"