From 1ce2f24a2253ebe2b05e216ecf54a23a055adb28 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Sat, 6 Oct 2018 22:11:00 +0300 Subject: [PATCH] feat: Add `indexes` property to IndexFilter --- filters/indexfilter.cpp | 45 +++++++++++++++++++++++++++++++++++++++ filters/indexfilter.h | 6 ++++++ tests/tst_indexfilter.qml | 20 +++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/filters/indexfilter.cpp b/filters/indexfilter.cpp index a82ab4a..d4a4cbd 100644 --- a/filters/indexfilter.cpp +++ b/filters/indexfilter.cpp @@ -1,6 +1,8 @@ #include "indexfilter.h" #include "qqmlsortfilterproxymodel.h" +#include + namespace qqsfpm { /*! @@ -76,6 +78,30 @@ void IndexFilter::setMaximumIndex(const QVariant& maximumIndex) invalidate(); } +/*! + \qmlproperty list IndexFilter::indexes + + This property holds the indexes for the filter. + Only rows with a source index contained in the \c indexes list will be proxied. + + If \c indexes is an empty array, no rows will be visible; in order to unset the filter, set \c indexes to \c null. + By default, \c indexes is \c null. +*/ +const QVariant& IndexFilter::indexes() const +{ + return m_indexes; +} + +void IndexFilter::setIndexes(const QVariant& indexes) +{ + if (m_indexes == indexes) + return; + + m_indexes = indexes; + Q_EMIT indexesChanged(); + invalidate(); +} + bool IndexFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const { int sourceRowCount = proxyModel.sourceModel()->rowCount(); @@ -97,6 +123,25 @@ bool IndexFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilter return false; } + if (m_indexes.isValid() && !m_indexes.isNull() && + m_indexes.canConvert()) { + // Workaround for QTBUG-42016 + QVariant variantList; + if (m_indexes.userType() == qMetaTypeId()) { + variantList = m_indexes.value().toVariant(); + } else { + variantList = m_indexes; + } + + QSequentialIterable iterable = variantList.value(); + for (const QVariant &v: iterable) { + bool isValid; + int index = v.toInt(&isValid); + if (isValid && sourceRow == index) + return true; + } + return false; + } return true; } diff --git a/filters/indexfilter.h b/filters/indexfilter.h index d693a9b..2195a46 100644 --- a/filters/indexfilter.h +++ b/filters/indexfilter.h @@ -10,6 +10,7 @@ class IndexFilter: public Filter { Q_OBJECT Q_PROPERTY(QVariant minimumIndex READ minimumIndex WRITE setMinimumIndex NOTIFY minimumIndexChanged) Q_PROPERTY(QVariant maximumIndex READ maximumIndex WRITE setMaximumIndex NOTIFY maximumIndexChanged) + Q_PROPERTY(QVariant indexes READ indexes WRITE setIndexes NOTIFY indexesChanged) public: using Filter::Filter; @@ -20,16 +21,21 @@ class IndexFilter: public Filter { const QVariant& maximumIndex() const; void setMaximumIndex(const QVariant& maximumIndex); + const QVariant& indexes() const; + void setIndexes(const QVariant& indexes); + protected: bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override; Q_SIGNALS: void minimumIndexChanged(); void maximumIndexChanged(); + void indexesChanged(); private: QVariant m_minimumIndex; QVariant m_maximumIndex; + QVariant m_indexes; }; } diff --git a/tests/tst_indexfilter.qml b/tests/tst_indexfilter.qml index b275c59..ea43b11 100644 --- a/tests/tst_indexfilter.qml +++ b/tests/tst_indexfilter.qml @@ -66,6 +66,26 @@ Item { property var expectedValues: [5, 3, 1, 2, 4] minimumIndex: undefined maximumIndex: null + }, + IndexFilter { + property string tag: "null index list" + property var expectedValues: [5, 3, 1, 2, 4] + indexes: null + }, + IndexFilter { + property string tag: "empty index list" + property var expectedValues: [] + indexes: [] + }, + IndexFilter { + property string tag: "valid index list" + property var expectedValues: [5, 1] + indexes: [2, 0] + }, + IndexFilter { + property string tag: "single index list" + property var expectedValues: [3] + indexes: [1] } ]