75void QQmlFunctionSorter::componentComplete()
77 Q_D(QQmlFunctionSorter);
78 const auto *metaObj =
this->metaObject();
79 for (
int idx = metaObj->methodCount() - 1; idx >= 0; idx--) {
81 QMetaMethod method = metaObj->method(idx);
82 if (method.nameView() ==
"compare") {
85 }
else if (method.nameView() ==
"sort") {
86 qmlWarning(
this) <<
"The 'sort' method is deprecated and will be removed in a future version. Rename it to 'compare'.";
92 if (!d->m_method.isValid())
95 if (d->m_method.parameterCount() != 2) {
96 qmlWarning(
this) << d->m_method.name() <<
" requires two parameters.";
100 QQmlData *data = QQmlData::get(
this);
101 if (!data || !data->outerContext) {
102 qmlWarning(
this) << d->m_method.name() <<
" requires a QML context.";
106 const QMetaType lhsParameterType = d->m_method.parameterMetaType(0);
107 const QMetaType rhsParameterType = d->m_method.parameterMetaType(1);
109 if (!lhsParameterType.isValid() || !rhsParameterType.isValid()) {
110 qmlWarning(
this) << d->m_method.name() <<
" parameters need to be a QML-registered type.";
114 if (lhsParameterType != rhsParameterType) {
115 qmlWarning(
this) << d->m_method.name() <<
" parameters need to have matching types.";
119 if (lhsParameterType == QMetaType::fromType<QVariant>()) {
120 qmlWarning(
this) << d->m_method.name() <<
" parameters must be type annotated.";
124 const QMetaType returnType = d->m_method.returnMetaType();
125 if (returnType != QMetaType::fromType<
int>()) {
126 qmlWarning(
this) << d->m_method.name() <<
" must return int data type.";
130 auto cu = QQmlMetaType::obtainCompilationUnit(lhsParameterType);
131 const QQmlType parameterQmlType = QQmlMetaType::qmlType(lhsParameterType);
133 QQmlRefPointer<QQmlContextData> context = data->outerContext;
134 QQmlEngine *engine = context->engine();
146 if (lhsParameterType.flags() & QMetaType::PointerToQObject) {
147 QObject *created0 =
nullptr;
148 QObject *created1 =
nullptr;
149 if (parameterQmlType.isInlineComponent()) {
150 const auto executableCu = engine->handle()->executableCompilationUnit(std::move(cu));
151 const QString icName = parameterQmlType.elementName();
152 created0 = QQmlObjectCreator(context, executableCu, context, icName).create(
153 executableCu->inlineComponentId(icName),
nullptr,
nullptr,
154 QQmlObjectCreator::InlineComponent);
155 created1 = QQmlObjectCreator(context, executableCu, context, icName).create(
156 executableCu->inlineComponentId(icName),
nullptr,
nullptr,
157 QQmlObjectCreator::InlineComponent);
158 }
else if (parameterQmlType.isComposite()) {
159 const auto executableCu = engine->handle()->executableCompilationUnit(std::move(cu));
160 created0 = QQmlObjectCreator(context, executableCu, context, QString()).create();
161 created1 = QQmlObjectCreator(context, executableCu, context, QString()).create();
163 created0 = parameterQmlType.metaObject()->newInstance();
164 created1 = parameterQmlType.metaObject()->newInstance();
167 if (!created0 || !created1) {
168 qmlWarning(
this) << d->m_method.name() <<
" could not create its parameter objects.";
174 QQmlEngine::setObjectOwnership(created0, QQmlEngine::CppOwnership);
175 QQmlEngine::setObjectOwnership(created1, QQmlEngine::CppOwnership);
176 created0->setParent(
this);
177 created1->setParent(
this);
179 const auto names = d->m_method.parameterNames();
180 created0->setObjectName(names[0]);
181 created1->setObjectName(names[1]);
182 d->m_lhsParameterData = QVariant::fromValue(created0);
183 d->m_rhsParameterData = QVariant::fromValue(created1);
185 d->m_lhsParameterData = QVariant(lhsParameterType);
186 d->m_rhsParameterData = QVariant(rhsParameterType);
193QPartialOrdering QQmlFunctionSorter::compare(
194 const QModelIndex& sourceLeft,
const QModelIndex& sourceRight,
195 const QQmlSortFilterProxyModel *proxyModel)
const
197 Q_D(
const QQmlFunctionSorter);
198 if (!d->m_method.isValid()
199 || !d->m_lhsParameterData.isValid()
200 || !d->m_rhsParameterData.isValid()) {
201 return QPartialOrdering::Unordered;
205 QSortFilterProxyModelHelper::setProperties(&d->m_lhsParameterData, proxyModel, sourceLeft);
206 QSortFilterProxyModelHelper::setProperties(&d->m_rhsParameterData, proxyModel, sourceRight);
208 void *argv[] = {&retVal, d->m_lhsParameterData.data(), d->m_rhsParameterData.data()};
209 QMetaObject::metacall(
210 const_cast<QQmlFunctionSorter *>(
this), QMetaObject::InvokeMetaMethod,
211 d->m_method.methodIndex(), argv);
214 ? QPartialOrdering::Equivalent
215 : ((retVal < 0) ? QPartialOrdering::Less : QPartialOrdering::Greater);