mirror of
https://github.com/status-im/SortFilterProxyModel.git
synced 2025-02-22 23:58:16 +00:00
added ExpresionSorter
This commit is contained in:
parent
0b850c37ec
commit
d3bee768f9
107
sorter.cpp
107
sorter.cpp
@ -104,9 +104,116 @@ int RoleSorter::compare(const QModelIndex &sourceLeft, const QModelIndex& source
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QQmlScriptString& ExpressionSorter::expression() const
|
||||
{
|
||||
return m_scriptString;
|
||||
}
|
||||
|
||||
void ExpressionSorter::setExpression(const QQmlScriptString& scriptString)
|
||||
{
|
||||
if (m_scriptString == scriptString)
|
||||
return;
|
||||
|
||||
m_scriptString = scriptString;
|
||||
updateExpression();
|
||||
|
||||
emit expressionChanged();
|
||||
emit sorterChanged();
|
||||
}
|
||||
|
||||
bool evaluateBoolExpression(QQmlExpression& expression)
|
||||
{
|
||||
QVariant variantResult = expression.evaluate();
|
||||
if (expression.hasError()) {
|
||||
qWarning() << expression.error();
|
||||
return false;
|
||||
}
|
||||
if (variantResult.canConvert<bool>()) {
|
||||
return variantResult.toBool();
|
||||
} else {
|
||||
qWarning("%s:%i:%i : Can't convert result to bool",
|
||||
expression.sourceFile().toUtf8().data(),
|
||||
expression.lineNumber(),
|
||||
expression.columnNumber());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ExpressionSorter::compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const
|
||||
{
|
||||
if (!m_scriptString.isEmpty()) {
|
||||
QVariantMap modelLeftMap, modelRightMap;
|
||||
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("index", sourceLeft.row());
|
||||
modelRightMap.insert("index", sourceRight.row());
|
||||
|
||||
QQmlExpression expression(m_scriptString, &context);
|
||||
|
||||
context.setContextProperty("modelLeft", modelLeftMap);
|
||||
context.setContextProperty("modelRight", modelRightMap);
|
||||
if (evaluateBoolExpression(expression))
|
||||
return -1;
|
||||
|
||||
context.setContextProperty("modelLeft", modelRightMap);
|
||||
context.setContextProperty("modelRight", modelLeftMap);
|
||||
if (evaluateBoolExpression(expression))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExpressionSorter::proxyModelCompleted()
|
||||
{
|
||||
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()) {
|
||||
modelLeftMap.insert(roleName, QVariant());
|
||||
modelRightMap.insert(roleName, QVariant());
|
||||
}
|
||||
modelLeftMap.insert("index", -1);
|
||||
modelRightMap.insert("index", -1);
|
||||
|
||||
m_context->setContextProperty("modelLeft", modelLeftMap);
|
||||
m_context->setContextProperty("modelRight", modelRightMap);
|
||||
|
||||
updateExpression();
|
||||
}
|
||||
|
||||
void ExpressionSorter::updateExpression()
|
||||
{
|
||||
if (!m_context)
|
||||
return;
|
||||
|
||||
delete m_expression;
|
||||
m_expression = new QQmlExpression(m_scriptString, m_context, 0, this);
|
||||
connect(m_expression, &QQmlExpression::valueChanged, this, &Sorter::sorterChanged);
|
||||
m_expression->setNotifyOnValueChanged(true);
|
||||
m_expression->evaluate();
|
||||
}
|
||||
|
||||
void registerSorterTypes() {
|
||||
qmlRegisterUncreatableType<Sorter>("SortFilterProxyModel", 0, 2, "Sorter", "Sorter is an abstract class");
|
||||
qmlRegisterType<RoleSorter>("SortFilterProxyModel", 0, 2, "RoleSorter");
|
||||
qmlRegisterType<ExpressionSorter>("SortFilterProxyModel", 0, 2, "ExpressionSorter");
|
||||
}
|
||||
|
||||
Q_COREAPP_STARTUP_FUNCTION(registerSorterTypes)
|
||||
|
28
sorter.h
28
sorter.h
@ -2,6 +2,7 @@
|
||||
#define SORTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlExpression>
|
||||
#include "qqmlsortfilterproxymodel.h"
|
||||
|
||||
namespace qqsfpm {
|
||||
@ -69,6 +70,33 @@ private:
|
||||
QString m_roleName;
|
||||
};
|
||||
|
||||
class ExpressionSorter : public Sorter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QQmlScriptString expression READ expression WRITE setExpression NOTIFY expressionChanged)
|
||||
|
||||
public:
|
||||
using Sorter::Sorter;
|
||||
|
||||
const QQmlScriptString& expression() const;
|
||||
void setExpression(const QQmlScriptString& scriptString);
|
||||
|
||||
signals:
|
||||
void expressionChanged();
|
||||
|
||||
protected:
|
||||
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const override;
|
||||
void proxyModelCompleted() override;
|
||||
|
||||
private:
|
||||
void updateContext();
|
||||
void updateExpression();
|
||||
|
||||
QQmlScriptString m_scriptString;
|
||||
QQmlExpression* m_expression = nullptr;
|
||||
QQmlContext* m_context = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SORTER_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user