mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 13:10:19 +00:00
Mobile/filtering: roll our own filtering for performance reasons
The regular expression based generic filtering made things very slow on a cell phone or other, slower device. With this the results seem more reasonable. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
51e7603d7e
commit
6248ddf529
2 changed files with 49 additions and 11 deletions
|
@ -1,29 +1,58 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include "qt-models/divelistmodel.h"
|
#include "qt-models/divelistmodel.h"
|
||||||
#include "core/qthelper.h"
|
#include "core/qthelper.h"
|
||||||
#include <QDateTime>
|
|
||||||
#include "core/settings/qPrefGeneral.h"
|
#include "core/settings/qPrefGeneral.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
DiveListSortModel::DiveListSortModel(QObject *parent) : QSortFilterProxyModel(parent)
|
DiveListSortModel::DiveListSortModel(QObject *parent) : QSortFilterProxyModel(parent)
|
||||||
{
|
{
|
||||||
|
updateFilterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiveListSortModel::updateFilterState()
|
||||||
|
{
|
||||||
|
if (filterString.isEmpty()) {
|
||||||
|
filteredRows.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// store this in local variables to avoid having to call these methods over and over
|
||||||
|
bool includeNotes = qPrefGeneral::filterFullTextNotes();
|
||||||
|
Qt::CaseSensitivity cs = qPrefGeneral::filterCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||||
|
|
||||||
|
// get the underlying model and re-calculate the filter value for each dive
|
||||||
|
DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel());
|
||||||
|
filteredRows.clear();
|
||||||
|
filteredRows.resize(mySourceModel->rowCount());
|
||||||
|
for (int i = 0; i < mySourceModel->rowCount(); i++) {
|
||||||
|
QString fullText = includeNotes? mySourceModel->at(i)->fullText() : mySourceModel->at(i)->fullTextNoNotes();
|
||||||
|
filteredRows.at(i) = fullText.contains(filterString, cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiveListSortModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||||
|
{
|
||||||
|
QSortFilterProxyModel::setSourceModel(sourceModel);
|
||||||
|
}
|
||||||
void DiveListSortModel::setFilter(QString f)
|
void DiveListSortModel::setFilter(QString f)
|
||||||
{
|
{
|
||||||
if (qPrefGeneral::filterFullTextNotes())
|
filterString = f;
|
||||||
setFilterRole(DiveListModel::FullTextRole);
|
updateFilterState();
|
||||||
else
|
invalidateFilter();
|
||||||
setFilterRole(DiveListModel::FullTextNoNotesRole);
|
|
||||||
|
|
||||||
setFilterRegExp(QString(".*%1.*").arg(f));
|
|
||||||
if (!qPrefGeneral::filterCaseSensitive())
|
|
||||||
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveListSortModel::resetFilter()
|
void DiveListSortModel::resetFilter()
|
||||||
{
|
{
|
||||||
setFilterRegExp("");
|
filterString = "";
|
||||||
|
filteredRows.clear();
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtering is way too slow on mobile. Maybe we should roll our own?
|
||||||
|
bool DiveListSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(source_parent)
|
||||||
|
|
||||||
|
return filteredRows.size() > source_row ? filteredRows[source_row] : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DiveListSortModel::shown()
|
int DiveListSortModel::shown()
|
||||||
|
@ -52,12 +81,14 @@ void DiveListSortModel::clear()
|
||||||
{
|
{
|
||||||
DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel());
|
DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel());
|
||||||
mySourceModel->clear();
|
mySourceModel->clear();
|
||||||
|
filteredRows.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveListSortModel::addAllDives()
|
void DiveListSortModel::addAllDives()
|
||||||
{
|
{
|
||||||
DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel());
|
DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel());
|
||||||
mySourceModel->addAllDives();
|
mySourceModel->addAllDives();
|
||||||
|
updateFilterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveListModel *DiveListModel::m_instance = NULL;
|
DiveListModel *DiveListModel::m_instance = NULL;
|
||||||
|
|
|
@ -12,6 +12,7 @@ class DiveListSortModel : public QSortFilterProxyModel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DiveListSortModel(QObject *parent = 0);
|
DiveListSortModel(QObject *parent = 0);
|
||||||
|
void setSourceModel(QAbstractItemModel *sourceModel);
|
||||||
Q_INVOKABLE void addAllDives();
|
Q_INVOKABLE void addAllDives();
|
||||||
Q_INVOKABLE void clear();
|
Q_INVOKABLE void clear();
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -20,6 +21,12 @@ public slots:
|
||||||
void setFilter(QString f);
|
void setFilter(QString f);
|
||||||
void resetFilter();
|
void resetFilter();
|
||||||
int shown();
|
int shown();
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||||
|
private:
|
||||||
|
std::vector<unsigned char> filteredRows; // using unsigned char because using 'bool' turns this into a bitfield
|
||||||
|
QString filterString;
|
||||||
|
void updateFilterState();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiveListModel : public QAbstractListModel
|
class DiveListModel : public QAbstractListModel
|
||||||
|
|
Loading…
Reference in a new issue