67void QQmlFunctionFilter::componentComplete()
69 Q_D(QQmlFunctionFilter);
70 const auto *metaObj = metaObject();
71 for (
int idx = metaObj->methodOffset(); idx < metaObj->methodCount(); idx++) {
73 QMetaMethod method = metaObj->method(idx);
74 if (method.nameView() ==
"filter") {
80 if (!d->method.isValid())
84 for (
int index = 0; index < d->method.parameterCount(); index++) {
85 const QMetaType parameterType = d->method.parameterMetaType(index);
86 if (!parameterType.isValid()) {
87 qmlWarning(
this) <<
"filter method parameter needs to be a QML-registered type";
97bool QQmlFunctionFilter::filterAcceptsRowInternal(
int row,
const QModelIndex& sourceParent,
const QQmlSortFilterProxyModel *proxyModel)
const
99 Q_D(
const QQmlFunctionFilter);
100 if (!d->method.isValid() ||
101 (d->parameterCache.has_value() && d->parameterCache->dataArgs.isEmpty()))
106 if (!d->parameterCache.has_value()) {
107 QQmlFunctionFilterPrivate::ParameterCache parameterCache;
108 const auto ¶ms = d->method.parameterNames();
109 for (
int index = 0; index < params.size(); index++) {
110 const int roleId = proxyModel->itemRoleForName(QString::fromUtf8(params.at(index)));
112 qmlWarning(
this) <<
"Parameter specified in the filter method " << params.at(index) <<
" doesn't exist in the model";
113 d->parameterCache = QQmlFunctionFilterPrivate::ParameterCache{};
116 parameterCache.paramsInfo.append({roleId, QVariant{}, d->method.parameterMetaType(index)});
118 d->parameterCache = std::move(parameterCache);
121 d->parameterCache->dataArgs.append(
nullptr);
122 for (
auto ¶m : d->parameterCache->paramsInfo)
123 d->parameterCache->dataArgs.append(¶m.value);
126 d->parameterCache->dataArgs[0] = &retVal;
128 auto filterData = [d, proxyModel,
this](
int row,
int column,
const QModelIndex &sourceParent) {
130 for (
auto ¶m : d->parameterCache->paramsInfo) {
131 QVariant value = proxyModel->sourceModel()->data(proxyModel->sourceModel()->index(row, column, sourceParent),
133 if (!value.isValid())
135 if (value.metaType() == param.expectedType) {
136 param.value = std::move(value);
139 auto *v4Engine = qmlEngine(
this)->handle();
140 QV4::Scope scope(v4Engine);
141 QV4::ScopedValue jsVal(scope, v4Engine->metaTypeToJS(value.metaType(), value.constData()));
142 QVariant convertedValue(param.expectedType);
143 if (!QV4::ExecutionEngine::metaTypeFromJS(jsVal, param.expectedType, convertedValue.data())) {
144 qmlWarning(
this) <<
"Failed to convert param " << d->method.parameterNames()[index] <<
" to " << param.expectedType.name();
147 param.value = std::move(convertedValue);
151 QMetaObject::metacall(
152 const_cast<QQmlFunctionFilter *>(
this), QMetaObject::InvokeMetaMethod,
153 d->method.methodIndex(), d->parameterCache->dataArgs.data());
157 filterData(row, column(), sourceParent);
159 const int columnCount = proxyModel->sourceModel()->columnCount(sourceParent);
160 for (
int column = 0; column < columnCount; column++) {
161 filterData(row, column, sourceParent);