aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrenatofilho <renato.filho@openbossa.org>2010-10-28 16:28:43 -0300
committerrenatofilho <renato.filho@openbossa.org>2010-10-28 17:40:12 -0300
commitbd8239b1cd99d25c26eb99a051072254342ab0bb (patch)
tree12fce76bd9206473ead1600e05d5591619f98393
parenta1524b78b632d99aa6076391d0d77e46271dd7c8 (diff)
Stop signal/slot connection if is impossible to register that on object.
Created unit test for bug #442, #437. Fixes bug #442. Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r--PySide/QtCore/glue/qobject_connect.cpp10
-rw-r--r--libpyside/qsignal.cpp13
-rw-r--r--libpyside/signalmanager.cpp2
-rw-r--r--tests/QtDeclarative/CMakeLists.txt1
-rwxr-xr-xtests/QtDeclarative/connect_python_qml.py30
-rw-r--r--tests/QtDeclarative/connect_python_qml.qml20
6 files changed, 66 insertions, 10 deletions
diff --git a/PySide/QtCore/glue/qobject_connect.cpp b/PySide/QtCore/glue/qobject_connect.cpp
index cf7877912..b98a4114a 100644
--- a/PySide/QtCore/glue/qobject_connect.cpp
+++ b/PySide/QtCore/glue/qobject_connect.cpp
@@ -32,7 +32,8 @@ static bool qobjectConnect(QObject* source, const char* signal, QObject* receive
return false;
signal++;
- PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal);
+ if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
+ return false;
bool isSignal = PySide::isSignal(slot);
slot++;
@@ -46,7 +47,9 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
return false;
signal++;
- PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal);
+ if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
+ return false;
+
int signalIndex = source->metaObject()->indexOfMethod(signal);
PySide::SignalManager& signalManager = PySide::SignalManager::instance();
@@ -70,7 +73,8 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
if (usingGlobalReceiver) {
signalManager.addGlobalSlot(slot, callback);
} else {
- PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot);
+ if (!PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot))
+ return false;
}
slotIndex = metaObject->indexOfSlot(slot);
}
diff --git a/libpyside/qsignal.cpp b/libpyside/qsignal.cpp
index 23ee7ff25..31d30fca1 100644
--- a/libpyside/qsignal.cpp
+++ b/libpyside/qsignal.cpp
@@ -523,6 +523,8 @@ char* getTypeName(PyObject* type)
return typeName;
} else if (PyString_Check(type)) {
return strdup(PyString_AS_STRING(type));
+ } else if (type == Py_None) {
+ return strdup("void");
}
return 0;
}
@@ -537,7 +539,7 @@ char* signalBuildSignature(const char *name, const char *signature)
char* signalParseSignature(PyObject *args)
{
char *signature = 0;
- if (args && (PyString_Check(args) || (!PySequence_Check(args) && (args != Py_None))))
+ if (args && (PyString_Check(args) || !PySequence_Check(args)))
return getTypeName(args);
for(Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) {
@@ -623,12 +625,11 @@ PyObject* signalNewFromMethod(PyObject* source, const QList<QMetaMethod>& method
item->d = new PySideSignalInstanceDataPrivate;
PySideSignalInstanceDataPrivate* selfPvt = item->d;
selfPvt->source = source;
- const char* cppSignature = m.signature();
+ QByteArray cppName(m.signature());
+ cppName = cppName.mid(0, cppName.indexOf('('));
// separe SignalName
- selfPvt->signalName = strdup(cppSignature);
- char* endName = strchr(selfPvt->signalName, '(');
- endName = '\0';
- selfPvt->signature = strdup(cppSignature);
+ selfPvt->signalName = strdup(cppName.data());
+ selfPvt->signature = strdup(m.signature());
selfPvt->homonymousMethod = 0;
selfPvt->next = 0;
}
diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp
index 69c449272..53f6a4510 100644
--- a/libpyside/signalmanager.cpp
+++ b/libpyside/signalmanager.cpp
@@ -482,7 +482,7 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q
if (methodIndex == -1) {
Shiboken::SbkBaseWrapper* self = (Shiboken::SbkBaseWrapper*) Shiboken::BindingManager::instance().retrieveWrapper(source);
if (!self->containsCppWrapper) {
- qWarning() << "You can't add dynamic signals or slots on an object originated from C++.";
+ qWarning() << "Invalid Signal signature:" << signature;
return false;
} else {
PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject));
diff --git a/tests/QtDeclarative/CMakeLists.txt b/tests/QtDeclarative/CMakeLists.txt
index 4896010bd..98b797c97 100644
--- a/tests/QtDeclarative/CMakeLists.txt
+++ b/tests/QtDeclarative/CMakeLists.txt
@@ -1,2 +1,3 @@
PYSIDE_TEST(qdeclarativenetwork_test.py FALSE)
PYSIDE_TEST(qdeclarativeview_test.py FALSE)
+PYSIDE_TEST(connect_python_qml.py FALSE)
diff --git a/tests/QtDeclarative/connect_python_qml.py b/tests/QtDeclarative/connect_python_qml.py
new file mode 100755
index 000000000..bb505156e
--- /dev/null
+++ b/tests/QtDeclarative/connect_python_qml.py
@@ -0,0 +1,30 @@
+'''Test case for bug #442'''
+
+from PySide import QtCore, QtGui, QtDeclarative
+from helper import adjust_filename, TimedQApplication
+import unittest
+
+class TestConnectionWithInvalidSignature(TimedQApplication):
+ def onButtonClicked(self):
+ self.buttonClicked = True
+ self.app.quit()
+
+ def onButtonFailClicked(self):
+ pass
+
+ def testFailConnection(self):
+ self.buttonClicked = False
+ self.buttonFailClicked = False
+ view = QtDeclarative.QDeclarativeView()
+ view.setSource(QtCore.QUrl(adjust_filename('connect_python_qml.qml', __file__)))
+ root = view.rootObject()
+ button = root.findChild(QtCore.QObject, "buttonMouseArea")
+ self.assertRaises(TypeError, QtCore.QObject.connect, [button,QtCore.SIGNAL('clicked()'), self.onButtonFailClicked])
+ button.clicked.connect(self.onButtonClicked)
+ button.clicked.emit()
+ view.show()
+ self.app.exec_()
+ self.assert_(self.buttonClicked)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/QtDeclarative/connect_python_qml.qml b/tests/QtDeclarative/connect_python_qml.qml
new file mode 100644
index 000000000..dbf890f6f
--- /dev/null
+++ b/tests/QtDeclarative/connect_python_qml.qml
@@ -0,0 +1,20 @@
+import Qt 4.7
+
+Rectangle {
+ id: page
+ width: 500; height: 200
+ color: "lightgray"
+
+ Rectangle {
+ id: button
+ width: 150; height: 40
+ color: "darkgray"
+ anchors.horizontalCenter: page.horizontalCenter
+ y: 150
+ MouseArea {
+ id: buttonMouseArea
+ objectName: "buttonMouseArea"
+ anchors.fill: parent
+ }
+ }
+}