diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2018-10-22 14:00:53 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-10-23 22:45:30 +0100 |
commit | 6248ddf5296538fb7c3b092624c318ebf5f56027 (patch) | |
tree | 0eccd7ae999adbc7d591fbedf0f85786bb2170f7 | |
parent | 51e7603d7ee10328c66b5eb7ab75a3e50cf86912 (diff) | |
download | subsurface-6248ddf5296538fb7c3b092624c318ebf5f56027.tar.gz |
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>
-rw-r--r-- | qt-models/divelistmodel.cpp | 51 | ||||
-rw-r--r-- | qt-models/divelistmodel.h | 7 |
2 files changed, 48 insertions, 10 deletions
diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 5a1cf1403..a12a1d9fa 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -1,29 +1,58 @@ // SPDX-License-Identifier: GPL-2.0 #include "qt-models/divelistmodel.h" #include "core/qthelper.h" -#include <QDateTime> #include "core/settings/qPrefGeneral.h" +#include <QDateTime> 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) { - if (qPrefGeneral::filterFullTextNotes()) - setFilterRole(DiveListModel::FullTextRole); - else - setFilterRole(DiveListModel::FullTextNoNotesRole); - - setFilterRegExp(QString(".*%1.*").arg(f)); - if (!qPrefGeneral::filterCaseSensitive()) - setFilterCaseSensitivity(Qt::CaseInsensitive); + filterString = f; + updateFilterState(); + invalidateFilter(); } 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() @@ -52,12 +81,14 @@ void DiveListSortModel::clear() { DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel()); mySourceModel->clear(); + filteredRows.clear(); } void DiveListSortModel::addAllDives() { DiveListModel *mySourceModel = qobject_cast<DiveListModel *>(sourceModel()); mySourceModel->addAllDives(); + updateFilterState(); } DiveListModel *DiveListModel::m_instance = NULL; diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h index caf2616a7..dcfc573ee 100644 --- a/qt-models/divelistmodel.h +++ b/qt-models/divelistmodel.h @@ -12,6 +12,7 @@ class DiveListSortModel : public QSortFilterProxyModel Q_OBJECT public: DiveListSortModel(QObject *parent = 0); + void setSourceModel(QAbstractItemModel *sourceModel); Q_INVOKABLE void addAllDives(); Q_INVOKABLE void clear(); public slots: @@ -20,6 +21,12 @@ public slots: void setFilter(QString f); void resetFilter(); 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 |