refactor: Refactor Sorter and Fitler to be consistent with ProxyRole

remove the friendness with QQSFPM
This commit is contained in:
Grecko 2017-09-17 18:03:39 +02:00
parent 7a2e70b980
commit 94a08b49ec
9 changed files with 154 additions and 171 deletions

View File

@ -38,7 +38,7 @@ void Filter::setEnabled(bool enabled)
m_enabled = enabled;
Q_EMIT enabledChanged();
Q_EMIT invalidate();
Q_EMIT invalidated();
}
/*!
@ -61,28 +61,23 @@ void Filter::setInverted(bool inverted)
m_inverted = inverted;
Q_EMIT invertedChanged();
filterChanged();
invalidate();
}
bool Filter::filterAcceptsRow(const QModelIndex &sourceIndex) const
bool Filter::filterAcceptsRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
return !m_enabled || filterRow(sourceIndex) ^ m_inverted;
return !m_enabled || filterRow(sourceIndex, proxyModel) ^ m_inverted;
}
QQmlSortFilterProxyModel* Filter::proxyModel() const
void Filter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
return m_proxyModel;
Q_UNUSED(proxyModel)
}
void Filter::proxyModelCompleted()
{
}
void Filter::filterChanged()
void Filter::invalidate()
{
if (m_enabled)
invalidate();
Q_EMIT invalidated();
}
/*!
@ -115,12 +110,12 @@ void RoleFilter::setRoleName(const QString& roleName)
m_roleName = roleName;
Q_EMIT roleNameChanged();
filterChanged();
invalidate();
}
QVariant RoleFilter::sourceData(const QModelIndex &sourceIndex) const
QVariant RoleFilter::sourceData(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
return proxyModel()->sourceData(sourceIndex, m_roleName);
return proxyModel.sourceData(sourceIndex, m_roleName);
}
/*!
@ -166,12 +161,12 @@ void ValueFilter::setValue(const QVariant& value)
m_value = value;
Q_EMIT valueChanged();
filterChanged();
invalidate();
}
bool ValueFilter::filterRow(const QModelIndex& sourceIndex) const
bool ValueFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
return !m_value.isValid() || m_value == sourceData(sourceIndex);
return !m_value.isValid() || m_value == sourceData(sourceIndex, proxyModel);
}
/*!
@ -217,7 +212,7 @@ void IndexFilter::setMinimumIndex(const QVariant& minimumIndex)
m_minimumIndex = minimumIndex;
Q_EMIT minimumIndexChanged();
filterChanged();
invalidate();
}
/*!
@ -244,12 +239,12 @@ void IndexFilter::setMaximumIndex(const QVariant& maximumIndex)
m_maximumIndex = maximumIndex;
Q_EMIT maximumIndexChanged();
filterChanged();
invalidate();
}
bool IndexFilter::filterRow(const QModelIndex& sourceIndex) const
bool IndexFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
int sourceRowCount = proxyModel()->sourceModel()->rowCount();
int sourceRowCount = proxyModel.sourceModel()->rowCount();
int sourceRow = sourceIndex.row();
bool minimumIsValid;
@ -315,7 +310,7 @@ void RegExpFilter::setPattern(const QString& pattern)
m_pattern = pattern;
m_regExp.setPattern(pattern);
Q_EMIT patternChanged();
filterChanged();
invalidate();
}
/*!
@ -347,7 +342,7 @@ void RegExpFilter::setSyntax(RegExpFilter::PatternSyntax syntax)
m_syntax = syntax;
m_regExp.setPatternSyntax(static_cast<QRegExp::PatternSyntax>(syntax));
Q_EMIT syntaxChanged();
filterChanged();
invalidate();
}
/*!
@ -368,12 +363,12 @@ void RegExpFilter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
m_caseSensitivity = caseSensitivity;
m_regExp.setCaseSensitivity(caseSensitivity);
Q_EMIT caseSensitivityChanged();
filterChanged();
invalidate();
}
bool RegExpFilter::filterRow(const QModelIndex& sourceIndex) const
bool RegExpFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
QString string = sourceData(sourceIndex).toString();
QString string = sourceData(sourceIndex, proxyModel).toString();
return m_regExp.indexIn(string) != -1;
}
@ -424,7 +419,7 @@ void RangeFilter::setMinimumValue(QVariant minimumValue)
m_minimumValue = minimumValue;
Q_EMIT minimumValueChanged();
filterChanged();
invalidate();
}
/*!
@ -448,7 +443,7 @@ void RangeFilter::setMinimumInclusive(bool minimumInclusive)
m_minimumInclusive = minimumInclusive;
Q_EMIT minimumInclusiveChanged();
filterChanged();
invalidate();
}
/*!
@ -473,7 +468,7 @@ void RangeFilter::setMaximumValue(QVariant maximumValue)
m_maximumValue = maximumValue;
Q_EMIT maximumValueChanged();
filterChanged();
invalidate();
}
/*!
@ -497,12 +492,12 @@ void RangeFilter::setMaximumInclusive(bool maximumInclusive)
m_maximumInclusive = maximumInclusive;
Q_EMIT maximumInclusiveChanged();
filterChanged();
invalidate();
}
bool RangeFilter::filterRow(const QModelIndex& sourceIndex) const
bool RangeFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
QVariant value = sourceData(sourceIndex);
QVariant value = sourceData(sourceIndex, proxyModel);
bool lessThanMin = m_minimumValue.isValid() &&
m_minimumInclusive ? value < m_minimumValue : value <= m_minimumValue;
bool moreThanMax = m_maximumValue.isValid() &&
@ -548,14 +543,19 @@ void ExpressionFilter::setExpression(const QQmlScriptString& scriptString)
updateExpression();
Q_EMIT expressionChanged();
filterChanged();
invalidate();
}
bool ExpressionFilter::filterRow(const QModelIndex& sourceIndex) const
void ExpressionFilter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
updateContext(proxyModel);
}
bool ExpressionFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
if (!m_scriptString.isEmpty()) {
QVariantMap modelMap;
QHash<int, QByteArray> roles = proxyModel()->roleNames();
QHash<int, QByteArray> roles = proxyModel.roleNames();
QQmlContext context(qmlContext(this));
auto addToContext = [&] (const QString &name, const QVariant& value) {
@ -564,7 +564,7 @@ bool ExpressionFilter::filterRow(const QModelIndex& sourceIndex) const
};
for (auto it = roles.cbegin(); it != roles.cend(); ++it)
addToContext(it.value(), proxyModel()->sourceData(sourceIndex, it.key()));
addToContext(it.value(), proxyModel.sourceData(sourceIndex, it.key()));
addToContext("index", sourceIndex.row());
context.setContextProperty("model", modelMap);
@ -589,16 +589,8 @@ bool ExpressionFilter::filterRow(const QModelIndex& sourceIndex) const
return true;
}
void ExpressionFilter::proxyModelCompleted()
void ExpressionFilter::updateContext(const QQmlSortFilterProxyModel& proxyModel)
{
updateContext();
}
void ExpressionFilter::updateContext()
{
if (!proxyModel())
return;
delete m_context;
m_context = new QQmlContext(qmlContext(this), this);
// what about roles changes ?
@ -609,7 +601,7 @@ void ExpressionFilter::updateContext()
modelMap.insert(name, value);
};
for (const QByteArray& roleName : proxyModel()->roleNames().values())
for (const QByteArray& roleName : proxyModel.roleNames().values())
addToContext(roleName, QVariant());
addToContext("index", -1);
@ -625,7 +617,7 @@ void ExpressionFilter::updateExpression()
delete m_expression;
m_expression = new QQmlExpression(m_scriptString, m_context, 0, this);
connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionFilter::filterChanged);
connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionFilter::invalidate);
m_expression->setNotifyOnValueChanged(true);
m_expression->evaluate();
}
@ -639,6 +631,12 @@ QQmlListProperty<Filter> FilterContainer::filters()
&FilterContainer::clear_filters);
}
void FilterContainer::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
for (Filter* filter : m_filters)
filter->proxyModelCompleted(proxyModel);
}
void FilterContainer::append_filter(QQmlListProperty<Filter>* list, Filter* filter)
{
if (!filter)
@ -646,8 +644,8 @@ void FilterContainer::append_filter(QQmlListProperty<Filter>* list, Filter* filt
FilterContainer* that = static_cast<FilterContainer*>(list->object);
that->m_filters.append(filter);
connect(filter, &Filter::invalidate, that, &FilterContainer::filterChanged);
that->filterChanged();
connect(filter, &Filter::invalidated, that, &FilterContainer::invalidate);
that->invalidate();
}
int FilterContainer::count_filter(QQmlListProperty<Filter>* list)
@ -666,15 +664,7 @@ void FilterContainer::clear_filters(QQmlListProperty<Filter> *list)
{
FilterContainer* that = static_cast<FilterContainer*>(list->object);
that->m_filters.clear();
that->filterChanged();
}
void FilterContainer::proxyModelCompleted()
{
for (Filter* filter : m_filters) {
filter->m_proxyModel = proxyModel();
filter->proxyModelCompleted();
}
that->invalidate();
}
/*!
@ -708,12 +698,12 @@ void FilterContainer::proxyModelCompleted()
}
\endcode
*/
bool AnyOfFilter::filterRow(const QModelIndex& sourceIndex) const
bool AnyOfFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
//return true if any of the enabled filters return true
return std::any_of(m_filters.begin(), m_filters.end(),
[&sourceIndex] (Filter* filter) {
return filter->enabled() && filter->filterAcceptsRow(sourceIndex);
[&sourceIndex, &proxyModel] (Filter* filter) {
return filter->enabled() && filter->filterAcceptsRow(sourceIndex, proxyModel);
}
);
}
@ -728,12 +718,12 @@ bool AnyOfFilter::filterRow(const QModelIndex& sourceIndex) const
Using it as a top level filter has the same effect as putting all its child filters as top level filters. It can however be usefull to use an AllOf filter when nested in an AnyOf filter.
*/
bool AllOfFilter::filterRow(const QModelIndex& sourceIndex) const
bool AllOfFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
//return true if all filters return false, or if there is no filter.
return std::all_of(m_filters.begin(), m_filters.end(),
[&sourceIndex] (Filter* filter) {
return filter->filterAcceptsRow(sourceIndex);
[&sourceIndex, &proxyModel] (Filter* filter) {
return filter->filterAcceptsRow(sourceIndex, proxyModel);
}
);
}

View File

@ -12,11 +12,9 @@ class Filter : public QObject
Q_OBJECT
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged)
friend class QQmlSortFilterProxyModel;
friend class FilterContainer;
public:
explicit Filter(QObject *parent = 0);
explicit Filter(QObject *parent = nullptr);
virtual ~Filter() = default;
bool enabled() const;
@ -25,23 +23,22 @@ public:
bool inverted() const;
void setInverted(bool inverted);
bool filterAcceptsRow(const QModelIndex &sourceIndex) const;
bool filterAcceptsRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const;
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
Q_SIGNALS:
void enabledChanged();
void invertedChanged();
void invalidate();
void invalidated();
protected:
QQmlSortFilterProxyModel* proxyModel() const;
virtual bool filterRow(const QModelIndex &sourceIndex) const = 0;
virtual void proxyModelCompleted();
void filterChanged();
virtual bool filterRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const = 0;
void invalidate();
private:
bool m_enabled = true;
bool m_inverted = false;
QQmlSortFilterProxyModel* m_proxyModel = nullptr;
};
class RoleFilter : public Filter
@ -59,7 +56,7 @@ Q_SIGNALS:
void roleNameChanged();
protected:
QVariant sourceData(const QModelIndex &sourceIndex) const;
QVariant sourceData(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const;
private:
QString m_roleName;
@ -76,7 +73,7 @@ public:
void setValue(const QVariant& value);
protected:
bool filterRow(const QModelIndex &sourceIndex) const override;
bool filterRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
Q_SIGNALS:
void valueChanged();
@ -100,7 +97,7 @@ public:
void setMaximumIndex(const QVariant& maximumIndex);
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
Q_SIGNALS:
void minimumIndexChanged();
@ -139,7 +136,7 @@ public:
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
Q_SIGNALS:
void patternChanged();
@ -175,7 +172,7 @@ public:
void setMaximumInclusive(bool maximumInclusive);
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
Q_SIGNALS:
void minimumValueChanged();
@ -201,15 +198,16 @@ public:
const QQmlScriptString& expression() const;
void setExpression(const QQmlScriptString& scriptString);
void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
void proxyModelCompleted() override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
Q_SIGNALS:
void expressionChanged();
private:
void updateContext();
void updateContext(const QQmlSortFilterProxyModel& proxyModel);
void updateExpression();
QQmlScriptString m_scriptString;
@ -227,15 +225,16 @@ public:
QQmlListProperty<Filter> filters();
void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
protected:
QList<Filter*> m_filters;
private:
static void append_filter(QQmlListProperty<Filter>* list, Filter* filter);
static int count_filter(QQmlListProperty<Filter>* list);
static Filter* at_filter(QQmlListProperty<Filter>* list, int index);
static void clear_filters(QQmlListProperty<Filter>* list);
protected:
void proxyModelCompleted() override;
QList<Filter*> m_filters;
};
class AnyOfFilter : public FilterContainer {
@ -245,7 +244,7 @@ public:
using FilterContainer::FilterContainer;
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
};
class AllOfFilter : public FilterContainer {
@ -255,7 +254,7 @@ public:
using FilterContainer::FilterContainer;
protected:
bool filterRow(const QModelIndex& sourceIndex) const override;
bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
};
}

View File

@ -37,6 +37,11 @@ QVariant ProxyRole::roleData(const QModelIndex& sourceIndex, const QQmlSortFilte
}
}
void ProxyRole::proxyModelCompleted(const QQmlSortFilterProxyModel &proxyModel)
{
Q_UNUSED(proxyModel)
}
void ProxyRole::invalidate()
{
Q_EMIT invalidated();
@ -72,7 +77,7 @@ void JoinRole::setSeparator(const QString& separator)
invalidate();
}
QVariant JoinRole::data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel)
QVariant JoinRole::data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
{
QString result;

View File

@ -11,7 +11,6 @@ class ProxyRole : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
friend class QQmlSortFilterProxyModel;
public:
explicit ProxyRole(QObject *parent = nullptr);
@ -20,6 +19,7 @@ public:
void setName(const QString& name);
QVariant roleData(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel);
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
protected:
void invalidate();

View File

@ -206,7 +206,7 @@ void QQmlSortFilterProxyModel::componentComplete()
{
m_completed = true;
for (const auto& filter : m_filters)
filter->proxyModelCompleted();
filter->proxyModelCompleted(*this);
invalidate();
sort(0);
}
@ -331,7 +331,7 @@ bool QQmlSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelInde
bool baseAcceptsRow = valueAccepted && QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
baseAcceptsRow = baseAcceptsRow && std::all_of(m_filters.begin(), m_filters.end(),
[=, &source_parent] (Filter* filter) {
return filter->filterAcceptsRow(sourceIndex);
return filter->filterAcceptsRow(sourceIndex, *this);
}
);
return baseAcceptsRow;
@ -348,7 +348,7 @@ bool QQmlSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM
}
for(auto sorter : m_sorters) {
if (sorter->enabled()) {
int comparison = sorter->compareRows(source_left, source_right);
int comparison = sorter->compareRows(source_left, source_right, *this);
if (comparison != 0)
return comparison < 0;
}
@ -454,8 +454,7 @@ void QQmlSortFilterProxyModel::append_filter(QQmlListProperty<Filter>* list, Fil
QQmlSortFilterProxyModel* that = static_cast<QQmlSortFilterProxyModel*>(list->object);
that->m_filters.append(filter);
connect(filter, &Filter::invalidate, that, &QQmlSortFilterProxyModel::invalidateFilter);
filter->m_proxyModel = that;
connect(filter, &Filter::invalidated, that, &QQmlSortFilterProxyModel::invalidateFilter);
that->invalidateFilter();
}
@ -485,8 +484,7 @@ void QQmlSortFilterProxyModel::append_sorter(QQmlListProperty<Sorter>* list, Sor
auto that = static_cast<QQmlSortFilterProxyModel*>(list->object);
that->m_sorters.append(sorter);
connect(sorter, &Sorter::invalidate, that, &QQmlSortFilterProxyModel::invalidate);
sorter->m_proxyModel = that;
connect(sorter, &Sorter::invalidated, that, &QQmlSortFilterProxyModel::invalidate);
that->invalidate();
}

View File

@ -40,7 +40,7 @@ void Sorter::setEnabled(bool enabled)
m_enabled = enabled;
Q_EMIT enabledChanged();
Q_EMIT invalidate();
Q_EMIT invalidated();
}
bool Sorter::ascendingOrder() const
@ -76,45 +76,41 @@ void Sorter::setSortOrder(Qt::SortOrder sortOrder)
m_sortOrder = sortOrder;
Q_EMIT sortOrderChanged();
sorterChanged();
invalidate();
}
int Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right) const
int Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right, const QQmlSortFilterProxyModel& proxyModel) const
{
int comparison = compare(source_left, source_right);
int comparison = compare(source_left, source_right, proxyModel);
return (m_sortOrder == Qt::AscendingOrder) ? comparison : -comparison;
}
QQmlSortFilterProxyModel* Sorter::proxyModel() const
int Sorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
return m_proxyModel;
}
int Sorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
{
if (lessThan(sourceLeft, sourceRight))
if (lessThan(sourceLeft, sourceRight, proxyModel))
return -1;
if (lessThan(sourceRight, sourceLeft))
if (lessThan(sourceRight, sourceLeft, proxyModel))
return 1;
return 0;
}
bool Sorter::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
void Sorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
Q_UNUSED(proxyModel)
}
bool Sorter::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
Q_UNUSED(sourceLeft)
Q_UNUSED(sourceRight)
Q_UNUSED(proxyModel)
return false;
}
void Sorter::proxyModelCompleted()
{
}
void Sorter::sorterChanged()
void Sorter::invalidate()
{
if (m_enabled)
Q_EMIT invalidate();
Q_EMIT invalidated();
}
const QString& RoleSorter::roleName() const
@ -151,23 +147,21 @@ void RoleSorter::setRoleName(const QString& roleName)
m_roleName = roleName;
Q_EMIT roleNameChanged();
sorterChanged();
invalidate();
}
QPair<QVariant, QVariant> RoleSorter::sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight) const
QPair<QVariant, QVariant> RoleSorter::sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
QPair<QVariant, QVariant> pair;
if (QQmlSortFilterProxyModel* proxy = proxyModel()) {
int role = proxy->roleForName(m_roleName);
pair.first = proxy->sourceData(sourceLeft, role);
pair.second = proxy->sourceData(sourceRight, role);
}
int role = proxyModel.roleForName(m_roleName);
pair.first = proxyModel.sourceData(sourceLeft, role);
pair.second = proxyModel.sourceData(sourceRight, role);
return pair;
}
int RoleSorter::compare(const QModelIndex &sourceLeft, const QModelIndex& sourceRight) const
int RoleSorter::compare(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
QPair<QVariant, QVariant> pair = sourceData(sourceLeft, sourceRight);
QPair<QVariant, QVariant> pair = sourceData(sourceLeft, sourceRight, proxyModel);
QVariant leftValue = pair.first;
QVariant rightValue = pair.second;
if (leftValue < rightValue)
@ -212,7 +206,7 @@ void StringSorter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
m_collator.setCaseSensitivity(caseSensitivity);
Q_EMIT caseSensitivityChanged();
sorterChanged();
invalidate();
}
/*!
@ -235,7 +229,7 @@ void StringSorter::setIgnorePunctation(bool ignorePunctation)
m_collator.setIgnorePunctuation(ignorePunctation);
Q_EMIT ignorePunctationChanged();
sorterChanged();
invalidate();
}
/*!
@ -255,7 +249,7 @@ void StringSorter::setLocale(const QLocale &locale)
m_collator.setLocale(locale);
Q_EMIT localeChanged();
sorterChanged();
invalidate();
}
/*!
@ -277,12 +271,12 @@ void StringSorter::setNumericMode(bool numericMode)
m_collator.setNumericMode(numericMode);
Q_EMIT numericModeChanged();
sorterChanged();
invalidate();
}
int StringSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
int StringSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
QPair<QVariant, QVariant> pair = sourceData(sourceLeft, sourceRight);
QPair<QVariant, QVariant> pair = sourceData(sourceLeft, sourceRight, proxyModel);
QString leftValue = pair.first.toString();
QString rightValue = pair.second.toString();
return m_collator.compare(leftValue, rightValue);
@ -326,7 +320,12 @@ void ExpressionSorter::setExpression(const QQmlScriptString& scriptString)
updateExpression();
Q_EMIT expressionChanged();
sorterChanged();
invalidate();
}
void ExpressionSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
updateContext(proxyModel);
}
bool evaluateBoolExpression(QQmlExpression& expression)
@ -347,17 +346,17 @@ bool evaluateBoolExpression(QQmlExpression& expression)
}
}
int ExpressionSorter::compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const
int ExpressionSorter::compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
{
if (!m_scriptString.isEmpty()) {
QVariantMap modelLeftMap, modelRightMap;
QHash<int, QByteArray> roles = proxyModel()->roleNames();
QHash<int, QByteArray> roles = proxyModel.roleNames();
QQmlContext context(qmlContext(this));
for (auto it = roles.cbegin(); it != roles.cend(); ++it) {
modelLeftMap.insert(it.value(), proxyModel()->sourceData(sourceLeft, it.key()));
modelRightMap.insert(it.value(), proxyModel()->sourceData(sourceRight, it.key()));
modelLeftMap.insert(it.value(), proxyModel.sourceData(sourceLeft, it.key()));
modelRightMap.insert(it.value(), proxyModel.sourceData(sourceRight, it.key()));
}
modelLeftMap.insert("index", sourceLeft.row());
modelRightMap.insert("index", sourceRight.row());
@ -377,23 +376,15 @@ int ExpressionSorter::compare(const QModelIndex& sourceLeft, const QModelIndex&
return 0;
}
void ExpressionSorter::proxyModelCompleted()
void ExpressionSorter::updateContext(const QQmlSortFilterProxyModel& proxyModel)
{
updateContext();
}
void ExpressionSorter::updateContext()
{
if (!proxyModel())
return;
delete m_context;
m_context = new QQmlContext(qmlContext(this), this);
QVariantMap modelLeftMap, modelRightMap;
// what about roles changes ?
for (const QByteArray& roleName : proxyModel()->roleNames().values()) {
for (const QByteArray& roleName : proxyModel.roleNames().values()) {
modelLeftMap.insert(roleName, QVariant());
modelRightMap.insert(roleName, QVariant());
}
@ -413,7 +404,7 @@ void ExpressionSorter::updateExpression()
delete m_expression;
m_expression = new QQmlExpression(m_scriptString, m_context, 0, this);
connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionSorter::sorterChanged);
connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionSorter::invalidate);
m_expression->setNotifyOnValueChanged(true);
m_expression->evaluate();
}

View File

@ -14,7 +14,6 @@ class Sorter : public QObject
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool ascendingOrder READ ascendingOrder WRITE setAscendingOrder NOTIFY sortOrderChanged)
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
friend class QQmlSortFilterProxyModel;
public:
Sorter(QObject* parent = nullptr);
@ -29,26 +28,24 @@ public:
Qt::SortOrder sortOrder() const;
void setSortOrder(Qt::SortOrder sortOrder);
int compareRows(const QModelIndex& source_left, const QModelIndex& source_right) const;
int compareRows(const QModelIndex& source_left, const QModelIndex& source_right, const QQmlSortFilterProxyModel& proxyModel) const;
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
Q_SIGNALS:
void enabledChanged();
void sortOrderChanged();
void invalidate();
void invalidated();
protected:
QQmlSortFilterProxyModel* proxyModel() const;
virtual int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const;
virtual bool lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const;
virtual void proxyModelCompleted();
void sorterChanged();
virtual int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
virtual bool lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
void invalidate();
private:
bool m_enabled = true;
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
QQmlSortFilterProxyModel* m_proxyModel = nullptr;
};
class RoleSorter : public Sorter
@ -66,8 +63,8 @@ Q_SIGNALS:
void roleNameChanged();
protected:
QPair<QVariant, QVariant> sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight) const;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
QPair<QVariant, QVariant> sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
private:
QString m_roleName;
@ -103,7 +100,7 @@ Q_SIGNALS:
void numericModeChanged();
protected:
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
private:
QCollator m_collator;
@ -120,15 +117,16 @@ public:
const QQmlScriptString& expression() const;
void setExpression(const QQmlScriptString& scriptString);
void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
Q_SIGNALS:
void expressionChanged();
protected:
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
void proxyModelCompleted() override;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
private:
void updateContext();
void updateContext(const QQmlSortFilterProxyModel& proxyModel);
void updateExpression();
QQmlScriptString m_scriptString;

View File

@ -1,13 +1,15 @@
#include "indexsorter.h"
#include <QtQml>
int IndexSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
int IndexSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const
{
Q_UNUSED(proxyModel)
return sourceLeft.row() - sourceRight.row();
}
int ReverseIndexSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const
int ReverseIndexSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const
{
Q_UNUSED(proxyModel)
return sourceRight.row() - sourceLeft.row();
}

View File

@ -7,14 +7,14 @@ class IndexSorter : public qqsfpm::Sorter
{
public:
using qqsfpm::Sorter::Sorter;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const override;
};
class ReverseIndexSorter : public qqsfpm::Sorter
{
public:
using qqsfpm::Sorter::Sorter;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const override;
};
#endif // INDEXSORTER_H