feat: Add FilterRole role type

This commit is contained in:
Grecko 2018-09-29 14:33:13 +02:00
parent 2b3a368ae1
commit f08fd2eaed
6 changed files with 144 additions and 3 deletions

View File

@ -26,7 +26,8 @@ HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
$$PWD/proxyroles/expressionrole.h \
$$PWD/proxyroles/singlerole.h \
$$PWD/proxyroles/regexprole.h \
$$PWD/sorters/filtersorter.h
$$PWD/sorters/filtersorter.h \
$$PWD/proxyroles/filterrole.h
SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
$$PWD/filters/filter.cpp \
@ -55,4 +56,5 @@ SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
$$PWD/proxyroles/proxyrolesqmltypes.cpp \
$$PWD/proxyroles/singlerole.cpp \
$$PWD/proxyroles/regexprole.cpp \
$$PWD/sorters/filtersorter.cpp
$$PWD/sorters/filtersorter.cpp \
$$PWD/proxyroles/filterrole.cpp

60
proxyroles/filterrole.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "filterrole.h"
#include "filters/filter.h"
namespace qqsfpm {
/*!
\qmltype FilterRole
\inherits SingleRole
\inqmlmodule SortFilterProxyModel
\brief A role resolving to \c true for rows matching all its filters
A FilterRole is a \l ProxyRole that returns \c true for rows matching all its filters.
In the following example, the \c isAdult role will be equal to \c true if the \c age role is superior or equal to 18.
SortFilterProxyModel {
sourceModel: personModel
proxyRoles: FilterRole {
name: "isAdult"
RangeFilter { roleName: "age"; minimumValue: 18; minimumInclusive: true }
}
}
\endcode
*/
/*!
\qmlproperty string FilterRole::filters
This property holds the list of filters for this filter role.
The data of this role will be equal to the \c true if all its filters match the model row, \c false otherwise.
\sa Filter
*/
void FilterRole::onFilterAppended(Filter* filter)
{
connect(filter, &Filter::invalidated, this, &FilterRole::invalidate);
invalidate();
}
void FilterRole::onFilterRemoved(Filter* filter)
{
disconnect(filter, &Filter::invalidated, this, &FilterRole::invalidate);
invalidate();
}
void FilterRole::onFiltersCleared()
{
invalidate();
}
QVariant FilterRole::data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
{
return std::all_of(m_filters.begin(), m_filters.end(),
[&] (Filter* filter) {
return filter->filterAcceptsRow(sourceIndex, proxyModel);
}
);
}
}

29
proxyroles/filterrole.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef FILTERROLE_H
#define FILTERROLE_H
#include "singlerole.h"
#include "filters/filtercontainer.h"
namespace qqsfpm {
class FilterRole : public SingleRole, public FilterContainer
{
Q_OBJECT
Q_INTERFACES(qqsfpm::FilterContainer)
Q_PROPERTY(QQmlListProperty<qqsfpm::Filter> filters READ filtersListProperty)
Q_CLASSINFO("DefaultProperty", "filters")
public:
using SingleRole::SingleRole;
private:
void onFilterAppended(Filter* filter) override;
void onFilterRemoved(Filter* filter) override;
void onFiltersCleared() override;
QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) override;
};
}
#endif // FILTERROLE_H

View File

@ -3,6 +3,7 @@
#include "switchrole.h"
#include "expressionrole.h"
#include "regexprole.h"
#include "filterrole.h"
#include <QQmlEngine>
#include <QCoreApplication>
@ -14,6 +15,7 @@ void registerProxyRoleTypes() {
qmlRegisterType<SwitchRole>("SortFilterProxyModel", 0, 2, "SwitchRole");
qmlRegisterType<ExpressionRole>("SortFilterProxyModel", 0, 2, "ExpressionRole");
qmlRegisterType<RegExpRole>("SortFilterProxyModel", 0, 2, "RegExpRole");
qmlRegisterType<FilterRole>("SortFilterProxyModel", 0, 2, "FilterRole");
}
Q_COREAPP_STARTUP_FUNCTION(registerProxyRoleTypes)

View File

@ -31,4 +31,5 @@ OTHER_FILES += \
DISTFILES += \
tst_filtercontainers.qml \
tst_regexprole.qml \
tst_filtersorter.qml
tst_filtersorter.qml \
tst_filterrole.qml

47
tests/tst_filterrole.qml Normal file
View File

@ -0,0 +1,47 @@
import QtQuick 2.0
import QtQml 2.2
import QtTest 1.1
import SortFilterProxyModel 0.2
import QtQml 2.2
Item {
ListModel {
id: listModel
ListElement { name: "1"; age: 18 }
ListElement { name: "2"; age: 22 }
ListElement { name: "3"; age: 45 }
ListElement { name: "4"; age: 10 }
}
SortFilterProxyModel {
id: testModel
sourceModel: listModel
proxyRoles: FilterRole {
name: "isOldEnough"
RangeFilter {
id: ageFilter
roleName: "age"
minimumInclusive: true
minimumValue: 18
}
}
}
TestCase {
name: "FilterRole"
function test_filterRole() {
compare(testModel.get(0, "isOldEnough"), true);
compare(testModel.get(1, "isOldEnough"), true);
compare(testModel.get(2, "isOldEnough"), true);
compare(testModel.get(3, "isOldEnough"), false);
ageFilter.minimumValue = 21;
compare(testModel.get(0, "isOldEnough"), false);
compare(testModel.get(1, "isOldEnough"), true);
compare(testModel.get(2, "isOldEnough"), true);
compare(testModel.get(3, "isOldEnough"), false);
}
}
}