summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <dvratil@kde.org>2016-08-05 12:14:05 (GMT)
committerDaniel Vrátil <dvratil@kde.org>2016-08-05 12:14:05 (GMT)
commit6bbd8b1059328f5396cfdb2f17cbc90f75c9c9f6 (patch)
tree1c8558f35961794a3236ef8b0df294cfc905eef9
parentd6a71a4ecf0455f1c02e2749ad32b751d64794c1 (diff)
KeySelectionCombo: add id filter, manual key refreshing and UI feedback
-rw-r--r--src/ui/keyselectioncombo.cpp120
-rw-r--r--src/ui/keyselectioncombo.h13
2 files changed, 115 insertions, 18 deletions
diff --git a/src/ui/keyselectioncombo.cpp b/src/ui/keyselectioncombo.cpp
index 443c3c7..184cbc9 100644
--- a/src/ui/keyselectioncombo.cpp
+++ b/src/ui/keyselectioncombo.cpp
@@ -31,6 +31,8 @@
#include <QSortFilterProxyModel>
#include <QVector>
+#include <QTimer>
+#include <QLineEdit>
#include <KLocalizedString>
#include <KMessageBox>
@@ -81,6 +83,27 @@ public:
endInsertRows();
}
+ void removeCustomItem(const QVariant &data)
+ {
+ for (int i = 0; i < mFrontItems.count(); ++i) {
+ if (mFrontItems[i]->data == data) {
+ beginRemoveRows(QModelIndex(), i, i);
+ delete mFrontItems.takeAt(i);
+ endRemoveRows();
+ return;
+ }
+ }
+ for (int i = 0; i < mBackItems.count(); ++i) {
+ if (mBackItems[i]->data == data) {
+ const int index = mFrontItems.count() + rowCount() + i;
+ beginRemoveRows(QModelIndex(), index, index);
+ delete mBackItems.takeAt(i);
+ endRemoveRows();
+ return;
+ }
+ }
+ }
+
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE
{
return mFrontItems.count() + QSortFilterProxyModel::rowCount(parent) + mBackItems.count();
@@ -132,6 +155,10 @@ public:
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE
{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
if (isCustomItem(index.row())) {
Q_ASSERT(!mFrontItems.isEmpty() || !mBackItems.isEmpty());
CustomItem *ci = static_cast<CustomItem*>(index.internalPointer());
@@ -194,7 +221,8 @@ class KeySelectionComboPrivate
{
public:
KeySelectionComboPrivate(KeySelectionCombo *parent)
- : q(parent)
+ : wasEnabled(true)
+ , q(parent)
{
}
@@ -202,6 +230,8 @@ public:
Kleo::KeyListSortFilterProxyModel *sortFilterProxy;
ProxyModel *proxyModel;
boost::shared_ptr<Kleo::KeyCache> cache;
+ QString defaultKey;
+ bool wasEnabled;
private:
KeySelectionCombo * const q;
@@ -216,25 +246,8 @@ KeySelectionCombo::KeySelectionCombo(QWidget* parent)
: QComboBox(parent)
, d(new KeySelectionComboPrivate(this))
{
- d->cache = Kleo::KeyCache::mutableInstance();
d->model = Kleo::AbstractKeyListModel::createFlatKeyListModel(this);
- if (!d->cache->initialized()) {
- setEnabled(false);
- connect(d->cache.get(), &Kleo::KeyCache::keyListingDone,
- this, [this]() {
- qDebug() << "Key listing done";
- setEnabled(true);
- // Set useKeyCache ensures that the cache is populated
- // so this can be a blocking call if the cache is not initalized
- d->model->useKeyCache(true, true);
- setCurrentIndex(0);
- });
- d->cache->startKeyListing();
- } else {
- d->model->useKeyCache(true, true);
- }
-
d->sortFilterProxy = new Kleo::KeyListSortFilterProxyModel(this);
d->sortFilterProxy->setSourceModel(d->model);
@@ -250,6 +263,10 @@ KeySelectionCombo::KeySelectionCombo(QWidget* parent)
Q_EMIT currentKeyChanged(currentKey());
}
});
+
+ d->cache = Kleo::KeyCache::mutableInstance();
+
+ QTimer::singleShot(0, this, &KeySelectionCombo::init);
}
KeySelectionCombo::~KeySelectionCombo()
@@ -257,11 +274,59 @@ KeySelectionCombo::~KeySelectionCombo()
delete d;
}
+void KeySelectionCombo::init()
+{
+ connect(d->cache.get(), &Kleo::KeyCache::keyListingDone,
+ this, [this]() {
+ qDebug() << "Key listing done";
+ // Set useKeyCache ensures that the cache is populated
+ // so this can be a blocking call if the cache is not initalized
+ d->model->useKeyCache(true, true);
+ d->proxyModel->removeCustomItem(QStringLiteral("-libkleo-loading-keys"));
+ setEnabled(d->wasEnabled);
+ bool match = false;
+ for (int i = 0; i < count(); ++i) {
+ const GpgME::Key key = itemData(i, Kleo::AbstractKeyListModel::KeyRole).value<GpgME::Key>();
+ if (d->defaultKey == key.primaryFingerprint()) {
+ setCurrentIndex(i);
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ setCurrentIndex(0);
+ }
+ Q_EMIT keyListingFinished();
+ });
+
+ if (!d->cache->initialized()) {
+ refreshKeys();
+ } else {
+ d->model->useKeyCache(true, true);
+ }
+}
+
+
void KeySelectionCombo::setKeyFilter(const boost::shared_ptr<const KeyFilter> &kf)
{
d->sortFilterProxy->setKeyFilter(kf);
}
+boost::shared_ptr<const KeyFilter> KeySelectionCombo::keyFilter() const
+{
+ return d->sortFilterProxy->keyFilter();
+}
+
+void KeySelectionCombo::setIdFilter(const QString &id)
+{
+ d->sortFilterProxy->setFilterRegExp(id);
+}
+
+QString KeySelectionCombo::idFilter() const
+{
+ return d->sortFilterProxy->filterRegExp().pattern();
+}
+
GpgME::Key Kleo::KeySelectionCombo::currentKey() const
{
return currentData(Kleo::KeyListModelInterface::KeyRole).value<GpgME::Key>();
@@ -275,6 +340,17 @@ void Kleo::KeySelectionCombo::setCurrentKey(const GpgME::Key &key)
}
}
+void KeySelectionCombo::refreshKeys()
+{
+ d->wasEnabled = isEnabled();
+ setEnabled(false);
+ const bool wasBlocked = blockSignals(true);
+ prependCustomItem(QIcon(), i18n("Loading keys ..."), QStringLiteral("-libkleo-loading-keys"));
+ setCurrentIndex(0);
+ blockSignals(wasBlocked);
+ d->cache->startKeyListing();
+}
+
void KeySelectionCombo::appendCustomItem(const QIcon &icon, const QString &text, const QVariant &data)
{
d->proxyModel->appendItem(icon, text, data);
@@ -285,6 +361,14 @@ void KeySelectionCombo::prependCustomItem(const QIcon &icon, const QString &text
d->proxyModel->prependItem(icon, text, data);
}
+void Kleo::KeySelectionCombo::setDefaultKey(const QString &fingerprint)
+{
+ d->defaultKey = fingerprint;
+}
+QString Kleo::KeySelectionCombo::defaultKey() const
+{
+ return d->defaultKey;
+}
#include "keyselectioncombo.moc"
diff --git a/src/ui/keyselectioncombo.h b/src/ui/keyselectioncombo.h
index a40020f..cbf16d4 100644
--- a/src/ui/keyselectioncombo.h
+++ b/src/ui/keyselectioncombo.h
@@ -47,16 +47,29 @@ public:
virtual ~KeySelectionCombo();
void setKeyFilter(const boost::shared_ptr<const KeyFilter> &kf);
+ boost::shared_ptr<const KeyFilter> keyFilter() const;
+
+ void setIdFilter(const QString &id);
+ QString idFilter() const;
+
+ void refreshKeys();
GpgME::Key currentKey() const;
void setCurrentKey(const GpgME::Key &key);
+ void setDefaultKey(const QString &fingerprint);
+ QString defaultKey() const;
+
void prependCustomItem(const QIcon &icon, const QString &text, const QVariant &data);
void appendCustomItem(const QIcon &icon, const QString &text, const QVariant &data);
Q_SIGNALS:
void customItemSelected(const QVariant &data);
void currentKeyChanged(const GpgME::Key &key);
+ void keyListingFinished();
+
+protected:
+ virtual void init();
private:
KeySelectionComboPrivate * const d;