File indexing completed on 2023-12-03 09:19:05
0001 /* 0002 SPDX-FileCopyrightText: 2002 Jean-Baptiste Mardelle <bj@altern.org> 0003 SPDX-FileCopyrightText: 2007, 2008, 2009, 2010, 2011, 2012 Rolf Eike Beer <kde@opensource.sf-tec.de> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "selectpublickeydialog.h" 0008 0009 #include "kgpgsettings.h" 0010 #include "core/images.h" 0011 #include "core/KGpgRootNode.h" 0012 #include "model/kgpgitemmodel.h" 0013 #include "model/selectkeyproxymodel.h" 0014 0015 #include <QAction> 0016 #include <QCheckBox> 0017 #include <QDialogButtonBox> 0018 #include <QHBoxLayout> 0019 #include <QLabel> 0020 #include <QLineEdit> 0021 #include <QPushButton> 0022 #include <QTableView> 0023 0024 #include <KActionCollection> 0025 #include <KConfigGroup> 0026 #include <KLocalizedString> 0027 0028 using namespace KgpgCore; 0029 0030 KgpgSelectPublicKeyDlg::KgpgSelectPublicKeyDlg(QWidget *parent, KGpgItemModel *model, const QKeySequence &goDefaultKey, const bool hideasciioption, const QList<QUrl> &files) 0031 : QDialog(parent), 0032 m_customoptions(nullptr), 0033 imodel(model), 0034 m_files(files), 0035 m_hideasciioption(hideasciioption) 0036 { 0037 QWidget *mainWidget = new QWidget(this); 0038 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0039 setLayout(mainLayout); 0040 mainLayout->setSizeConstraint(QLayout::SetMinimumSize); 0041 mainLayout->addWidget(mainWidget); 0042 0043 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0044 m_okButton = buttonBox->button(QDialogButtonBox::Ok); 0045 m_okButton->setDefault(true); 0046 m_okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0047 m_detailsButton = new QPushButton(this); 0048 m_detailsButton->setText(i18n("&Options") + QStringLiteral(" >>")); 0049 m_detailsButton->setIcon(QIcon::fromTheme(QStringLiteral("help-about"))); 0050 connect(m_detailsButton, &QPushButton::clicked, this, &KgpgSelectPublicKeyDlg::toggleDetails); 0051 buttonBox->addButton(m_detailsButton, QDialogButtonBox::ActionRole); 0052 connect(buttonBox, &QDialogButtonBox::accepted, this, &KgpgSelectPublicKeyDlg::accept); 0053 connect(buttonBox, &QDialogButtonBox::rejected, this, &KgpgSelectPublicKeyDlg::reject); 0054 m_okButton->setDefault(true); 0055 0056 int fcount = files.count(); 0057 bool fmode = (fcount > 0); 0058 0059 switch (fcount) { 0060 case 0: 0061 setWindowTitle(i18n("Select Public Key")); 0062 break; 0063 case 1: 0064 setWindowTitle(i18n("Select Public Key for %1", files.first().fileName())); 0065 break; 0066 default: 0067 setWindowTitle(i18np("Select Public Key for %2 and one more file", "Select Public Key for %2 and %1 more files", files.count() - 1, files.first().fileName())); 0068 } 0069 0070 QWidget *page = new QWidget(this); 0071 0072 m_searchbar = new QWidget(page); 0073 QHBoxLayout *searchbarHBoxLayout = new QHBoxLayout(m_searchbar); 0074 searchbarHBoxLayout->setContentsMargins(0, 0, 0, 0); 0075 QLabel *searchlabel = new QLabel(i18n("&Search: "), m_searchbar); 0076 searchbarHBoxLayout->addWidget(searchlabel); 0077 0078 m_searchlineedit = new QLineEdit(m_searchbar); 0079 searchbarHBoxLayout->addWidget(m_searchlineedit); 0080 m_searchlineedit->setClearButtonEnabled(true); 0081 searchlabel->setBuddy(m_searchlineedit); 0082 0083 iproxy = new SelectKeyProxyModel(this); 0084 iproxy->setKeyModel(imodel); 0085 0086 m_keyslist = new QTableView(page); 0087 m_keyslist->setSortingEnabled(true); 0088 m_keyslist->setSelectionMode(QAbstractItemView::ExtendedSelection); 0089 m_keyslist->setSelectionBehavior(QAbstractItemView::SelectRows); 0090 m_keyslist->setModel(iproxy); 0091 m_keyslist->resizeColumnsToContents(); 0092 m_keyslist->setWhatsThis(i18n("<b>Public keys list</b>: select the key that will be used for encryption.")); 0093 connect(m_searchlineedit, &QLineEdit::textChanged, iproxy, &SelectKeyProxyModel::setFilterFixedString); 0094 0095 optionsbox = new QWidget(); 0096 QVBoxLayout *optionsboxVBoxLayout = new QVBoxLayout(optionsbox); 0097 optionsboxVBoxLayout->setContentsMargins(0, 0, 0, 0); 0098 optionsbox->hide(); 0099 0100 if (m_hideasciioption) 0101 m_cbarmor = nullptr; 0102 else 0103 { 0104 m_cbarmor = new QCheckBox(i18n("ASCII armored encryption"), optionsbox); 0105 optionsboxVBoxLayout->addWidget(m_cbarmor); 0106 m_cbarmor->setChecked(KGpgSettings::asciiArmor()); 0107 m_cbarmor->setWhatsThis(i18n("<b>ASCII encryption</b>: makes it possible to open the encrypted file/message in a text editor")); 0108 } 0109 0110 m_cbuntrusted = new QCheckBox(i18n("Allow encryption with untrusted keys"), optionsbox); 0111 optionsboxVBoxLayout->addWidget(m_cbuntrusted); 0112 // connect before setting the state so the model gets the right state from the start 0113 connect(m_cbuntrusted, &QCheckBox::toggled, this, &KgpgSelectPublicKeyDlg::slotUntrusted); 0114 m_cbuntrusted->setChecked(KGpgSettings::allowUntrustedKeys()); 0115 m_cbuntrusted->setWhatsThis(i18n("<b>Allow encryption with untrusted keys</b>: when you import a public key, it is usually " 0116 "marked as untrusted and you cannot use it unless you sign it in order to make it 'trusted'. Checking this " 0117 "box enables you to use any key, even if it has not be signed.")); 0118 0119 m_cbhideid = new QCheckBox(i18n("Hide user id"), optionsbox); 0120 optionsboxVBoxLayout->addWidget(m_cbhideid); 0121 m_cbhideid->setChecked(KGpgSettings::hideUserID()); 0122 m_cbhideid->setWhatsThis(i18n("<b>Hide user ID</b>: Do not put the keyid into encrypted packets. This option hides the receiver " 0123 "of the message and is a countermeasure against traffic analysis. It may slow down the decryption process because " 0124 "all available secret keys are tried.")); 0125 0126 m_cbsymmetric = new QCheckBox(i18n("Symmetrical encryption"), optionsbox); 0127 optionsboxVBoxLayout->addWidget(m_cbsymmetric); 0128 m_cbsymmetric->setWhatsThis(i18n("<b>Symmetrical encryption</b>: encryption does not use keys. You just need to give a password " 0129 "to encrypt/decrypt the file")); 0130 0131 QVBoxLayout *dialoglayout = new QVBoxLayout(page); 0132 dialoglayout->setContentsMargins(0, 0, 0, 0); 0133 dialoglayout->addWidget(m_searchbar); 0134 dialoglayout->addWidget(m_keyslist); 0135 page->setLayout(dialoglayout); 0136 0137 if (KGpgSettings::allowCustomEncryptionOptions()) 0138 { 0139 QWidget *expertbox = new QWidget(page); 0140 QHBoxLayout *expertboxHBoxLayout = new QHBoxLayout(expertbox); 0141 expertboxHBoxLayout->setContentsMargins(0, 0, 0, 0); 0142 (void) new QLabel(i18n("Custom option:"), expertbox); 0143 0144 m_customoptions = new QLineEdit(expertbox); 0145 expertboxHBoxLayout->addWidget(m_customoptions); 0146 m_customoptions->setText(KGpgSettings::customEncryptionOptions()); 0147 m_customoptions->setWhatsThis(i18n("<b>Custom option</b>: for experienced users only, allows you to enter a gpg command line option, like: '--armor'")); 0148 0149 dialoglayout->addWidget(expertbox); 0150 } 0151 0152 KActionCollection *actcol = new KActionCollection(this); 0153 QAction *action = actcol->addAction(QLatin1String( "go_default_key" )); 0154 action->setText(i18n("&Go to Default Key")); 0155 actcol->setDefaultShortcut(action, goDefaultKey); 0156 0157 connect(action, &QAction::triggered, this, &KgpgSelectPublicKeyDlg::slotGotoDefaultKey); 0158 connect(m_cbsymmetric, &QCheckBox::toggled, this, &KgpgSelectPublicKeyDlg::slotSymmetric); 0159 connect(m_keyslist->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KgpgSelectPublicKeyDlg::slotSelectionChanged); 0160 connect(m_keyslist, &QTableView::doubleClicked, this, &KgpgSelectPublicKeyDlg::slotOk); 0161 0162 setMinimumSize(550, 200); 0163 updateGeometry(); 0164 0165 mainLayout->addWidget(page); 0166 mainLayout->addWidget(optionsbox); 0167 mainLayout->addWidget(buttonBox); 0168 slotSelectionChanged(); 0169 0170 if (fmode) 0171 slotGotoDefaultKey(); 0172 } 0173 0174 QStringList KgpgSelectPublicKeyDlg::selectedKeys() const 0175 { 0176 if (getSymmetric()) 0177 return QStringList(); 0178 0179 QStringList selectedKeys; 0180 0181 const QModelIndexList indexes = m_keyslist->selectionModel()->selectedIndexes(); 0182 for (const QModelIndex &idx : indexes) { 0183 if (idx.column() != 0) 0184 continue; 0185 KGpgNode *nd = iproxy->nodeForIndex(idx); 0186 if (nd->getType() == ITYPE_GROUP) 0187 selectedKeys << nd->getName(); 0188 else 0189 selectedKeys << nd->getId(); 0190 } 0191 0192 return selectedKeys; 0193 } 0194 0195 bool KgpgSelectPublicKeyDlg::getSymmetric() const 0196 { 0197 return m_cbsymmetric->isChecked(); 0198 } 0199 0200 QString KgpgSelectPublicKeyDlg::getCustomOptions() const 0201 { 0202 if (m_customoptions == nullptr) 0203 return QString(); 0204 return m_customoptions->text().simplified(); 0205 } 0206 0207 bool KgpgSelectPublicKeyDlg::getUntrusted() const 0208 { 0209 return m_cbuntrusted->isChecked(); 0210 } 0211 0212 bool KgpgSelectPublicKeyDlg::getArmor() const 0213 { 0214 return m_hideasciioption || m_cbarmor->isChecked(); 0215 } 0216 0217 const QList<QUrl> &KgpgSelectPublicKeyDlg::getFiles() const 0218 { 0219 return m_files; 0220 } 0221 0222 bool KgpgSelectPublicKeyDlg::getHideId() const 0223 { 0224 return m_cbhideid->isChecked(); 0225 } 0226 0227 void KgpgSelectPublicKeyDlg::slotOk() 0228 { 0229 if (getSymmetric() || m_keyslist->selectionModel()->hasSelection()) 0230 accept(); 0231 } 0232 0233 void KgpgSelectPublicKeyDlg::slotSelectionChanged() 0234 { 0235 m_okButton->setEnabled(getSymmetric() || m_keyslist->selectionModel()->hasSelection()); 0236 } 0237 0238 void KgpgSelectPublicKeyDlg::slotSymmetric(const bool state) 0239 { 0240 m_keyslist->setDisabled(state); 0241 m_cbuntrusted->setDisabled(state); 0242 m_cbhideid->setDisabled(state); 0243 m_searchbar->setDisabled(state); 0244 slotSelectionChanged(); 0245 } 0246 0247 void KgpgSelectPublicKeyDlg::slotUntrusted(const bool state) 0248 { 0249 iproxy->setShowUntrusted(state); 0250 } 0251 0252 void KgpgSelectPublicKeyDlg::slotGotoDefaultKey() 0253 { 0254 KGpgNode *nd = imodel->getRootNode()->findKey(KGpgSettings::defaultKey()); 0255 if (nd == nullptr) 0256 return; 0257 QModelIndex sidx = imodel->nodeIndex(nd); 0258 QModelIndex pidx = iproxy->mapFromSource(sidx); 0259 m_keyslist->selectionModel()->setCurrentIndex(pidx, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 0260 } 0261 0262 void KgpgSelectPublicKeyDlg::toggleDetails() 0263 { 0264 const bool isVisible = optionsbox->isVisible(); 0265 optionsbox->setVisible(!isVisible); 0266 m_detailsButton->setText(i18n("&Options") + (isVisible ? QStringLiteral(" >>") : QStringLiteral(" <<"))); 0267 }