From: Michael Brasser Date: Wed, 16 May 2012 02:31:59 +0000 (+1000) Subject: Fix signal handlers for signals with default arguments. X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=9af1a7d0aee4f9ed48b2519779388830a8dd03e9;p=konrad%2Fqtdeclarative.git Fix signal handlers for signals with default arguments. For cloned signals, connect to the index of the original. This was a regression caused by the switch to QQmlNotifierEndpoint for signal handlers. This change also makes parameters with default arguments available from QML, while previously they were unavailable. Change-Id: I1feb3412c3e9b0f2a5d6644c404c56d53c5544ac Reviewed-by: Martin Jones --- diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index b3d07c3..629c8a5 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -228,6 +228,18 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *scope, const QMetaMethod &signal, setIsEvaluating(false); addToObject(owner); callback = &subscriptionCallback; + + /* + If this is a cloned method, connect to the 'original'. For example, + for the signal 'void aSignal(int parameter = 0)', if the method + index refers to 'aSignal()', get the index of 'aSignal(int)'. + This ensures that 'parameter' will be available from QML. + */ + if (signal.attributes() & QMetaMethod::Cloned) { + do { + --m_index; + } while (scope->metaObject()->method(m_index).attributes() & QMetaMethod::Cloned); + } QQmlNotifierEndpoint::connect(scope, m_index, engine); } diff --git a/tests/auto/qml/qqmllanguage/data/signalWithDefaultArg.qml b/tests/auto/qml/qqmllanguage/data/signalWithDefaultArg.qml new file mode 100644 index 0000000..e9f86fe --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/signalWithDefaultArg.qml @@ -0,0 +1,23 @@ +import Test 1.0 +import QtQuick 2.0 + +MyQmlObject { + property real signalCount: 0 + property real signalArg: 0 + + signal noArgSignal + signal argSignal(real arg) + + function emitNoArgSignal() { noArgSignal(); } + function emitArgSignal() { argSignal(22); } + + onSignalWithDefaultArg: { + signalArg = parameter + signalCount++ + } + + Component.onCompleted: { + noArgSignal.connect(signalWithDefaultArg) + argSignal.connect(signalWithDefaultArg) + } +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 90dea4a..a359a34 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -164,6 +164,7 @@ signals: void basicSignal(); void basicParameterizedSignal(int parameter); void oddlyNamedNotifySignal(); + void signalWithDefaultArg(int parameter = 5); private: friend class tst_qqmllanguage; diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index e33f636..05029b9 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -173,6 +173,7 @@ private slots: void propertyInit(); void remoteLoadCrash(); + void signalWithDefaultArg(); // regression tests for crashes void crash1(); @@ -2313,6 +2314,37 @@ void tst_qqmllanguage::remoteLoadCrash() delete o; } +void tst_qqmllanguage::signalWithDefaultArg() +{ + QQmlComponent component(&engine, TEST_FILE("signalWithDefaultArg.qml")); + + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->property("signalCount").toInt(), 0); + QCOMPARE(object->property("signalArg").toInt(), 0); + + emit object->signalWithDefaultArg(); + QCOMPARE(object-> property("signalCount").toInt(), 1); + QCOMPARE(object->property("signalArg").toInt(), 5); + + emit object->signalWithDefaultArg(15); + QCOMPARE(object->property("signalCount").toInt(), 2); + QCOMPARE(object->property("signalArg").toInt(), 15); + + const QMetaObject *metaObject = object->metaObject(); + + metaObject->invokeMethod(object, "emitNoArgSignal"); + QCOMPARE(object->property("signalCount").toInt(), 3); + QCOMPARE(object->property("signalArg").toInt(), 5); + + metaObject->invokeMethod(object, "emitArgSignal"); + QCOMPARE(object->property("signalCount").toInt(), 4); + QCOMPARE(object->property("signalArg").toInt(), 22); + + delete object; +} + // QTBUG-20639 void tst_qqmllanguage::globalEnums() {