feat: Add FilterContainer and SorterContainer attached types
feat: Add FilterContainer and SorterContainer attached types
This commit is contained in:
parent
7921c92f5a
commit
314598ae54
|
@ -1,4 +1,6 @@
|
|||
#include "filtercontainer.h"
|
||||
#include "filter.h"
|
||||
#include <QtQml>
|
||||
|
||||
namespace qqsfpm {
|
||||
|
||||
|
@ -66,4 +68,53 @@ void FilterContainer::clear_filters(QQmlListProperty<Filter> *list)
|
|||
that->clearFilters();
|
||||
}
|
||||
|
||||
FilterContainerAttached::FilterContainerAttached(QObject* object) : QObject(object),
|
||||
m_filter(qobject_cast<Filter*>(object))
|
||||
{
|
||||
if (!m_filter)
|
||||
qmlWarning(object) << "FilterContainer must be attached to a Filter";
|
||||
}
|
||||
|
||||
FilterContainerAttached::~FilterContainerAttached()
|
||||
{
|
||||
if (m_filter && m_container) {
|
||||
FilterContainer* container = qobject_cast<FilterContainer*>(m_container.data());
|
||||
container->removeFilter(m_filter);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlattachedproperty bool FilterContainer::container
|
||||
This attached property allows you to include in a \l FilterContainer a \l Filter that
|
||||
has been instantiated outside of the \l FilterContainer, for example in an Instantiator.
|
||||
*/
|
||||
QObject* FilterContainerAttached::container() const
|
||||
{
|
||||
return m_container;
|
||||
}
|
||||
|
||||
void FilterContainerAttached::setContainer(QObject* object)
|
||||
{
|
||||
if (m_container == object)
|
||||
return;
|
||||
|
||||
FilterContainer* container = qobject_cast<FilterContainer*>(object);
|
||||
if (object && !container)
|
||||
qmlWarning(parent()) << "container must inherits from FilterContainer, " << object->metaObject()->className() << " provided";
|
||||
|
||||
if (m_container && m_filter)
|
||||
qobject_cast<FilterContainer*>(m_container.data())->removeFilter(m_filter);
|
||||
|
||||
m_container = container ? object : nullptr;
|
||||
if (container && m_filter)
|
||||
container->appendFilter(m_filter);
|
||||
|
||||
Q_EMIT containerChanged();
|
||||
}
|
||||
|
||||
FilterContainerAttached* FilterContainerAttached::qmlAttachedProperties(QObject* object)
|
||||
{
|
||||
return new FilterContainerAttached(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <QList>
|
||||
#include <QQmlListProperty>
|
||||
#include <qqml.h>
|
||||
#include <QPointer>
|
||||
|
||||
namespace qqsfpm {
|
||||
|
||||
|
@ -34,9 +36,33 @@ private:
|
|||
static void clear_filters(QQmlListProperty<Filter>* list);
|
||||
};
|
||||
|
||||
class FilterContainerAttached : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QObject* container READ container WRITE setContainer NOTIFY containerChanged)
|
||||
|
||||
public:
|
||||
FilterContainerAttached(QObject* object);
|
||||
~FilterContainerAttached();
|
||||
|
||||
QObject* container() const;
|
||||
void setContainer(QObject* object);
|
||||
|
||||
static FilterContainerAttached* qmlAttachedProperties(QObject* object);
|
||||
|
||||
Q_SIGNALS:
|
||||
void containerChanged();
|
||||
|
||||
private:
|
||||
QPointer<QObject> m_container = nullptr;
|
||||
Filter* m_filter = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define FilterContainer_iid "fr.grecko.SortFilterProxyModel.FilterContainer"
|
||||
Q_DECLARE_INTERFACE(qqsfpm::FilterContainer, FilterContainer_iid)
|
||||
|
||||
QML_DECLARE_TYPEINFO(qqsfpm::FilterContainerAttached, QML_HAS_ATTACHED_PROPERTIES)
|
||||
|
||||
#endif // FILTERCONTAINER_H
|
||||
|
|
|
@ -20,6 +20,7 @@ void registerFiltersTypes() {
|
|||
qmlRegisterType<ExpressionFilter>("SortFilterProxyModel", 0, 2, "ExpressionFilter");
|
||||
qmlRegisterType<AnyOfFilter>("SortFilterProxyModel", 0, 2, "AnyOf");
|
||||
qmlRegisterType<AllOfFilter>("SortFilterProxyModel", 0, 2, "AllOf");
|
||||
qmlRegisterUncreatableType<FilterContainerAttached>("SortFilterProxyModel", 0, 2, "FilterContainer", "FilterContainer can only be used as an attaching type");
|
||||
}
|
||||
|
||||
Q_COREAPP_STARTUP_FUNCTION(registerFiltersTypes)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "sortercontainer.h"
|
||||
#include "sorter.h"
|
||||
#include <QtQml>
|
||||
|
||||
namespace qqsfpm {
|
||||
|
||||
|
@ -66,4 +68,53 @@ void SorterContainer::clear_sorters(QQmlListProperty<Sorter> *list)
|
|||
that->clearSorters();
|
||||
}
|
||||
|
||||
SorterContainerAttached::SorterContainerAttached(QObject* object) : QObject(object),
|
||||
m_sorter(qobject_cast<Sorter*>(object))
|
||||
{
|
||||
if (!m_sorter)
|
||||
qmlWarning(object) << "SorterContainerAttached must be attached to a Sorter";
|
||||
}
|
||||
|
||||
SorterContainerAttached::~SorterContainerAttached()
|
||||
{
|
||||
if (m_sorter && m_container) {
|
||||
SorterContainer* container = qobject_cast<SorterContainer*>(m_container.data());
|
||||
container->removeSorter(m_sorter);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlattachedproperty bool SorterContainer::container
|
||||
This attached property allows you to include in a \l SorterContainer a \l Sorter that
|
||||
has been instantiated outside of the \l SorterContainer, for example in an Instantiator.
|
||||
*/
|
||||
QObject* SorterContainerAttached::container() const
|
||||
{
|
||||
return m_container;
|
||||
}
|
||||
|
||||
void SorterContainerAttached::setContainer(QObject* object)
|
||||
{
|
||||
if (m_container == object)
|
||||
return;
|
||||
|
||||
SorterContainer* container = qobject_cast<SorterContainer*>(object);
|
||||
if (object && !container)
|
||||
qmlWarning(parent()) << "container must inherits from SorterContainer, " << object->metaObject()->className() << " provided";
|
||||
|
||||
if (m_container && m_sorter)
|
||||
qobject_cast<SorterContainer*>(m_container.data())->removeSorter(m_sorter);
|
||||
|
||||
m_container = container ? object : nullptr;
|
||||
if (container && m_sorter)
|
||||
container->appendSorter(m_sorter);
|
||||
|
||||
Q_EMIT containerChanged();
|
||||
}
|
||||
|
||||
SorterContainerAttached* SorterContainerAttached::qmlAttachedProperties(QObject* object)
|
||||
{
|
||||
return new SorterContainerAttached(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <QList>
|
||||
#include <QQmlListProperty>
|
||||
#include <qqml.h>
|
||||
#include <QPointer>
|
||||
|
||||
namespace qqsfpm {
|
||||
|
||||
|
@ -34,9 +36,33 @@ private:
|
|||
static void clear_sorters(QQmlListProperty<Sorter>* list);
|
||||
};
|
||||
|
||||
class SorterContainerAttached : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QObject* container READ container WRITE setContainer NOTIFY containerChanged)
|
||||
|
||||
public:
|
||||
SorterContainerAttached(QObject* object);
|
||||
~SorterContainerAttached();
|
||||
|
||||
QObject* container() const;
|
||||
void setContainer(QObject* object);
|
||||
|
||||
static SorterContainerAttached* qmlAttachedProperties(QObject* object);
|
||||
|
||||
Q_SIGNALS:
|
||||
void containerChanged();
|
||||
|
||||
private:
|
||||
QPointer<QObject> m_container = nullptr;
|
||||
Sorter* m_sorter = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define SorterContainer_iid "fr.grecko.SortFilterProxyModel.SorterContainer"
|
||||
Q_DECLARE_INTERFACE(qqsfpm::SorterContainer, SorterContainer_iid)
|
||||
|
||||
QML_DECLARE_TYPEINFO(qqsfpm::SorterContainerAttached, QML_HAS_ATTACHED_PROPERTIES)
|
||||
|
||||
#endif // SORTERSSORTERCONTAINER_H
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "stringsorter.h"
|
||||
#include "filtersorter.h"
|
||||
#include "expressionsorter.h"
|
||||
#include "sortercontainer.h"
|
||||
#include <QQmlEngine>
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
@ -14,6 +15,7 @@ void registerSorterTypes() {
|
|||
qmlRegisterType<StringSorter>("SortFilterProxyModel", 0, 2, "StringSorter");
|
||||
qmlRegisterType<FilterSorter>("SortFilterProxyModel", 0, 2, "FilterSorter");
|
||||
qmlRegisterType<ExpressionSorter>("SortFilterProxyModel", 0, 2, "ExpressionSorter");
|
||||
qmlRegisterUncreatableType<SorterContainerAttached>("SortFilterProxyModel", 0, 2, "SorterContainer", "SorterContainer can only be used as an attaching type");
|
||||
}
|
||||
|
||||
Q_COREAPP_STARTUP_FUNCTION(registerSorterTypes)
|
||||
|
|
|
@ -26,11 +26,11 @@ OTHER_FILES += \
|
|||
tst_proxyroles.qml \
|
||||
tst_joinrole.qml \
|
||||
tst_switchrole.qml \
|
||||
tst_expressionrole.qml
|
||||
|
||||
DISTFILES += \
|
||||
tst_expressionrole.qml \
|
||||
tst_filtercontainerattached.qml \
|
||||
tst_filtercontainers.qml \
|
||||
tst_regexprole.qml \
|
||||
tst_filtersorter.qml \
|
||||
tst_filterrole.qml \
|
||||
tst_delayed.qml
|
||||
tst_delayed.qml \
|
||||
tst_sortercontainerattached.qml
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import QtQuick 2.0
|
||||
import SortFilterProxyModel 0.2
|
||||
import QtQml.Models 2.2
|
||||
import QtQml 2.2
|
||||
import QtTest 1.1
|
||||
|
||||
Item {
|
||||
|
||||
ListModel {
|
||||
id: dataModel
|
||||
ListElement { a: 0; b: 0; c: 0 }
|
||||
ListElement { a: 0; b: 0; c: 1 }
|
||||
ListElement { a: 0; b: 1; c: 0 }
|
||||
ListElement { a: 0; b: 1; c: 1 }
|
||||
ListElement { a: 1; b: 0; c: 0 }
|
||||
ListElement { a: 1; b: 0; c: 1 }
|
||||
ListElement { a: 1; b: 1; c: 0 }
|
||||
ListElement { a: 1; b: 1; c: 1 }
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: testModel
|
||||
sourceModel: dataModel
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
id: filterInstantiator
|
||||
model: ["a", "b", "c"]
|
||||
delegate: ValueFilter {
|
||||
FilterContainer.container: testModel
|
||||
roleName: modelData
|
||||
value: 1
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
name: "FilterContainerAttached"
|
||||
|
||||
function modelValues() {
|
||||
var modelValues = [];
|
||||
|
||||
for (var i = 0; i < testModel.count; i++)
|
||||
modelValues.push(testModel.get(i));
|
||||
|
||||
return modelValues;
|
||||
}
|
||||
|
||||
function test_filterContainers() {
|
||||
compare(filterInstantiator.count, 3);
|
||||
compare(modelValues(), [ { a: 1, b: 1, c: 1 }]);
|
||||
filterInstantiator.model = ["a", "b"];
|
||||
wait(0);
|
||||
compare(filterInstantiator.count, 2)
|
||||
compare(modelValues(), [ { a: 1, b: 1, c: 0 }, { a: 1, b: 1, c: 1 }]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
import QtQuick 2.0
|
||||
import SortFilterProxyModel 0.2
|
||||
import QtQml.Models 2.2
|
||||
import QtQml 2.2
|
||||
import QtTest 1.1
|
||||
|
||||
Item {
|
||||
|
||||
ListModel {
|
||||
id: dataModel
|
||||
ListElement { a: 3; b: 2; c: 9 }
|
||||
ListElement { a: 3; b: 5; c: 0 }
|
||||
ListElement { a: 3; b: 2; c: 8 }
|
||||
ListElement { a: 2; b: 9; c: 1 }
|
||||
ListElement { a: 2; b: 1; c: 7 }
|
||||
ListElement { a: 2; b: 6; c: 2 }
|
||||
ListElement { a: 1; b: 8; c: 6 }
|
||||
ListElement { a: 1; b: 7; c: 3 }
|
||||
ListElement { a: 1; b: 8; c: 5 }
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: testModel
|
||||
sourceModel: dataModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: sorterRoleModel
|
||||
ListElement { roleName: "a" }
|
||||
ListElement { roleName: "b" }
|
||||
ListElement { roleName: "c" }
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
id: sorterInstantiator
|
||||
model: sorterRoleModel
|
||||
delegate: RoleSorter {
|
||||
SorterContainer.container: testModel
|
||||
roleName: model.roleName
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
name: "SorterContainerAttached"
|
||||
|
||||
function modelValues() {
|
||||
var modelValues = [];
|
||||
|
||||
for (var i = 0; i < testModel.count; i++)
|
||||
modelValues.push(testModel.get(i));
|
||||
|
||||
return modelValues;
|
||||
}
|
||||
|
||||
function test_sorterContainers() {
|
||||
compare(sorterInstantiator.count, 3);
|
||||
compare(modelValues(), [
|
||||
{ a: 1, b: 7, c: 3 },
|
||||
{ a: 1, b: 8, c: 5 },
|
||||
{ a: 1, b: 8, c: 6 },
|
||||
{ a: 2, b: 1, c: 7 },
|
||||
{ a: 2, b: 6, c: 2 },
|
||||
{ a: 2, b: 9, c: 1 },
|
||||
{ a: 3, b: 2, c: 8 },
|
||||
{ a: 3, b: 2, c: 9 },
|
||||
{ a: 3, b: 5, c: 0 }
|
||||
]);
|
||||
sorterRoleModel.remove(0); // a, b, c --> b, c
|
||||
wait(0);
|
||||
compare(sorterInstantiator.count, 2);
|
||||
compare(JSON.stringify(modelValues()), JSON.stringify([
|
||||
{ a: 2, b: 1, c: 7 },
|
||||
{ a: 3, b: 2, c: 8 },
|
||||
{ a: 3, b: 2, c: 9 },
|
||||
{ a: 3, b: 5, c: 0 },
|
||||
{ a: 2, b: 6, c: 2 },
|
||||
{ a: 1, b: 7, c: 3 },
|
||||
{ a: 1, b: 8, c: 5 },
|
||||
{ a: 1, b: 8, c: 6 },
|
||||
{ a: 2, b: 9, c: 1 },
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue