80void QQmlFunctionSorter::componentComplete()
82 Q_D(QQmlFunctionSorter);
83 const auto *metaObj =
this->metaObject();
84 for (
int idx = metaObj->methodCount() - 1; idx >= 0; idx--) {
86 QMetaMethod method = metaObj->method(idx);
87 if (method.nameView() ==
"compare") {
90 }
else if (method.nameView() ==
"sort") {
91 qmlWarning(
this) <<
"The 'sort' method is deprecated and will be removed in a future version. Rename it to 'compare'.";
97 if (!d->m_method.isValid())
100 if (d->m_method.parameterCount() != 2) {
101 qmlWarning(
this) << d->m_method.name() <<
" requires two parameters.";
105 QQmlData *data = QQmlData::get(
this);
106 if (!data || !data->outerContext) {
107 qmlWarning(
this) << d->m_method.name() <<
" requires a QML context.";
111 const QMetaType lhsParameterType = d->m_method.parameterMetaType(0);
112 const QMetaType rhsParameterType = d->m_method.parameterMetaType(1);
114 if (!lhsParameterType.isValid() || !rhsParameterType.isValid()) {
115 qmlWarning(
this) << d->m_method.name() <<
" parameters need to be a QML-registered type.";
119 if (lhsParameterType != rhsParameterType) {
120 qmlWarning(
this) << d->m_method.name() <<
" parameters need to have matching types.";
124 if (lhsParameterType == QMetaType::fromType<QVariant>()) {
125 qmlWarning(
this) << d->m_method.name() <<
" parameters must be type annotated.";
129 const QMetaType returnType = d->m_method.returnMetaType();
130 if (returnType != QMetaType::fromType<
int>()) {
131 qmlWarning(
this) << d->m_method.name() <<
" must return int data type.";
135 auto cu = QQmlMetaType::obtainCompilationUnit(lhsParameterType);
136 const QQmlType parameterQmlType = QQmlMetaType::qmlType(lhsParameterType);
138 QQmlRefPointer<QQmlContextData> context = data->outerContext;
139 QQmlEngine *engine = context->engine();
151 if (lhsParameterType.flags() & QMetaType::PointerToQObject) {
152 QObject *created0 =
nullptr;
153 QObject *created1 =
nullptr;
154 if (parameterQmlType.isInlineComponent()) {
155 const auto executableCu = engine->handle()->executableCompilationUnit(std::move(cu));
156 const QString icName = parameterQmlType.elementName();
157 created0 = QQmlObjectCreator(context, executableCu, context, icName).create(
158 executableCu->inlineComponentId(icName),
nullptr,
nullptr,
159 QQmlObjectCreator::InlineComponent);
160 created1 = QQmlObjectCreator(context, executableCu, context, icName).create(
161 executableCu->inlineComponentId(icName),
nullptr,
nullptr,
162 QQmlObjectCreator::InlineComponent);
163 }
else if (parameterQmlType.isComposite()) {
164 const auto executableCu = engine->handle()->executableCompilationUnit(std::move(cu));
165 created0 = QQmlObjectCreator(context, executableCu, context, QString()).create();
166 created1 = QQmlObjectCreator(context, executableCu, context, QString()).create();
168 created0 = parameterQmlType.metaObject()->newInstance();
169 created1 = parameterQmlType.metaObject()->newInstance();
172 const auto names = d->m_method.parameterNames();
173 created0->setObjectName(names[0]);
174 created1->setObjectName(names[1]);
175 d->m_lhsParameterData = QVariant::fromValue(created0);
176 d->m_rhsParameterData = QVariant::fromValue(created1);
178 d->m_lhsParameterData = QVariant(lhsParameterType);
179 d->m_rhsParameterData = QVariant(rhsParameterType);
186QPartialOrdering QQmlFunctionSorter::compare(
187 const QModelIndex& sourceLeft,
const QModelIndex& sourceRight,
188 const QQmlSortFilterProxyModel *proxyModel)
const
190 Q_D(
const QQmlFunctionSorter);
191 if (!d->m_method.isValid()
192 || !d->m_lhsParameterData.isValid()
193 || !d->m_rhsParameterData.isValid()) {
194 return QPartialOrdering::Unordered;
198 QSortFilterProxyModelHelper::setProperties(&d->m_lhsParameterData, proxyModel, sourceLeft);
199 QSortFilterProxyModelHelper::setProperties(&d->m_rhsParameterData, proxyModel, sourceRight);
201 void *argv[] = {&retVal, d->m_lhsParameterData.data(), d->m_rhsParameterData.data()};
202 QMetaObject::metacall(
203 const_cast<QQmlFunctionSorter *>(
this), QMetaObject::InvokeMetaMethod,
204 d->m_method.methodIndex(), argv);
207 ? QPartialOrdering::Equivalent
208 : ((retVal < 0) ? QPartialOrdering::Less : QPartialOrdering::Greater);