Dive list: make filter model aware of its source

The data-flow from C-core to list-view is as follows:

C-core --> DiveTripModel --> MultiSortFilterModel --> DiveListView

The control-flow, on the other hand, differs as DiveListView
accesses both MultiSortFilterModel and DiveTripModel, whereas
MultiSortFilterModel is mostly unaware of its source model.

This is in principle legitimate, as the MultiSortFilterModel might
be used for different sources. In our particular case, this is
not so. MultiSortFilterModel is written for a particular use case.

Therefore, model control-flow follow after data-flow: Let MultiSortFilterModel
set its own source model and DiveListView access the MultiSortFilterModel,
which then manages its source model.

This is not bike-shedding, but will enable a more flexible and
higher-performance sorting.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2018-10-29 14:56:48 +01:00 committed by Dirk Hohndel
parent 4636fcc834
commit 803111ef02
5 changed files with 18 additions and 12 deletions

View file

@ -33,12 +33,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
setItemDelegate(new DiveListDelegate(this));
setUniformRowHeights(true);
setItemDelegateForColumn(DiveTripModel::RATING, new StarWidgetsDelegate(this));
MultiFilterSortModel *model = MultiFilterSortModel::instance();
model->setSortRole(DiveTripModel::SORT_ROLE);
model->setFilterKeyColumn(-1); // filter all columns
model->setFilterCaseSensitivity(Qt::CaseInsensitive);
model->setSourceModel(DiveTripModel::instance());
setModel(model);
setModel(MultiFilterSortModel::instance());
setSortingEnabled(false);
setContextMenuPolicy(Qt::DefaultContextMenu);
@ -503,8 +498,7 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
header()->setSectionsClickable(true);
connect(header(), SIGNAL(sectionPressed(int)), this, SLOT(headerClicked(int)), Qt::UniqueConnection);
DiveTripModel *tripModel = DiveTripModel::instance();
tripModel->setLayout(layout); // Note: setLayout() resets the whole model
MultiFilterSortModel::instance()->setLayout(layout);
if (!forceSort)
return;

View file

@ -320,9 +320,6 @@ DiveTripModel::DiveTripModel(QObject *parent) :
connect(&diveListNotifier, &DiveListNotifier::divesSelected, this, &DiveTripModel::divesSelected);
connect(&diveListNotifier, &DiveListNotifier::divesDeselected, this, &DiveTripModel::divesDeselected);
connect(&diveListNotifier, &DiveListNotifier::currentDiveChanged, this, &DiveTripModel::currentDiveChanged);
// Update trip headers if filter finished
connect(MultiFilterSortModel::instance(), &MultiFilterSortModel::filterFinished, this, &DiveTripModel::filterFinished);
}
int DiveTripModel::columnCount(const QModelIndex&) const

View file

@ -55,6 +55,7 @@ public:
int rowCount(const QModelIndex &parent) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &index) const;
void filterFinished();
signals:
// The propagation of selection changes is complex.
// The control flow of dive-selection goes:
@ -74,7 +75,6 @@ private slots:
void divesSelected(dive_trip *trip, const QVector<dive *> &dives);
void divesDeselected(dive_trip *trip, const QVector<dive *> &dives);
void currentDiveChanged();
void filterFinished();
private:
// The model has up to two levels. At the top level, we have either trips or dives
// that do not belong to trips. Such a top-level item is represented by the "Item"

View file

@ -562,6 +562,16 @@ MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyMo
divesDisplayed(0),
curr_dive_site(NULL)
{
setSortRole(DiveTripModel::SORT_ROLE);
setFilterKeyColumn(-1); // filter all columns
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSourceModel(DiveTripModel::instance());
}
void MultiFilterSortModel::setLayout(DiveTripModel::Layout layout)
{
DiveTripModel *tripModel = DiveTripModel::instance();
tripModel->setLayout(layout); // Note: setLayout() resets the whole model
}
void MultiFilterSortModel::divesAdded(const QVector<dive *> &dives)
@ -656,6 +666,8 @@ void MultiFilterSortModel::myInvalidate()
invalidateFilter();
// Tell the dive trip model to update the displayed-counts
DiveTripModel::instance()->filterFinished();
emit filterFinished();
#if !defined(SUBSURFACE_MOBILE)

View file

@ -2,6 +2,8 @@
#ifndef FILTERMODELS_H
#define FILTERMODELS_H
#include "divetripmodel.h" // For DiveTripModel::Layout. TODO: remove in due course
#include <QStringListModel>
#include <QSortFilterProxyModel>
#include <stdint.h>
@ -132,6 +134,7 @@ slots:
void startFilterDiveSite(struct dive_site *ds);
void stopFilterDiveSite();
void filterChanged(const QModelIndex &from, const QModelIndex &to, const QVector<int> &roles);
void setLayout(DiveTripModel::Layout layout);
signals:
void filterFinished();