Fixed signal connection with native c++ slot.

Fixes bug #860.

Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
          Hugo Parente <hugo.lima@openbossa.org>
This commit is contained in:
Renato Filho 2011-06-03 11:32:47 -03:00
commit 21dc823972

View file

@ -727,8 +727,8 @@ QStringList getArgsFromSignature(const char* signature, bool* isShortCircuit)
QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* callback, bool encodeName) QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* callback, bool encodeName)
{ {
QString functionName; QByteArray functionName;
QString signature; QByteArray signature;
QStringList args; QStringList args;
int numArgs = -1; int numArgs = -1;
bool useSelf = false; bool useSelf = false;
@ -743,31 +743,32 @@ QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* ca
numArgs = objCode->co_flags & CO_VARARGS ? -1 : objCode->co_argcount; numArgs = objCode->co_flags & CO_VARARGS ? -1 : objCode->co_argcount;
} else if (PyCFunction_Check(callback)) { } else if (PyCFunction_Check(callback)) {
functionName = ((PyCFunctionObject*)callback)->m_ml->ml_name; functionName = ((PyCFunctionObject*)callback)->m_ml->ml_name;
useSelf = 0;//((PyCFunctionObject*)callback)->m_self; // commented out to fix bug 736 useSelf = ((PyCFunctionObject*)callback)->m_self;
int flags = ((PyCFunctionObject*)callback)->m_ml->ml_flags; int flags = ((PyCFunctionObject*)callback)->m_ml->ml_flags;
if (receiver) { if (receiver) {
//Search for signature on metaobject //Search for signature on metaobject
const QMetaObject *mo = receiver->metaObject(); const QMetaObject *mo = receiver->metaObject();
QByteArray prefix(functionName);
prefix += '(';
for(int i=0; i < mo->methodCount(); i++) { for(int i=0; i < mo->methodCount(); i++) {
QMetaMethod me = mo->method(i); QMetaMethod me = mo->method(i);
if (QString(me.signature()).startsWith(functionName)) { if ((strncmp(me.signature(), prefix, prefix.size()) == 0) &&
numArgs = me.parameterTypes().size()+1; QMetaObject::checkConnectArgs(signal, me.signature())) {
numArgs = me.parameterTypes().size() + useSelf;
break; break;
} }
} }
} }
if (numArgs == -1) { if (numArgs == -1) {
if (flags & METH_O) if (flags & METH_VARARGS)
numArgs = 1;
else if (flags & METH_VARARGS)
numArgs = -1; numArgs = -1;
else if (flags & METH_NOARGS) else if (flags & METH_NOARGS)
numArgs = 0; numArgs = 0;
} }
} else if (PyCallable_Check(callback)) { } else if (PyCallable_Check(callback)) {
functionName = "__callback"+QString::number((size_t)callback); functionName = "__callback"+QByteArray::number((qlonglong)callback);
} }
Q_ASSERT(!functionName.isEmpty()); Q_ASSERT(!functionName.isEmpty());
@ -775,7 +776,7 @@ QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* ca
bool isShortCircuit = false; bool isShortCircuit = false;
if (encodeName) if (encodeName)
signature = codeCallbackName(callback, functionName); signature = qPrintable(codeCallbackName(callback, functionName));
else else
signature = functionName; signature = functionName;
@ -785,7 +786,7 @@ QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* ca
signature.append('('); signature.append('(');
if (numArgs == -1) if (numArgs == -1)
numArgs = std::numeric_limits<int>::max(); numArgs = std::numeric_limits<int>::max();
while (args.count() && args.count() > numArgs - useSelf) { while (args.count() && (args.count() > (numArgs - useSelf))) {
args.removeLast(); args.removeLast();
} }
signature.append(args.join(",")); signature.append(args.join(","));