Commit 0f3b374b authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Use tree views for key lists in group dialog

Put the two tree views below each other so that the dialog doesn't
get too wide.

GnuPG-bug-id: 5175, 5239
parent df4ce810
......@@ -10,8 +10,9 @@
#include "editgroupdialog.h"
#include "view/keytreeview.h"
#include <Libkleo/KeyListModel>
#include <Libkleo/KeyListSortFilterProxyModel>
#include <KConfigGroup>
#include <KGuiItem>
......@@ -21,47 +22,23 @@
#include <KStandardGuiItem>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QItemSelectionModel>
#include <QLabel>
#include <QLineEdit>
#include <QListView>
#include <QPushButton>
#include <QSortFilterProxyModel>
#include <QTreeView>
#include <QVBoxLayout>
#include <Libkleo/Formatting>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
Q_DECLARE_METATYPE(GpgME::Key)
namespace
{
class ProxyModel : public AbstractKeyListSortFilterProxyModel
{
Q_OBJECT
public:
ProxyModel(QObject *parent = nullptr)
: AbstractKeyListSortFilterProxyModel(parent)
{
}
~ProxyModel() override = default;
ProxyModel *clone() const override
{
// compiler-generated copy ctor is fine!
return new ProxyModel(*this);
}
};
}
class EditGroupDialog::Private
{
friend class ::Kleo::Dialogs::EditGroupDialog;
......@@ -70,15 +47,13 @@ class EditGroupDialog::Private
struct {
QLineEdit *groupNameEdit = nullptr;
QLineEdit *availableKeysFilter = nullptr;
QListView *availableKeysList = nullptr;
KeyTreeView *availableKeysList = nullptr;
QLineEdit *groupKeysFilter = nullptr;
QListView *groupKeysList = nullptr;
KeyTreeView *groupKeysList = nullptr;
QDialogButtonBox *buttonBox = nullptr;
} ui;
AbstractKeyListModel *availableKeysModel = nullptr;
ProxyModel *availableKeysFilterModel = nullptr;
AbstractKeyListModel *groupKeysModel = nullptr;
ProxyModel *groupKeysFilterModel = nullptr;
public:
Private(EditGroupDialog *qq)
......@@ -94,7 +69,7 @@ public:
mainLayout->addWidget(new KSeparator(Qt::Horizontal));
auto centerLayout = new QHBoxLayout();
auto centerLayout = new QVBoxLayout();
auto availableKeysLayout = new QVBoxLayout();
availableKeysLayout->addWidget(new QLabel(i18n("Available keys:")));
......@@ -106,32 +81,25 @@ public:
availableKeysModel = AbstractKeyListModel::createFlatKeyListModel(q);
availableKeysModel->useKeyCache(true, KeyList::AllKeys);
availableKeysFilterModel = new ProxyModel(q);
availableKeysFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
availableKeysFilterModel->setFilterKeyColumn(KeyList::Summary);
availableKeysFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
availableKeysFilterModel->setSourceModel(availableKeysModel);
availableKeysFilterModel->sort(KeyList::Summary, Qt::AscendingOrder);
ui.availableKeysList = new QListView();
ui.availableKeysList->setModel(availableKeysFilterModel);
ui.availableKeysList->setModelColumn(KeyList::Summary);
ui.availableKeysList->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.availableKeysList->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui.availableKeysList = new KeyTreeView(q);
ui.availableKeysList->view()->setRootIsDecorated(false);
ui.availableKeysList->setFlatModel(availableKeysModel);
ui.availableKeysList->setHierarchicalView(false);
availableKeysLayout->addWidget(ui.availableKeysList, /*stretch=*/ 1);
centerLayout->addLayout(availableKeysLayout, /*stretch=*/ 1);
auto buttonsLayout = new QVBoxLayout();
auto buttonsLayout = new QHBoxLayout();
buttonsLayout->addStretch(1);
auto addButton = new QPushButton();
addButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right")));
addButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
addButton->setToolTip(i18n("Add the selected keys to the group"));
addButton->setEnabled(false);
buttonsLayout->addWidget(addButton);
auto removeButton = new QPushButton();
removeButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left")));
removeButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
removeButton->setToolTip(i18n("Remove the selected keys from the group"));
removeButton->setEnabled(false);
buttonsLayout->addWidget(removeButton);
......@@ -149,17 +117,10 @@ public:
groupKeysLayout->addWidget(ui.groupKeysFilter);
groupKeysModel = AbstractKeyListModel::createFlatKeyListModel(q);
groupKeysFilterModel = new ProxyModel(q);
groupKeysFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
groupKeysFilterModel->setFilterKeyColumn(KeyList::Summary);
groupKeysFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
groupKeysFilterModel->setSourceModel(groupKeysModel);
groupKeysFilterModel->sort(KeyList::Summary, Qt::AscendingOrder);
ui.groupKeysList = new QListView();
ui.groupKeysList->setModel(groupKeysFilterModel);
ui.groupKeysList->setModelColumn(KeyList::Summary);
ui.groupKeysList->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.groupKeysList->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui.groupKeysList = new KeyTreeView(q);
ui.groupKeysList->view()->setRootIsDecorated(false);
ui.groupKeysList->setFlatModel(groupKeysModel);
ui.groupKeysList->setHierarchicalView(false);
groupKeysLayout->addWidget(ui.groupKeysList, /*stretch=*/ 1);
centerLayout->addLayout(groupKeysLayout, /*stretch=*/ 1);
......@@ -179,13 +140,15 @@ public:
q, [okButton] (const QString &text) {
okButton->setEnabled(!text.trimmed().isEmpty());
});
connect(ui.availableKeysFilter, &QLineEdit::textChanged, availableKeysFilterModel, &QSortFilterProxyModel::setFilterFixedString);
connect(ui.availableKeysList->selectionModel(), &QItemSelectionModel::selectionChanged,
connect(ui.availableKeysFilter, &QLineEdit::textChanged,
ui.availableKeysList, &KeyTreeView::setStringFilter);
connect(ui.availableKeysList->view()->selectionModel(), &QItemSelectionModel::selectionChanged,
q, [addButton] (const QItemSelection &selected, const QItemSelection &) {
addButton->setEnabled(!selected.isEmpty());
});
connect(ui.groupKeysFilter, &QLineEdit::textChanged, groupKeysFilterModel, &QSortFilterProxyModel::setFilterFixedString);
connect(ui.groupKeysList->selectionModel(), &QItemSelectionModel::selectionChanged,
connect(ui.groupKeysFilter, &QLineEdit::textChanged,
ui.groupKeysList, &KeyTreeView::setStringFilter);
connect(ui.groupKeysList->view()->selectionModel(), &QItemSelectionModel::selectionChanged,
q, [removeButton] (const QItemSelection &selected, const QItemSelection &) {
removeButton->setEnabled(!selected.isEmpty());
});
......@@ -198,7 +161,7 @@ public:
const auto fm = q->fontMetrics();
const QSize sizeHint = q->sizeHint();
const QSize defaultSize = QSize(qMax(sizeHint.width(), 150 * fm.horizontalAdvance(QLatin1Char('x'))),
sizeHint.height() + 12 * fm.lineSpacing());
sizeHint.height());
restoreLayout(defaultSize);
}
......@@ -212,12 +175,25 @@ private:
{
KConfigGroup configGroup(KSharedConfig::openConfig(), "EditGroupDialog");
configGroup.writeEntry("Size", q->size());
KConfigGroup availableKeysConfig = configGroup.group("AvailableKeysView");
ui.availableKeysList->saveLayout(availableKeysConfig);
KConfigGroup groupKeysConfig = configGroup.group("GroupKeysView");
ui.groupKeysList->saveLayout(groupKeysConfig);
configGroup.sync();
}
void restoreLayout(const QSize &defaultSize)
{
const KConfigGroup configGroup(KSharedConfig::openConfig(), "EditGroupDialog");
const KConfigGroup availableKeysConfig = configGroup.group("AvailableKeysView");
ui.availableKeysList->restoreLayout(availableKeysConfig);
const KConfigGroup groupKeysConfig = configGroup.group("GroupKeysView");
ui.groupKeysList->restoreLayout(groupKeysConfig);
const QSize size = configGroup.readEntry("Size", defaultSize);
if (size.isValid()) {
q->resize(size);
......@@ -228,44 +204,19 @@ private:
void removeKeysFromGroup();
};
namespace {
std::vector<Key> getSelectedKeys(const QListView *view)
{
const QModelIndexList selectedRows = view->selectionModel()->selectedRows();
if (selectedRows.isEmpty()) {
return std::vector<Key>();
}
const KeyListModelInterface *const keyListModel = dynamic_cast<KeyListModelInterface *>(view->model());
Q_ASSERT(keyListModel);
return keyListModel->keys(selectedRows);
}
void setSelectedKeys(const QListView *view, const std::vector<Key> &keys)
{
const KeyListModelInterface *const keyListModel = dynamic_cast<KeyListModelInterface *>(view->model());
Q_ASSERT(keyListModel);
const QModelIndexList indexes = keyListModel->indexes(keys);
for (const QModelIndex &idx : indexes) {
if (idx.isValid()) {
view->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
}
}
}
}
void EditGroupDialog::Private::addKeysToGroup()
{
const std::vector<Key> selectedGroupKeys = getSelectedKeys(ui.groupKeysList);
const std::vector<Key> selectedGroupKeys = ui.groupKeysList->selectedKeys();
const std::vector<Key> selectedKeys = getSelectedKeys(ui.availableKeysList);
const std::vector<Key> selectedKeys = ui.availableKeysList->selectedKeys();
groupKeysModel->addKeys(selectedKeys);
setSelectedKeys(ui.groupKeysList, selectedGroupKeys);
ui.groupKeysList->selectKeys(selectedGroupKeys);
}
void EditGroupDialog::Private::removeKeysFromGroup()
{
const std::vector<Key> selectedKeys = getSelectedKeys(ui.groupKeysList);
const std::vector<Key> selectedKeys = ui.groupKeysList->selectedKeys();
for (const Key &key : selectedKeys) {
groupKeysModel->removeKey(key);
}
......@@ -278,9 +229,7 @@ EditGroupDialog::EditGroupDialog(QWidget *parent)
setWindowTitle(i18nc("@title:window", "Edit Group"));
}
EditGroupDialog::~EditGroupDialog()
{
}
EditGroupDialog::~EditGroupDialog() = default;
void EditGroupDialog::setInitialFocus(FocusWidget widget)
{
......@@ -321,5 +270,3 @@ std::vector<Key> EditGroupDialog::groupKeys() const
}
return keys;
}
#include "editgroupdialog.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment