desktop: make divecomputer table sortable

Add a small proxy-model on top of DiveComputerModel so that clicking
on table headers makes the table sortable.

The UI feature here is not as important as the fact that the UI does
its own sorting and we can keep the device-table in the core sorted
differently.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-10-10 12:40:27 +02:00 committed by Dirk Hohndel
parent 5931be4c88
commit 215e5a4544
4 changed files with 50 additions and 3 deletions

View file

@ -20,7 +20,9 @@ DiveComputerManagementDialog::DiveComputerManagementDialog(QWidget *parent, Qt::
void DiveComputerManagementDialog::init()
{
model.reset(new DiveComputerModel);
ui.tableView->setModel(model.data());
proxyModel.setSourceModel(model.get());
ui.tableView->setModel(&proxyModel);
ui.tableView->setSortingEnabled(true);
ui.tableView->resizeColumnsToContents();
ui.tableView->setColumnWidth(DiveComputerModel::REMOVE, 22);
layout()->activate();

View file

@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef DIVECOMPUTERMANAGEMENTDIALOG_H
#define DIVECOMPUTERMANAGEMENTDIALOG_H
#include <QDialog>
#include "ui_divecomputermanagementdialog.h"
#include "qt-models/divecomputermodel.h"
#include <QDialog>
#include <memory>
class QModelIndex;
@ -23,7 +25,8 @@ slots:
private:
explicit DiveComputerManagementDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
Ui::DiveComputerManagementDialog ui;
QScopedPointer<DiveComputerModel> model;
std::unique_ptr<DiveComputerModel> model;
DiveComputerSortedModel proxyModel;
};
#endif // DIVECOMPUTERMANAGEMENTDIALOG_H

View file

@ -79,3 +79,37 @@ void DiveComputerModel::keepWorkingList()
mark_divelist_changed(true);
device_table.devices = dcs;
}
// Convenience function to access alternative columns
static QString getData(const QModelIndex &idx, int col)
{
const QAbstractItemModel *model = idx.model();
QModelIndex idx2 = model->index(idx.row(), col, idx.parent());
return model->data(idx2).toString();
}
// Helper function: sort data pointed to by the given indexes.
// For equal data, sort by two alternative rows.
// All sorting is by case-insensitive string comparison.
static bool sortHelper(const QModelIndex &i1, const QModelIndex &i2, int altRow1, int altRow2)
{
if(int cmp = i1.data().toString().compare(i2.data().toString()))
return cmp < 0;
if(int cmp = getData(i1, altRow1).compare(getData(i2, altRow1)))
return cmp < 0;
return getData(i1, altRow2).compare(getData(i2, altRow2)) < 0;
}
bool DiveComputerSortedModel::lessThan(const QModelIndex &i1, const QModelIndex &i2) const
{
// We assume that i1.column() == i2.column()
switch (i1.column()) {
case DiveComputerModel::ID:
return sortHelper(i1, i2, DiveComputerModel::MODEL, DiveComputerModel::NICKNAME);
case DiveComputerModel::MODEL:
default:
return sortHelper(i1, i2, DiveComputerModel::ID, DiveComputerModel::NICKNAME);
case DiveComputerModel::NICKNAME:
return sortHelper(i1, i2, DiveComputerModel::MODEL, DiveComputerModel::ID);
}
}

View file

@ -4,6 +4,7 @@
#include "qt-models/cleanertablemodel.h"
#include "core/device.h"
#include <QSortFilterProxyModel>
class DiveComputerModel : public CleanerTableModel {
Q_OBJECT
@ -29,4 +30,11 @@ private:
QVector<device> dcs;
};
class DiveComputerSortedModel : public QSortFilterProxyModel {
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
private:
bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const;
};
#endif