File indexing completed on 2024-06-23 05:13:51

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     crypto/gui/signencryptemailconflictdialog.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "signencryptemailconflictdialog.h"
0013 
0014 #include <crypto/recipient.h>
0015 #include <crypto/sender.h>
0016 
0017 #include "certificateselectionline.h"
0018 #include "dialogs/certificateselectiondialog.h"
0019 
0020 #include "utils/gui-helper.h"
0021 #include "utils/kleo_assert.h"
0022 #include <Libkleo/GnuPG>
0023 
0024 #include <Libkleo/Compliance>
0025 #include <Libkleo/Formatting>
0026 #include <Libkleo/Stl_Util>
0027 #include <Libkleo/SystemInfo>
0028 
0029 #include <gpgme++/key.h>
0030 
0031 #include <KMime/Types>
0032 
0033 #include <KColorScheme>
0034 #include <KLocalizedString>
0035 
0036 #include <QCheckBox>
0037 #include <QDialogButtonBox>
0038 #include <QGroupBox>
0039 #include <QLabel>
0040 #include <QLayout>
0041 #include <QPointer>
0042 #include <QPushButton>
0043 #include <QRadioButton>
0044 #include <QSignalBlocker>
0045 #include <QToolButton>
0046 
0047 #include <algorithm>
0048 #include <iterator>
0049 
0050 using namespace Kleo;
0051 using namespace Kleo::Crypto;
0052 using namespace Kleo::Crypto::Gui;
0053 using namespace Kleo::Dialogs;
0054 using namespace GpgME;
0055 
0056 Q_DECLARE_METATYPE(GpgME::Key)
0057 Q_DECLARE_METATYPE(GpgME::UserID)
0058 
0059 static CertificateSelectionDialog *create_certificate_selection_dialog(QWidget *parent, Protocol proto)
0060 {
0061     auto const dlg = new CertificateSelectionDialog(parent);
0062     dlg->setOptions(proto == OpenPGP   ? CertificateSelectionDialog::OpenPGPFormat
0063                         : proto == CMS ? CertificateSelectionDialog::CMSFormat
0064                                        : CertificateSelectionDialog::AnyFormat);
0065     return dlg;
0066 }
0067 
0068 static CertificateSelectionDialog *create_encryption_certificate_selection_dialog(QWidget *parent, Protocol proto, const QString &mailbox)
0069 {
0070     CertificateSelectionDialog *const dlg = create_certificate_selection_dialog(parent, proto);
0071     dlg->setCustomLabelText(i18n("Please select an encryption certificate for recipient \"%1\"", mailbox));
0072     dlg->setOptions(CertificateSelectionDialog::SingleSelection | //
0073                     CertificateSelectionDialog::EncryptOnly | //
0074                     dlg->options());
0075     return dlg;
0076 }
0077 
0078 static CertificateSelectionDialog *create_signing_certificate_selection_dialog(QWidget *parent, Protocol proto, const QString &mailbox)
0079 {
0080     CertificateSelectionDialog *const dlg = create_certificate_selection_dialog(parent, proto);
0081     dlg->setCustomLabelText(i18n("Please select a signing certificate for sender \"%1\"", mailbox));
0082     dlg->setOptions(CertificateSelectionDialog::SingleSelection | //
0083                     CertificateSelectionDialog::SignOnly | //
0084                     CertificateSelectionDialog::SecretKeys | //
0085                     dlg->options());
0086     return dlg;
0087 }
0088 
0089 static QString make_top_label_conflict_text(bool sign, bool enc)
0090 {
0091     return sign && enc ? i18n(
0092                "Kleopatra cannot unambiguously determine matching certificates "
0093                "for all recipients/senders of the message.\n"
0094                "Please select the correct certificates for each recipient:")
0095         : sign ? i18n(
0096               "Kleopatra cannot unambiguously determine matching certificates "
0097               "for the sender of the message.\n"
0098               "Please select the correct certificates for the sender:")
0099         : enc ? i18n(
0100               "Kleopatra cannot unambiguously determine matching certificates "
0101               "for all recipients of the message.\n"
0102               "Please select the correct certificates for each recipient:")
0103               : (kleo_assert_fail(sign || enc), QString());
0104 }
0105 
0106 static QString make_top_label_quickmode_text(bool sign, bool enc)
0107 {
0108     return enc ? i18n("Please verify that correct certificates have been selected for each recipient:")
0109         : sign ? i18n("Please verify that the correct certificate has been selected for the sender:")
0110                : (kleo_assert_fail(sign || enc), QString());
0111 }
0112 
0113 class SignEncryptEMailConflictDialog::Private
0114 {
0115     friend class ::Kleo::Crypto::Gui::SignEncryptEMailConflictDialog;
0116     SignEncryptEMailConflictDialog *const q;
0117 
0118 public:
0119     explicit Private(SignEncryptEMailConflictDialog *qq)
0120         : q(qq)
0121         , senders()
0122         , recipients()
0123         , sign(true)
0124         , encrypt(true)
0125         , presetProtocol(UnknownProtocol)
0126         , ui(q)
0127     {
0128     }
0129 
0130 private:
0131     void updateTopLabelText()
0132     {
0133         ui.conflictTopLB.setText(make_top_label_conflict_text(sign, encrypt));
0134         ui.quickModeTopLB.setText(make_top_label_quickmode_text(sign, encrypt));
0135     }
0136 
0137     void showHideWidgets()
0138     {
0139         const Protocol proto = q->selectedProtocol();
0140         const bool quickMode = q->isQuickMode();
0141 
0142         const bool needProtocolSelection = presetProtocol == UnknownProtocol;
0143 
0144         const bool needShowAllRecipientsCB = quickMode ? false
0145             : needProtocolSelection                    ? needShowAllRecipients(OpenPGP) || needShowAllRecipients(CMS)
0146                                                        : needShowAllRecipients(proto);
0147 
0148         ui.showAllRecipientsCB.setVisible(needShowAllRecipientsCB);
0149 
0150         ui.pgpRB.setVisible(needProtocolSelection);
0151         ui.cmsRB.setVisible(needProtocolSelection);
0152 
0153         const bool showAll = !needShowAllRecipientsCB || ui.showAllRecipientsCB.isChecked();
0154 
0155         bool first;
0156         first = true;
0157         for (const CertificateSelectionLine &line : std::as_const(ui.signers)) {
0158             line.showHide(proto, first, showAll, sign);
0159         }
0160         ui.selectSigningCertificatesGB.setVisible(sign && (showAll || !first));
0161 
0162         first = true;
0163         for (const CertificateSelectionLine &line : std::as_const(ui.recipients)) {
0164             line.showHide(proto, first, showAll, encrypt);
0165         }
0166         ui.selectEncryptionCertificatesGB.setVisible(encrypt && (showAll || !first));
0167     }
0168 
0169     bool needShowAllRecipients(Protocol proto) const
0170     {
0171         if (sign) {
0172             if (const unsigned int num = std::count_if(ui.signers.cbegin(), ui.signers.cend(), [proto](const CertificateSelectionLine &l) {
0173                     return l.wasInitiallyAmbiguous(proto);
0174                 })) {
0175                 if (num != ui.signers.size()) {
0176                     return true;
0177                 }
0178             }
0179         }
0180         if (encrypt) {
0181             if (const unsigned int num = std::count_if(ui.recipients.cbegin(), ui.recipients.cend(), [proto](const CertificateSelectionLine &l) {
0182                     return l.wasInitiallyAmbiguous(proto);
0183                 })) {
0184                 if (num != ui.recipients.size()) {
0185                     return true;
0186                 }
0187             }
0188         }
0189         return false;
0190     }
0191 
0192     void createSendersAndRecipients()
0193     {
0194         ui.clearSendersAndRecipients();
0195 
0196         ui.addSelectSigningCertificatesGB();
0197         for (const Sender &s : std::as_const(senders)) {
0198             addSigner(s);
0199         }
0200 
0201         ui.addSelectEncryptionCertificatesGB();
0202         for (const Sender &s : std::as_const(senders)) {
0203             addRecipient(s);
0204         }
0205         for (const Recipient &r : std::as_const(recipients)) {
0206             addRecipient(r);
0207         }
0208     }
0209 
0210     void addSigner(const Sender &s)
0211     {
0212         ui.addSigner(s.mailbox().prettyAddress(),
0213                      s.signingCertificateCandidates(OpenPGP),
0214                      s.isSigningAmbiguous(OpenPGP),
0215                      s.signingCertificateCandidates(CMS),
0216                      s.isSigningAmbiguous(CMS),
0217                      q);
0218     }
0219 
0220     void addRecipient(const Sender &s)
0221     {
0222         ui.addRecipient(s.mailbox().prettyAddress(),
0223                         s.encryptToSelfCertificateCandidates(OpenPGP),
0224                         s.isEncryptionAmbiguous(OpenPGP),
0225                         s.encryptToSelfCertificateCandidates(CMS),
0226                         s.isEncryptionAmbiguous(CMS),
0227                         q);
0228     }
0229 
0230     void addRecipient(const Recipient &r)
0231     {
0232         ui.addRecipient(r.mailbox().prettyAddress(),
0233                         r.encryptionCertificateCandidates(OpenPGP),
0234                         r.isEncryptionAmbiguous(OpenPGP),
0235                         r.encryptionCertificateCandidates(CMS),
0236                         r.isEncryptionAmbiguous(CMS),
0237                         q);
0238     }
0239 
0240     bool isComplete(Protocol proto) const;
0241 
0242 private:
0243     void updateComplianceStatus()
0244     {
0245         if (!DeVSCompliance::isCompliant()) {
0246             return;
0247         }
0248         if (q->selectedProtocol() == UnknownProtocol || (q->resolvedSigningKeys().empty() && q->resolvedEncryptionKeys().empty())) {
0249             return;
0250         }
0251         // Handle compliance
0252         bool de_vs = true;
0253         for (const auto &key : q->resolvedSigningKeys()) {
0254             if (!DeVSCompliance::keyIsCompliant(key)) {
0255                 de_vs = false;
0256                 break;
0257             }
0258         }
0259         if (de_vs) {
0260             for (const auto &key : q->resolvedEncryptionKeys()) {
0261                 if (!DeVSCompliance::keyIsCompliant(key)) {
0262                     de_vs = false;
0263                     break;
0264                 }
0265             }
0266         }
0267 
0268         auto btn = ui.buttonBox.button(QDialogButtonBox::Ok);
0269 
0270         DeVSCompliance::decorate(btn, de_vs);
0271         ui.complianceLB.setText(DeVSCompliance::name(de_vs));
0272         ui.complianceLB.setVisible(true);
0273     }
0274 
0275     void updateDialogStatus()
0276     {
0277         ui.setOkButtonEnabled(q->isComplete());
0278         updateComplianceStatus();
0279     }
0280     void slotCompleteChanged()
0281     {
0282         updateDialogStatus();
0283     }
0284     void slotShowAllRecipientsToggled(bool)
0285     {
0286         showHideWidgets();
0287     }
0288     void slotProtocolChanged()
0289     {
0290         showHideWidgets();
0291         updateDialogStatus();
0292     }
0293     void slotCertificateSelectionDialogRequested()
0294     {
0295         const QObject *const s = q->sender();
0296         const Protocol proto = q->selectedProtocol();
0297         QPointer<CertificateSelectionDialog> dlg;
0298         for (const CertificateSelectionLine &l : std::as_const(ui.signers))
0299             if (s == l.toolButton()) {
0300                 dlg = create_signing_certificate_selection_dialog(q, proto, l.mailboxText());
0301                 if (dlg->exec()) {
0302                     l.addAndSelectCertificate(dlg->selectedCertificate());
0303                 }
0304                 // ### switch to key.protocol(), in case proto == UnknownProtocol
0305                 break;
0306             }
0307         for (const CertificateSelectionLine &l : std::as_const(ui.recipients))
0308             if (s == l.toolButton()) {
0309                 dlg = create_encryption_certificate_selection_dialog(q, proto, l.mailboxText());
0310                 if (dlg->exec()) {
0311                     l.addAndSelectCertificate(dlg->selectedCertificate());
0312                 }
0313                 // ### switch to key.protocol(), in case proto == UnknownProtocol
0314                 break;
0315             }
0316 #ifndef Q_OS_WIN
0317         // This leads to a crash on Windows. We don't really
0318         // leak memory here anyway because the destruction of the
0319         // dialog happens when the parent (q) is destroyed anyway.
0320         delete dlg;
0321 #endif
0322     }
0323 
0324 private:
0325     std::vector<Sender> senders;
0326     std::vector<Recipient> recipients;
0327 
0328     bool sign : 1;
0329     bool encrypt : 1;
0330     Protocol presetProtocol;
0331 
0332 private:
0333     struct Ui {
0334         QLabel conflictTopLB, quickModeTopLB;
0335         QCheckBox showAllRecipientsCB;
0336         QRadioButton pgpRB, cmsRB;
0337         QGroupBox selectSigningCertificatesGB;
0338         QGroupBox selectEncryptionCertificatesGB;
0339         QCheckBox quickModeCB;
0340         QDialogButtonBox buttonBox;
0341         QVBoxLayout vlay;
0342         QHBoxLayout hlay;
0343         QHBoxLayout hlay2;
0344         QGridLayout glay;
0345         std::vector<CertificateSelectionLine> signers, recipients;
0346         QLabel complianceLB;
0347 
0348         void setOkButtonEnabled(bool enable)
0349         {
0350             return buttonBox.button(QDialogButtonBox::Ok)->setEnabled(enable);
0351         }
0352 
0353         explicit Ui(SignEncryptEMailConflictDialog *q)
0354             : conflictTopLB(make_top_label_conflict_text(true, true), q)
0355             , quickModeTopLB(make_top_label_quickmode_text(true, true), q)
0356             , showAllRecipientsCB(i18n("Show all recipients"), q)
0357             , pgpRB(i18n("OpenPGP"), q)
0358             , cmsRB(i18n("S/MIME"), q)
0359             , selectSigningCertificatesGB(i18n("Select Signing Certificate"), q)
0360             , selectEncryptionCertificatesGB(i18n("Select Encryption Certificate"), q)
0361             , quickModeCB(i18n("Only show this dialog in case of conflicts (experimental)"), q)
0362             , buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q)
0363             , vlay(q)
0364             , hlay()
0365             , glay()
0366             , signers()
0367             , recipients()
0368         {
0369             KDAB_SET_OBJECT_NAME(conflictTopLB);
0370             KDAB_SET_OBJECT_NAME(quickModeTopLB);
0371             KDAB_SET_OBJECT_NAME(showAllRecipientsCB);
0372             KDAB_SET_OBJECT_NAME(pgpRB);
0373             KDAB_SET_OBJECT_NAME(cmsRB);
0374             KDAB_SET_OBJECT_NAME(selectSigningCertificatesGB);
0375             KDAB_SET_OBJECT_NAME(selectEncryptionCertificatesGB);
0376             KDAB_SET_OBJECT_NAME(quickModeCB);
0377             KDAB_SET_OBJECT_NAME(buttonBox);
0378             KDAB_SET_OBJECT_NAME(hlay);
0379             KDAB_SET_OBJECT_NAME(glay);
0380             KDAB_SET_OBJECT_NAME(vlay);
0381 
0382             q->setWindowTitle(i18nc("@title:window", "Select Certificates for Message"));
0383 
0384             conflictTopLB.hide();
0385 
0386             selectSigningCertificatesGB.setFlat(true);
0387             selectEncryptionCertificatesGB.setFlat(true);
0388             selectSigningCertificatesGB.setAlignment(Qt::AlignCenter);
0389             selectEncryptionCertificatesGB.setAlignment(Qt::AlignCenter);
0390 
0391             glay.setColumnStretch(2, 1);
0392             glay.setColumnStretch(3, 1);
0393 
0394             vlay.setSizeConstraint(QLayout::SetMinimumSize);
0395 
0396             vlay.addWidget(&conflictTopLB);
0397             vlay.addWidget(&quickModeTopLB);
0398 
0399             hlay.addWidget(&showAllRecipientsCB);
0400             hlay.addStretch(1);
0401             hlay.addWidget(&pgpRB);
0402             hlay.addWidget(&cmsRB);
0403             vlay.addLayout(&hlay);
0404 
0405             addSelectSigningCertificatesGB();
0406             addSelectEncryptionCertificatesGB();
0407             vlay.addLayout(&glay);
0408 
0409             vlay.addStretch(1);
0410 
0411             complianceLB.setVisible(false);
0412             hlay2.addStretch(1);
0413             hlay2.addWidget(&complianceLB, 0, Qt::AlignRight);
0414             hlay2.addWidget(&buttonBox, 0, Qt::AlignRight);
0415 
0416             vlay.addWidget(&quickModeCB, 0, Qt::AlignRight);
0417             vlay.addLayout(&hlay2);
0418 
0419             connect(&buttonBox, &QDialogButtonBox::accepted, q, &SignEncryptEMailConflictDialog::accept);
0420             connect(&buttonBox, &QDialogButtonBox::rejected, q, &SignEncryptEMailConflictDialog::reject);
0421 
0422             connect(&showAllRecipientsCB, SIGNAL(toggled(bool)), q, SLOT(slotShowAllRecipientsToggled(bool)));
0423             connect(&pgpRB, SIGNAL(toggled(bool)), q, SLOT(slotProtocolChanged()));
0424             connect(&cmsRB, SIGNAL(toggled(bool)), q, SLOT(slotProtocolChanged()));
0425         }
0426 
0427         void clearSendersAndRecipients()
0428         {
0429             std::vector<CertificateSelectionLine> sig, enc;
0430             sig.swap(signers);
0431             enc.swap(recipients);
0432             std::for_each(sig.begin(), sig.end(), std::mem_fn(&CertificateSelectionLine::kill));
0433             std::for_each(enc.begin(), enc.end(), std::mem_fn(&CertificateSelectionLine::kill));
0434             glay.removeWidget(&selectSigningCertificatesGB);
0435             glay.removeWidget(&selectEncryptionCertificatesGB);
0436         }
0437 
0438         void addSelectSigningCertificatesGB()
0439         {
0440             glay.addWidget(&selectSigningCertificatesGB, glay.rowCount(), 0, 1, CertificateSelectionLine::NumColumns);
0441         }
0442         void addSelectEncryptionCertificatesGB()
0443         {
0444             glay.addWidget(&selectEncryptionCertificatesGB, glay.rowCount(), 0, 1, CertificateSelectionLine::NumColumns);
0445         }
0446 
0447         void addSigner(const QString &mailbox, const std::vector<Key> &pgp, bool pgpAmbiguous, const std::vector<Key> &cms, bool cmsAmbiguous, QWidget *q)
0448         {
0449             CertificateSelectionLine line(i18n("From:"), mailbox, pgp, pgpAmbiguous, cms, cmsAmbiguous, q, glay);
0450             signers.push_back(line);
0451         }
0452 
0453         void addRecipient(const QString &mailbox, const std::vector<Key> &pgp, bool pgpAmbiguous, const std::vector<Key> &cms, bool cmsAmbiguous, QWidget *q)
0454         {
0455             CertificateSelectionLine line(i18n("To:"), mailbox, pgp, pgpAmbiguous, cms, cmsAmbiguous, q, glay);
0456             recipients.push_back(line);
0457         }
0458 
0459     } ui;
0460 };
0461 
0462 SignEncryptEMailConflictDialog::SignEncryptEMailConflictDialog(QWidget *parent)
0463     : QDialog(parent)
0464     , d(new Private(this))
0465 {
0466 }
0467 
0468 SignEncryptEMailConflictDialog::~SignEncryptEMailConflictDialog()
0469 {
0470 }
0471 
0472 void SignEncryptEMailConflictDialog::setPresetProtocol(Protocol p)
0473 {
0474     if (p == d->presetProtocol) {
0475         return;
0476     }
0477     const QSignalBlocker pgpBlocker(d->ui.pgpRB);
0478     const QSignalBlocker cmsBlocker(d->ui.cmsRB);
0479     really_check(d->ui.pgpRB, p == OpenPGP);
0480     really_check(d->ui.cmsRB, p == CMS);
0481     d->presetProtocol = p;
0482     d->showHideWidgets();
0483     d->updateDialogStatus();
0484 }
0485 
0486 Protocol SignEncryptEMailConflictDialog::selectedProtocol() const
0487 {
0488     if (d->presetProtocol != UnknownProtocol) {
0489         return d->presetProtocol;
0490     }
0491     if (d->ui.pgpRB.isChecked()) {
0492         return OpenPGP;
0493     }
0494     if (d->ui.cmsRB.isChecked()) {
0495         return CMS;
0496     }
0497     return UnknownProtocol;
0498 }
0499 
0500 void SignEncryptEMailConflictDialog::setSubject(const QString &subject)
0501 {
0502     setWindowTitle(i18nc("@title:window", "Select Certificates for Message \"%1\"", subject));
0503 }
0504 
0505 void SignEncryptEMailConflictDialog::setSign(bool sign)
0506 {
0507     if (sign == d->sign) {
0508         return;
0509     }
0510     d->sign = sign;
0511     d->updateTopLabelText();
0512     d->showHideWidgets();
0513     d->updateDialogStatus();
0514 }
0515 
0516 void SignEncryptEMailConflictDialog::setEncrypt(bool encrypt)
0517 {
0518     if (encrypt == d->encrypt) {
0519         return;
0520     }
0521     d->encrypt = encrypt;
0522     d->updateTopLabelText();
0523     d->showHideWidgets();
0524     d->updateDialogStatus();
0525 }
0526 
0527 void SignEncryptEMailConflictDialog::setSenders(const std::vector<Sender> &senders)
0528 {
0529     if (senders == d->senders) {
0530         return;
0531     }
0532     d->senders = senders;
0533     d->createSendersAndRecipients();
0534     d->showHideWidgets();
0535     d->updateDialogStatus();
0536 }
0537 
0538 void SignEncryptEMailConflictDialog::setRecipients(const std::vector<Recipient> &recipients)
0539 {
0540     if (d->recipients == recipients) {
0541         return;
0542     }
0543     d->recipients = recipients;
0544     d->createSendersAndRecipients();
0545     d->showHideWidgets();
0546     d->updateDialogStatus();
0547 }
0548 
0549 void SignEncryptEMailConflictDialog::pickProtocol()
0550 {
0551     if (selectedProtocol() != UnknownProtocol) {
0552         return; // already picked
0553     }
0554 
0555     const bool pgp = d->isComplete(OpenPGP);
0556     const bool cms = d->isComplete(CMS);
0557 
0558     if (pgp && !cms) {
0559         d->ui.pgpRB.setChecked(true);
0560     } else if (cms && !pgp) {
0561         d->ui.cmsRB.setChecked(true);
0562     }
0563 }
0564 
0565 bool SignEncryptEMailConflictDialog::isComplete() const
0566 {
0567     const Protocol proto = selectedProtocol();
0568     return proto != UnknownProtocol && d->isComplete(proto);
0569 }
0570 
0571 bool SignEncryptEMailConflictDialog::Private::isComplete(Protocol proto) const
0572 {
0573     return (!sign
0574             || std::none_of(ui.signers.cbegin(), //
0575                             ui.signers.cend(),
0576                             [proto](const CertificateSelectionLine &l) {
0577                                 return l.isStillAmbiguous(proto);
0578                             }))
0579         && (!encrypt
0580             || std::none_of(ui.recipients.cbegin(), //
0581                             ui.recipients.cend(),
0582                             [proto](const CertificateSelectionLine &l) {
0583                                 return l.isStillAmbiguous(proto);
0584                             }));
0585 }
0586 
0587 static std::vector<Key> get_keys(const std::vector<CertificateSelectionLine> &lines, Protocol proto)
0588 {
0589     if (proto == UnknownProtocol) {
0590         return std::vector<Key>();
0591     }
0592     Q_ASSERT(proto == OpenPGP || proto == CMS);
0593 
0594     std::vector<Key> keys;
0595     keys.reserve(lines.size());
0596     std::transform(lines.cbegin(), lines.cend(), std::back_inserter(keys), [proto](const CertificateSelectionLine &l) {
0597         return l.key(proto);
0598     });
0599     return keys;
0600 }
0601 
0602 std::vector<Key> SignEncryptEMailConflictDialog::resolvedSigningKeys() const
0603 {
0604     return d->sign ? get_keys(d->ui.signers, selectedProtocol()) : std::vector<Key>();
0605 }
0606 
0607 std::vector<Key> SignEncryptEMailConflictDialog::resolvedEncryptionKeys() const
0608 {
0609     return d->encrypt ? get_keys(d->ui.recipients, selectedProtocol()) : std::vector<Key>();
0610 }
0611 
0612 void SignEncryptEMailConflictDialog::setQuickMode(bool on)
0613 {
0614     d->ui.quickModeCB.setChecked(on);
0615 }
0616 
0617 bool SignEncryptEMailConflictDialog::isQuickMode() const
0618 {
0619     return d->ui.quickModeCB.isChecked();
0620 }
0621 
0622 void SignEncryptEMailConflictDialog::setConflict(bool conflict)
0623 {
0624     d->ui.conflictTopLB.setVisible(conflict);
0625     d->ui.quickModeTopLB.setVisible(!conflict);
0626 }
0627 
0628 #include "moc_signencryptemailconflictdialog.cpp"