mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +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
 | ||||
| #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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue