File indexing completed on 2024-06-23 05:13:50
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 crypto/gui/resolverecipientspage.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 "resolverecipientspage.h" 0013 #include "resolverecipientspage_p.h" 0014 0015 #include <dialogs/certificateselectiondialog.h> 0016 0017 #include <crypto/certificateresolver.h> 0018 0019 #include <Libkleo/Formatting> 0020 #include <Libkleo/KeyCache> 0021 0022 #include <gpgme++/key.h> 0023 0024 #include <KLocalizedString> 0025 0026 #include <QButtonGroup> 0027 #include <QComboBox> 0028 #include <QHBoxLayout> 0029 #include <QLabel> 0030 #include <QListWidget> 0031 #include <QPointer> 0032 #include <QPushButton> 0033 #include <QRadioButton> 0034 #include <QStringList> 0035 #include <QToolButton> 0036 #include <QVBoxLayout> 0037 0038 using namespace GpgME; 0039 using namespace Kleo; 0040 using namespace Kleo::Dialogs; 0041 using namespace Kleo::Crypto; 0042 using namespace Kleo::Crypto::Gui; 0043 using namespace KMime::Types; 0044 0045 ResolveRecipientsPage::ListWidget::ListWidget(QWidget *parent, Qt::WindowFlags flags) 0046 : QWidget(parent, flags) 0047 , m_protocol(UnknownProtocol) 0048 { 0049 m_listWidget = new QListWidget; 0050 m_listWidget->setSelectionMode(QAbstractItemView::MultiSelection); 0051 auto const layout = new QVBoxLayout(this); 0052 layout->addWidget(m_listWidget); 0053 connect(m_listWidget, &QListWidget::itemSelectionChanged, this, &ListWidget::onSelectionChange); 0054 } 0055 0056 ResolveRecipientsPage::ListWidget::~ListWidget() 0057 { 0058 } 0059 0060 void ResolveRecipientsPage::ListWidget::onSelectionChange() 0061 { 0062 const auto widgetskeys = widgets.keys(); 0063 for (const QString &i : widgetskeys) { 0064 Q_ASSERT(items.contains(i)); 0065 widgets[i]->setSelected(items[i]->isSelected()); 0066 } 0067 Q_EMIT selectionChanged(); 0068 } 0069 0070 void ResolveRecipientsPage::ListWidget::addEntry(const Mailbox &mbox) 0071 { 0072 addEntry(mbox.prettyAddress(), mbox.prettyAddress(), mbox); 0073 } 0074 0075 void ResolveRecipientsPage::ListWidget::addEntry(const QString &id, const QString &name) 0076 { 0077 addEntry(id, name, Mailbox()); 0078 } 0079 0080 void ResolveRecipientsPage::ListWidget::addEntry(const QString &id, const QString &name, const Mailbox &mbox) 0081 { 0082 Q_ASSERT(!widgets.contains(id) && !items.contains(id)); 0083 auto item = new QListWidgetItem; 0084 item->setData(IdRole, id); 0085 auto wid = new ItemWidget(id, name, mbox, this); 0086 connect(wid, &ItemWidget::changed, this, &ListWidget::completeChanged); 0087 wid->setProtocol(m_protocol); 0088 item->setSizeHint(wid->sizeHint()); 0089 m_listWidget->addItem(item); 0090 m_listWidget->setItemWidget(item, wid); 0091 widgets[id] = wid; 0092 items[id] = item; 0093 } 0094 0095 Mailbox ResolveRecipientsPage::ListWidget::mailbox(const QString &id) const 0096 { 0097 return widgets.contains(id) ? widgets[id]->mailbox() : Mailbox(); 0098 } 0099 0100 void ResolveRecipientsPage::ListWidget::setCertificates(const QString &id, const std::vector<Key> &pgp, const std::vector<Key> &cms) 0101 { 0102 Q_ASSERT(widgets.contains(id)); 0103 widgets[id]->setCertificates(pgp, cms); 0104 } 0105 0106 Key ResolveRecipientsPage::ListWidget::selectedCertificate(const QString &id) const 0107 { 0108 return widgets.contains(id) ? widgets[id]->selectedCertificate() : Key(); 0109 } 0110 0111 GpgME::Key ResolveRecipientsPage::ListWidget::selectedCertificate(const QString &id, GpgME::Protocol prot) const 0112 { 0113 return widgets.contains(id) ? widgets[id]->selectedCertificate(prot) : Key(); 0114 } 0115 0116 QStringList ResolveRecipientsPage::ListWidget::identifiers() const 0117 { 0118 return widgets.keys(); 0119 } 0120 0121 void ResolveRecipientsPage::ListWidget::setProtocol(GpgME::Protocol prot) 0122 { 0123 if (m_protocol == prot) { 0124 return; 0125 } 0126 m_protocol = prot; 0127 for (ItemWidget *i : std::as_const(widgets)) { 0128 i->setProtocol(prot); 0129 } 0130 } 0131 0132 void ResolveRecipientsPage::ListWidget::removeEntry(const QString &id) 0133 { 0134 if (!widgets.contains(id)) { 0135 return; 0136 } 0137 delete items[id]; 0138 items.remove(id); 0139 delete widgets[id]; 0140 widgets.remove(id); 0141 } 0142 0143 void ResolveRecipientsPage::ListWidget::showSelectionDialog(const QString &id) 0144 { 0145 if (!widgets.contains(id)) { 0146 return; 0147 } 0148 widgets[id]->showSelectionDialog(); 0149 } 0150 0151 QStringList ResolveRecipientsPage::ListWidget::selectedEntries() const 0152 { 0153 QStringList entries; 0154 const QList<QListWidgetItem *> items = m_listWidget->selectedItems(); 0155 entries.reserve(items.count()); 0156 for (const QListWidgetItem *i : items) { 0157 entries.append(i->data(IdRole).toString()); 0158 } 0159 return entries; 0160 } 0161 0162 ResolveRecipientsPage::ItemWidget::ItemWidget(const QString &id, const QString &name, const Mailbox &mbox, QWidget *parent, Qt::WindowFlags flags) 0163 : QWidget(parent, flags) 0164 , m_id(id) 0165 , m_mailbox(mbox) 0166 , m_protocol(UnknownProtocol) 0167 , m_selected(false) 0168 { 0169 Q_ASSERT(!m_id.isEmpty()); 0170 setAutoFillBackground(true); 0171 auto layout = new QHBoxLayout(this); 0172 layout->setContentsMargins(0, 0, 0, 0); 0173 layout->addSpacing(15); 0174 m_nameLabel = new QLabel; 0175 m_nameLabel->setText(name); 0176 layout->addWidget(m_nameLabel); 0177 layout->addStretch(); 0178 m_certLabel = new QLabel; 0179 m_certLabel->setText(i18n("<i>No certificate selected</i>")); 0180 layout->addWidget(m_certLabel); 0181 m_certCombo = new QComboBox; 0182 connect(m_certCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed())); 0183 layout->addWidget(m_certCombo); 0184 m_selectButton = new QToolButton; 0185 m_selectButton->setText(i18n("...")); 0186 connect(m_selectButton, &QAbstractButton::clicked, this, &ItemWidget::showSelectionDialog); 0187 layout->addWidget(m_selectButton); 0188 layout->addSpacing(15); 0189 setCertificates(std::vector<Key>(), std::vector<Key>()); 0190 } 0191 0192 void ResolveRecipientsPage::ItemWidget::updateVisibility() 0193 { 0194 m_certLabel->setVisible(m_certCombo->count() == 0); 0195 m_certCombo->setVisible(m_certCombo->count() > 0); 0196 } 0197 0198 ResolveRecipientsPage::ItemWidget::~ItemWidget() 0199 { 0200 } 0201 0202 QString ResolveRecipientsPage::ItemWidget::id() const 0203 { 0204 return m_id; 0205 } 0206 0207 void ResolveRecipientsPage::ItemWidget::setSelected(bool selected) 0208 { 0209 if (m_selected == selected) { 0210 return; 0211 } 0212 m_selected = selected; 0213 setBackgroundRole(selected ? QPalette::Highlight : QPalette::Base); 0214 const QPalette::ColorRole foreground = selected ? QPalette::HighlightedText : QPalette::Text; 0215 setForegroundRole(foreground); 0216 m_nameLabel->setForegroundRole(foreground); 0217 m_certLabel->setForegroundRole(foreground); 0218 } 0219 0220 bool ResolveRecipientsPage::ItemWidget::isSelected() const 0221 { 0222 return m_selected; 0223 } 0224 0225 static CertificateSelectionDialog *createCertificateSelectionDialog(QWidget *parent, GpgME::Protocol prot) 0226 { 0227 auto const dlg = new CertificateSelectionDialog(parent); 0228 const CertificateSelectionDialog::Options options = // 0229 CertificateSelectionDialog::SingleSelection | // 0230 CertificateSelectionDialog::EncryptOnly | // 0231 CertificateSelectionDialog::MultiSelection | // 0232 CertificateSelectionDialog::optionsFromProtocol(prot); 0233 dlg->setOptions(options); 0234 return dlg; 0235 } 0236 0237 void ResolveRecipientsPage::ItemWidget::showSelectionDialog() 0238 { 0239 QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog(this, m_protocol); 0240 0241 if (dlg->exec() == QDialog::Accepted && dlg /* still with us? */) { 0242 const GpgME::Key cert = dlg->selectedCertificate(); 0243 if (!cert.isNull()) { 0244 addCertificateToComboBox(cert); 0245 selectCertificateInComboBox(cert); 0246 } 0247 } 0248 delete dlg; 0249 } 0250 0251 Mailbox ResolveRecipientsPage::ItemWidget::mailbox() const 0252 { 0253 return m_mailbox; 0254 } 0255 0256 void ResolveRecipientsPage::ItemWidget::selectCertificateInComboBox(const Key &key) 0257 { 0258 m_certCombo->setCurrentIndex(m_certCombo->findData(QLatin1StringView(key.keyID()))); 0259 } 0260 0261 void ResolveRecipientsPage::ItemWidget::addCertificateToComboBox(const GpgME::Key &key) 0262 { 0263 m_certCombo->addItem(Formatting::formatForComboBox(key), QByteArray(key.keyID())); 0264 if (m_certCombo->count() == 1) { 0265 m_certCombo->setCurrentIndex(0); 0266 } 0267 updateVisibility(); 0268 } 0269 0270 void ResolveRecipientsPage::ItemWidget::resetCertificates() 0271 { 0272 std::vector<Key> certs; 0273 Key selected; 0274 switch (m_protocol) { 0275 case OpenPGP: 0276 certs = m_pgp; 0277 break; 0278 case CMS: 0279 certs = m_cms; 0280 break; 0281 case UnknownProtocol: 0282 certs = m_cms; 0283 certs.insert(certs.end(), m_pgp.begin(), m_pgp.end()); 0284 } 0285 0286 m_certCombo->clear(); 0287 for (const Key &i : std::as_const(certs)) { 0288 addCertificateToComboBox(i); 0289 } 0290 if (!m_selectedCertificates[m_protocol].isNull()) { 0291 selectCertificateInComboBox(m_selectedCertificates[m_protocol]); 0292 } else if (m_certCombo->count() > 0) { 0293 m_certCombo->setCurrentIndex(0); 0294 } 0295 updateVisibility(); 0296 Q_EMIT changed(); 0297 } 0298 0299 void ResolveRecipientsPage::ItemWidget::setProtocol(Protocol prot) 0300 { 0301 if (m_protocol == prot) { 0302 return; 0303 } 0304 m_selectedCertificates[m_protocol] = selectedCertificate(); 0305 if (m_protocol != UnknownProtocol) { 0306 (m_protocol == OpenPGP ? m_pgp : m_cms) = certificates(); 0307 } 0308 m_protocol = prot; 0309 resetCertificates(); 0310 } 0311 0312 void ResolveRecipientsPage::ItemWidget::setCertificates(const std::vector<Key> &pgp, const std::vector<Key> &cms) 0313 { 0314 m_pgp = pgp; 0315 m_cms = cms; 0316 resetCertificates(); 0317 } 0318 0319 Key ResolveRecipientsPage::ItemWidget::selectedCertificate() const 0320 { 0321 return KeyCache::instance()->findByKeyIDOrFingerprint(m_certCombo->itemData(m_certCombo->currentIndex(), ListWidget::IdRole).toString().toStdString()); 0322 } 0323 0324 GpgME::Key ResolveRecipientsPage::ItemWidget::selectedCertificate(GpgME::Protocol prot) const 0325 { 0326 return prot == m_protocol ? selectedCertificate() : m_selectedCertificates.value(prot); 0327 } 0328 0329 std::vector<Key> ResolveRecipientsPage::ItemWidget::certificates() const 0330 { 0331 std::vector<Key> certs; 0332 for (int i = 0; i < m_certCombo->count(); ++i) { 0333 certs.push_back(KeyCache::instance()->findByKeyIDOrFingerprint(m_certCombo->itemData(i, ListWidget::IdRole).toString().toStdString())); 0334 } 0335 return certs; 0336 } 0337 0338 class ResolveRecipientsPage::Private 0339 { 0340 friend class ::Kleo::Crypto::Gui::ResolveRecipientsPage; 0341 ResolveRecipientsPage *const q; 0342 0343 public: 0344 explicit Private(ResolveRecipientsPage *qq); 0345 ~Private(); 0346 0347 void setSelectedProtocol(Protocol protocol); 0348 void selectionChanged(); 0349 void removeSelectedEntries(); 0350 void addRecipient(); 0351 void addRecipient(const Mailbox &mbox); 0352 void addRecipient(const QString &id, const QString &name); 0353 void updateProtocolRBVisibility(); 0354 void protocolSelected(int prot); 0355 void writeSelectedCertificatesToPreferences(); 0356 void completeChangedInternal(); 0357 0358 private: 0359 ListWidget *m_listWidget; 0360 QPushButton *m_addButton; 0361 QPushButton *m_removeButton; 0362 QRadioButton *m_pgpRB; 0363 QRadioButton *m_cmsRB; 0364 QLabel *m_additionalRecipientsLabel; 0365 Protocol m_presetProtocol; 0366 Protocol m_selectedProtocol; 0367 bool m_multipleProtocolsAllowed; 0368 std::shared_ptr<RecipientPreferences> m_recipientPreferences; 0369 }; 0370 0371 ResolveRecipientsPage::Private::Private(ResolveRecipientsPage *qq) 0372 : q(qq) 0373 , m_presetProtocol(UnknownProtocol) 0374 , m_selectedProtocol(m_presetProtocol) 0375 , m_multipleProtocolsAllowed(false) 0376 , m_recipientPreferences() 0377 { 0378 connect(q, SIGNAL(completeChanged()), q, SLOT(completeChangedInternal())); 0379 q->setTitle(i18n("<b>Recipients</b>")); 0380 auto const layout = new QVBoxLayout(q); 0381 m_listWidget = new ListWidget; 0382 connect(m_listWidget, SIGNAL(selectionChanged()), q, SLOT(selectionChanged())); 0383 connect(m_listWidget, &ListWidget::completeChanged, q, &WizardPage::completeChanged); 0384 layout->addWidget(m_listWidget); 0385 m_additionalRecipientsLabel = new QLabel; 0386 m_additionalRecipientsLabel->setWordWrap(true); 0387 layout->addWidget(m_additionalRecipientsLabel); 0388 m_additionalRecipientsLabel->setVisible(false); 0389 auto buttonWidget = new QWidget; 0390 auto buttonLayout = new QHBoxLayout(buttonWidget); 0391 buttonLayout->setContentsMargins(0, 0, 0, 0); 0392 m_addButton = new QPushButton; 0393 connect(m_addButton, SIGNAL(clicked()), q, SLOT(addRecipient())); 0394 m_addButton->setText(i18n("Add Recipient...")); 0395 buttonLayout->addWidget(m_addButton); 0396 m_removeButton = new QPushButton; 0397 m_removeButton->setEnabled(false); 0398 m_removeButton->setText(i18n("Remove Selected")); 0399 connect(m_removeButton, SIGNAL(clicked()), q, SLOT(removeSelectedEntries())); 0400 buttonLayout->addWidget(m_removeButton); 0401 buttonLayout->addStretch(); 0402 layout->addWidget(buttonWidget); 0403 auto protocolWidget = new QWidget; 0404 auto protocolLayout = new QHBoxLayout(protocolWidget); 0405 auto protocolGroup = new QButtonGroup(q); 0406 connect(protocolGroup, &QButtonGroup::idClicked, q, [this](int buttonClicked) { 0407 protocolSelected(buttonClicked); 0408 }); 0409 m_pgpRB = new QRadioButton; 0410 m_pgpRB->setText(i18n("OpenPGP")); 0411 protocolGroup->addButton(m_pgpRB, OpenPGP); 0412 protocolLayout->addWidget(m_pgpRB); 0413 m_cmsRB = new QRadioButton; 0414 m_cmsRB->setText(i18n("S/MIME")); 0415 protocolGroup->addButton(m_cmsRB, CMS); 0416 protocolLayout->addWidget(m_cmsRB); 0417 protocolLayout->addStretch(); 0418 layout->addWidget(protocolWidget); 0419 } 0420 0421 ResolveRecipientsPage::Private::~Private() 0422 { 0423 } 0424 0425 void ResolveRecipientsPage::Private::completeChangedInternal() 0426 { 0427 const bool isComplete = q->isComplete(); 0428 const std::vector<Key> keys = q->resolvedCertificates(); 0429 const bool haveSecret = std::find_if(keys.begin(), 0430 keys.end(), 0431 [](const Key &key) { 0432 return key.hasSecret(); 0433 }) 0434 != keys.end(); 0435 if (isComplete && !haveSecret) { 0436 q->setExplanation( 0437 i18n("<b>Warning:</b> None of the selected certificates seem to be your own. You will not be able to decrypt the encrypted data again.")); 0438 } else { 0439 q->setExplanation(QString()); 0440 } 0441 } 0442 0443 void ResolveRecipientsPage::Private::updateProtocolRBVisibility() 0444 { 0445 const bool visible = !m_multipleProtocolsAllowed && m_presetProtocol == UnknownProtocol; 0446 m_cmsRB->setVisible(visible); 0447 m_pgpRB->setVisible(visible); 0448 if (visible) { 0449 if (m_selectedProtocol == CMS) { 0450 m_cmsRB->click(); 0451 } else { 0452 m_pgpRB->click(); 0453 } 0454 } 0455 } 0456 0457 bool ResolveRecipientsPage::isComplete() const 0458 { 0459 const QStringList ids = d->m_listWidget->identifiers(); 0460 if (ids.isEmpty()) { 0461 return false; 0462 } 0463 0464 for (const QString &i : ids) { 0465 if (d->m_listWidget->selectedCertificate(i).isNull()) { 0466 return false; 0467 } 0468 } 0469 0470 return true; 0471 } 0472 0473 ResolveRecipientsPage::ResolveRecipientsPage(QWidget *parent) 0474 : WizardPage(parent) 0475 , d(new Private(this)) 0476 { 0477 } 0478 0479 ResolveRecipientsPage::~ResolveRecipientsPage() 0480 { 0481 } 0482 0483 Protocol ResolveRecipientsPage::selectedProtocol() const 0484 { 0485 return d->m_selectedProtocol; 0486 } 0487 0488 void ResolveRecipientsPage::Private::setSelectedProtocol(Protocol protocol) 0489 { 0490 if (m_selectedProtocol == protocol) { 0491 return; 0492 } 0493 m_selectedProtocol = protocol; 0494 m_listWidget->setProtocol(m_selectedProtocol); 0495 Q_EMIT q->selectedProtocolChanged(); 0496 } 0497 0498 void ResolveRecipientsPage::Private::protocolSelected(int p) 0499 { 0500 const auto protocol = static_cast<Protocol>(p); 0501 Q_ASSERT(protocol != UnknownProtocol); 0502 setSelectedProtocol(protocol); 0503 } 0504 0505 void ResolveRecipientsPage::setPresetProtocol(Protocol prot) 0506 { 0507 if (d->m_presetProtocol == prot) { 0508 return; 0509 } 0510 d->m_presetProtocol = prot; 0511 d->setSelectedProtocol(prot); 0512 if (prot != UnknownProtocol) { 0513 d->m_multipleProtocolsAllowed = false; 0514 } 0515 d->updateProtocolRBVisibility(); 0516 } 0517 0518 Protocol ResolveRecipientsPage::presetProtocol() const 0519 { 0520 return d->m_presetProtocol; 0521 } 0522 0523 bool ResolveRecipientsPage::multipleProtocolsAllowed() const 0524 { 0525 return d->m_multipleProtocolsAllowed; 0526 } 0527 0528 void ResolveRecipientsPage::setMultipleProtocolsAllowed(bool allowed) 0529 { 0530 if (d->m_multipleProtocolsAllowed == allowed) { 0531 return; 0532 } 0533 d->m_multipleProtocolsAllowed = allowed; 0534 if (d->m_multipleProtocolsAllowed) { 0535 setPresetProtocol(UnknownProtocol); 0536 d->setSelectedProtocol(UnknownProtocol); 0537 } 0538 d->updateProtocolRBVisibility(); 0539 } 0540 0541 void ResolveRecipientsPage::Private::addRecipient(const QString &id, const QString &name) 0542 { 0543 m_listWidget->addEntry(id, name); 0544 } 0545 0546 void ResolveRecipientsPage::Private::addRecipient(const Mailbox &mbox) 0547 { 0548 m_listWidget->addEntry(mbox); 0549 } 0550 0551 void ResolveRecipientsPage::Private::addRecipient() 0552 { 0553 QPointer<CertificateSelectionDialog> dlg = createCertificateSelectionDialog(q, q->selectedProtocol()); 0554 if (dlg->exec() != QDialog::Accepted || !dlg /*q already deleted*/) { 0555 return; 0556 } 0557 const std::vector<Key> keys = dlg->selectedCertificates(); 0558 0559 int i = 0; 0560 for (const Key &key : keys) { 0561 const QStringList existing = m_listWidget->identifiers(); 0562 QString rec = i18n("Recipient"); 0563 while (existing.contains(rec)) { 0564 rec = i18nc("%1 == number", "Recipient (%1)", ++i); 0565 } 0566 addRecipient(rec, rec); 0567 const std::vector<Key> pgp = key.protocol() == OpenPGP ? std::vector<Key>(1, key) : std::vector<Key>(); 0568 const std::vector<Key> cms = key.protocol() == CMS ? std::vector<Key>(1, key) : std::vector<Key>(); 0569 m_listWidget->setCertificates(rec, pgp, cms); 0570 } 0571 Q_EMIT q->completeChanged(); 0572 } 0573 0574 static QString listKeysForInfo(const std::vector<Key> &keys) 0575 { 0576 QStringList list; 0577 std::transform(keys.begin(), keys.end(), list.begin(), &Formatting::formatKeyLink); 0578 return list.join(QLatin1StringView("<br/>")); 0579 } 0580 0581 void ResolveRecipientsPage::setAdditionalRecipientsInfo(const std::vector<Key> &recipients) 0582 { 0583 d->m_additionalRecipientsLabel->setVisible(!recipients.empty()); 0584 if (recipients.empty()) { 0585 return; 0586 } 0587 d->m_additionalRecipientsLabel->setText(i18n("<qt><p>Recipients predefined via GnuPG settings:</p>%1</qt>", listKeysForInfo(recipients))); 0588 } 0589 0590 std::vector<Key> ResolveRecipientsPage::resolvedCertificates() const 0591 { 0592 std::vector<Key> certs; 0593 const QStringList identifiers = d->m_listWidget->identifiers(); 0594 for (const QString &i : identifiers) { 0595 const GpgME::Key cert = d->m_listWidget->selectedCertificate(i); 0596 if (!cert.isNull()) { 0597 certs.push_back(cert); 0598 } 0599 } 0600 return certs; 0601 } 0602 0603 void ResolveRecipientsPage::Private::selectionChanged() 0604 { 0605 m_removeButton->setEnabled(!m_listWidget->selectedEntries().isEmpty()); 0606 } 0607 0608 void ResolveRecipientsPage::Private::removeSelectedEntries() 0609 { 0610 const auto selectedEntries{m_listWidget->selectedEntries()}; 0611 for (const QString &i : selectedEntries) { 0612 m_listWidget->removeEntry(i); 0613 } 0614 Q_EMIT q->completeChanged(); 0615 } 0616 0617 void ResolveRecipientsPage::setRecipientsUserMutable(bool isMutable) 0618 { 0619 d->m_addButton->setVisible(isMutable); 0620 d->m_removeButton->setVisible(isMutable); 0621 } 0622 0623 bool ResolveRecipientsPage::recipientsUserMutable() const 0624 { 0625 return d->m_addButton->isVisible(); 0626 } 0627 0628 std::shared_ptr<RecipientPreferences> ResolveRecipientsPage::recipientPreferences() const 0629 { 0630 return d->m_recipientPreferences; 0631 } 0632 0633 void ResolveRecipientsPage::setRecipientPreferences(const std::shared_ptr<RecipientPreferences> &prefs) 0634 { 0635 d->m_recipientPreferences = prefs; 0636 } 0637 0638 void ResolveRecipientsPage::Private::writeSelectedCertificatesToPreferences() 0639 { 0640 if (!m_recipientPreferences) { 0641 return; 0642 } 0643 0644 const auto identifiers{m_listWidget->identifiers()}; 0645 for (const QString &i : identifiers) { 0646 const Mailbox mbox = m_listWidget->mailbox(i); 0647 if (!mbox.hasAddress()) { 0648 continue; 0649 } 0650 const Key pgp = m_listWidget->selectedCertificate(i, OpenPGP); 0651 if (!pgp.isNull()) { 0652 m_recipientPreferences->setPreferredCertificate(mbox, OpenPGP, pgp); 0653 } 0654 const Key cms = m_listWidget->selectedCertificate(i, CMS); 0655 if (!cms.isNull()) { 0656 m_recipientPreferences->setPreferredCertificate(mbox, CMS, cms); 0657 } 0658 } 0659 } 0660 0661 void ResolveRecipientsPage::onNext() 0662 { 0663 d->writeSelectedCertificatesToPreferences(); 0664 } 0665 0666 #include "moc_resolverecipientspage.cpp" 0667 #include "moc_resolverecipientspage_p.cpp"