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

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     crypto/gui/signerresolvepage.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "signerresolvepage.h"
0013 #include "signerresolvepage_p.h"
0014 
0015 #include "signingcertificateselectiondialog.h"
0016 
0017 #include "crypto/certificateresolver.h"
0018 #include "utils/certificatepair.h"
0019 
0020 #include <Libkleo/Formatting>
0021 #include <Libkleo/KeyCache>
0022 
0023 #include <utils/kleo_assert.h>
0024 
0025 #include <gpgme++/key.h>
0026 
0027 #include <KLocalizedString>
0028 #include <QDialog>
0029 
0030 #include <QButtonGroup>
0031 #include <QCheckBox>
0032 #include <QGridLayout>
0033 #include <QGroupBox>
0034 #include <QLabel>
0035 #include <QPointer>
0036 #include <QPushButton>
0037 #include <QRadioButton>
0038 #include <QVBoxLayout>
0039 
0040 using namespace GpgME;
0041 using namespace Kleo;
0042 using namespace Kleo::Crypto;
0043 using namespace Kleo::Crypto::Gui;
0044 
0045 namespace
0046 {
0047 static SignerResolvePage::Operation operationFromFlags(bool sign, bool encrypt)
0048 {
0049     if (!encrypt && sign) {
0050         return SignerResolvePage::SignOnly;
0051     }
0052     if (!sign && encrypt) {
0053         return SignerResolvePage::EncryptOnly;
0054     }
0055     return SignerResolvePage::SignAndEncrypt;
0056 }
0057 
0058 static QString formatLabel(Protocol p, const Key &key)
0059 {
0060     return i18nc("%1=protocol (S/Mime, OpenPGP), %2=certificate",
0061                  "Sign using %1: %2",
0062                  Formatting::displayName(p),
0063                  !key.isNull() ? Formatting::formatForComboBox(key) : i18n("No certificate selected"));
0064 }
0065 
0066 static std::vector<Protocol> supportedProtocols()
0067 {
0068     std::vector<Protocol> protocols;
0069     protocols.push_back(OpenPGP);
0070     protocols.push_back(CMS);
0071     return protocols;
0072 }
0073 }
0074 
0075 AbstractSigningProtocolSelectionWidget::AbstractSigningProtocolSelectionWidget(QWidget *p, Qt::WindowFlags f)
0076     : QWidget(p, f)
0077 {
0078 }
0079 
0080 ReadOnlyProtocolSelectionWidget::ReadOnlyProtocolSelectionWidget(QWidget *p, Qt::WindowFlags f)
0081     : AbstractSigningProtocolSelectionWidget(p, f)
0082 {
0083     auto const layout = new QVBoxLayout(this);
0084     layout->setContentsMargins(0, 0, 0, 0);
0085     const auto supportedProtocolsLst = supportedProtocols();
0086     for (const Protocol i : supportedProtocolsLst) {
0087         auto const l = new QLabel;
0088         l->setText(formatLabel(i, Key()));
0089         layout->addWidget(l);
0090         m_labels[i] = l;
0091     }
0092 }
0093 
0094 void ReadOnlyProtocolSelectionWidget::setProtocolChecked(Protocol protocol, bool checked)
0095 {
0096     QLabel *const l = label(protocol);
0097     Q_ASSERT(l);
0098     l->setVisible(checked);
0099 }
0100 
0101 bool ReadOnlyProtocolSelectionWidget::isProtocolChecked(Protocol protocol) const
0102 {
0103     QLabel *const l = label(protocol);
0104     Q_ASSERT(l);
0105     return l->isVisible();
0106 }
0107 
0108 std::set<Protocol> ReadOnlyProtocolSelectionWidget::checkedProtocols() const
0109 {
0110     std::set<Protocol> res;
0111     for (const Protocol i : supportedProtocols()) {
0112         if (isProtocolChecked(i)) {
0113             res.insert(i);
0114         }
0115     }
0116     return res;
0117 }
0118 
0119 SigningProtocolSelectionWidget::SigningProtocolSelectionWidget(QWidget *parent, Qt::WindowFlags f)
0120     : AbstractSigningProtocolSelectionWidget(parent, f)
0121 {
0122     m_buttonGroup = new QButtonGroup(this);
0123     connect(m_buttonGroup, &QButtonGroup::idClicked, this, &SigningProtocolSelectionWidget::userSelectionChanged);
0124 
0125     auto const layout = new QVBoxLayout(this);
0126     layout->setContentsMargins(0, 0, 0, 0);
0127     for (const Protocol i : supportedProtocols()) {
0128         auto const b = new QCheckBox;
0129         b->setText(formatLabel(i, Key()));
0130         m_buttons[i] = b;
0131         layout->addWidget(b);
0132         m_buttonGroup->addButton(b);
0133     }
0134     setExclusive(true);
0135 }
0136 
0137 void SigningProtocolSelectionWidget::setProtocolChecked(Protocol p, bool checked)
0138 {
0139     Q_ASSERT(p != UnknownProtocol);
0140     QCheckBox *const b = button(p);
0141     Q_ASSERT(b);
0142     b->setChecked(checked);
0143 }
0144 
0145 bool SigningProtocolSelectionWidget::isProtocolChecked(Protocol p) const
0146 {
0147     Q_ASSERT(p != UnknownProtocol);
0148     const QAbstractButton *const b = button(p);
0149     Q_ASSERT(b);
0150     return b->isChecked();
0151 }
0152 
0153 std::set<Protocol> SigningProtocolSelectionWidget::checkedProtocols() const
0154 {
0155     std::set<Protocol> res;
0156     for (auto it = m_buttons.begin(), end = m_buttons.end(); it != end; ++it)
0157         if (it->second->isChecked()) {
0158             res.insert(it->first);
0159         }
0160     return res;
0161 }
0162 
0163 void SigningProtocolSelectionWidget::setExclusive(bool exclusive)
0164 {
0165     if (exclusive == isExclusive()) {
0166         return;
0167     }
0168     m_buttonGroup->setExclusive(exclusive);
0169     Q_EMIT userSelectionChanged();
0170 }
0171 
0172 QCheckBox *SigningProtocolSelectionWidget::button(Protocol p) const
0173 {
0174     const auto it = m_buttons.find(p);
0175     return it == m_buttons.end() ? nullptr : it->second;
0176 }
0177 
0178 QLabel *ReadOnlyProtocolSelectionWidget::label(Protocol p) const
0179 {
0180     const auto it = m_labels.find(p);
0181     return it == m_labels.end() ? nullptr : it->second;
0182 }
0183 
0184 bool SigningProtocolSelectionWidget::isExclusive() const
0185 {
0186     return m_buttonGroup->exclusive();
0187 }
0188 
0189 void SigningProtocolSelectionWidget::setCertificate(Protocol prot, const Key &key)
0190 {
0191     QAbstractButton *const b = button(prot);
0192     Q_ASSERT(b);
0193     b->setText(formatLabel(prot, key));
0194 }
0195 
0196 void ReadOnlyProtocolSelectionWidget::setCertificate(Protocol prot, const Key &key)
0197 {
0198     QLabel *const l = label(prot);
0199     l->setText(formatLabel(prot, key));
0200 }
0201 
0202 namespace
0203 {
0204 
0205 class ValidatorImpl : public SignerResolvePage::Validator
0206 {
0207 public:
0208     QString explanation() const override
0209     {
0210         return QString();
0211     }
0212     bool isComplete() const override
0213     {
0214         return true;
0215     }
0216     QString customWindowTitle() const override
0217     {
0218         return QString();
0219     }
0220 };
0221 }
0222 
0223 class SignerResolvePage::Private
0224 {
0225     friend class ::Kleo::Crypto::Gui::SignerResolvePage;
0226     SignerResolvePage *const q;
0227 
0228 public:
0229     explicit Private(SignerResolvePage *qq);
0230     ~Private();
0231 
0232     void setOperation(Operation operation);
0233     void operationButtonClicked(int operation);
0234     void selectCertificates();
0235     void setCertificates(const CertificatePair &certs);
0236     void updateModeSelectionWidgets();
0237     void updateUi();
0238     bool protocolSelected(Protocol p) const;
0239     bool protocolSelectionActuallyUserMutable() const;
0240 
0241 private:
0242     QButtonGroup *signEncryptGroup;
0243     QRadioButton *signAndEncryptRB;
0244     QRadioButton *encryptOnlyRB;
0245     QRadioButton *signOnlyRB;
0246     QGroupBox *signingCertificateBox;
0247     QLabel *signerLabelLabel;
0248     QLabel *signerLabel;
0249     QGroupBox *encryptBox;
0250     QCheckBox *textArmorCO;
0251     QPushButton *selectCertificatesButton;
0252     SigningProtocolSelectionWidget *signingProtocolSelectionWidget;
0253     ReadOnlyProtocolSelectionWidget *readOnlyProtocolSelectionWidget;
0254     std::vector<Protocol> presetProtocols;
0255     bool signingMutable;
0256     bool encryptionMutable;
0257     bool signingSelected;
0258     bool encryptionSelected;
0259     bool multipleProtocolsAllowed;
0260     bool protocolSelectionUserMutable;
0261     CertificatePair certificates;
0262     std::shared_ptr<SignerResolvePage::Validator> validator;
0263     std::shared_ptr<SigningPreferences> signingPreferences;
0264 };
0265 
0266 bool SignerResolvePage::Private::protocolSelectionActuallyUserMutable() const
0267 {
0268     return (q->protocolSelectionUserMutable() || presetProtocols.empty()) && q->operation() == SignOnly;
0269 }
0270 
0271 SignerResolvePage::Private::Private(SignerResolvePage *qq)
0272     : q(qq)
0273     , presetProtocols()
0274     , signingMutable(true)
0275     , encryptionMutable(true)
0276     , signingSelected(false)
0277     , encryptionSelected(false)
0278     , multipleProtocolsAllowed(false)
0279     , protocolSelectionUserMutable(true)
0280     , validator(new ValidatorImpl)
0281 
0282 {
0283     auto layout = new QVBoxLayout(q);
0284 
0285     signEncryptGroup = new QButtonGroup(q);
0286     q->connect(signEncryptGroup, &QButtonGroup::idClicked, q, [this](int buttonClicked) {
0287         operationButtonClicked(buttonClicked);
0288     });
0289 
0290     signAndEncryptRB = new QRadioButton;
0291     signAndEncryptRB->setText(i18n("Sign and encrypt (OpenPGP only)"));
0292     signAndEncryptRB->setChecked(true);
0293     signEncryptGroup->addButton(signAndEncryptRB, SignAndEncrypt);
0294     layout->addWidget(signAndEncryptRB);
0295 
0296     encryptOnlyRB = new QRadioButton;
0297     encryptOnlyRB->setText(i18n("Encrypt only"));
0298     signEncryptGroup->addButton(encryptOnlyRB, EncryptOnly);
0299     layout->addWidget(encryptOnlyRB);
0300 
0301     signOnlyRB = new QRadioButton;
0302     signOnlyRB->setText(i18n("Sign only"));
0303     signEncryptGroup->addButton(signOnlyRB, SignOnly);
0304     layout->addWidget(signOnlyRB);
0305 
0306     encryptBox = new QGroupBox;
0307     encryptBox->setTitle(i18n("Encryption Options"));
0308     QBoxLayout *const encryptLayout = new QVBoxLayout(encryptBox);
0309     textArmorCO = new QCheckBox;
0310     textArmorCO->setText(i18n("Text output (ASCII armor)"));
0311     encryptLayout->addWidget(textArmorCO);
0312     layout->addWidget(encryptBox);
0313 
0314     signingCertificateBox = new QGroupBox;
0315     signingCertificateBox->setTitle(i18n("Signing Options"));
0316     auto signerLayout = new QGridLayout(signingCertificateBox);
0317     signerLayout->setColumnStretch(1, 1);
0318 
0319     signerLabelLabel = new QLabel;
0320     signerLabelLabel->setText(i18n("Signer:"));
0321     signerLayout->addWidget(signerLabelLabel, 1, 0);
0322     signerLabel = new QLabel;
0323     signerLayout->addWidget(signerLabel, 1, 1);
0324     signerLabelLabel->setVisible(false);
0325     signerLabel->setVisible(false);
0326 
0327     signingProtocolSelectionWidget = new SigningProtocolSelectionWidget;
0328     connect(signingProtocolSelectionWidget, SIGNAL(userSelectionChanged()), q, SLOT(updateUi()));
0329     signerLayout->addWidget(signingProtocolSelectionWidget, 2, 0, 1, -1);
0330 
0331     readOnlyProtocolSelectionWidget = new ReadOnlyProtocolSelectionWidget;
0332     signerLayout->addWidget(readOnlyProtocolSelectionWidget, 3, 0, 1, -1);
0333 
0334     selectCertificatesButton = new QPushButton;
0335     selectCertificatesButton->setText(i18n("Change Signing Certificates..."));
0336     selectCertificatesButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
0337     signerLayout->addWidget(selectCertificatesButton, 4, 0, 1, -1, Qt::AlignLeft);
0338     q->connect(selectCertificatesButton, SIGNAL(clicked()), q, SLOT(selectCertificates()));
0339     layout->addWidget(signingCertificateBox);
0340     layout->addStretch();
0341 }
0342 
0343 void SignerResolvePage::setValidator(const std::shared_ptr<SignerResolvePage::Validator> &validator)
0344 {
0345     Q_ASSERT(validator);
0346     d->validator = validator;
0347     d->updateUi();
0348 }
0349 
0350 std::shared_ptr<SignerResolvePage::Validator> SignerResolvePage::validator() const
0351 {
0352     return d->validator;
0353 }
0354 
0355 SignerResolvePage::Private::~Private()
0356 {
0357 }
0358 
0359 bool SignerResolvePage::Private::protocolSelected(Protocol p) const
0360 {
0361     Q_ASSERT(p != UnknownProtocol);
0362     return signingProtocolSelectionWidget->isProtocolChecked(p);
0363 }
0364 
0365 void SignerResolvePage::Private::setCertificates(const CertificatePair &certs)
0366 {
0367     certificates = certs;
0368     readOnlyProtocolSelectionWidget->setCertificate(GpgME::OpenPGP, certs.openpgp);
0369     signingProtocolSelectionWidget->setCertificate(GpgME::OpenPGP, certs.openpgp);
0370     readOnlyProtocolSelectionWidget->setCertificate(GpgME::CMS, certs.cms);
0371     signingProtocolSelectionWidget->setCertificate(GpgME::CMS, certs.cms);
0372     updateUi();
0373 }
0374 
0375 void SignerResolvePage::Private::updateUi()
0376 {
0377     const bool ismutable = protocolSelectionActuallyUserMutable();
0378     readOnlyProtocolSelectionWidget->setVisible(!ismutable);
0379     signingProtocolSelectionWidget->setVisible(ismutable);
0380 
0381     q->setExplanation(validator->explanation());
0382     Q_EMIT q->completeChanged();
0383 
0384     const QString customTitle = validator->customWindowTitle();
0385     if (!customTitle.isEmpty()) {
0386         Q_EMIT q->windowTitleChanged(customTitle);
0387     }
0388     selectCertificatesButton->setEnabled(signingProtocolSelectionWidget->checkedProtocols().size() > 0);
0389 }
0390 
0391 void SignerResolvePage::setProtocolSelectionUserMutable(bool ismutable)
0392 {
0393     if (d->protocolSelectionUserMutable == ismutable) {
0394         return;
0395     }
0396     d->protocolSelectionUserMutable = ismutable;
0397     d->updateModeSelectionWidgets();
0398 }
0399 
0400 bool SignerResolvePage::protocolSelectionUserMutable() const
0401 {
0402     return d->protocolSelectionUserMutable;
0403 }
0404 
0405 void SignerResolvePage::setMultipleProtocolsAllowed(bool allowed)
0406 {
0407     if (d->multipleProtocolsAllowed == allowed) {
0408         return;
0409     }
0410     d->multipleProtocolsAllowed = allowed;
0411     d->updateModeSelectionWidgets();
0412 }
0413 
0414 bool SignerResolvePage::multipleProtocolsAllowed() const
0415 {
0416     return d->multipleProtocolsAllowed;
0417 }
0418 
0419 void SignerResolvePage::Private::updateModeSelectionWidgets()
0420 {
0421     const bool bothMutable = signingMutable && encryptionMutable;
0422     const bool noSigningPossible = !signingSelected && !signingMutable;
0423     const bool noEncryptionPossible = !encryptionSelected && !encryptionMutable;
0424     signAndEncryptRB->setChecked(signingSelected && encryptionSelected);
0425     signOnlyRB->setChecked(signingSelected && !encryptionSelected);
0426     encryptOnlyRB->setChecked(encryptionSelected && !signingSelected);
0427     const bool canSignAndEncrypt = !noSigningPossible && !noEncryptionPossible && bothMutable && presetProtocols != std::vector<Protocol>(1, CMS);
0428     const bool canSignOnly = !encryptionSelected || encryptionMutable;
0429     const bool canEncryptOnly = !signingSelected || signingMutable;
0430 
0431     signAndEncryptRB->setEnabled(canSignAndEncrypt);
0432     signOnlyRB->setEnabled(canSignOnly);
0433     encryptOnlyRB->setEnabled(canEncryptOnly);
0434     const bool buttonsVisible = signingMutable || encryptionMutable;
0435     signOnlyRB->setVisible(buttonsVisible);
0436     encryptOnlyRB->setVisible(buttonsVisible);
0437     signAndEncryptRB->setVisible(buttonsVisible);
0438     signingProtocolSelectionWidget->setExclusive(!multipleProtocolsAllowed);
0439     signingCertificateBox->setVisible(!noSigningPossible);
0440     encryptBox->setVisible(!noEncryptionPossible);
0441     updateUi();
0442 }
0443 
0444 void SignerResolvePage::Private::selectCertificates()
0445 {
0446     QPointer<SigningCertificateSelectionDialog> dlg = new SigningCertificateSelectionDialog(q);
0447     dlg->setAllowedProtocols(signingProtocolSelectionWidget->checkedProtocols());
0448     if (dlg->exec() == QDialog::Accepted && dlg) {
0449         const auto certs = dlg->selectedCertificates();
0450         setCertificates(certs);
0451         if (signingPreferences && dlg->rememberAsDefault()) {
0452             signingPreferences->setPreferredCertificate(OpenPGP, certs.openpgp);
0453             signingPreferences->setPreferredCertificate(CMS, certs.cms);
0454         }
0455     }
0456 
0457     delete dlg;
0458     updateUi();
0459 }
0460 
0461 void SignerResolvePage::Private::operationButtonClicked(int mode_)
0462 {
0463     const auto op = static_cast<SignerResolvePage::Operation>(mode_);
0464     signingCertificateBox->setEnabled(op != EncryptOnly);
0465     encryptBox->setEnabled(op != SignOnly);
0466     if (op == SignAndEncrypt) {
0467         signingProtocolSelectionWidget->setProtocolChecked(CMS, false);
0468         readOnlyProtocolSelectionWidget->setProtocolChecked(CMS, false);
0469         signingProtocolSelectionWidget->setProtocolChecked(OpenPGP, true);
0470         readOnlyProtocolSelectionWidget->setProtocolChecked(OpenPGP, true);
0471     }
0472     updateUi();
0473 }
0474 
0475 void SignerResolvePage::Private::setOperation(Operation op)
0476 {
0477     switch (op) {
0478     case SignOnly:
0479         signOnlyRB->click();
0480         break;
0481     case EncryptOnly:
0482         encryptOnlyRB->click();
0483         break;
0484     case SignAndEncrypt:
0485         signAndEncryptRB->click();
0486         break;
0487     }
0488 }
0489 
0490 SignerResolvePage::Operation SignerResolvePage::operation() const
0491 {
0492     return operationFromFlags(signingSelected(), encryptionSelected());
0493 }
0494 
0495 SignerResolvePage::SignerResolvePage(QWidget *parent, Qt::WindowFlags f)
0496     : WizardPage(parent, f)
0497     , d(new Private(this))
0498 {
0499     setTitle(i18n("<b>Choose Operation to be Performed</b>"));
0500     //    setSubTitle( i18n( "TODO" ) );
0501     setPresetProtocol(UnknownProtocol);
0502     d->setCertificates({});
0503     d->updateModeSelectionWidgets();
0504     d->operationButtonClicked(EncryptOnly);
0505 }
0506 
0507 SignerResolvePage::~SignerResolvePage()
0508 {
0509 }
0510 
0511 void SignerResolvePage::setSignersAndCandidates(const std::vector<KMime::Types::Mailbox> &signers, const std::vector<std::vector<GpgME::Key>> &keys)
0512 {
0513     kleo_assert(signers.empty() || signers.size() == keys.size());
0514 
0515     switch (signers.size()) {
0516     case 0:
0517         d->signerLabelLabel->setVisible(false);
0518         d->signerLabel->setVisible(false); // TODO: use default identity?
0519         break;
0520     case 1:
0521         d->signerLabelLabel->setVisible(true);
0522         d->signerLabel->setVisible(true); // TODO: use default identity?
0523         d->signerLabel->setText(signers.front().prettyAddress());
0524         break;
0525     default: // > 1
0526         kleo_assert(!"Resolving multiple signers not implemented");
0527     }
0528     d->updateUi();
0529 }
0530 
0531 void SignerResolvePage::setPresetProtocol(Protocol protocol)
0532 {
0533     std::vector<Protocol> protocols;
0534     if (protocol != CMS) {
0535         protocols.push_back(OpenPGP);
0536     }
0537     if (protocol != OpenPGP) {
0538         protocols.push_back(CMS);
0539     }
0540     setPresetProtocols(protocols);
0541     d->updateUi();
0542 }
0543 
0544 void SignerResolvePage::setPresetProtocols(const std::vector<Protocol> &protocols)
0545 {
0546     d->presetProtocols = protocols;
0547     for (const Protocol i : supportedProtocols()) {
0548         const bool checked = std::find(protocols.begin(), protocols.end(), i) != protocols.end();
0549         d->signingProtocolSelectionWidget->setProtocolChecked(i, checked);
0550         d->readOnlyProtocolSelectionWidget->setProtocolChecked(i, checked);
0551     }
0552     d->updateModeSelectionWidgets();
0553 }
0554 
0555 std::set<Protocol> SignerResolvePage::selectedProtocols() const
0556 {
0557     return d->signingProtocolSelectionWidget->checkedProtocols();
0558 }
0559 
0560 std::vector<Key> SignerResolvePage::signingCertificates(Protocol protocol) const
0561 {
0562     std::vector<Key> result;
0563     if (protocol != CMS && d->signingProtocolSelectionWidget->isProtocolChecked(OpenPGP) && !d->certificates.openpgp.isNull()) {
0564         result.push_back(d->certificates.openpgp);
0565     }
0566     if (protocol != OpenPGP && d->signingProtocolSelectionWidget->isProtocolChecked(CMS) && !d->certificates.cms.isNull()) {
0567         result.push_back(d->certificates.cms);
0568     }
0569     return result;
0570 }
0571 
0572 std::vector<Key> SignerResolvePage::resolvedSigners() const
0573 {
0574     std::vector<Key> result = signingCertificates(CMS);
0575     const std::vector<Key> pgp = signingCertificates(OpenPGP);
0576     result.insert(result.end(), pgp.begin(), pgp.end());
0577     return result;
0578 }
0579 
0580 bool SignerResolvePage::isComplete() const
0581 {
0582     Q_ASSERT(d->validator);
0583     return d->validator->isComplete();
0584 }
0585 
0586 bool SignerResolvePage::encryptionSelected() const
0587 {
0588     return !d->signOnlyRB->isChecked();
0589 }
0590 
0591 void SignerResolvePage::setEncryptionSelected(bool selected)
0592 {
0593     d->encryptionSelected = selected;
0594     d->updateModeSelectionWidgets();
0595     d->setOperation(operationFromFlags(d->signingSelected, d->encryptionSelected));
0596 }
0597 
0598 bool SignerResolvePage::signingSelected() const
0599 {
0600     return !d->encryptOnlyRB->isChecked();
0601 }
0602 
0603 void SignerResolvePage::setSigningSelected(bool selected)
0604 {
0605     d->signingSelected = selected;
0606     d->updateModeSelectionWidgets();
0607     d->setOperation(operationFromFlags(d->signingSelected, d->encryptionSelected));
0608 }
0609 
0610 bool SignerResolvePage::isEncryptionUserMutable() const
0611 {
0612     return d->encryptionMutable;
0613 }
0614 
0615 bool SignerResolvePage::isSigningUserMutable() const
0616 {
0617     return d->signingMutable;
0618 }
0619 
0620 void SignerResolvePage::setEncryptionUserMutable(bool ismutable)
0621 {
0622     d->encryptionMutable = ismutable;
0623     d->updateModeSelectionWidgets();
0624 }
0625 
0626 void SignerResolvePage::setSigningUserMutable(bool ismutable)
0627 {
0628     d->signingMutable = ismutable;
0629     d->updateModeSelectionWidgets();
0630 }
0631 
0632 std::set<Protocol> SignerResolvePage::selectedProtocolsWithoutSigningCertificate() const
0633 {
0634     std::set<Protocol> res;
0635     for (const Protocol i : selectedProtocols()) {
0636         if (signingCertificates(i).empty()) {
0637             res.insert(i);
0638         }
0639     }
0640     return res;
0641 }
0642 
0643 bool SignerResolvePage::isAsciiArmorEnabled() const
0644 {
0645     return d->textArmorCO->isChecked();
0646 }
0647 
0648 void SignerResolvePage::setAsciiArmorEnabled(bool enabled)
0649 {
0650     d->textArmorCO->setChecked(enabled);
0651 }
0652 
0653 void SignerResolvePage::setSigningPreferences(const std::shared_ptr<SigningPreferences> &prefs)
0654 {
0655     d->signingPreferences = prefs;
0656     const CertificatePair certs = {prefs ? prefs->preferredCertificate(OpenPGP) : Key(), prefs ? prefs->preferredCertificate(CMS) : Key()};
0657     d->setCertificates(certs);
0658 }
0659 
0660 std::shared_ptr<SigningPreferences> SignerResolvePage::signingPreferences() const
0661 {
0662     return d->signingPreferences;
0663 }
0664 
0665 void SignerResolvePage::onNext()
0666 {
0667 }
0668 
0669 #include "moc_signerresolvepage.cpp"
0670 #include "moc_signerresolvepage_p.cpp"