diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 4 | ||||
-rw-r--r-- | src/qml/types/qqmlconnections.cpp | 72 | ||||
-rw-r--r-- | src/qml/types/qqmlconnections_p.h | 4 |
3 files changed, 77 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 20c8d53573..9c3c9de81e 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -206,8 +206,12 @@ void QQmlEnginePrivate::defineModule() qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding"); qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding"); // Only available in >= 2.8 qmlRegisterType<QQmlBind, 14>(uri, 2, 14, "Binding"); + + // TODO: We won't need Connections to be a custom type anymore once we can drop the + // automatic signal handler inference from undeclared properties. qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser); qmlRegisterCustomType<QQmlConnections, 1>(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3 + #if QT_CONFIG(qml_animation) qmlRegisterType<QQmlTimer>(uri, 2, 0, "Timer"); #endif diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 8ec754a9df..14aadb6c86 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -44,6 +44,7 @@ #include <private/qqmlboundsignal_p.h> #include <qqmlcontext.h> #include <private/qqmlcontext_p.h> +#include <private/qqmlvmemetaobject_p.h> #include <qqmlinfo.h> #include <QtCore/qdebug.h> @@ -105,7 +106,7 @@ public: \qml MouseArea { Connections { - onClicked: foo(parameters) + function onClicked(mouse) { foo(mouse) } } } \endqml @@ -122,7 +123,7 @@ public: \qml Connections { target: area - onClicked: foo(parameters) + function onClicked(mouse) { foo(mouse) } } \endqml @@ -270,8 +271,73 @@ void QQmlConnections::connectSignals() if (!d->componentcomplete || (d->targetSet && !target())) return; - if (d->bindings.isEmpty()) + if (d->bindings.isEmpty()) { + connectSignalsToMethods(); + } else { + qmlWarning(this) << tr("Implicitly defined onFoo properties in Connections are deprecated. " + "Use this syntax instead: function onFoo(<arguments>) { ... }"); + connectSignalsToBindings(); + } +} + +void QQmlConnections::connectSignalsToMethods() +{ + Q_D(QQmlConnections); + + QObject *target = this->target(); + QQmlData *ddata = QQmlData::get(this); + if (!ddata) return; + + QV4::ExecutionEngine *engine = ddata->context->engine->handle(); + + QQmlContextData *ctxtdata = ddata->outerContext; + for (int i = ddata->propertyCache->methodOffset(), + end = ddata->propertyCache->methodOffset() + ddata->propertyCache->methodCount(); + i < end; + ++i) { + + QQmlPropertyData *handler = ddata->propertyCache->method(i); + if (!handler || !handler->isVMEFunction()) + continue; + + const QString propName = handler->name(this); + + QQmlProperty prop(target, propName); + if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) { + int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex(); + auto *signal = new QQmlBoundSignal(target, signalIndex, this, qmlEngine(this)); + signal->setEnabled(d->enabled); + + QV4::Scope scope(engine); + QV4::ScopedContext global(scope, engine->rootContext()); + + QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(this); + Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this + + QV4::ScopedFunctionObject method(scope, vmeMetaObject->vmeMethod(handler->coreIndex())); + + QQmlBoundSignalExpression *expression = + ctxtdata ? new QQmlBoundSignalExpression( + target, signalIndex, ctxtdata, this, + method->as<QV4::FunctionObject>()->function()) + : nullptr; + + signal->takeExpression(expression); + d->boundsignals += signal; + } else if (!d->ignoreUnknownSignals && propName.startsWith("on") && propName.length() > 2 + && propName.at(2).isUpper()) { + qmlWarning(this) << tr("Detected function \"%1\" in Connections element. " + "This is probably intended to be a signal handler but no " + "signal of the target matches the name.").arg(propName); + } + } +} + +// TODO: Drop this as soon as we can +void QQmlConnections::connectSignalsToBindings() +{ + Q_D(QQmlConnections); QObject *target = this->target(); QQmlData *ddata = QQmlData::get(this); QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr; diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index f6ad1eb46c..1acc86239f 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -91,10 +91,14 @@ Q_SIGNALS: private: void connectSignals(); + void connectSignalsToMethods(); + void connectSignalsToBindings(); + void classBegin() override; void componentComplete() override; }; +// TODO: Drop this class as soon as we can class QQmlConnectionsParser : public QQmlCustomParser { public: |