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
 | // 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue