File indexing completed on 2025-01-05 04:55:48
0001 /* -*- c++ -*- 0002 keyapprovaldialog.h 0003 0004 This file is part of libkleopatra, the KDE keymanagement library 0005 SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB 0006 0007 Based on kpgpui.h 0008 SPDX-FileCopyrightText: 2001, 2002 the KPGP authors 0009 See file libkdenetwork/AUTHORS.kpgp for details 0010 0011 SPDX-License-Identifier: GPL-2.0-or-later 0012 */ 0013 0014 #include <config-libkleo.h> 0015 0016 #include "keyapprovaldialog.h" 0017 0018 #include "keyrequester.h" 0019 0020 #include <KLocalizedString> 0021 #include <KSeparator> 0022 0023 #include <QGpgME/Protocol> 0024 0025 #include <QComboBox> 0026 #include <QDialogButtonBox> 0027 #include <QGridLayout> 0028 #include <QLabel> 0029 #include <QPushButton> 0030 #include <QScreen> 0031 #include <QScrollArea> 0032 #include <QStringList> 0033 #include <QVBoxLayout> 0034 0035 #include <gpgme++/key.h> 0036 0037 static Kleo::EncryptionPreference cb2pref(int i) 0038 { 0039 switch (i) { 0040 default: 0041 case 0: 0042 return Kleo::UnknownPreference; 0043 case 1: 0044 return Kleo::NeverEncrypt; 0045 case 2: 0046 return Kleo::AlwaysEncrypt; 0047 case 3: 0048 return Kleo::AlwaysEncryptIfPossible; 0049 case 4: 0050 return Kleo::AlwaysAskForEncryption; 0051 case 5: 0052 return Kleo::AskWheneverPossible; 0053 } 0054 } 0055 0056 static int pref2cb(Kleo::EncryptionPreference p) 0057 { 0058 switch (p) { 0059 default: 0060 return 0; 0061 case Kleo::NeverEncrypt: 0062 return 1; 0063 case Kleo::AlwaysEncrypt: 0064 return 2; 0065 case Kleo::AlwaysEncryptIfPossible: 0066 return 3; 0067 case Kleo::AlwaysAskForEncryption: 0068 return 4; 0069 case Kleo::AskWheneverPossible: 0070 return 5; 0071 } 0072 } 0073 0074 static QStringList preferencesStrings() 0075 { 0076 return QStringList() << xi18n("<placeholder>none</placeholder>") // 0077 << i18n("Never Encrypt with This Key") // 0078 << i18n("Always Encrypt with This Key") // 0079 << i18n("Encrypt Whenever Encryption is Possible") // 0080 << i18n("Always Ask") // 0081 << i18n("Ask Whenever Encryption is Possible"); 0082 } 0083 0084 class Q_DECL_HIDDEN Kleo::KeyApprovalDialog::KeyApprovalDialogPrivate 0085 { 0086 public: 0087 KeyApprovalDialogPrivate() 0088 { 0089 } 0090 0091 Kleo::KeyRequester *selfRequester = nullptr; 0092 QStringList addresses; 0093 std::vector<Kleo::KeyRequester *> requesters; 0094 std::vector<QComboBox *> preferences; 0095 bool prefsChanged = false; 0096 }; 0097 0098 Kleo::KeyApprovalDialog::KeyApprovalDialog(const std::vector<Item> &recipients, const std::vector<GpgME::Key> &sender, QWidget *parent) 0099 : QDialog(parent) 0100 , d(new KeyApprovalDialogPrivate()) 0101 { 0102 setWindowTitle(i18nc("@title:window", "Encryption Key Approval")); 0103 auto mainLayout = new QVBoxLayout(this); 0104 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0105 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0106 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0107 connect(buttonBox, &QDialogButtonBox::accepted, this, &KeyApprovalDialog::accept); 0108 connect(buttonBox, &QDialogButtonBox::rejected, this, &KeyApprovalDialog::reject); 0109 okButton->setDefault(true); 0110 Q_ASSERT(!recipients.empty()); 0111 0112 QFrame *page = new QFrame(this); 0113 mainLayout->addWidget(page); 0114 mainLayout->addWidget(buttonBox); 0115 auto vlay = new QVBoxLayout(page); 0116 vlay->setContentsMargins(0, 0, 0, 0); 0117 0118 vlay->addWidget(new QLabel(i18n("The following keys will be used for encryption:"), page)); 0119 0120 auto sv = new QScrollArea(page); 0121 sv->setWidgetResizable(true); 0122 vlay->addWidget(sv); 0123 0124 QWidget *view = new QWidget(sv->viewport()); 0125 0126 auto glay = new QGridLayout(view); 0127 glay->setColumnStretch(1, 1); 0128 sv->setWidget(view); 0129 0130 int row = -1; 0131 0132 if (!sender.empty()) { 0133 ++row; 0134 glay->addWidget(new QLabel(i18n("Your keys:"), view), row, 0); 0135 d->selfRequester = new EncryptionKeyRequester(true, EncryptionKeyRequester::AllProtocols, view); 0136 d->selfRequester->setKeys(sender); 0137 glay->addWidget(d->selfRequester, row, 1); 0138 ++row; 0139 glay->addWidget(new KSeparator(Qt::Horizontal, view), row, 0, 1, 2); 0140 } 0141 0142 const QStringList prefs = preferencesStrings(); 0143 0144 for (auto it = recipients.begin(); it != recipients.end(); ++it) { 0145 ++row; 0146 glay->addWidget(new QLabel(i18n("Recipient:"), view), row, 0); 0147 glay->addWidget(new QLabel(it->address, view), row, 1); 0148 d->addresses.push_back(it->address); 0149 0150 ++row; 0151 glay->addWidget(new QLabel(i18n("Encryption keys:"), view), row, 0); 0152 KeyRequester *req = new EncryptionKeyRequester(true, EncryptionKeyRequester::AllProtocols, view); 0153 req->setKeys(it->keys); 0154 glay->addWidget(req, row, 1); 0155 d->requesters.push_back(req); 0156 0157 ++row; 0158 glay->addWidget(new QLabel(i18n("Encryption preference:"), view), row, 0); 0159 auto cb = new QComboBox(view); 0160 cb->setEditable(false); 0161 cb->addItems(prefs); 0162 glay->addWidget(cb, row, 1); 0163 cb->setCurrentIndex(pref2cb(it->pref)); 0164 connect(cb, qOverload<int>(&QComboBox::activated), this, &KeyApprovalDialog::slotPrefsChanged); 0165 d->preferences.push_back(cb); 0166 } 0167 0168 QSize size = sizeHint(); 0169 0170 // don't make the dialog too large 0171 const QSize desk = screen()->size(); 0172 resize(QSize(qMin(size.width(), 3 * desk.width() / 4), qMin(size.height(), 7 * desk.height() / 8))); 0173 } 0174 0175 Kleo::KeyApprovalDialog::~KeyApprovalDialog() = default; 0176 0177 std::vector<GpgME::Key> Kleo::KeyApprovalDialog::senderKeys() const 0178 { 0179 return d->selfRequester ? d->selfRequester->keys() : std::vector<GpgME::Key>(); 0180 } 0181 0182 std::vector<Kleo::KeyApprovalDialog::Item> Kleo::KeyApprovalDialog::items() const 0183 { 0184 Q_ASSERT(d->requesters.size() == static_cast<unsigned int>(d->addresses.size())); 0185 Q_ASSERT(d->requesters.size() == d->preferences.size()); 0186 0187 std::vector<Item> result; 0188 result.reserve(d->requesters.size()); 0189 QStringList::const_iterator ait = d->addresses.constBegin(); 0190 auto rit = d->requesters.begin(); 0191 auto cit = d->preferences.begin(); 0192 while (ait != d->addresses.constEnd()) { 0193 result.push_back(Item(*ait++, (*rit++)->keys(), cb2pref((*cit++)->currentIndex()))); 0194 } 0195 return result; 0196 } 0197 0198 bool Kleo::KeyApprovalDialog::preferencesChanged() const 0199 { 0200 return d->prefsChanged; 0201 } 0202 0203 void Kleo::KeyApprovalDialog::slotPrefsChanged() 0204 { 0205 d->prefsChanged = true; 0206 } 0207 0208 #include "moc_keyapprovaldialog.cpp"