summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Heinecke <aheinecke@intevation.de>2016-04-27 13:47:52 (GMT)
committerAndre Heinecke <aheinecke@intevation.de>2016-08-02 09:53:58 (GMT)
commite10e15be16d65566f27c62e10a0d3d90814a8c3d (patch)
tree75e63a1d784ff5516e7638285663dd35c2ca0e74
parenteeb042f1febebdefe4836f4e88a2ae02659780c6 (diff)
Add new widget for certificate selection
This will be the widget to end all certificate selection widgets. Promised. The idea is that it is input and E-Mail centric and less about the protocol. It also uses the subwidgets based on models and filters to be easily customizable. Maniphest-Tasks: T2348
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/crypto/gui/certificateselectionwidget.cpp146
-rw-r--r--src/crypto/gui/certificateselectionwidget.h91
-rw-r--r--src/dialogs/certificateselectiondialog.cpp5
-rw-r--r--src/dialogs/certificateselectiondialog.h2
5 files changed, 243 insertions, 3 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7a7578d..b2dc5ec 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -145,6 +145,7 @@ set(_kleopatra_SRCS
crypto/gui/wizardpage.cpp
crypto/gui/certificateselectionline.cpp
+ crypto/gui/certificateselectionwidget.cpp
crypto/gui/certificatecombobox.cpp
crypto/gui/signingcertificateselectionwidget.cpp
crypto/gui/signingcertificateselectiondialog.cpp
@@ -168,6 +169,7 @@ set(_kleopatra_SRCS
crypto/gui/encryptemailwizard.cpp
crypto/gui/signemailwizard.cpp
crypto/gui/signencryptwizard.cpp
+ crypto/gui/certificateselectionwidget.cpp
crypto/gui/verifychecksumsdialog.cpp
diff --git a/src/crypto/gui/certificateselectionwidget.cpp b/src/crypto/gui/certificateselectionwidget.cpp
new file mode 100644
index 0000000..d7c2fbf
--- /dev/null
+++ b/src/crypto/gui/certificateselectionwidget.cpp
@@ -0,0 +1,146 @@
+/* crypto/gui/certificateselectionwidget.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2016 Intevation GmbH
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "certificateselectionwidget.h"
+
+#include <QHBoxLayout>
+#include <QComboBox>
+#include <QLineEdit>
+#include <QCompleter>
+#include <QFontMetrics>
+
+#include <boost/shared_ptr.hpp>
+
+#include "models/keylistmodel.h"
+#include "models/keylistsortfilterproxymodel.h"
+#include "models/keycache.h"
+#include "dialogs/certificateselectiondialog.h"
+#include "certificatecombobox.h"
+
+#include <KLocalizedString>
+
+#include <gpgme++/key.h>
+
+using namespace Kleo;
+using namespace Kleo::Dialogs;
+using namespace GpgME;
+
+Q_DECLARE_METATYPE(Key);
+
+#define MINIMUM_WIDTH_STR "Short LongLong <LongLong@MiddleDomain.co.uk> (12345678 - OpenPGP)"
+#define MINIMUM_MAIL_WIDTH_STR "Short.Short@MiddleDomain.co.uk"
+CertificateSelectionWidget::CertificateSelectionWidget(QWidget *parent,
+ int options, bool mailbox,
+ const QString &defaultFpr)
+ : QWidget(parent),
+ mCombo(new CertificateComboBox(i18n("Please select a certificate"))),
+ mMailEntry(new QLineEdit()),
+ mOptions(options),
+ mModel(AbstractKeyListModel::createFlatKeyListModel(this)),
+ mFilterModel(new KeyListSortFilterProxyModel(this))
+{
+ QHBoxLayout *hLay = new QHBoxLayout;
+ mMailEntry->setPlaceholderText(i18n("E-Mail"));
+ mMailEntry->setVisible(mailbox);
+ hLay->addWidget(mMailEntry, 1);
+ hLay->addWidget(mCombo, 1);
+ QFontMetrics fm(font());
+ mCombo->setMinimumWidth(fm.width(QStringLiteral(MINIMUM_WIDTH_STR)));
+ mCombo->setMaxVisibleItems(8); // According to VDG
+ mMailEntry->setMinimumWidth(fm.width(QStringLiteral(MINIMUM_MAIL_WIDTH_STR)));
+
+ QCompleter *completer = new QCompleter(this);
+ completer->setModel(mModel);
+ completer->setCompletionRole(Qt::EditRole);
+ completer->setCompletionColumn(KeyListModelInterface::PrettyEMail);
+ mMailEntry->setCompleter(completer);
+
+ mFilterModel->setSourceModel(mModel);
+ mCombo->setModel(mFilterModel);
+ mCombo->setModelColumn(KeyListModelInterface::Summary);
+
+ connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged,
+ this, &CertificateSelectionWidget::keysMayHaveChanged);
+ connect(mMailEntry, &QLineEdit::textChanged,
+ this, &CertificateSelectionWidget::mailEntryChanged);
+ connect(mCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &CertificateSelectionWidget::keyChanged);
+
+ keysMayHaveChanged();
+
+ if (mailbox) {
+ // When there is no mail entry shown we just show our stuff.
+ mCombo->setCurrentIndex(-1);
+ }
+
+ setLayout(hLay);
+}
+
+void CertificateSelectionWidget::keysMayHaveChanged()
+{
+ std::vector<Key> keys = (mOptions & CertificateSelectionDialog::SecretKeys) ? KeyCache::instance()->secretKeys()
+ : KeyCache::instance()->keys();
+ CertificateSelectionDialog::filterAllowedKeys(keys, mOptions);
+ bool wasUnselected = mCombo->currentIndex() == -1;
+ mModel->setKeys(keys);
+ mFilterModel->sort(KeyListModelInterface::Summary);
+ if (wasUnselected && mMailEntry->isVisible() && mMailEntry->text().isEmpty()) {
+ mCombo->setCurrentIndex(-1);
+ }
+}
+
+void CertificateSelectionWidget::mailEntryChanged()
+{
+ const QString mailText = mMailEntry->text();
+ if (mailText.isEmpty()) {
+ mCombo->setCurrentIndex(-1);
+ return;
+ }
+ mFilterModel->setFilterFixedString(mailText);
+ if (mFilterModel->rowCount()) {
+ mCombo->setModel(mFilterModel);
+ if (mCombo->currentIndex() == -1) {
+ mCombo->setCurrentIndex(0);
+ }
+ } else {
+ mCombo->setInitialText(i18n("(no matching certificates found)"));
+ mCombo->setCurrentIndex(-1);
+ }
+}
+
+Key CertificateSelectionWidget::key() const
+{
+ int idx = mCombo->currentIndex();
+ if (idx == -1) {
+ return Key();
+ }
+ return mCombo->currentData(KeyListModelInterface::KeyRole).value<Key>();
+}
diff --git a/src/crypto/gui/certificateselectionwidget.h b/src/crypto/gui/certificateselectionwidget.h
new file mode 100644
index 0000000..b538aaa
--- /dev/null
+++ b/src/crypto/gui/certificateselectionwidget.h
@@ -0,0 +1,91 @@
+/* crypto/gui/certificateselectionwidget.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2016 Intevation GmbH
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+#ifndef CRYPTO_GUI_CERTIFICATESELECTIONWIDGET_H
+#define CRYPTO_GUI_CERTIFICATESELECTIONWIDGET_H
+
+class QLineEdit;
+
+#include <QWidget>
+#include <QString>
+
+#include "dialogs/certificateselectiondialog.h"
+
+namespace Kleo
+{
+class AbstractKeyListModel;
+class KeyListSortFilterProxyModel;
+class CertificateComboBox;
+
+/** Generic Certificate Selection Widget.
+ *
+ * This class does not care about protocols. By default it will
+ * prefer OpenPGP. Uses the KeyCache directly to fill the choices for
+ * the selected capabilities.
+ *
+ * The widget will use a single line HBox Layout. For larger dialog
+ * see certificateslectiondialog.
+ */
+class CertificateSelectionWidget: public QWidget
+{
+ Q_OBJECT
+public:
+ /** Create the certificate selection line.
+ *
+ * @param parent: The usual widget parent.
+ * @param options: The options to use. See certificateselectiondialog.
+ * @param mailbox: If a mailbox entry should be shown.
+ * @param defaultFpr: The default fingerprint to fill this with.
+ */
+ CertificateSelectionWidget(QWidget *parent = Q_NULLPTR,
+ int otions = Dialogs::CertificateSelectionDialog::AnyFormat,
+ bool mailbox = true,
+ const QString &defaultFpr = QString());
+
+ /** Get the selected key */
+ GpgME::Key key() const;
+
+Q_SIGNALS:
+ /** Emited when the selected key changed. */
+ void keyChanged();
+
+private Q_SLOTS:
+ void keysMayHaveChanged();
+ void mailEntryChanged();
+
+private:
+ CertificateComboBox *mCombo;
+ QLineEdit *mMailEntry;
+ int mOptions;
+ AbstractKeyListModel *mModel;
+ KeyListSortFilterProxyModel *mFilterModel;
+};
+}
+#endif // CRYPTO_GUI_CERTIFICATESELECTIONWIDGET_H
diff --git a/src/dialogs/certificateselectiondialog.cpp b/src/dialogs/certificateselectiondialog.cpp
index 613d41f..44a6c12 100644
--- a/src/dialogs/certificateselectiondialog.cpp
+++ b/src/dialogs/certificateselectiondialog.cpp
@@ -107,7 +107,6 @@ private:
{
return !keys.empty();
}
- void filterAllowedKeys(std::vector<Key> &keys);
void updateLabelText()
{
ui.label.setText(!customLabelText.isEmpty() ? customLabelText :
@@ -291,7 +290,7 @@ void CertificateSelectionDialog::Private::slotKeysMayHaveChanged()
{
q->setEnabled(true);
std::vector<Key> keys = (options & SecretKeys) ? KeyCache::instance()->secretKeys() : KeyCache::instance()->keys();
- filterAllowedKeys(keys);
+ q->filterAllowedKeys(keys, options);
const std::vector<Key> selected = q->selectedCertificates();
if (AbstractKeyListModel *const model = ui.tabWidget.flatModel()) {
model->setKeys(keys);
@@ -302,7 +301,7 @@ void CertificateSelectionDialog::Private::slotKeysMayHaveChanged()
q->selectCertificates(selected);
}
-void CertificateSelectionDialog::Private::filterAllowedKeys(std::vector<Key> &keys)
+void CertificateSelectionDialog::filterAllowedKeys(std::vector<Key> &keys, int options)
{
std::vector<Key>::iterator end = keys.end();
diff --git a/src/dialogs/certificateselectiondialog.h b/src/dialogs/certificateselectiondialog.h
index 6cdbae1..057a604 100644
--- a/src/dialogs/certificateselectiondialog.h
+++ b/src/dialogs/certificateselectiondialog.h
@@ -96,6 +96,8 @@ public:
std::vector<GpgME::Key> selectedCertificates() const;
GpgME::Key selectedCertificate() const;
+ static void filterAllowedKeys(std::vector<GpgME::Key> &keys, int options);
+
public Q_SLOTS:
void setStringFilter(const QString &text);
void setKeyFilter(const boost::shared_ptr<Kleo::KeyFilter> &filter);