Add a 'filterCallback' property to SortFilterModel.

Allows setting a callback function from QML to replace the
default filter implementation.
This commit is contained in:
Eike Hein 2015-02-27 18:54:07 +01:00
parent 54899c56ba
commit 80c32e6d51
2 changed files with 55 additions and 0 deletions

View File

@ -20,6 +20,8 @@
#include "datamodel.h"
#include "datasource.h"
#include <QQmlContext>
#include <QQmlEngine>
#include <QTimer>
#include <QDebug>
@ -90,6 +92,22 @@ void SortFilterModel::setModel(QAbstractItemModel *model)
emit sourceModelChanged(model);
}
bool SortFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
if (m_filterCallback.isCallable()) {
QJSValueList args;
args << QJSValue(source_row);
const QModelIndex idx = sourceModel()->index(source_row, filterKeyColumn(), source_parent);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
args << engine->toScriptValue<QVariant>(idx.data(m_roleIds.value(m_filterRole)));
return const_cast<SortFilterModel *>(this)->m_filterCallback.call(args).toBool();
}
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
void SortFilterModel::setFilterRegExp(const QString &exp)
{
if (exp == filterRegExp()) {
@ -119,6 +137,26 @@ QString SortFilterModel::filterString() const
return m_filterString;
}
QJSValue SortFilterModel::filterCallback() const
{
return m_filterCallback;
}
void SortFilterModel::setFilterCallback(const QJSValue& callback)
{
if (m_filterCallback.strictlyEquals(callback)) {
return;
}
if (!callback.isNull() && !callback.isCallable()) {
return;
}
m_filterCallback = callback;
emit filterCallbackChanged(callback);
}
void SortFilterModel::setFilterRole(const QString &role)
{
QSortFilterProxyModel::setFilterRole(roleNameToId(role));

View File

@ -21,6 +21,7 @@
#define DATAMODEL_H
#include <QAbstractItemModel>
#include <QJSValue>
#include <QSortFilterProxyModel>
#include <QVector>
@ -56,6 +57,16 @@ class SortFilterModel : public QSortFilterProxyModel
*/
Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged REVISION 1)
/**
* A JavaScript callable that is passed the source model row index as first argument and the value
* of filterRole as second argument. The callable's return value is evaluated as boolean to determine
* whether the row is accepted (true) or filtered out (false). It overrides the default implementation
* that uses filterRegExp or filterString; while filterCallable is set those two properties are
* ignored. Attempts to write a non-callable to this property are silently ignored, but you can set
* it to null.
*/
Q_PROPERTY(QJSValue filterCallback READ filterCallback WRITE setFilterCallback NOTIFY filterCallbackChanged REVISION 1)
/**
* The role of the sourceModel on which filterRegExp must be applied.
*/
@ -90,6 +101,9 @@ public:
void setFilterString(const QString &filterString);
QString filterString() const;
void setFilterCallback(const QJSValue &callback);
QJSValue filterCallback() const;
void setFilterRole(const QString &role);
QString filterRole() const;
@ -121,9 +135,11 @@ Q_SIGNALS:
void sourceModelChanged(QObject *);
void filterRegExpChanged(const QString &);
Q_REVISION(1) void filterStringChanged(const QString &);
Q_REVISION(1) void filterCallbackChanged(const QJSValue &);
protected:
int roleNameToId(const QString &name);
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
protected Q_SLOTS:
void syncRoleNames();
@ -132,6 +148,7 @@ private:
QString m_filterRole;
QString m_sortRole;
QString m_filterString;
QJSValue m_filterCallback;
QHash<QString, int> m_roleIds;
};