Make sure to sort entries by account (name) in the overview list.

master
Johan Ouwerkerk 2020-05-31 16:43:16 +02:00
parent 6182d26d6f
commit 532f606142
4 changed files with 75 additions and 1 deletions

View File

@ -88,7 +88,9 @@ Kirigami.ScrollablePage {
ListView {
id: mainList
model: accounts
model: Models.SortedAccountListModel {
sourceModel: accounts
}
/*
* Use a Loader to get a switch-like statement to select an
* appropriate delegate based on properties of the account model.

View File

@ -34,6 +34,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qmlRegisterUncreatableType<model::SimpleAccountListModel>("Keysmith.Models", 1, 0, "AccountListModel", "Use the Keysmith singleton to obtain an AccountListModel");
qmlRegisterUncreatableType<model::PasswordRequest>("Keysmith.Models", 1, 0, "PasswordRequestModel", "Use the Keysmith singleton to obtain an PasswordRequestModel");
qmlRegisterUncreatableType<model::AccountView>("Keysmith.Models", 1, 0, "Account", "Use an AccountListModel from the Keysmith singleton to obtain an Account");
qmlRegisterType<model::SortedAccountsListModel>("Keysmith.Models", 1, 0, "SortedAccountListModel");
qmlRegisterType<model::AccountNameValidator>("Keysmith.Validators", 1, 0, "AccountNameValidator");
qmlRegisterType<validators::Base32Validator>("Keysmith.Validators", 1, 0, "Base32SecretValidator");
qmlRegisterType<validators::UnsignedLongValidator>("Keysmith.Validators", 1, 0, "HOTPCounterValidator");

View File

@ -260,4 +260,64 @@ namespace model
qCDebug(logger) << "Ignoring new accounts model: not a valid object";
}
}
SortedAccountsListModel::SortedAccountsListModel(QObject *parent) : QSortFilterProxyModel(parent)
{
}
void SortedAccountsListModel::setSourceModel(QAbstractItemModel *sourceModel)
{
SimpleAccountListModel *model = qobject_cast<SimpleAccountListModel*>(sourceModel);
if (!model) {
qCDebug(logger) << "Not setting source model: it is not an accounts list model!";
return;
}
QSortFilterProxyModel::setSourceModel(sourceModel);
qCDebug(logger) << "Updating properties & resorting the model";
setSortRole(SimpleAccountListModel::NonStandardRoles::AccountRole);
setDynamicSortFilter(true);
setSortLocaleAware(true);
sort(0);
}
bool SortedAccountsListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
QAbstractItemModel *source = sourceModel();
Q_ASSERT_X(source, Q_FUNC_INFO, "should have a source model at this point");
SimpleAccountListModel *model = qobject_cast<SimpleAccountListModel*>(source);
// useless junk: implement sorting as no-op: claim equality between left & right
if (!model) {
qCDebug(logger) << "Short-circuiting lessThan operator: source model is not an accounts list model!";
return false;
}
QVariant leftValue = model->data(source_left, SimpleAccountListModel::NonStandardRoles::AccountRole);
QVariant rightValue = model->data(source_right, SimpleAccountListModel::NonStandardRoles::AccountRole);
AccountView * leftAccount = leftValue.isNull() ? nullptr : leftValue.value<AccountView*>();
AccountView * rightAccount = rightValue.isNull() ? nullptr : rightValue.value<AccountView*>();
// useless junk: implement sorting as no-op: claim left == right
if (!leftAccount && !rightAccount) {
qCDebug(logger) << "Short-circuiting lessThan operator: both source model indices do not point to accounts";
return false;
}
// Sort actual accounts before useless junk: claim left >= right
if (!leftAccount) {
qCDebug(logger) << "Short-circuiting lessThan operator: left source model index does not point to an account";
return false;
}
// Sort actual accounts before useless junk: claim left < right
if (!rightAccount) {
qCDebug(logger) << "Short-circuiting lessThan operator: right source model index does not point to an account";
return true;
}
// actual sorting by account name
return leftAccount->name().localeAwareCompare(rightAccount->name()) < 0;
}
}

View File

@ -13,6 +13,7 @@
#include <QHash>
#include <QModelIndex>
#include <QObject>
#include <QSortFilterProxyModel>
#include <QString>
#include <QValidator>
#include <QVector>
@ -87,6 +88,16 @@ namespace model
QHash<QString, accounts::Account*> m_accounts;
};
class SortedAccountsListModel: public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit SortedAccountsListModel(QObject *parent = nullptr);
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
};
class AccountNameValidator: public QValidator
{
Q_OBJECT