1 /************************************************************************
2  *
3  * Copyright 2010-2012 Jakob Leben (jakob.leben@gmail.com)
4  *
5  * This file is part of SuperCollider Qt GUI.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  ************************************************************************/
21 
22 #include "primitives.h"
23 #include "../QObjectProxy.h"
24 #include "../QcObjectFactory.h"
25 #include "../QcApplication.h"
26 #include "../Common.h"
27 #include "../type_codec.hpp"
28 #include "../metatype.hpp"
29 #include "../painting.h"
30 
31 #include <PyrObject.h>
32 #include <PyrKernel.h>
33 #include <GC.h>
34 #include <SCBase.h>
35 
36 #include <QMetaObject>
37 #include <QMetaProperty>
38 #include <QMetaMethod>
39 
40 #if defined _WIN32
41 #    include "SC_Win32Utils.h"
42 #elif defined __FreeBSD__
43 #    include <stdlib.h>
44 #else
45 #    include <alloca.h>
46 #endif
47 
48 #define IS_OBJECT_NIL(a) IsNil(slotRawObject(a)->slots)
49 
50 #define QOBJECT_FROM_SLOT(s) ((QObjectProxy*)slotRawPtr(slotRawObject(s)->slots))
51 
52 #define CLASS_NAME(slot) slotRawSymbol(&slotRawObject(slot)->classptr->name)->name
53 
54 namespace QtCollider {
55 
56 int QObject_Finalize(struct VMGlobals*, struct PyrObject*);
57 
58 QC_LANG_PRIMITIVE(QObject_New, 2, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
59     if (NotSym(a + 0))
60         return errWrongType;
61 
62     PyrObject* scObject = slotRawObject(r);
63     QString qtClassName = QString(slotRawSymbol(a + 0)->name);
64 
65     qcSCObjectDebugMsg(1, scObject, QStringLiteral("CREATE: %2").arg(qtClassName));
66 
67     if (!QcApplication::compareThread())
68         return QtCollider::wrongThreadError();
69 
70     QcAbstractFactory* f = QtCollider::factories().value(qtClassName);
71 
72     if (!f) {
73         qcErrorMsg(QStringLiteral("Factory for class '%1' not found!").arg(qtClassName));
74         return errFailed;
75     }
76 
77     QObjectProxy* proxy = 0;
78 
79     MetaValue args[10];
80 
81     PyrSlot* argSlot = a + 1;
82     int argc;
83 
84     if (isKindOfSlot(argSlot, class_array)) {
85         PyrObject* array = slotRawObject(argSlot);
86         argSlot = array->slots;
87         argc = array->size;
88     } else {
89         argc = 1;
90     }
91 
92     for (int i = 0; i < argc && i < 10; ++i) {
93         PyrSlot* slot = argSlot + i;
94         MetaType* type = MetaType::find(slot);
95         if (type) {
96             void* mem = alloca(type->size());
97             Q_ASSERT(mem);
98             args[i].read(mem, type, slot);
99         }
100     }
101 
102     proxy = f->newInstance(scObject, args);
103     if (!proxy)
104         return errFailed;
105 
106     SetPtr(scObject->slots, proxy);
107 
108     InstallFinalizer(g, scObject, 1, QObject_Finalize);
109 
110     return errNone;
111 }
112 
113 QC_LANG_PRIMITIVE(QObject_Destroy, 0, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
114     qcSCObjectDebugMsg(1, slotRawObject(r), "DESTROY");
115 
116     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
117 
118     if (!proxy->compareThread())
119         return QtCollider::wrongThreadError();
120 
121     // Post the destruction event asynchronously;
122     DestroyEvent* e = new DestroyEvent(QObjectProxy::DestroyObject);
123     QApplication::postEvent(proxy, e);
124 
125     return errNone;
126 }
127 
QObject_Finalize(struct VMGlobals *,struct PyrObject * obj)128 int QObject_Finalize(struct VMGlobals*, struct PyrObject* obj) {
129     qcSCObjectDebugMsg(1, obj, "FINALIZE");
130 
131     QObjectProxy* proxy = (QObjectProxy*)slotRawPtr(obj->slots);
132 
133     // Invalidate proxy's SC object pointer directly.
134     // Note that it is protected by language mutex;
135     proxy->finalize();
136 
137     // Post the destruction event asynchronously;
138     DestroyEvent* e = new DestroyEvent(QObjectProxy::DestroyProxyAndObject);
139     QApplication::postEvent(proxy, e);
140 
141     return errNone;
142 }
143 
144 QC_LANG_PRIMITIVE(QObject_SetParent, 1, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
145     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
146 
147     QObjectProxy* parent = QtCollider::get(a);
148     if (!parent)
149         return errWrongType;
150 
151     qcSCObjectDebugMsg(1, slotRawObject(r), "SET PARENT");
152 
153     if (!proxy->compareThread())
154         return QtCollider::wrongThreadError();
155 
156     bool ok = proxy->setParent(parent);
157 
158     return ok ? errNone : errFailed;
159 }
160 
qcGetProperties(const QMetaObject * mo,PyrSlot * r,VMGlobals * g)161 static void qcGetProperties(const QMetaObject* mo, PyrSlot* r, VMGlobals* g) {
162     int count = mo->propertyCount();
163 
164     PyrObject* array = newPyrArray(g->gc, count, 0, true);
165     SetObject(r, array);
166 
167     PyrSlot* s = array->slots;
168     for (int i = 0; i < count; ++i, ++s) {
169         SetSymbol(s, getsym(mo->property(i).name()));
170         array->size++;
171     }
172 }
173 
qcGetMethods(const QMetaObject * mo,bool getPlain,bool getSignals,bool getSlots,PyrSlot * r,VMGlobals * g)174 static void qcGetMethods(const QMetaObject* mo, bool getPlain, bool getSignals, bool getSlots, PyrSlot* r,
175                          VMGlobals* g) {
176     int count = mo->methodCount();
177 
178     PyrObject* array = newPyrArray(g->gc, count, 0, true);
179     SetObject(r, array);
180 
181     PyrSlot* s = array->slots;
182     for (int i = 0; i < count; ++i) {
183         QMetaMethod method = mo->method(i);
184         switch (method.methodType()) {
185         case QMetaMethod::Method:
186             if (!getPlain || (method.access() != QMetaMethod::Public))
187                 continue;
188             break;
189         case QMetaMethod::Signal:
190             if (!getSignals)
191                 continue;
192             break;
193         case QMetaMethod::Slot:
194             if (!getSlots || (method.access() != QMetaMethod::Public))
195                 continue;
196             break;
197         default:
198             continue;
199         }
200         QtCollider::set(s, QString::fromLatin1(method.methodSignature()));
201         array->size++;
202         g->gc->GCWrite(array, s);
203         ++s;
204     }
205 }
206 
207 QC_LANG_PRIMITIVE(QMetaObject_Properties, 0, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
208     if (!QcApplication::compareThread())
209         return QtCollider::wrongThreadError();
210 
211     PyrSlot* sClassName = slotRawObject(r)->slots + 0;
212     if (NotSym(sClassName))
213         return errWrongType;
214     QString className(slotRawSymbol(sClassName)->name);
215 
216     QcAbstractFactory* f = QtCollider::factories().value(className);
217 
218     if (!f) {
219         qcErrorMsg(QStringLiteral("Factory for class '%1' not found!").arg(className));
220         return errFailed;
221     }
222 
223     const QMetaObject* mo = f->metaObject();
224     qcGetProperties(mo, r, g);
225 
226     return errNone;
227 }
228 
229 QC_LANG_PRIMITIVE(QMetaObject_Methods, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
230     if (!QcApplication::compareThread())
231         return QtCollider::wrongThreadError();
232 
233     PyrSlot* sClassName = slotRawObject(r)->slots + 0;
234     if (NotSym(sClassName))
235         return errWrongType;
236     QString className(slotRawSymbol(sClassName)->name);
237 
238     QcAbstractFactory* f = QtCollider::factories().value(className);
239 
240     if (!f) {
241         qcErrorMsg(QStringLiteral("Factory for class '%1' not found!").arg(className));
242         return errFailed;
243     }
244 
245     bool getPlain = IsTrue(a + 0);
246     bool getSignals = IsTrue(a + 1);
247     bool getSlots = IsTrue(a + 2);
248 
249     const QMetaObject* mo = f->metaObject();
250     qcGetMethods(mo, getPlain, getSignals, getSlots, r, g);
251 
252     return errNone;
253 }
254 
255 QC_LANG_PRIMITIVE(QObject_GetProperties, 0, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
256     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
257     if (!proxy->compareThread())
258         return QtCollider::wrongThreadError();
259 
260     QObject* obj = proxy->object();
261     if (!obj) {
262         SetNil(r);
263         return errNone;
264     }
265 
266     const QMetaObject* mo = obj->metaObject();
267     qcGetProperties(mo, r, g);
268 
269     return errNone;
270 }
271 
272 QC_LANG_PRIMITIVE(QObject_GetMethods, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
273     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
274     if (!proxy->compareThread())
275         return QtCollider::wrongThreadError();
276 
277     QObject* obj = proxy->object();
278     if (!obj) {
279         SetNil(r);
280         return errNone;
281     }
282 
283     bool getPlain = IsTrue(a + 0);
284     bool getSignals = IsTrue(a + 1);
285     bool getSlots = IsTrue(a + 2);
286 
287     const QMetaObject* mo = obj->metaObject();
288     qcGetMethods(mo, getPlain, getSignals, getSlots, r, g);
289 
290     return errNone;
291 }
292 
293 QC_LANG_PRIMITIVE(QObject_SetProperty, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
294     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
295 
296     if (NotSym(a))
297         return errWrongType;
298     PyrSymbol* property = slotRawSymbol(a);
299     bool sync = IsTrue(a + 2);
300 
301     qcSCObjectDebugMsg(1, slotRawObject(r), QStringLiteral("SET: %1").arg(property->name));
302 
303     if (!proxy->compareThread())
304         return QtCollider::wrongThreadError();
305 
306     QVariant val = QtCollider::get(a + 1);
307 
308     if (sync && !QtCollider::isPaintingObject(proxy)) {
309         proxy->setProperty(property->name, val);
310     } else {
311         SetPropertyEvent* e = new SetPropertyEvent();
312         e->property = property;
313         e->value = val;
314         QApplication::postEvent(proxy, e);
315     }
316 
317     return errNone;
318 }
319 
320 QC_LANG_PRIMITIVE(QObject_GetProperty, 1, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
321     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
322 
323     if (NotSym(a))
324         return errWrongType;
325     PyrSymbol* symProp = slotRawSymbol(a);
326 
327     qcSCObjectDebugMsg(1, slotRawObject(r), QStringLiteral("GET: %1").arg(symProp->name));
328 
329     if (!proxy->compareThread())
330         return QtCollider::wrongThreadError();
331 
332     QVariant val = proxy->property(symProp->name);
333     if (!val.isValid()) {
334         qcDebugMsg(1, QStringLiteral("WARNING: Invalid property '%1'").arg(symProp->name));
335         SetNil(r);
336         return errNone;
337     }
338 
339     if (QtCollider::set(r, val))
340         return errNone;
341     else
342         return errFailed;
343 }
344 
345 QC_LANG_PRIMITIVE(QObject_SetEventHandler, 4, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
346     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
347 
348     if (NotInt(a + 0) || NotSym(a + 1))
349         return errWrongType;
350     int eventType = QtCollider::get(a + 0);
351     PyrSymbol* method = 0;
352     slotSymbolVal(a + 1, &method);
353     Synchronicity sync = IsTrue(a + 2) ? Synchronous : Asynchronous;
354     bool enabled = IsTrue(a + 3);
355 
356     qcSCObjectDebugMsg(1, slotRawObject(r),
357                        QStringLiteral("SET EVENT HANDLER: type %1 -> %2 [%3, %4]")
358                            .arg(eventType)
359                            .arg(method->name)
360                            .arg(sync == Synchronous ? "SYNC" : "ASYNC")
361                            .arg(enabled ? "on" : "off"));
362 
363     if (!proxy->compareThread())
364         return QtCollider::wrongThreadError();
365 
366     bool ok = proxy->setEventHandler(eventType, method, sync, enabled);
367 
368     return ok ? errNone : errFailed;
369 }
370 
371 QC_LANG_PRIMITIVE(QObject_SetEventHandlerEnabled, 2, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
372     if (NotInt(a + 0))
373         return errWrongType;
374     bool enabled = IsTrue(a + 1);
375     if (!enabled && !IsFalse(a + 1))
376         return errWrongType;
377     int type = QtCollider::get(a + 0);
378 
379     qcSCObjectDebugMsg(1, slotRawObject(r),
380                        QStringLiteral("SET EVENT HANDLER STATE: type %1 = %2").arg(type).arg(enabled ? "on" : "off"));
381 
382     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
383 
384     if (!proxy->compareThread())
385         return QtCollider::wrongThreadError();
386 
387     bool ok = proxy->setEventHandlerEnabled(type, enabled);
388 
389     return ok ? errNone : errFailed;
390 }
391 
392 QC_LANG_PRIMITIVE(QObject_ConnectMethod, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
393     if (NotSym(a + 0) || NotSym(a + 1))
394         return errWrongType;
395 
396     PyrSymbol* signal = slotRawSymbol(a + 0);
397     PyrSymbol* handler = slotRawSymbol(a + 1);
398     Qt::ConnectionType ctype = IsTrue(a + 2) ? Qt::DirectConnection : Qt::QueuedConnection;
399 
400     qcSCObjectDebugMsg(1, slotRawObject(r),
401                        QStringLiteral("CONNECT METHOD: %1 -> %2 [%3]")
402                            .arg(signal->name)
403                            .arg(handler->name)
404                            .arg(IsTrue(a + 2) ? "SYNC" : "ASYNC"));
405 
406     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
407 
408     if (!proxy->compareThread())
409         return QtCollider::wrongThreadError();
410 
411     bool ok = proxy->connectMethod(signal->name, handler, ctype);
412 
413     return ok ? errNone : errFailed;
414 }
415 
416 QC_LANG_PRIMITIVE(QObject_DisconnectMethod, 2, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
417     if (NotSym(a + 0) || NotSym(a + 1))
418         return errWrongType;
419 
420     PyrSymbol* signal = slotRawSymbol(a + 0);
421     PyrSymbol* handler = slotRawSymbol(a + 1);
422 
423     qcSCObjectDebugMsg(1, slotRawObject(r),
424                        QStringLiteral("DISCONNECT METHOD: %1 -> %2").arg(signal->name).arg(handler->name));
425 
426     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
427 
428     if (!proxy->compareThread())
429         return QtCollider::wrongThreadError();
430 
431     bool ok = proxy->disconnectMethod(signal->name, handler);
432 
433     return ok ? errNone : errFailed;
434 }
435 
436 QC_LANG_PRIMITIVE(QObject_ConnectObject, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
437     if (NotSym(a + 0) || NotObj(a + 1))
438         return errWrongType;
439 
440     PyrSymbol* signal = slotRawSymbol(a + 0);
441     PyrObject* handlerObj = slotRawObject(a + 1);
442     Qt::ConnectionType ctype = IsTrue(a + 2) ? Qt::DirectConnection : Qt::QueuedConnection;
443 
444     qcSCObjectDebugMsg(1, slotRawObject(r),
445                        QStringLiteral("CONNECT OBJECT: %1 -> %2 [%3]")
446                            .arg(signal->name)
447                            .arg(slotRawSymbol(&handlerObj->classptr->name)->name)
448                            .arg(IsTrue(a + 2) ? "SYNC" : "ASYNC"));
449 
450     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
451 
452     if (!proxy->compareThread())
453         return QtCollider::wrongThreadError();
454 
455     bool ok = proxy->connectObject(signal->name, handlerObj, ctype);
456 
457     return ok ? errNone : errFailed;
458 }
459 
460 QC_LANG_PRIMITIVE(QObject_DisconnectObject, 2, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
461     if (NotSym(a + 0) || NotObj(a + 1))
462         return errWrongType;
463 
464     PyrSymbol* signal = slotRawSymbol(a + 0);
465     PyrObject* handlerObj = slotRawObject(a + 1);
466 
467     qcSCObjectDebugMsg(1, slotRawObject(r), QStringLiteral("DISCONNECT OBJECT: %1").arg(signal->name));
468 
469     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
470 
471     if (!proxy->compareThread())
472         return QtCollider::wrongThreadError();
473 
474     bool ok = proxy->disconnectObject(signal->name, handlerObj);
475 
476     return ok ? errNone : errFailed;
477 }
478 
479 QC_LANG_PRIMITIVE(QObject_ConnectSlot, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
480     // Args: signal, receiver, slot
481     if (!isKindOfSlot(a + 1, SC_CLASS(QObject)) || NotSym(a + 0) || NotSym(a + 2))
482         return errWrongType;
483 
484     PyrSymbol* symSig = slotRawSymbol(a + 0);
485     PyrSymbol* symSlot = slotRawSymbol(a + 2);
486     QObjectProxy* sndProxy = QOBJECT_FROM_SLOT(r);
487     QObjectProxy* rcvProxy = QOBJECT_FROM_SLOT(a + 1);
488 
489     qcSCObjectDebugMsg(1, slotRawObject(r),
490                        QStringLiteral("CONNECT TO SLOT: %1 -> %2").arg(symSig->name).arg(symSlot->name));
491 
492     QString strSig = QStringLiteral("2") + symSig->name;
493     QString strSlot = QStringLiteral("1") + symSlot->name;
494 
495     sndProxy->lock();
496     rcvProxy->lock();
497     bool ok;
498     if (!sndProxy->object() || !rcvProxy->object()) {
499         ok = true;
500     } else {
501         ok = QObject::connect(sndProxy->object(), strSig.toStdString().c_str(), rcvProxy->object(),
502                               strSlot.toStdString().c_str());
503     }
504     sndProxy->unlock();
505     rcvProxy->unlock();
506 
507     if (!ok) {
508         qcErrorMsg(QStringLiteral("Failed to connect %1::%2 to %3::%4!\n")
509                        .arg(sndProxy->scClassName())
510                        .arg(symSig->name)
511                        .arg(rcvProxy->scClassName())
512                        .arg(symSlot->name));
513         return errFailed;
514     }
515 
516     return errNone;
517 }
518 
519 QC_LANG_PRIMITIVE(QObject_InvokeMethod, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
520     if (NotSym(a + 0))
521         return errWrongType;
522 
523     PyrSymbol* method = slotRawSymbol(a + 0);
524     PyrSlot* methodArgs = a + 1;
525     bool sync = !IsFalse(a + 2);
526 
527     qcSCObjectDebugMsg(1, slotRawObject(r),
528                        QStringLiteral("INVOKE: '%1' [%2]").arg(method->name).arg(sync ? "SYNC" : "ASYNC"));
529 
530     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
531 
532     PyrSlot* retSlot;
533     Qt::ConnectionType cType;
534 
535     if (sync) {
536         if (!proxy->compareThread())
537             return QtCollider::wrongThreadError();
538         retSlot = r;
539         cType = Qt::DirectConnection;
540     } else {
541         retSlot = 0;
542         cType = Qt::QueuedConnection;
543     }
544 
545     bool ok = proxy->invokeMethod(method->name, retSlot, methodArgs, cType);
546 
547     return ok ? errNone : errFailed;
548 }
549 
550 QC_LANG_PRIMITIVE(QObject_IsValid, 0, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
551     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
552 
553     bool needLock = !proxy->compareThread();
554 
555     if (needLock)
556         proxy->lock();
557 
558     bool hasObject = proxy->object() != 0;
559 
560     if (needLock)
561         proxy->unlock();
562 
563     SetBool(r, hasObject);
564 
565     return errNone;
566 }
567 
568 QC_LANG_PRIMITIVE(QObject_GetChildren, 1, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
569     if (NotSym(a) && NotNil(a))
570         return errWrongType;
571 
572     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
573     PyrSymbol* className = IsSym(a) ? slotRawSymbol(a) : 0;
574 
575     qcSCObjectDebugMsg(1, slotRawObject(r),
576                        QStringLiteral("GET CHILDREN: of class '%1'").arg(className ? className->name : "QObject"));
577 
578     if (!proxy->compareThread())
579         return QtCollider::wrongThreadError();
580 
581     QList<PyrObject*> children = proxy->children(className);
582 
583     int count = children.count();
584     PyrObject* array = newPyrArray(g->gc, count, 0, true);
585     SetObject(r, array);
586 
587     PyrSlot* s = array->slots;
Q_FOREACH(PyrObject * obj,children)588     Q_FOREACH (PyrObject* obj, children) {
589         SetObject(s, obj);
590         ++array->size;
591         g->gc->GCWrite(array, s);
592         ++s;
593     }
594 
595     return errNone;
596 }
597 
598 QC_LANG_PRIMITIVE(QObject_GetParent, 1, PyrSlot* r, PyrSlot* a, VMGlobals* g) {
599     if (NotSym(a) && NotNil(a))
600         return errWrongType;
601 
602     QObjectProxy* proxy = QOBJECT_FROM_SLOT(r);
603     PyrSymbol* className = IsSym(a) ? slotRawSymbol(a) : 0;
604 
605     qcSCObjectDebugMsg(1, slotRawObject(r), QStringLiteral("GET PARENT"));
606 
607     if (!proxy->compareThread())
608         return QtCollider::wrongThreadError();
609 
610     PyrObject* parent = proxy->parent(className);
611 
612     if (parent)
613         SetObject(r, parent);
614     else
615         SetNil(r);
616 
617     return errNone;
618 }
619 
defineQObjectPrimitives()620 void defineQObjectPrimitives() {
621     LangPrimitiveDefiner definer;
622     definer.define<QObject_New>();
623     definer.define<QObject_Destroy>();
624     definer.define<QObject_SetParent>();
625     definer.define<QMetaObject_Properties>();
626     definer.define<QMetaObject_Methods>();
627     definer.define<QObject_GetProperties>();
628     definer.define<QObject_GetMethods>();
629     definer.define<QObject_SetProperty>();
630     definer.define<QObject_GetProperty>();
631     definer.define<QObject_SetEventHandler>();
632     definer.define<QObject_SetEventHandlerEnabled>();
633     definer.define<QObject_ConnectMethod>();
634     definer.define<QObject_DisconnectMethod>();
635     definer.define<QObject_ConnectObject>();
636     definer.define<QObject_DisconnectObject>();
637     definer.define<QObject_ConnectSlot>();
638     definer.define<QObject_InvokeMethod>();
639     definer.define<QObject_IsValid>();
640     definer.define<QObject_GetChildren>();
641     definer.define<QObject_GetParent>();
642 }
643 
644 } // namespace QtCollider
645