summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2018-10-22 14:00:53 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-10-23 22:45:30 +0100
commit6248ddf5296538fb7c3b092624c318ebf5f56027 (patch)
tree0eccd7ae999adbc7d591fbedf0f85786bb2170f7
parent51e7603d7ee10328c66b5eb7ab75a3e50cf86912 (diff)
downloadsubsurface-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.cpp51
-rw-r--r--qt-models/divelistmodel.h7
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