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"