b38e7f90047df75fd40a9a3ca2c860ee5a9431b4
[profile/ivi/qtbase.git] / src / corelib / kernel / qmetaobject.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qmetaobject.h"
43 #include "qmetatype.h"
44 #include "qobject.h"
45
46 #include <qcoreapplication.h>
47 #include <qcoreevent.h>
48 #include <qdatastream.h>
49 #include <qstringlist.h>
50 #include <qthread.h>
51 #include <qvarlengtharray.h>
52 #include <qvariant.h>
53 #include <qhash.h>
54 #include <qdebug.h>
55 #include <qsemaphore.h>
56
57 #include "private/qobject_p.h"
58 #include "private/qmetaobject_p.h"
59
60 // for normalizeTypeInternal
61 #include "private/qmetaobject_moc_p.h"
62
63 #include <ctype.h>
64
65 QT_BEGIN_NAMESPACE
66
67 /*!
68     \class QMetaObject
69
70     \brief The QMetaObject class contains meta-information about Qt
71     objects.
72
73     \ingroup objectmodel
74
75     The Qt \l{Meta-Object System} in Qt is responsible for the
76     signals and slots inter-object communication mechanism, runtime
77     type information, and the Qt property system. A single
78     QMetaObject instance is created for each QObject subclass that is
79     used in an application, and this instance stores all the
80     meta-information for the QObject subclass. This object is
81     available as QObject::metaObject().
82
83     This class is not normally required for application programming,
84     but it is useful if you write meta-applications, such as scripting
85     engines or GUI builders.
86
87     The functions you are most likely to find useful are these:
88     \list
89     \o className() returns the name of a class.
90     \o superClass() returns the superclass's meta-object.
91     \o method() and methodCount() provide information
92        about a class's meta-methods (signals, slots and other
93        \l{Q_INVOKABLE}{invokable} member functions).
94     \o enumerator() and enumeratorCount() and provide information about
95        a class's enumerators.
96     \o propertyCount() and property() provide information about a
97        class's properties.
98     \o constructor() and constructorCount() provide information
99        about a class's meta-constructors.
100     \endlist
101
102     The index functions indexOfConstructor(), indexOfMethod(),
103     indexOfEnumerator(), and indexOfProperty() map names of constructors,
104     member functions, enumerators, or properties to indexes in the
105     meta-object. For example, Qt uses indexOfMethod() internally when you
106     connect a signal to a slot.
107
108     Classes can also have a list of \e{name}--\e{value} pairs of
109     additional class information, stored in QMetaClassInfo objects.
110     The number of pairs is returned by classInfoCount(), single pairs
111     are returned by classInfo(), and you can search for pairs with
112     indexOfClassInfo().
113
114     \sa QMetaClassInfo, QMetaEnum, QMetaMethod, QMetaProperty, QMetaType,
115         {Meta-Object System}
116 */
117
118 /*!
119     \enum QMetaObject::Call
120
121     \internal
122
123     \value InvokeSlot
124     \value EmitSignal
125     \value ReadProperty
126     \value WriteProperty
127     \value ResetProperty
128     \value QueryPropertyDesignable
129     \value QueryPropertyScriptable
130     \value QueryPropertyStored
131     \value QueryPropertyEditable
132     \value QueryPropertyUser
133     \value CreateInstance
134 */
135
136 /*!
137     \enum QMetaMethod::Access
138
139     This enum describes the access level of a method, following the conventions used in C++.
140
141     \value Private
142     \value Protected
143     \value Public
144 */
145
146 static inline const QMetaObjectPrivate *priv(const uint* data)
147 { return reinterpret_cast<const QMetaObjectPrivate*>(data); }
148
149 static inline const QByteArrayData &stringData(const QMetaObject *mo, int index)
150 {
151     Q_ASSERT(priv(mo->d.data)->revision >= 7);
152     const QByteArrayData &data = mo->d.stringdata[index];
153     Q_ASSERT(data.ref.isStatic());
154     Q_ASSERT(data.alloc == 0);
155     Q_ASSERT(data.capacityReserved == 0);
156     Q_ASSERT(data.size >= 0);
157     return data;
158 }
159
160 static inline QByteArray toByteArray(const QByteArrayData &d)
161 {
162     return QByteArray(reinterpret_cast<const QStaticByteArrayData<0> &>(d));
163 }
164
165 static inline const char *legacyString(const QMetaObject *mo, int index)
166 {
167     Q_ASSERT(priv(mo->d.data)->revision <= 6);
168     return reinterpret_cast<const char *>(mo->d.stringdata) + index;
169 }
170
171 static inline const char *rawStringData(const QMetaObject *mo, int index)
172 {
173     if (priv(mo->d.data)->revision >= 7)
174         return stringData(mo, index).data();
175     else
176         return legacyString(mo, index);
177 }
178
179 static inline int stringSize(const QMetaObject *mo, int index)
180 {
181     if (priv(mo->d.data)->revision >= 7)
182         return stringData(mo, index).size;
183     else
184         return qstrlen(legacyString(mo, index));
185 }
186
187 static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
188 {
189     if (typeInfo & IsUnresolvedType) {
190         return toByteArray(stringData(mo, typeInfo & TypeNameIndexMask));
191     } else {
192         // ### Use the QMetaType::typeName() that returns QByteArray
193         const char *t = QMetaType::typeName(typeInfo);
194         return QByteArray::fromRawData(t, qstrlen(t));
195     }
196 }
197
198 static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
199 {
200     return typeNameFromTypeInfo(mo, typeInfo).constData();
201 }
202
203 static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
204 {
205     if (!(typeInfo & IsUnresolvedType))
206         return typeInfo;
207     return QMetaType::type(toByteArray(stringData(mo, typeInfo & TypeNameIndexMask)));
208 }
209
210 class QMetaMethodPrivate : public QMetaMethod
211 {
212 public:
213     static const QMetaMethodPrivate *get(const QMetaMethod *q)
214     { return static_cast<const QMetaMethodPrivate *>(q); }
215
216     inline QByteArray signature() const;
217     inline QByteArray name() const;
218     inline int typesDataIndex() const;
219     inline const char *rawReturnTypeName() const;
220     inline int returnType() const;
221     inline int parameterCount() const;
222     inline int parametersDataIndex() const;
223     inline uint parameterTypeInfo(int index) const;
224     inline int parameterType(int index) const;
225     inline void getParameterTypes(int *types) const;
226     inline QList<QByteArray> parameterTypes() const;
227     inline QList<QByteArray> parameterNames() const;
228     inline QByteArray tag() const;
229
230 private:
231     QMetaMethodPrivate();
232 };
233
234 /*!
235     \since 4.5
236
237     Constructs a new instance of this class. You can pass up to ten arguments
238     (\a val0, \a val1, \a val2, \a val3, \a val4, \a val5, \a val6, \a val7,
239     \a val8, and \a val9) to the constructor. Returns the new object, or 0 if
240     no suitable constructor is available.
241
242     Note that only constructors that are declared with the Q_INVOKABLE
243     modifier are made available through the meta-object system.
244
245     \sa Q_ARG(), constructor()
246 */
247 QObject *QMetaObject::newInstance(QGenericArgument val0,
248                                   QGenericArgument val1,
249                                   QGenericArgument val2,
250                                   QGenericArgument val3,
251                                   QGenericArgument val4,
252                                   QGenericArgument val5,
253                                   QGenericArgument val6,
254                                   QGenericArgument val7,
255                                   QGenericArgument val8,
256                                   QGenericArgument val9) const
257 {
258     QByteArray constructorName = className();
259     {
260         int idx = constructorName.lastIndexOf(':');
261         if (idx != -1)
262             constructorName.remove(0, idx+1); // remove qualified part
263     }
264     QVarLengthArray<char, 512> sig;
265     sig.append(constructorName.constData(), constructorName.length());
266     sig.append('(');
267
268     enum { MaximumParamCount = 10 };
269     const char *typeNames[] = {val0.name(), val1.name(), val2.name(), val3.name(), val4.name(),
270                                val5.name(), val6.name(), val7.name(), val8.name(), val9.name()};
271
272     int paramCount;
273     for (paramCount = 0; paramCount < MaximumParamCount; ++paramCount) {
274         int len = qstrlen(typeNames[paramCount]);
275         if (len <= 0)
276             break;
277         sig.append(typeNames[paramCount], len);
278         sig.append(',');
279     }
280     if (paramCount == 0)
281         sig.append(')'); // no parameters
282     else
283         sig[sig.size() - 1] = ')';
284     sig.append('\0');
285
286     int idx = indexOfConstructor(sig.constData());
287     if (idx < 0) {
288         QByteArray norm = QMetaObject::normalizedSignature(sig.constData());
289         idx = indexOfConstructor(norm.constData());
290     }
291     if (idx < 0)
292         return 0;
293
294     QVariant ret(QMetaType::QObjectStar, (void*)0);
295     void *param[] = {ret.data(), val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
296                      val5.data(), val6.data(), val7.data(), val8.data(), val9.data()};
297
298     if (static_metacall(CreateInstance, idx, param) >= 0)
299         return 0;
300     return *reinterpret_cast<QObject**>(param[0]);
301 }
302
303 /*!
304     \internal
305 */
306 int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
307 {
308     const QMetaObjectExtraData *extra = reinterpret_cast<const QMetaObjectExtraData *>(d.extradata);
309     if (priv(d.data)->revision >= 6) {
310         if (!extra || !extra->static_metacall)
311             return 0;
312         extra->static_metacall(0, cl, idx, argv);
313         return -1;
314     } else if (priv(d.data)->revision >= 2) {
315         if (!extra || !extra->static_metacall)
316             return 0;
317         typedef int (*OldMetacall)(QMetaObject::Call, int, void **);
318         OldMetacall o = reinterpret_cast<OldMetacall>(extra->static_metacall);
319         return o(cl, idx, argv);
320     }
321     return 0;
322 }
323
324 /*!
325     \internal
326 */
327 int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv)
328 {
329     if (QMetaObject *mo = object->d_ptr->metaObject)
330         return static_cast<QAbstractDynamicMetaObject*>(mo)->metaCall(cl, idx, argv);
331     else
332         return object->qt_metacall(cl, idx, argv);
333 }
334
335 /*!
336     Returns the class name.
337
338     \sa superClass()
339 */
340 const char *QMetaObject::className() const
341 {
342     return rawStringData(this, 0);
343 }
344
345 /*!
346     \fn QMetaObject *QMetaObject::superClass() const
347
348     Returns the meta-object of the superclass, or 0 if there is no
349     such object.
350
351     \sa className()
352 */
353
354 /*!
355     \internal
356
357     Returns \a obj if object \a obj inherits from this
358     meta-object; otherwise returns 0.
359 */
360 QObject *QMetaObject::cast(QObject *obj) const
361 {
362     if (obj) {
363         const QMetaObject *m = obj->metaObject();
364         do {
365             if (m == this)
366                 return obj;
367         } while ((m = m->d.superdata));
368     }
369     return 0;
370 }
371
372 /*!
373     \internal
374
375     Returns \a obj if object \a obj inherits from this
376     meta-object; otherwise returns 0.
377 */
378 const QObject *QMetaObject::cast(const QObject *obj) const
379 {
380     if (obj) {
381         const QMetaObject *m = obj->metaObject();
382         do {
383             if (m == this)
384                 return obj;
385         } while ((m = m->d.superdata));
386     }
387     return 0;
388 }
389
390 #ifndef QT_NO_TRANSLATION
391 /*!
392     \internal
393 */
394 QString QMetaObject::tr(const char *s, const char *c, int n) const
395 {
396     return QCoreApplication::translate(rawStringData(this, 0), s, c, QCoreApplication::CodecForTr, n);
397 }
398
399 /*!
400     \internal
401 */
402 QString QMetaObject::trUtf8(const char *s, const char *c, int n) const
403 {
404     return QCoreApplication::translate(rawStringData(this, 0), s, c, QCoreApplication::UnicodeUTF8, n);
405 }
406 #endif // QT_NO_TRANSLATION
407
408 /*!
409     Returns the method offset for this class; i.e. the index position
410     of this class's first member function.
411
412     The offset is the sum of all the methods in the class's
413     superclasses (which is always positive since QObject has the
414     deleteLater() slot and a destroyed() signal).
415
416     \sa method(), methodCount(), indexOfMethod()
417 */
418 int QMetaObject::methodOffset() const
419 {
420     int offset = 0;
421     const QMetaObject *m = d.superdata;
422     while (m) {
423         offset += priv(m->d.data)->methodCount;
424         m = m->d.superdata;
425     }
426     return offset;
427 }
428
429
430 /*!
431     Returns the enumerator offset for this class; i.e. the index
432     position of this class's first enumerator.
433
434     If the class has no superclasses with enumerators, the offset is
435     0; otherwise the offset is the sum of all the enumerators in the
436     class's superclasses.
437
438     \sa enumerator(), enumeratorCount(), indexOfEnumerator()
439 */
440 int QMetaObject::enumeratorOffset() const
441 {
442     int offset = 0;
443     const QMetaObject *m = d.superdata;
444     while (m) {
445         offset += priv(m->d.data)->enumeratorCount;
446         m = m->d.superdata;
447     }
448     return offset;
449 }
450
451 /*!
452     Returns the property offset for this class; i.e. the index
453     position of this class's first property.
454
455     The offset is the sum of all the properties in the class's
456     superclasses (which is always positive since QObject has the
457     name() property).
458
459     \sa property(), propertyCount(), indexOfProperty()
460 */
461 int QMetaObject::propertyOffset() const
462 {
463     int offset = 0;
464     const QMetaObject *m = d.superdata;
465     while (m) {
466         offset += priv(m->d.data)->propertyCount;
467         m = m->d.superdata;
468     }
469     return offset;
470 }
471
472 /*!
473     Returns the class information offset for this class; i.e. the
474     index position of this class's first class information item.
475
476     If the class has no superclasses with class information, the
477     offset is 0; otherwise the offset is the sum of all the class
478     information items in the class's superclasses.
479
480     \sa classInfo(), classInfoCount(), indexOfClassInfo()
481 */
482 int QMetaObject::classInfoOffset() const
483 {
484     int offset = 0;
485     const QMetaObject *m = d.superdata;
486     while (m) {
487         offset += priv(m->d.data)->classInfoCount;
488         m = m->d.superdata;
489     }
490     return offset;
491 }
492
493 /*!
494     \since 4.5
495
496     Returns the number of constructors in this class.
497
498     \sa constructor(), indexOfConstructor()
499 */
500 int QMetaObject::constructorCount() const
501 {
502     if (priv(d.data)->revision < 2)
503         return 0;
504     return priv(d.data)->constructorCount;
505 }
506
507 /*!
508     Returns the number of methods in this class, including the number of
509     properties provided by each base class. These include signals and slots
510     as well as normal member functions.
511
512     Use code like the following to obtain a QStringList containing the methods
513     specific to a given class:
514
515     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp methodCount
516
517     \sa method(), methodOffset(), indexOfMethod()
518 */
519 int QMetaObject::methodCount() const
520 {
521     int n = priv(d.data)->methodCount;
522     const QMetaObject *m = d.superdata;
523     while (m) {
524         n += priv(m->d.data)->methodCount;
525         m = m->d.superdata;
526     }
527     return n;
528 }
529
530 /*!
531     Returns the number of enumerators in this class.
532
533     \sa enumerator(), enumeratorOffset(), indexOfEnumerator()
534 */
535 int QMetaObject::enumeratorCount() const
536 {
537     int n = priv(d.data)->enumeratorCount;
538     const QMetaObject *m = d.superdata;
539     while (m) {
540         n += priv(m->d.data)->enumeratorCount;
541         m = m->d.superdata;
542     }
543     return n;
544 }
545
546 /*!
547     Returns the number of properties in this class, including the number of
548     properties provided by each base class.
549
550     Use code like the following to obtain a QStringList containing the properties
551     specific to a given class:
552
553     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp propertyCount
554
555     \sa property(), propertyOffset(), indexOfProperty()
556 */
557 int QMetaObject::propertyCount() const
558 {
559     int n = priv(d.data)->propertyCount;
560     const QMetaObject *m = d.superdata;
561     while (m) {
562         n += priv(m->d.data)->propertyCount;
563         m = m->d.superdata;
564     }
565     return n;
566 }
567
568 /*!
569     Returns the number of items of class information in this class.
570
571     \sa classInfo(), classInfoOffset(), indexOfClassInfo()
572 */
573 int QMetaObject::classInfoCount() const
574 {
575     int n = priv(d.data)->classInfoCount;
576     const QMetaObject *m = d.superdata;
577     while (m) {
578         n += priv(m->d.data)->classInfoCount;
579         m = m->d.superdata;
580     }
581     return n;
582 }
583
584 // Returns true if the method defined by the given meta-object&handle
585 // matches the given name, argument count and argument types, otherwise
586 // returns false.
587 static bool methodMatch(const QMetaObject *m, int handle,
588                         const QByteArray &name, int argc,
589                         const QArgumentType *types)
590 {
591     Q_ASSERT(priv(m->d.data)->revision >= 7);
592     if (int(m->d.data[handle + 1]) != argc)
593         return false;
594
595     if (toByteArray(stringData(m, m->d.data[handle])) != name)
596         return false;
597
598     int paramsIndex = m->d.data[handle + 2] + 1;
599     for (int i = 0; i < argc; ++i) {
600         uint typeInfo = m->d.data[paramsIndex + i];
601         if (types[i].type()) {
602             if (types[i].type() != typeFromTypeInfo(m, typeInfo))
603                 return false;
604         } else {
605             if (types[i].name() != typeNameFromTypeInfo(m, typeInfo))
606                 return false;
607         }
608     }
609
610     return true;
611 }
612
613 /** \internal
614 * \obsolete
615 * helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within
616 * the baseObject
617 * \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything.
618 * \a normalizeStringData set to true if we should do a second pass for old moc generated files normalizing all the symbols.
619 */
620 template<int MethodType>
621 static inline int indexOfMethodRelative(const QMetaObject **baseObject,
622                                         const char *method,
623                                         bool normalizeStringData)
624 {
625     QByteArray methodName;
626     QArgumentTypeArray methodArgumentTypes;
627     for (const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
628         int i = (MethodType == MethodSignal && priv(m->d.data)->revision >= 4)
629                 ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1);
630         const int end = (MethodType == MethodSlot && priv(m->d.data)->revision >= 4)
631                         ? (priv(m->d.data)->signalCount) : 0;
632         if (!normalizeStringData) {
633             for (; i >= end; --i) {
634                 if (priv(m->d.data)->revision >= 7) {
635                     if (methodName.isEmpty())
636                         methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodArgumentTypes);
637                     int handle = priv(m->d.data)->methodData + 5*i;
638                     if (methodMatch(m, handle, methodName, methodArgumentTypes.size(),
639                                     methodArgumentTypes.constData())) {
640                         *baseObject = m;
641                         return i;
642                     }
643                 } else {
644                     const char *stringdata = legacyString(m, m->d.data[priv(m->d.data)->methodData + 5*i]);
645                     if (method[0] == stringdata[0] && strcmp(method + 1, stringdata + 1) == 0) {
646                         *baseObject = m;
647                         return i;
648                     }
649                 }
650             }
651         } else if (priv(m->d.data)->revision < 5) {
652             for (; i >= end; --i) {
653                 const char *stringdata = legacyString(m, m->d.data[priv(m->d.data)->methodData + 5 * i]);
654                 const QByteArray normalizedSignature = QMetaObject::normalizedSignature(stringdata);
655                 if (normalizedSignature == method) {
656                     *baseObject = m;
657                     return i;
658                 }
659             }
660         }
661     }
662     return -1;
663 }
664
665 /** \internal
666 * helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within
667 * the baseObject
668 * \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything.
669 */
670 template<int MethodType>
671 static inline int indexOfMethodRelative(const QMetaObject **baseObject,
672                                         const QByteArray &name, int argc,
673                                         const QArgumentType *types)
674 {
675     for (const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
676         Q_ASSERT(priv(m->d.data)->revision >= 7);
677         int i = (MethodType == MethodSignal)
678                  ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1);
679         const int end = (MethodType == MethodSlot)
680                         ? (priv(m->d.data)->signalCount) : 0;
681
682         for (; i >= end; --i) {
683             int handle = priv(m->d.data)->methodData + 5*i;
684             if (methodMatch(m, handle, name, argc, types)) {
685                 *baseObject = m;
686                 return i;
687             }
688         }
689     }
690     return -1;
691 }
692
693
694 /*!
695     \since 4.5
696
697     Finds \a constructor and returns its index; otherwise returns -1.
698
699     Note that the \a constructor has to be in normalized form, as returned
700     by normalizedSignature().
701
702     \sa constructor(), constructorCount(), normalizedSignature()
703 */
704 int QMetaObject::indexOfConstructor(const char *constructor) const
705 {
706     if (priv(d.data)->revision < 2)
707         return -1;
708     else if (priv(d.data)->revision >= 7) {
709         QArgumentTypeArray types;
710         QByteArray name = QMetaObjectPrivate::decodeMethodSignature(constructor, types);
711         return QMetaObjectPrivate::indexOfConstructor(this, name, types.size(), types.constData());
712     } else {
713         for (int i = priv(d.data)->constructorCount-1; i >= 0; --i) {
714             const char *data = legacyString(this, d.data[priv(d.data)->constructorData + 5*i]);
715             if (data[0] == constructor[0] && strcmp(constructor + 1, data + 1) == 0) {
716                 return i;
717             }
718         }
719     }
720     return -1;
721 }
722
723 /*!
724     Finds \a method and returns its index; otherwise returns -1.
725
726     Note that the \a method has to be in normalized form, as returned
727     by normalizedSignature().
728
729     \sa method(), methodCount(), methodOffset(), normalizedSignature()
730 */
731 int QMetaObject::indexOfMethod(const char *method) const
732 {
733     const QMetaObject *m = this;
734     int i;
735     if (priv(m->d.data)->revision >= 7) {
736         QArgumentTypeArray types;
737         QByteArray name = QMetaObjectPrivate::decodeMethodSignature(method, types);
738         i = indexOfMethodRelative<0>(&m, name, types.size(), types.constData());
739     } else {
740         i = indexOfMethodRelative<0>(&m, method, false);
741         if (i < 0) {
742             m = this;
743             i = indexOfMethodRelative<0>(&m, method, true);
744         }
745     }
746     if (i >= 0)
747         i += m->methodOffset();
748     return i;
749 }
750
751 // Parses a string of comma-separated types into QArgumentTypes.
752 static void argumentTypesFromString(const char *str, const char *end,
753                                     QArgumentTypeArray &types)
754 {
755     Q_ASSERT(str <= end);
756     while (str != end) {
757         if (!types.isEmpty())
758             ++str; // Skip comma
759         const char *begin = str;
760         int level = 0;
761         while (str != end && (level > 0 || *str != ',')) {
762             if (*str == '<')
763                 ++level;
764             else if (*str == '>')
765                 --level;
766             ++str;
767         }
768         types += QArgumentType(QByteArray(begin, str - begin));
769     }
770 }
771
772 // Given a method \a signature (e.g. "foo(int,double)"), this function
773 // populates the argument \a types array and returns the method name.
774 QByteArray QMetaObjectPrivate::decodeMethodSignature(
775         const char *signature, QArgumentTypeArray &types)
776 {
777     const char *lparens = strchr(signature, '(');
778     if (!lparens)
779         return QByteArray();
780     const char *rparens = strchr(lparens + 1, ')');
781     if (!rparens || *(rparens+1))
782         return QByteArray();
783     int nameLength = lparens - signature;
784     argumentTypesFromString(lparens + 1, rparens, types);
785     return QByteArray::fromRawData(signature, nameLength);
786 }
787
788 /*!
789     Finds \a signal and returns its index; otherwise returns -1.
790
791     This is the same as indexOfMethod(), except that it will return
792     -1 if the method exists but isn't a signal.
793
794     Note that the \a signal has to be in normalized form, as returned
795     by normalizedSignature().
796
797     \sa indexOfMethod(), normalizedSignature(), method(), methodCount(), methodOffset()
798 */
799 int QMetaObject::indexOfSignal(const char *signal) const
800 {
801     const QMetaObject *m = this;
802     int i;
803     if (priv(m->d.data)->revision >= 7) {
804         QArgumentTypeArray types;
805         QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signal, types);
806         i = QMetaObjectPrivate::indexOfSignalRelative(&m, name, types.size(), types.constData());
807     } else {
808         i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, false);
809         if (i < 0) {
810             m = this;
811             i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, true);
812         }
813     }
814     if (i >= 0)
815         i += m->methodOffset();
816     return i;
817 }
818
819 /*! \internal
820     \obsolete
821     Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object.
822
823     \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
824 */
825 int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
826                                               const char *signal,
827                                               bool normalizeStringData)
828 {
829     int i = indexOfMethodRelative<MethodSignal>(baseObject, signal, normalizeStringData);
830 #ifndef QT_NO_DEBUG
831     const QMetaObject *m = *baseObject;
832     if (i >= 0 && m && m->d.superdata) {
833         int conflict = m->d.superdata->indexOfMethod(signal);
834         if (conflict >= 0)
835             qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
836                      signal, rawStringData(m->d.superdata, 0), rawStringData(m, 0));
837     }
838 #endif
839     return i;
840 }
841
842 /*! \internal
843     Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object.
844
845     \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
846 */
847 int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
848                                               const QByteArray &name, int argc,
849                                               const QArgumentType *types)
850 {
851     int i = indexOfMethodRelative<MethodSignal>(baseObject, name, argc, types);
852 #ifndef QT_NO_DEBUG
853     const QMetaObject *m = *baseObject;
854     if (i >= 0 && m && m->d.superdata) {
855         int conflict = indexOfMethod(m->d.superdata, name, argc, types);
856         if (conflict >= 0) {
857             QMetaMethod conflictMethod = m->d.superdata->method(conflict);
858             qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
859                      conflictMethod.methodSignature().constData(),
860                      rawStringData(m->d.superdata, 0), rawStringData(m, 0));
861         }
862      }
863  #endif
864      return i;
865 }
866
867 /*!
868     Finds \a slot and returns its index; otherwise returns -1.
869
870     This is the same as indexOfMethod(), except that it will return
871     -1 if the method exists but isn't a slot.
872
873     \sa indexOfMethod(), method(), methodCount(), methodOffset()
874 */
875 int QMetaObject::indexOfSlot(const char *slot) const
876 {
877     const QMetaObject *m = this;
878     int i;
879     if (priv(m->d.data)->revision >= 7) {
880         QArgumentTypeArray types;
881         QByteArray name = QMetaObjectPrivate::decodeMethodSignature(slot, types);
882         i = QMetaObjectPrivate::indexOfSlotRelative(&m, name, types.size(), types.constData());
883     } else {
884         i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, false);
885         if (i < 0)
886             i = QMetaObjectPrivate::indexOfSlotRelative(&m, slot, true);
887     }
888     if (i >= 0)
889         i += m->methodOffset();
890     return i;
891 }
892
893 // same as indexOfSignalRelative but for slots.
894 int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m,
895                                     const char *slot,
896                                     bool normalizeStringData)
897 {
898     return indexOfMethodRelative<MethodSlot>(m, slot, normalizeStringData);
899 }
900
901 // same as indexOfSignalRelative but for slots.
902 int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m,
903                                             const QByteArray &name, int argc,
904                                             const QArgumentType *types)
905 {
906     return indexOfMethodRelative<MethodSlot>(m, name, argc, types);
907 }
908
909 int QMetaObjectPrivate::indexOfSignal(const QMetaObject *m, const QByteArray &name,
910                                       int argc, const QArgumentType *types)
911 {
912     int i = indexOfSignalRelative(&m, name, argc, types);
913     if (i >= 0)
914         i += m->methodOffset();
915     return i;
916 }
917
918 int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m, const QByteArray &name,
919                                     int argc, const QArgumentType *types)
920 {
921     int i = indexOfSlotRelative(&m, name, argc, types);
922     if (i >= 0)
923         i += m->methodOffset();
924     return i;
925 }
926
927 int QMetaObjectPrivate::indexOfMethod(const QMetaObject *m, const QByteArray &name,
928                                       int argc, const QArgumentType *types)
929 {
930     int i = indexOfMethodRelative<0>(&m, name, argc, types);
931     if (i >= 0)
932         i += m->methodOffset();
933     return i;
934 }
935
936 int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArray &name,
937                                            int argc, const QArgumentType *types)
938 {
939     for (int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) {
940         int handle = priv(m->d.data)->constructorData + 5*i;
941         if (methodMatch(m, handle, name, argc, types))
942             return i;
943     }
944     return -1;
945 }
946
947 /*!
948     \internal
949
950     Returns true if the \a signalTypes and \a methodTypes are
951     compatible; otherwise returns false.
952 */
953 bool QMetaObjectPrivate::checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
954                                           int methodArgc, const QArgumentType *methodTypes)
955 {
956     if (signalArgc < methodArgc)
957         return false;
958     for (int i = 0; i < methodArgc; ++i) {
959         if (signalTypes[i] != methodTypes[i])
960             return false;
961     }
962     return true;
963 }
964
965 /*!
966     \internal
967
968     Returns true if the \a signal and \a method arguments are
969     compatible; otherwise returns false.
970 */
971 bool QMetaObjectPrivate::checkConnectArgs(const QMetaMethodPrivate *signal,
972                                           const QMetaMethodPrivate *method)
973 {
974     if (signal->methodType() != QMetaMethod::Signal)
975         return false;
976     if (signal->parameterCount() < method->parameterCount())
977         return false;
978     const QMetaObject *smeta = signal->enclosingMetaObject();
979     const QMetaObject *rmeta = method->enclosingMetaObject();
980     for (int i = 0; i < method->parameterCount(); ++i) {
981         uint sourceTypeInfo = signal->parameterTypeInfo(i);
982         uint targetTypeInfo = method->parameterTypeInfo(i);
983         if ((sourceTypeInfo & IsUnresolvedType)
984             || (targetTypeInfo & IsUnresolvedType)) {
985             QByteArray sourceName = typeNameFromTypeInfo(smeta, sourceTypeInfo);
986             QByteArray targetName = typeNameFromTypeInfo(rmeta, targetTypeInfo);
987             if (sourceName != targetName)
988                 return false;
989         } else {
990             int sourceType = typeFromTypeInfo(smeta, sourceTypeInfo);
991             int targetType = typeFromTypeInfo(rmeta, targetTypeInfo);
992             if (sourceType != targetType)
993                 return false;
994         }
995     }
996     return true;
997 }
998
999 static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name)
1000 {
1001     while (self) {
1002         if (strcmp(rawStringData(self, 0), name) == 0)
1003             return self;
1004         if (self->d.extradata) {
1005             const QMetaObject **e;
1006             if (priv(self->d.data)->revision < 2) {
1007                 e = (const QMetaObject**)(self->d.extradata);
1008             } else
1009             {
1010                 const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(self->d.extradata);
1011                 e = extra->objects;
1012             }
1013             if (e) {
1014                 while (*e) {
1015                     if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
1016                         return m;
1017                     ++e;
1018                 }
1019             }
1020         }
1021         self = self->d.superdata;
1022     }
1023     return self;
1024 }
1025
1026 /*!
1027     Finds enumerator \a name and returns its index; otherwise returns
1028     -1.
1029
1030     \sa enumerator(), enumeratorCount(), enumeratorOffset()
1031 */
1032 int QMetaObject::indexOfEnumerator(const char *name) const
1033 {
1034     const QMetaObject *m = this;
1035     while (m) {
1036         const QMetaObjectPrivate *d = priv(m->d.data);
1037         for (int i = d->enumeratorCount - 1; i >= 0; --i) {
1038             const char *prop = rawStringData(m, m->d.data[d->enumeratorData + 4*i]);
1039             if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
1040                 i += m->enumeratorOffset();
1041                 return i;
1042             }
1043         }
1044         m = m->d.superdata;
1045     }
1046     return -1;
1047 }
1048
1049 /*!
1050     Finds property \a name and returns its index; otherwise returns
1051     -1.
1052
1053     \sa property(), propertyCount(), propertyOffset()
1054 */
1055 int QMetaObject::indexOfProperty(const char *name) const
1056 {
1057     const QMetaObject *m = this;
1058     while (m) {
1059         const QMetaObjectPrivate *d = priv(m->d.data);
1060         for (int i = d->propertyCount-1; i >= 0; --i) {
1061             const char *prop = rawStringData(m, m->d.data[d->propertyData + 3*i]);
1062             if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
1063                 i += m->propertyOffset();
1064                 return i;
1065             }
1066         }
1067         m = m->d.superdata;
1068     }
1069
1070     if (priv(this->d.data)->revision >= 3 && (priv(this->d.data)->flags & DynamicMetaObject)) {
1071         QAbstractDynamicMetaObject *me = 
1072             const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this));
1073
1074         return me->createProperty(name, 0);
1075     }
1076
1077     return -1;
1078 }
1079
1080 /*!
1081     Finds class information item \a name and returns its index;
1082     otherwise returns -1.
1083
1084     \sa classInfo(), classInfoCount(), classInfoOffset()
1085 */
1086 int QMetaObject::indexOfClassInfo(const char *name) const
1087 {
1088     int i = -1;
1089     const QMetaObject *m = this;
1090     while (m && i < 0) {
1091         for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i)
1092             if (strcmp(name, rawStringData(m, m->d.data[priv(m->d.data)->classInfoData + 2*i])) == 0) {
1093                 i += m->classInfoOffset();
1094                 break;
1095             }
1096         m = m->d.superdata;
1097     }
1098     return i;
1099 }
1100
1101 /*!
1102     \since 4.5
1103
1104     Returns the meta-data for the constructor with the given \a index.
1105
1106     \sa constructorCount(), newInstance()
1107 */
1108 QMetaMethod QMetaObject::constructor(int index) const
1109 {
1110     int i = index;
1111     QMetaMethod result;
1112     if (priv(d.data)->revision >= 2 && i >= 0 && i < priv(d.data)->constructorCount) {
1113         result.mobj = this;
1114         result.handle = priv(d.data)->constructorData + 5*i;
1115     }
1116     return result;
1117 }
1118
1119 /*!
1120     Returns the meta-data for the method with the given \a index.
1121
1122     \sa methodCount(), methodOffset(), indexOfMethod()
1123 */
1124 QMetaMethod QMetaObject::method(int index) const
1125 {
1126     int i = index;
1127     i -= methodOffset();
1128     if (i < 0 && d.superdata)
1129         return d.superdata->method(index);
1130
1131     QMetaMethod result;
1132     if (i >= 0 && i < priv(d.data)->methodCount) {
1133         result.mobj = this;
1134         result.handle = priv(d.data)->methodData + 5*i;
1135     }
1136     return result;
1137 }
1138
1139 /*!
1140     Returns the meta-data for the enumerator with the given \a index.
1141
1142     \sa enumeratorCount(), enumeratorOffset(), indexOfEnumerator()
1143 */
1144 QMetaEnum QMetaObject::enumerator(int index) const
1145 {
1146     int i = index;
1147     i -= enumeratorOffset();
1148     if (i < 0 && d.superdata)
1149         return d.superdata->enumerator(index);
1150
1151     QMetaEnum result;
1152     if (i >= 0 && i < priv(d.data)->enumeratorCount) {
1153         result.mobj = this;
1154         result.handle = priv(d.data)->enumeratorData + 4*i;
1155     }
1156     return result;
1157 }
1158
1159 /*!
1160     Returns the meta-data for the property with the given \a index.
1161     If no such property exists, a null QMetaProperty is returned.
1162
1163     \sa propertyCount(), propertyOffset(), indexOfProperty()
1164 */
1165 QMetaProperty QMetaObject::property(int index) const
1166 {
1167     int i = index;
1168     i -= propertyOffset();
1169     if (i < 0 && d.superdata)
1170         return d.superdata->property(index);
1171
1172     QMetaProperty result;
1173     if (i >= 0 && i < priv(d.data)->propertyCount) {
1174         int handle = priv(d.data)->propertyData + 3*i;
1175         int flags = d.data[handle + 2];
1176         result.mobj = this;
1177         result.handle = handle;
1178         result.idx = i;
1179
1180         if (flags & EnumOrFlag) {
1181             const char *type;
1182             if (priv(d.data)->revision >= 7)
1183                 type = rawTypeNameFromTypeInfo(this, d.data[handle + 1]);
1184             else
1185                 type = legacyString(this, d.data[handle + 1]);
1186             result.menum = enumerator(indexOfEnumerator(type));
1187             if (!result.menum.isValid()) {
1188                 const char *enum_name = type;
1189                 const char *scope_name = rawStringData(this, 0);
1190                 char *scope_buffer = 0;
1191
1192                 const char *colon = strrchr(enum_name, ':');
1193                 // ':' will always appear in pairs
1194                 Q_ASSERT(colon <= enum_name || *(colon-1) == ':');
1195                 if (colon > enum_name) {
1196                     int len = colon-enum_name-1;
1197                     scope_buffer = (char *)malloc(len+1);
1198                     qMemCopy(scope_buffer, enum_name, len);
1199                     scope_buffer[len] = '\0';
1200                     scope_name = scope_buffer;
1201                     enum_name = colon+1;
1202                 }
1203
1204                 const QMetaObject *scope = 0;
1205                 if (qstrcmp(scope_name, "Qt") == 0)
1206                     scope = &QObject::staticQtMetaObject;
1207                 else
1208                     scope = QMetaObject_findMetaObject(this, scope_name);
1209                 if (scope)
1210                     result.menum = scope->enumerator(scope->indexOfEnumerator(enum_name));
1211                 if (scope_buffer)
1212                     free(scope_buffer);
1213             }
1214         }
1215     }
1216     return result;
1217 }
1218
1219 /*!
1220     \since 4.2
1221
1222     Returns the property that has the \c USER flag set to true.
1223
1224     \sa QMetaProperty::isUser()
1225 */
1226 QMetaProperty QMetaObject::userProperty() const
1227 {
1228     const int propCount = propertyCount();
1229     for (int i = propCount - 1; i >= 0; --i) {
1230         const QMetaProperty prop = property(i);
1231         if (prop.isUser())
1232             return prop;
1233     }
1234     return QMetaProperty();
1235 }
1236
1237 /*!
1238     Returns the meta-data for the item of class information with the
1239     given \a index.
1240
1241     Example:
1242
1243     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 0
1244
1245     \sa classInfoCount(), classInfoOffset(), indexOfClassInfo()
1246  */
1247 QMetaClassInfo QMetaObject::classInfo(int index) const
1248 {
1249     int i = index;
1250     i -= classInfoOffset();
1251     if (i < 0 && d.superdata)
1252         return d.superdata->classInfo(index);
1253
1254     QMetaClassInfo result;
1255     if (i >= 0 && i < priv(d.data)->classInfoCount) {
1256         result.mobj = this;
1257         result.handle = priv(d.data)->classInfoData + 2*i;
1258     }
1259     return result;
1260 }
1261
1262 /*!
1263     Returns true if the \a signal and \a method arguments are
1264     compatible; otherwise returns false.
1265
1266     Both \a signal and \a method are expected to be normalized.
1267
1268     \sa normalizedSignature()
1269 */
1270 bool QMetaObject::checkConnectArgs(const char *signal, const char *method)
1271 {
1272     const char *s1 = signal;
1273     const char *s2 = method;
1274     while (*s1++ != '(') { }                        // scan to first '('
1275     while (*s2++ != '(') { }
1276     if (*s2 == ')' || qstrcmp(s1,s2) == 0)        // method has no args or
1277         return true;                                //   exact match
1278     int s1len = qstrlen(s1);
1279     int s2len = qstrlen(s2);
1280     if (s2len < s1len && strncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',')
1281         return true;                                // method has less args
1282     return false;
1283 }
1284
1285 /*!
1286     \since 5.0
1287     \overload
1288
1289     Returns true if the \a signal and \a method arguments are
1290     compatible; otherwise returns false.
1291 */
1292 bool QMetaObject::checkConnectArgs(const QMetaMethod &signal,
1293                                    const QMetaMethod &method)
1294 {
1295     return QMetaObjectPrivate::checkConnectArgs(
1296             QMetaMethodPrivate::get(&signal),
1297             QMetaMethodPrivate::get(&method));
1298 }
1299
1300 static void qRemoveWhitespace(const char *s, char *d)
1301 {
1302     char last = 0;
1303     while (*s && is_space(*s))
1304         s++;
1305     while (*s) {
1306         while (*s && !is_space(*s))
1307             last = *d++ = *s++;
1308         while (*s && is_space(*s))
1309             s++;
1310         if (*s && ((is_ident_char(*s) && is_ident_char(last))
1311                    || ((*s == ':') && (last == '<')))) {
1312             last = *d++ = ' ';
1313         }
1314     }
1315     *d = '\0';
1316 }
1317
1318 static char *qNormalizeType(char *d, int &templdepth, QByteArray &result)
1319 {
1320     const char *t = d;
1321     while (*d && (templdepth
1322                    || (*d != ',' && *d != ')'))) {
1323         if (*d == '<')
1324             ++templdepth;
1325         if (*d == '>')
1326             --templdepth;
1327         ++d;
1328     }
1329     if (strncmp("void", t, d - t) != 0)
1330         result += normalizeTypeInternal(t, d);
1331
1332     return d;
1333 }
1334
1335
1336 /*!
1337     \since 4.2
1338
1339     Normalizes a \a type.
1340
1341     See QMetaObject::normalizedSignature() for a description on how
1342     Qt normalizes.
1343
1344     Example:
1345
1346     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 1
1347
1348     \sa normalizedSignature()
1349  */
1350 QByteArray QMetaObject::normalizedType(const char *type)
1351 {
1352     QByteArray result;
1353
1354     if (!type || !*type)
1355         return result;
1356
1357     QVarLengthArray<char> stackbuf(qstrlen(type) + 1);
1358     qRemoveWhitespace(type, stackbuf.data());
1359     int templdepth = 0;
1360     qNormalizeType(stackbuf.data(), templdepth, result);
1361
1362     return result;
1363 }
1364
1365 /*!
1366     Normalizes the signature of the given \a method.
1367
1368     Qt uses normalized signatures to decide whether two given signals
1369     and slots are compatible. Normalization reduces whitespace to a
1370     minimum, moves 'const' to the front where appropriate, removes
1371     'const' from value types and replaces const references with
1372     values.
1373
1374     \sa checkConnectArgs(), normalizedType()
1375  */
1376 QByteArray QMetaObject::normalizedSignature(const char *method)
1377 {
1378     QByteArray result;
1379     if (!method || !*method)
1380         return result;
1381     int len = int(strlen(method));
1382     QVarLengthArray<char> stackbuf(len + 1);
1383     char *d = stackbuf.data();
1384     qRemoveWhitespace(method, d);
1385
1386     result.reserve(len);
1387
1388     int argdepth = 0;
1389     int templdepth = 0;
1390     while (*d) {
1391         if (argdepth == 1) {
1392             d = qNormalizeType(d, templdepth, result);
1393             if (!*d) //most likely an invalid signature.
1394                 break;
1395         }
1396         if (*d == '(')
1397             ++argdepth;
1398         if (*d == ')')
1399             --argdepth;
1400         result += *d++;
1401     }
1402
1403     return result;
1404 }
1405
1406 enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
1407
1408 /*!
1409     Invokes the \a member (a signal or a slot name) on the object \a
1410     obj. Returns true if the member could be invoked. Returns false
1411     if there is no such member or the parameters did not match.
1412
1413     The invocation can be either synchronous or asynchronous,
1414     depending on \a type:
1415
1416     \list
1417     \o If \a type is Qt::DirectConnection, the member will be invoked immediately.
1418
1419     \o If \a type is Qt::QueuedConnection,
1420        a QEvent will be sent and the member is invoked as soon as the application
1421        enters the main event loop.
1422
1423     \o If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
1424        the same way as for Qt::QueuedConnection, except that the current thread
1425        will block until the event is delivered. Using this connection type to
1426        communicate between objects in the same thread will lead to deadlocks.
1427
1428     \o If \a type is Qt::AutoConnection, the member is invoked
1429        synchronously if \a obj lives in the same thread as the
1430        caller; otherwise it will invoke the member asynchronously.
1431     \endlist
1432
1433     The return value of the \a member function call is placed in \a
1434     ret. If the invocation is asynchronous, the return value cannot
1435     be evaluated. You can pass up to ten arguments (\a val0, \a val1,
1436     \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, \a val8,
1437     and \a val9) to the \a member function.
1438
1439     QGenericArgument and QGenericReturnArgument are internal
1440     helper classes. Because signals and slots can be dynamically
1441     invoked, you must enclose the arguments using the Q_ARG() and
1442     Q_RETURN_ARG() macros. Q_ARG() takes a type name and a
1443     const reference of that type; Q_RETURN_ARG() takes a type name
1444     and a non-const reference.
1445
1446     You only need to pass the name of the signal or slot to this function,
1447     not the entire signature. For example, to asynchronously invoke
1448     the \l{QPushButton::animateClick()}{animateClick()} slot on a
1449     QPushButton, use the following code:
1450
1451     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 2
1452
1453     With asynchronous method invocations, the parameters must be of
1454     types that are known to Qt's meta-object system, because Qt needs
1455     to copy the arguments to store them in an event behind the
1456     scenes. If you try to use a queued connection and get the error
1457     message
1458
1459     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 3
1460
1461     call qRegisterMetaType() to register the data type before you
1462     call invokeMethod().
1463
1464     To synchronously invoke the \c compute(QString, int, double) slot on
1465     some arbitrary object \c obj retrieve its return value:
1466
1467     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 4
1468
1469     If the "compute" slot does not take exactly one QString, one int
1470     and one double in the specified order, the call will fail.
1471
1472     \sa Q_ARG(), Q_RETURN_ARG(), qRegisterMetaType(), QMetaMethod::invoke()
1473 */
1474 bool QMetaObject::invokeMethod(QObject *obj,
1475                                const char *member,
1476                                Qt::ConnectionType type,
1477                                QGenericReturnArgument ret,
1478                                QGenericArgument val0,
1479                                QGenericArgument val1,
1480                                QGenericArgument val2,
1481                                QGenericArgument val3,
1482                                QGenericArgument val4,
1483                                QGenericArgument val5,
1484                                QGenericArgument val6,
1485                                QGenericArgument val7,
1486                                QGenericArgument val8,
1487                                QGenericArgument val9)
1488 {
1489     if (!obj)
1490         return false;
1491
1492     QVarLengthArray<char, 512> sig;
1493     int len = qstrlen(member);
1494     if (len <= 0)
1495         return false;
1496     sig.append(member, len);
1497     sig.append('(');
1498
1499     const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(),
1500                                val4.name(), val5.name(), val6.name(), val7.name(), val8.name(),
1501                                val9.name()};
1502
1503     int paramCount;
1504     for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
1505         len = qstrlen(typeNames[paramCount]);
1506         if (len <= 0)
1507             break;
1508         sig.append(typeNames[paramCount], len);
1509         sig.append(',');
1510     }
1511     if (paramCount == 1)
1512         sig.append(')'); // no parameters
1513     else
1514         sig[sig.size() - 1] = ')';
1515     sig.append('\0');
1516
1517     const QMetaObject *meta = obj->metaObject();
1518     int idx = meta->indexOfMethod(sig.constData());
1519     if (idx < 0) {
1520         QByteArray norm = QMetaObject::normalizedSignature(sig.constData());
1521         idx = meta->indexOfMethod(norm.constData());
1522     }
1523
1524     if (idx < 0 || idx >= meta->methodCount()) {
1525         qWarning("QMetaObject::invokeMethod: No such method %s::%s",
1526                  meta->className(), sig.constData());
1527         return false;
1528     }
1529     QMetaMethod method = meta->method(idx);
1530     return method.invoke(obj, type, ret,
1531                          val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
1532 }
1533
1534 /*! \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member,
1535                                        QGenericReturnArgument ret,
1536                                        QGenericArgument val0 = QGenericArgument(0),
1537                                        QGenericArgument val1 = QGenericArgument(),
1538                                        QGenericArgument val2 = QGenericArgument(),
1539                                        QGenericArgument val3 = QGenericArgument(),
1540                                        QGenericArgument val4 = QGenericArgument(),
1541                                        QGenericArgument val5 = QGenericArgument(),
1542                                        QGenericArgument val6 = QGenericArgument(),
1543                                        QGenericArgument val7 = QGenericArgument(),
1544                                        QGenericArgument val8 = QGenericArgument(),
1545                                        QGenericArgument val9 = QGenericArgument());
1546     \overload invokeMethod()
1547
1548     This overload always invokes the member using the connection type Qt::AutoConnection.
1549 */
1550
1551 /*! \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member,
1552                              Qt::ConnectionType type,
1553                              QGenericArgument val0 = QGenericArgument(0),
1554                              QGenericArgument val1 = QGenericArgument(),
1555                              QGenericArgument val2 = QGenericArgument(),
1556                              QGenericArgument val3 = QGenericArgument(),
1557                              QGenericArgument val4 = QGenericArgument(),
1558                              QGenericArgument val5 = QGenericArgument(),
1559                              QGenericArgument val6 = QGenericArgument(),
1560                              QGenericArgument val7 = QGenericArgument(),
1561                              QGenericArgument val8 = QGenericArgument(),
1562                              QGenericArgument val9 = QGenericArgument())
1563
1564     \overload invokeMethod()
1565
1566     This overload can be used if the return value of the member is of no interest.
1567 */
1568
1569 /*!
1570     \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member,
1571                              QGenericArgument val0 = QGenericArgument(0),
1572                              QGenericArgument val1 = QGenericArgument(),
1573                              QGenericArgument val2 = QGenericArgument(),
1574                              QGenericArgument val3 = QGenericArgument(),
1575                              QGenericArgument val4 = QGenericArgument(),
1576                              QGenericArgument val5 = QGenericArgument(),
1577                              QGenericArgument val6 = QGenericArgument(),
1578                              QGenericArgument val7 = QGenericArgument(),
1579                              QGenericArgument val8 = QGenericArgument(),
1580                              QGenericArgument val9 = QGenericArgument())
1581
1582     \overload invokeMethod()
1583
1584     This overload invokes the member using the connection type Qt::AutoConnection and
1585     ignores return values.
1586 */
1587
1588 /*!
1589     \class QMetaMethod
1590
1591     \brief The QMetaMethod class provides meta-data about a member
1592     function.
1593
1594     \ingroup objectmodel
1595
1596     A QMetaMethod has a methodType(), a methodSignature(), a list of
1597     parameterTypes() and parameterNames(), a return typeName(), a
1598     tag(), and an access() specifier. You can use invoke() to invoke
1599     the method on an arbitrary QObject.
1600
1601     \sa QMetaObject, QMetaEnum, QMetaProperty, {Qt's Property System}
1602 */
1603
1604 /*!
1605     \enum QMetaMethod::Attributes
1606
1607     \internal
1608
1609     \value Compatibility
1610     \value Cloned
1611     \value Scriptable
1612 */
1613
1614 /*!
1615     \fn bool QMetaMethod::isValid() const
1616     \since 5.0
1617
1618     Returns true if this method is valid (can be introspected and
1619     invoked), otherwise returns false.
1620 */
1621
1622 /*!
1623     \fn const QMetaObject *QMetaMethod::enclosingMetaObject() const
1624     \internal
1625 */
1626
1627 /*!
1628     \enum QMetaMethod::MethodType
1629
1630     \value Method  The function is a plain member function.
1631     \value Signal  The function is a signal.
1632     \value Slot    The function is a slot.
1633     \value Constructor The function is a constructor.
1634 */
1635
1636 /*!
1637     \fn QMetaMethod::QMetaMethod()
1638     \internal
1639 */
1640
1641 QByteArray QMetaMethodPrivate::signature() const
1642 {
1643     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1644     QByteArray result;
1645     result.reserve(256);
1646     result += name();
1647     result += '(';
1648     QList<QByteArray> argTypes = parameterTypes();
1649     for (int i = 0; i < argTypes.size(); ++i) {
1650         if (i)
1651             result += ',';
1652         result += argTypes.at(i);
1653     }
1654     result += ')';
1655     return result;
1656 }
1657
1658 QByteArray QMetaMethodPrivate::name() const
1659 {
1660     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1661     return toByteArray(stringData(mobj, mobj->d.data[handle]));
1662 }
1663
1664 int QMetaMethodPrivate::typesDataIndex() const
1665 {
1666     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1667     return mobj->d.data[handle + 2];
1668 }
1669
1670 const char *QMetaMethodPrivate::rawReturnTypeName() const
1671 {
1672     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1673     uint typeInfo = mobj->d.data[typesDataIndex()];
1674     if (typeInfo & IsUnresolvedType)
1675         return rawStringData(mobj, typeInfo & TypeNameIndexMask);
1676     else {
1677         if (typeInfo == QMetaType::Void) {
1678             // QMetaMethod::typeName() is documented to return an empty string
1679             // if the return type is void, but QMetaType::typeName() returns
1680             // "void".
1681             return "";
1682         }
1683         return QMetaType::typeName(typeInfo);
1684     }
1685 }
1686
1687 int QMetaMethodPrivate::returnType() const
1688 {
1689     return parameterType(-1);
1690 }
1691
1692 int QMetaMethodPrivate::parameterCount() const
1693 {
1694     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1695     return mobj->d.data[handle + 1];
1696 }
1697
1698 int QMetaMethodPrivate::parametersDataIndex() const
1699 {
1700     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1701     return typesDataIndex() + 1;
1702 }
1703
1704 uint QMetaMethodPrivate::parameterTypeInfo(int index) const
1705 {
1706     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1707     return mobj->d.data[parametersDataIndex() + index];
1708 }
1709
1710 int QMetaMethodPrivate::parameterType(int index) const
1711 {
1712     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1713     return typeFromTypeInfo(mobj, parameterTypeInfo(index));
1714 }
1715
1716 void QMetaMethodPrivate::getParameterTypes(int *types) const
1717 {
1718     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1719     int dataIndex = parametersDataIndex();
1720     int argc = parameterCount();
1721     for (int i = 0; i < argc; ++i) {
1722         int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
1723         *(types++) = id;
1724     }
1725 }
1726
1727 QList<QByteArray> QMetaMethodPrivate::parameterTypes() const
1728 {
1729     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1730     QList<QByteArray> list;
1731     int argc = parameterCount();
1732     int paramsIndex = parametersDataIndex();
1733     for (int i = 0; i < argc; ++i)
1734         list += typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
1735     return list;
1736 }
1737
1738 QList<QByteArray> QMetaMethodPrivate::parameterNames() const
1739 {
1740     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1741     QList<QByteArray> list;
1742     int argc = parameterCount();
1743     int namesIndex = parametersDataIndex() + argc;
1744     for (int i = 0; i < argc; ++i)
1745         list += toByteArray(stringData(mobj, mobj->d.data[namesIndex + i]));
1746     return list;
1747 }
1748
1749 QByteArray QMetaMethodPrivate::tag() const
1750 {
1751     Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1752     return toByteArray(stringData(mobj, mobj->d.data[handle + 3]));
1753 }
1754
1755 /*!
1756     \since 5.0
1757
1758     Returns the signature of this method (e.g.,
1759     \c{setValue(double)}).
1760
1761     \sa parameterTypes(), parameterNames()
1762 */
1763 QByteArray QMetaMethod::methodSignature() const
1764 {
1765     if (!mobj)
1766         return QByteArray();
1767     if (priv(mobj->d.data)->revision >= 7) {
1768         return QMetaMethodPrivate::get(this)->signature();
1769     } else {
1770         const char *sig = rawStringData(mobj, mobj->d.data[handle]);
1771         return QByteArray::fromRawData(sig, qstrlen(sig));
1772     }
1773 }
1774
1775 /*!
1776     \since 5.0
1777
1778     Returns the name of this method.
1779
1780     \sa methodSignature(), parameterCount()
1781 */
1782 QByteArray QMetaMethod::name() const
1783 {
1784     if (!mobj)
1785         return QByteArray();
1786     return QMetaMethodPrivate::get(this)->name();
1787 }
1788
1789 /*!
1790     \since 5.0
1791
1792     Returns the return type of this method.
1793
1794     The return value is one of the types that are registered
1795     with QMetaType, or 0 if the type is not registered.
1796
1797     \sa parameterType(), QMetaType, typeName()
1798 */
1799 int QMetaMethod::returnType() const
1800  {
1801      if (!mobj)
1802          return 0;
1803     return QMetaMethodPrivate::get(this)->returnType();
1804 }
1805
1806 /*!
1807     \since 5.0
1808
1809     Returns the number of parameters of this method.
1810
1811     \sa parameterType(), parameterNames()
1812 */
1813 int QMetaMethod::parameterCount() const
1814 {
1815     if (!mobj)
1816         return 0;
1817     return QMetaMethodPrivate::get(this)->parameterCount();
1818 }
1819
1820 /*!
1821     \since 5.0
1822
1823     Returns the type of the parameter at the given \a index.
1824
1825     The return value is one of the types that are registered
1826     with QMetaType, or 0 if the type is not registered.
1827
1828     \sa parameterCount(), returnType(), QMetaType
1829 */
1830 int QMetaMethod::parameterType(int index) const
1831 {
1832     if (!mobj || index < 0)
1833         return 0;
1834     if (index >= QMetaMethodPrivate::get(this)->parameterCount())
1835         return 0;
1836     return QMetaMethodPrivate::get(this)->parameterType(index);
1837 }
1838
1839 /*!
1840     \since 5.0
1841     \internal
1842
1843     Gets the parameter \a types of this method. The storage
1844     for \a types must be able to hold parameterCount() items.
1845
1846     \sa parameterCount(), returnType(), parameterType()
1847 */
1848 void QMetaMethod::getParameterTypes(int *types) const
1849 {
1850     if (!mobj)
1851         return;
1852     QMetaMethodPrivate::get(this)->getParameterTypes(types);
1853 }
1854
1855 /*!
1856     Returns a list of parameter types.
1857
1858     \sa parameterNames(), methodSignature()
1859 */
1860 QList<QByteArray> QMetaMethod::parameterTypes() const
1861 {
1862     if (!mobj)
1863         return QList<QByteArray>();
1864     if (priv(mobj->d.data)->revision >= 7) {
1865         return QMetaMethodPrivate::get(this)->parameterTypes();
1866     } else {
1867         return QMetaObjectPrivate::parameterTypeNamesFromSignature(
1868                     legacyString(mobj, mobj->d.data[handle]));
1869     }
1870 }
1871
1872 /*!
1873     Returns a list of parameter names.
1874
1875     \sa parameterTypes(), methodSignature()
1876 */
1877 QList<QByteArray> QMetaMethod::parameterNames() const
1878 {
1879     QList<QByteArray> list;
1880     if (!mobj)
1881         return list;
1882     if (priv(mobj->d.data)->revision >= 7) {
1883         return QMetaMethodPrivate::get(this)->parameterNames();
1884     } else {
1885         const char *names =  rawStringData(mobj, mobj->d.data[handle + 1]);
1886         if (*names == 0) {
1887             // do we have one or zero arguments?
1888             const char *signature = rawStringData(mobj, mobj->d.data[handle]);
1889             while (*signature && *signature != '(')
1890                 ++signature;
1891             if (*++signature != ')')
1892                 list += QByteArray();
1893         } else {
1894             --names;
1895             do {
1896                 const char *begin = ++names;
1897                 while (*names && *names != ',')
1898                     ++names;
1899                 list += QByteArray(begin, names - begin);
1900             } while (*names);
1901         }
1902         return list;
1903     }
1904 }
1905
1906
1907 /*!
1908     Returns the return type name of this method, or an empty string if the
1909     return type is \e void.
1910 */
1911 const char *QMetaMethod::typeName() const
1912 {
1913     if (!mobj)
1914         return 0;
1915     if (priv(mobj->d.data)->revision >= 7)
1916         return QMetaMethodPrivate::get(this)->rawReturnTypeName();
1917     else
1918         return legacyString(mobj, mobj->d.data[handle + 2]);
1919 }
1920
1921 /*!
1922     Returns the tag associated with this method.
1923
1924     Tags are special macros recognized by \c moc that make it
1925     possible to add extra information about a method.
1926
1927     Tag information can be added in the following
1928     way in the function declaration:
1929
1930     \code
1931         #define THISISTESTTAG // tag text
1932         ...
1933         private slots:
1934             THISISTESTTAG void testFunc();
1935     \endcode
1936
1937     and the information can be accessed by using:
1938
1939     \code
1940         MainWindow win;
1941         win.show();
1942
1943         int functionIndex = win.metaObject()->indexOfSlot("testFunc()");
1944         QMetaMethod mm = metaObject()->method(functionIndex);
1945         qDebug() << mm.tag(); // prints THISISTESTTAG
1946     \endcode
1947
1948     For the moment,
1949     \c moc doesn't support any special tags.
1950 */
1951 const char *QMetaMethod::tag() const
1952 {
1953     if (!mobj)
1954         return 0;
1955     if (priv(mobj->d.data)->revision >= 7)
1956         return QMetaMethodPrivate::get(this)->tag().constData();
1957     else
1958         return legacyString(mobj, mobj->d.data[handle + 3]);
1959 }
1960
1961
1962 /*! \internal */
1963 int QMetaMethod::attributes() const
1964 {
1965     if (!mobj)
1966         return false;
1967     return ((mobj->d.data[handle + 4])>>4);
1968 }
1969
1970 /*!
1971   \since 4.6
1972
1973   Returns this method's index.
1974 */
1975 int QMetaMethod::methodIndex() const
1976 {
1977     if (!mobj)
1978         return -1;
1979     return ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
1980 }
1981
1982 /*!
1983     \internal
1984
1985     Returns the method revision if one was
1986     specified by Q_REVISION, otherwise returns 0.
1987  */
1988 int QMetaMethod::revision() const
1989 {
1990     if (!mobj)
1991         return 0;
1992     if ((QMetaMethod::Access)(mobj->d.data[handle + 4] & MethodRevisioned)) {
1993         int offset = priv(mobj->d.data)->methodData
1994                      + priv(mobj->d.data)->methodCount * 5
1995                      + (handle - priv(mobj->d.data)->methodData) / 5;
1996         return mobj->d.data[offset];
1997     }
1998     return 0;
1999 }
2000
2001 /*!
2002     Returns the access specification of this method (private,
2003     protected, or public).
2004
2005     Signals are always protected, meaning that you can only emit them
2006     from the class or from a subclass.
2007
2008     \sa methodType()
2009 */
2010 QMetaMethod::Access QMetaMethod::access() const
2011 {
2012     if (!mobj)
2013         return Private;
2014     return (QMetaMethod::Access)(mobj->d.data[handle + 4] & AccessMask);
2015 }
2016
2017 /*!
2018     Returns the type of this method (signal, slot, or method).
2019
2020     \sa access()
2021 */
2022 QMetaMethod::MethodType QMetaMethod::methodType() const
2023 {
2024     if (!mobj)
2025         return QMetaMethod::Method;
2026     return (QMetaMethod::MethodType)((mobj->d.data[handle + 4] & MethodTypeMask)>>2);
2027 }
2028
2029 /*!
2030     Invokes this method on the object \a object. Returns true if the member could be invoked.
2031     Returns false if there is no such member or the parameters did not match.
2032
2033     The invocation can be either synchronous or asynchronous, depending on the
2034     \a connectionType:
2035
2036     \list
2037     \o If \a connectionType is Qt::DirectConnection, the member will be invoked immediately.
2038
2039     \o If \a connectionType is Qt::QueuedConnection,
2040        a QEvent will be posted and the member is invoked as soon as the application
2041        enters the main event loop.
2042
2043     \o If \a connectionType is Qt::AutoConnection, the member is invoked
2044        synchronously if \a object lives in the same thread as the
2045        caller; otherwise it will invoke the member asynchronously.
2046     \endlist
2047
2048     The return value of this method call is placed in \a
2049     returnValue. If the invocation is asynchronous, the return value cannot
2050     be evaluated. You can pass up to ten arguments (\a val0, \a val1,
2051     \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, \a val8,
2052     and \a val9) to this method call.
2053
2054     QGenericArgument and QGenericReturnArgument are internal
2055     helper classes. Because signals and slots can be dynamically
2056     invoked, you must enclose the arguments using the Q_ARG() and
2057     Q_RETURN_ARG() macros. Q_ARG() takes a type name and a
2058     const reference of that type; Q_RETURN_ARG() takes a type name
2059     and a non-const reference.
2060
2061     To asynchronously invoke the
2062     \l{QPushButton::animateClick()}{animateClick()} slot on a
2063     QPushButton:
2064
2065     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 6
2066
2067     With asynchronous method invocations, the parameters must be of
2068     types that are known to Qt's meta-object system, because Qt needs
2069     to copy the arguments to store them in an event behind the
2070     scenes. If you try to use a queued connection and get the error
2071     message
2072
2073     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 7
2074
2075     call qRegisterMetaType() to register the data type before you
2076     call QMetaMethod::invoke().
2077
2078     To synchronously invoke the \c compute(QString, int, double) slot on
2079     some arbitrary object \c obj retrieve its return value:
2080
2081     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 8
2082
2083     QMetaObject::normalizedSignature() is used here to ensure that the format 
2084     of the signature is what invoke() expects.  E.g. extra whitespace is 
2085     removed.
2086
2087     If the "compute" slot does not take exactly one QString, one int
2088     and one double in the specified order, the call will fail.
2089
2090     \warning this method will not test the validity of the arguments: \a object
2091     must be an instance of the class of the QMetaObject of which this QMetaMethod
2092     has been constructed with.  The arguments must have the same type as the ones
2093     expected by the method, else, the behaviour is undefined.
2094
2095     \sa Q_ARG(), Q_RETURN_ARG(), qRegisterMetaType(), QMetaObject::invokeMethod()
2096 */
2097 bool QMetaMethod::invoke(QObject *object,
2098                          Qt::ConnectionType connectionType,
2099                          QGenericReturnArgument returnValue,
2100                          QGenericArgument val0,
2101                          QGenericArgument val1,
2102                          QGenericArgument val2,
2103                          QGenericArgument val3,
2104                          QGenericArgument val4,
2105                          QGenericArgument val5,
2106                          QGenericArgument val6,
2107                          QGenericArgument val7,
2108                          QGenericArgument val8,
2109                          QGenericArgument val9) const
2110 {
2111     if (!object || !mobj)
2112         return false;
2113
2114     Q_ASSERT(mobj->cast(object));
2115
2116     // check return type
2117     if (returnValue.data()) {
2118         const char *retType = typeName();
2119         if (qstrcmp(returnValue.name(), retType) != 0) {
2120             // normalize the return value as well
2121             // the trick here is to make a function signature out of the return type
2122             // so that we can call normalizedSignature() and avoid duplicating code
2123             QByteArray unnormalized;
2124             int len = qstrlen(returnValue.name());
2125
2126             unnormalized.reserve(len + 3);
2127             unnormalized = "_(";        // the function is called "_"
2128             unnormalized.append(returnValue.name());
2129             unnormalized.append(')');
2130
2131             QByteArray normalized = QMetaObject::normalizedSignature(unnormalized.constData());
2132             normalized.truncate(normalized.length() - 1); // drop the ending ')'
2133
2134             if (qstrcmp(normalized.constData() + 2, retType) != 0)
2135                 return false;
2136         }
2137     }
2138
2139     // check argument count (we don't allow invoking a method if given too few arguments)
2140     const char *typeNames[] = {
2141         returnValue.name(),
2142         val0.name(),
2143         val1.name(),
2144         val2.name(),
2145         val3.name(),
2146         val4.name(),
2147         val5.name(),
2148         val6.name(),
2149         val7.name(),
2150         val8.name(),
2151         val9.name()
2152     };
2153     int paramCount;
2154     for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
2155         if (qstrlen(typeNames[paramCount]) <= 0)
2156             break;
2157     }
2158     int metaMethodArgumentCount = 0;
2159     if (priv(mobj->d.data)->revision >= 7) {
2160         metaMethodArgumentCount = QMetaMethodPrivate::get(this)->parameterCount();
2161     } else {
2162         // based on QMetaObject::parameterNames()
2163         const char *names = rawStringData(mobj, mobj->d.data[handle + 1]);
2164         if (*names == 0) {
2165             // do we have one or zero arguments?
2166             const char *signature = rawStringData(mobj, mobj->d.data[handle]);
2167             while (*signature && *signature != '(')
2168                 ++signature;
2169             if (*++signature != ')')
2170                 ++metaMethodArgumentCount;
2171         } else {
2172             --names;
2173             do {
2174                 ++names;
2175                 while (*names && *names != ',')
2176                     ++names;
2177                 ++metaMethodArgumentCount;
2178             } while (*names);
2179         }
2180     }
2181     if (paramCount <= metaMethodArgumentCount)
2182         return false;
2183
2184     // check connection type
2185     QThread *currentThread = QThread::currentThread();
2186     QThread *objectThread = object->thread();
2187     if (connectionType == Qt::AutoConnection) {
2188         connectionType = currentThread == objectThread
2189                          ? Qt::DirectConnection
2190                          : Qt::QueuedConnection;
2191     }
2192
2193 #ifdef QT_NO_THREAD
2194     if (connectionType == Qt::BlockingQueuedConnection) {
2195         connectionType = Qt::DirectConnection;
2196     }
2197 #endif
2198
2199     // invoke!
2200     void *param[] = {
2201         returnValue.data(),
2202         val0.data(),
2203         val1.data(),
2204         val2.data(),
2205         val3.data(),
2206         val4.data(),
2207         val5.data(),
2208         val6.data(),
2209         val7.data(),
2210         val8.data(),
2211         val9.data()
2212     };
2213     // recompute the methodIndex by reversing the arithmetic in QMetaObject::property()
2214     int idx_relative = ((handle - priv(mobj->d.data)->methodData) / 5);
2215     int idx_offset =  mobj->methodOffset();
2216     QObjectPrivate::StaticMetaCallFunction callFunction =
2217         (QMetaObjectPrivate::get(mobj)->revision >= 6 && mobj->d.extradata)
2218         ? reinterpret_cast<const QMetaObjectExtraData *>(mobj->d.extradata)->static_metacall : 0;
2219
2220     if (connectionType == Qt::DirectConnection) {
2221         if (callFunction) {
2222             callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param);
2223             return true;
2224         } else {
2225             return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) < 0;
2226         }
2227     } else if (connectionType == Qt::QueuedConnection) {
2228         if (returnValue.data()) {
2229             qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in "
2230                      "queued connections");
2231             return false;
2232         }
2233
2234         int nargs = 1; // include return type
2235         void **args = (void **) malloc(paramCount * sizeof(void *));
2236         Q_CHECK_PTR(args);
2237         int *types = (int *) malloc(paramCount * sizeof(int));
2238         Q_CHECK_PTR(types);
2239         types[0] = 0; // return type
2240         args[0] = 0;
2241
2242         for (int i = 1; i < paramCount; ++i) {
2243             types[i] = QMetaType::type(typeNames[i]);
2244             if (types[i]) {
2245                 args[i] = QMetaType::create(types[i], param[i]);
2246                 ++nargs;
2247             } else if (param[i]) {
2248                 qWarning("QMetaMethod::invoke: Unable to handle unregistered datatype '%s'",
2249                          typeNames[i]);
2250                 for (int x = 1; x < i; ++x) {
2251                     if (types[x] && args[x])
2252                         QMetaType::destroy(types[x], args[x]);
2253                 }
2254                 free(types);
2255                 free(args);
2256                 return false;
2257             }
2258         }
2259
2260         QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2261                                                         0, -1, nargs, types, args));
2262     } else { // blocking queued connection
2263 #ifndef QT_NO_THREAD
2264         if (currentThread == objectThread) {
2265             qWarning("QMetaMethod::invoke: Dead lock detected in "
2266                         "BlockingQueuedConnection: Receiver is %s(%p)",
2267                         mobj->className(), object);
2268         }
2269
2270         QSemaphore semaphore;
2271         QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2272                                                         0, -1, 0, 0, param, &semaphore));
2273         semaphore.acquire();
2274 #endif // QT_NO_THREAD
2275     }
2276     return true;
2277 }
2278
2279 /*! \fn bool QMetaMethod::invoke(QObject *object,
2280                                  QGenericReturnArgument returnValue,
2281                                  QGenericArgument val0 = QGenericArgument(0),
2282                                  QGenericArgument val1 = QGenericArgument(),
2283                                  QGenericArgument val2 = QGenericArgument(),
2284                                  QGenericArgument val3 = QGenericArgument(),
2285                                  QGenericArgument val4 = QGenericArgument(),
2286                                  QGenericArgument val5 = QGenericArgument(),
2287                                  QGenericArgument val6 = QGenericArgument(),
2288                                  QGenericArgument val7 = QGenericArgument(),
2289                                  QGenericArgument val8 = QGenericArgument(),
2290                                  QGenericArgument val9 = QGenericArgument()) const
2291     \overload invoke()
2292
2293     This overload always invokes this method using the connection type Qt::AutoConnection.
2294 */
2295
2296 /*! \fn bool QMetaMethod::invoke(QObject *object,
2297                                  Qt::ConnectionType connectionType,
2298                                  QGenericArgument val0 = QGenericArgument(0),
2299                                  QGenericArgument val1 = QGenericArgument(),
2300                                  QGenericArgument val2 = QGenericArgument(),
2301                                  QGenericArgument val3 = QGenericArgument(),
2302                                  QGenericArgument val4 = QGenericArgument(),
2303                                  QGenericArgument val5 = QGenericArgument(),
2304                                  QGenericArgument val6 = QGenericArgument(),
2305                                  QGenericArgument val7 = QGenericArgument(),
2306                                  QGenericArgument val8 = QGenericArgument(),
2307                                  QGenericArgument val9 = QGenericArgument()) const
2308
2309     \overload invoke()
2310
2311     This overload can be used if the return value of the member is of no interest.
2312 */
2313
2314 /*!
2315     \fn bool QMetaMethod::invoke(QObject *object,
2316                                  QGenericArgument val0 = QGenericArgument(0),
2317                                  QGenericArgument val1 = QGenericArgument(),
2318                                  QGenericArgument val2 = QGenericArgument(),
2319                                  QGenericArgument val3 = QGenericArgument(),
2320                                  QGenericArgument val4 = QGenericArgument(),
2321                                  QGenericArgument val5 = QGenericArgument(),
2322                                  QGenericArgument val6 = QGenericArgument(),
2323                                  QGenericArgument val7 = QGenericArgument(),
2324                                  QGenericArgument val8 = QGenericArgument(),
2325                                  QGenericArgument val9 = QGenericArgument()) const
2326
2327     \overload invoke()
2328
2329     This overload invokes this method using the
2330     connection type Qt::AutoConnection and ignores return values.
2331 */
2332
2333 /*!
2334     \class QMetaEnum
2335     \brief The QMetaEnum class provides meta-data about an enumerator.
2336
2337     \ingroup objectmodel
2338
2339     Use name() for the enumerator's name. The enumerator's keys (names
2340     of each enumerated item) are returned by key(); use keyCount() to find
2341     the number of keys. isFlag() returns whether the enumerator is
2342     meant to be used as a flag, meaning that its values can be combined
2343     using the OR operator.
2344
2345     The conversion functions keyToValue(), valueToKey(), keysToValue(),
2346     and valueToKeys() allow conversion between the integer
2347     representation of an enumeration or set value and its literal
2348     representation. The scope() function returns the class scope this
2349     enumerator was declared in.
2350
2351     \sa QMetaObject, QMetaMethod, QMetaProperty
2352 */
2353
2354 /*!
2355     \fn bool QMetaEnum::isValid() const
2356
2357     Returns true if this enum is valid (has a name); otherwise returns
2358     false.
2359
2360     \sa name()
2361 */
2362
2363 /*!
2364     \fn const QMetaObject *QMetaEnum::enclosingMetaObject() const
2365     \internal
2366 */
2367
2368
2369 /*!
2370     \fn QMetaEnum::QMetaEnum()
2371     \internal
2372 */
2373
2374 /*!
2375     Returns the name of the enumerator (without the scope).
2376
2377     For example, the Qt::AlignmentFlag enumeration has \c
2378     AlignmentFlag as the name and \l Qt as the scope.
2379
2380     \sa isValid(), scope()
2381 */
2382 const char *QMetaEnum::name() const
2383 {
2384     if (!mobj)
2385         return 0;
2386     return rawStringData(mobj, mobj->d.data[handle]);
2387 }
2388
2389 /*!
2390     Returns the number of keys.
2391
2392     \sa key()
2393 */
2394 int QMetaEnum::keyCount() const
2395 {
2396     if (!mobj)
2397         return 0;
2398     return mobj->d.data[handle + 2];
2399 }
2400
2401
2402 /*!
2403     Returns the key with the given \a index, or 0 if no such key exists.
2404
2405     \sa keyCount(), value(), valueToKey()
2406 */
2407 const char *QMetaEnum::key(int index) const
2408 {
2409     if (!mobj)
2410         return 0;
2411     int count = mobj->d.data[handle + 2];
2412     int data = mobj->d.data[handle + 3];
2413     if (index >= 0  && index < count)
2414         return rawStringData(mobj, mobj->d.data[data + 2*index]);
2415     return 0;
2416 }
2417
2418 /*!
2419     Returns the value with the given \a index; or returns -1 if there
2420     is no such value.
2421
2422     \sa keyCount(), key(), keyToValue()
2423 */
2424 int QMetaEnum::value(int index) const
2425 {
2426     if (!mobj)
2427         return 0;
2428     int count = mobj->d.data[handle + 2];
2429     int data = mobj->d.data[handle + 3];
2430     if (index >= 0  && index < count)
2431         return mobj->d.data[data + 2*index + 1];
2432     return -1;
2433 }
2434
2435
2436 /*!
2437     Returns true if this enumerator is used as a flag; otherwise returns
2438     false.
2439
2440     When used as flags, enumerators can be combined using the OR
2441     operator.
2442
2443     \sa keysToValue(), valueToKeys()
2444 */
2445 bool QMetaEnum::isFlag() const
2446 {
2447     return mobj && mobj->d.data[handle + 1];
2448 }
2449
2450
2451 /*!
2452     Returns the scope this enumerator was declared in.
2453
2454     For example, the Qt::AlignmentFlag enumeration has \c Qt as
2455     the scope and \c AlignmentFlag as the name.
2456
2457     \sa name()
2458 */
2459 const char *QMetaEnum::scope() const
2460 {
2461     return mobj?rawStringData(mobj, 0) : 0;
2462 }
2463
2464 /*!
2465     Returns the integer value of the given enumeration \a key, or -1
2466     if \a key is not defined.
2467
2468     If \a key is not defined, *\a{ok} is set to false; otherwise
2469     *\a{ok} is set to true.
2470
2471     For flag types, use keysToValue().
2472
2473     \sa valueToKey(), isFlag(), keysToValue()
2474 */
2475 int QMetaEnum::keyToValue(const char *key, bool *ok) const
2476 {
2477     if (ok != 0)
2478         *ok = false;
2479     if (!mobj || !key)
2480         return -1;
2481     uint scope = 0;
2482     const char *qualified_key = key;
2483     const char *s = key + qstrlen(key);
2484     while (s > key && *s != ':')
2485         --s;
2486     if (s > key && *(s-1)==':') {
2487         scope = s - key - 1;
2488         key += scope + 2;
2489     }
2490     int count = mobj->d.data[handle + 2];
2491     int data = mobj->d.data[handle + 3];
2492     for (int i = 0; i < count; ++i) {
2493         if ((!scope || (stringSize(mobj, 0) == int(scope) && strncmp(qualified_key, rawStringData(mobj, 0), scope) == 0))
2494              && strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) {
2495             if (ok != 0)
2496                 *ok = true;
2497             return mobj->d.data[data + 2*i + 1];
2498         }
2499     }
2500     return -1;
2501 }
2502
2503 /*!
2504     Returns the string that is used as the name of the given
2505     enumeration \a value, or 0 if \a value is not defined.
2506
2507     For flag types, use valueToKeys().
2508
2509     \sa isFlag(), valueToKeys()
2510 */
2511 const char* QMetaEnum::valueToKey(int value) const
2512 {
2513     if (!mobj)
2514         return 0;
2515     int count = mobj->d.data[handle + 2];
2516     int data = mobj->d.data[handle + 3];
2517     for (int i = 0; i < count; ++i)
2518         if (value == (int)mobj->d.data[data + 2*i + 1])
2519             return rawStringData(mobj, mobj->d.data[data + 2*i]);
2520     return 0;
2521 }
2522
2523 /*!
2524     Returns the value derived from combining together the values of
2525     the \a keys using the OR operator, or -1 if \a keys is not
2526     defined. Note that the strings in \a keys must be '|'-separated.
2527
2528     If \a key is not defined, *\a{ok} is set to false; otherwise
2529     *\a{ok} is set to true.
2530
2531     \sa isFlag(), valueToKey(), valueToKeys()
2532 */
2533 int QMetaEnum::keysToValue(const char *keys, bool *ok) const
2534 {
2535     if (ok != 0)
2536         *ok = false;
2537     if (!mobj || !keys)
2538         return -1;
2539     if (ok != 0)
2540         *ok = true;
2541     QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|'));
2542     if (l.isEmpty())
2543         return 0;
2544     //#### TODO write proper code, do not use QStringList
2545     int value = 0;
2546     int count = mobj->d.data[handle + 2];
2547     int data = mobj->d.data[handle + 3];
2548     for (int li = 0; li < l.size(); ++li) {
2549         QString trimmed = l.at(li).trimmed();
2550         QByteArray qualified_key = trimmed.toLatin1();
2551         const char *key = qualified_key.constData();
2552         uint scope = 0;
2553         const char *s = key + qstrlen(key);
2554         while (s > key && *s != ':')
2555             --s;
2556         if (s > key && *(s-1)==':') {
2557             scope = s - key - 1;
2558             key += scope + 2;
2559         }
2560         int i;
2561         for (i = count-1; i >= 0; --i)
2562             if ((!scope || (stringSize(mobj, 0) == int(scope) && strncmp(qualified_key.constData(), rawStringData(mobj, 0), scope) == 0))
2563                  && strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) {
2564                 value |= mobj->d.data[data + 2*i + 1];
2565                 break;
2566             }
2567         if (i < 0) {
2568             if (ok != 0)
2569                 *ok = false;
2570             value |= -1;
2571         }
2572     }
2573     return value;
2574 }
2575
2576 /*!
2577     Returns a byte array of '|'-separated keys that represents the
2578     given \a value.
2579
2580     \sa isFlag(), valueToKey(), keysToValue()
2581 */
2582 QByteArray QMetaEnum::valueToKeys(int value) const
2583 {
2584     QByteArray keys;
2585     if (!mobj)
2586         return keys;
2587     int count = mobj->d.data[handle + 2];
2588     int data = mobj->d.data[handle + 3];
2589     int v = value;
2590     for(int i = 0; i < count; i++) {
2591         int k = mobj->d.data[data + 2*i + 1];
2592         if ((k != 0 && (v & k) == k ) ||  (k == value))  {
2593             v = v & ~k;
2594             if (!keys.isEmpty())
2595                 keys += '|';
2596             if (priv(mobj->d.data)->revision >= 7)
2597                 keys += toByteArray(stringData(mobj, mobj->d.data[data + 2*i]));
2598             else
2599                 keys += legacyString(mobj, mobj->d.data[data + 2*i]);
2600         }
2601     }
2602     return keys;
2603 }
2604
2605 static QByteArray qualifiedName(const QMetaEnum &e)
2606 {
2607     return QByteArray(e.scope()) + "::" + e.name();
2608 }
2609
2610 /*!
2611     \class QMetaProperty
2612     \brief The QMetaProperty class provides meta-data about a property.
2613
2614     \ingroup objectmodel
2615
2616     Property meta-data is obtained from an object's meta-object. See
2617     QMetaObject::property() and QMetaObject::propertyCount() for
2618     details.
2619
2620     \section1 Property Meta-Data
2621
2622     A property has a name() and a type(), as well as various
2623     attributes that specify its behavior: isReadable(), isWritable(),
2624     isDesignable(), isScriptable(), and isStored().
2625
2626     If the property is an enumeration, isEnumType() returns true; if the
2627     property is an enumeration that is also a flag (i.e. its values
2628     can be combined using the OR operator), isEnumType() and
2629     isFlagType() both return true. The enumerator for these types is
2630     available from enumerator().
2631
2632     The property's values are set and retrieved with read(), write(),
2633     and reset(); they can also be changed through QObject's set and get
2634     functions. See QObject::setProperty() and QObject::property() for
2635     details.
2636
2637     \section1 Copying and Assignment
2638
2639     QMetaProperty objects can be copied by value. However, each copy will
2640     refer to the same underlying property meta-data.
2641
2642     \sa QMetaObject, QMetaEnum, QMetaMethod, {Qt's Property System}
2643 */
2644
2645 /*!
2646     \fn bool QMetaProperty::isValid() const
2647
2648     Returns true if this property is valid (readable); otherwise
2649     returns false.
2650
2651     \sa isReadable()
2652 */
2653
2654 /*!
2655     \fn const QMetaObject *QMetaProperty::enclosingMetaObject() const
2656     \internal
2657 */
2658
2659 /*!
2660     \internal
2661 */
2662 QMetaProperty::QMetaProperty()
2663     : mobj(0), handle(0), idx(0)
2664 {
2665 }
2666
2667
2668 /*!
2669     Returns this property's name.
2670
2671     \sa type(), typeName()
2672 */
2673 const char *QMetaProperty::name() const
2674 {
2675     if (!mobj)
2676         return 0;
2677     int handle = priv(mobj->d.data)->propertyData + 3*idx;
2678     return rawStringData(mobj, mobj->d.data[handle]);
2679 }
2680
2681 /*!
2682     Returns the name of this property's type.
2683
2684     \sa type(), name()
2685 */
2686 const char *QMetaProperty::typeName() const
2687 {
2688     if (!mobj)
2689         return 0;
2690     int handle = priv(mobj->d.data)->propertyData + 3*idx;
2691     if (priv(mobj->d.data)->revision >= 7)
2692         return rawTypeNameFromTypeInfo(mobj, mobj->d.data[handle + 1]);
2693     else
2694         return legacyString(mobj, mobj->d.data[handle + 1]);
2695 }
2696
2697 /*!
2698     Returns this property's type. The return value is one
2699     of the values of the QVariant::Type enumeration.
2700
2701     \sa userType(), typeName(), name()
2702 */
2703 QVariant::Type QMetaProperty::type() const
2704 {
2705     if (!mobj)
2706         return QVariant::Invalid;
2707     int handle = priv(mobj->d.data)->propertyData + 3*idx;
2708
2709     uint type;
2710     if (priv(mobj->d.data)->revision >= 7) {
2711         type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]);
2712         if (type >= QMetaType::User)
2713             return QVariant::UserType;
2714     } else {
2715         uint flags = mobj->d.data[handle + 2];
2716         type = flags >> 24;
2717     }
2718     if (type)
2719         return QVariant::Type(type);
2720     if (isEnumType()) {
2721         int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
2722         if (enumMetaTypeId == 0)
2723             return QVariant::Int;
2724     }
2725 #ifdef QT_COORD_TYPE
2726     // qreal metatype must be resolved at runtime.
2727     if (strcmp(typeName(), "qreal") == 0)
2728         return QVariant::Type(qMetaTypeId<qreal>());
2729 #endif
2730
2731     return QVariant::UserType;
2732 }
2733
2734 /*!
2735     \since 4.2
2736
2737     Returns this property's user type. The return value is one
2738     of the values that are registered with QMetaType, or 0 if
2739     the type is not registered.
2740
2741     \sa type(), QMetaType, typeName()
2742  */
2743 int QMetaProperty::userType() const
2744 {
2745     if (!mobj)
2746         return 0;
2747     if (priv(mobj->d.data)->revision >= 7) {
2748         int handle = priv(mobj->d.data)->propertyData + 3*idx;
2749         int type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]);
2750         if (type)
2751             return type;
2752     } else {
2753         QVariant::Type tp = type();
2754         if (tp != QVariant::UserType)
2755             return tp;
2756     }
2757     if (isEnumType()) {
2758         int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
2759         if (enumMetaTypeId == 0)
2760             return QVariant::Int; // Match behavior of QMetaType::type()
2761         return enumMetaTypeId;
2762     }
2763     return QMetaType::type(typeName());
2764 }
2765
2766 /*!
2767   \since 4.6
2768
2769   Returns this property's index.
2770 */
2771 int QMetaProperty::propertyIndex() const
2772 {
2773     if (!mobj)
2774         return -1;
2775     return idx + mobj->propertyOffset();
2776 }
2777
2778 /*!
2779     Returns true if the property's type is an enumeration value that
2780     is used as a flag; otherwise returns false.
2781
2782     Flags can be combined using the OR operator. A flag type is
2783     implicitly also an enum type.
2784
2785     \sa isEnumType(), enumerator(), QMetaEnum::isFlag()
2786 */
2787
2788 bool QMetaProperty::isFlagType() const
2789 {
2790     return isEnumType() && menum.isFlag();
2791 }
2792
2793 /*!
2794     Returns true if the property's type is an enumeration value;
2795     otherwise returns false.
2796
2797     \sa enumerator(), isFlagType()
2798 */
2799 bool QMetaProperty::isEnumType() const
2800 {
2801     if (!mobj)
2802         return false;
2803     int handle = priv(mobj->d.data)->propertyData + 3*idx;
2804     int flags = mobj->d.data[handle + 2];
2805     return (flags & EnumOrFlag) && menum.name();
2806 }
2807
2808 /*!
2809     \internal
2810
2811     Returns true if the property has a C++ setter function that
2812     follows Qt's standard "name" / "setName" pattern. Designer and uic
2813     query hasStdCppSet() in order to avoid expensive
2814     QObject::setProperty() calls. All properties in Qt [should] follow
2815     this pattern.
2816 */
2817 bool QMetaProperty::hasStdCppSet() const
2818 {
2819     if (!mobj)
2820         return false;
2821     int handle = priv(mobj->d.data)->propertyData + 3*idx;
2822     int flags = mobj->d.data[handle + 2];
2823     return (flags & StdCppSet);
2824 }
2825
2826 /*!
2827     Returns the enumerator if this property's type is an enumerator
2828     type; otherwise the returned value is undefined.
2829
2830     \sa isEnumType(), isFlagType()
2831 */
2832 QMetaEnum QMetaProperty::enumerator() const
2833 {
2834     return menum;
2835 }
2836
2837 /*!
2838     Reads the property's value from the given \a object. Returns the value
2839     if it was able to read it; otherwise returns an invalid variant.
2840
2841     \sa write(), reset(), isReadable()
2842 */
2843 QVariant QMetaProperty::read(const QObject *object) const
2844 {
2845     if (!object || !mobj)
2846         return QVariant();
2847
2848     uint t = QVariant::Int;
2849     if (isEnumType()) {
2850         /*
2851           try to create a QVariant that can be converted to this enum
2852           type (only works if the enum has already been registered
2853           with QMetaType)
2854         */
2855         int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
2856         if (enumMetaTypeId != 0)
2857             t = enumMetaTypeId;
2858     } else {
2859         int handle = priv(mobj->d.data)->propertyData + 3*idx;
2860         const char *typeName = 0;
2861         if (priv(mobj->d.data)->revision >= 7) {
2862             uint typeInfo = mobj->d.data[handle + 1];
2863             if (!(typeInfo & IsUnresolvedType))
2864                 t = typeInfo;
2865             else {
2866                 typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
2867                 t = QMetaType::type(typeName);
2868             }
2869         } else {
2870             uint flags = mobj->d.data[handle + 2];
2871             t = (flags >> 24);
2872             if (t == QVariant::Invalid) {
2873                 typeName = legacyString(mobj, mobj->d.data[handle + 1]);
2874                 t = QMetaType::type(typeName);
2875                 if (t == QVariant::Invalid)
2876                     t = QVariant::nameToType(typeName);
2877             }
2878         }
2879         if (t == QVariant::Invalid) {
2880             qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name());
2881             return QVariant();
2882         }
2883     }
2884
2885     // the status variable is changed by qt_metacall to indicate what it did
2886     // this feature is currently only used by QtDBus and should not be depended
2887     // upon. Don't change it without looking into QDBusAbstractInterface first
2888     // -1 (unchanged): normal qt_metacall, result stored in argv[0]
2889     // changed: result stored directly in value
2890     int status = -1;
2891     QVariant value;
2892     void *argv[] = { 0, &value, &status };
2893     if (t == QMetaType::QVariant) {
2894         argv[0] = &value;
2895     } else {
2896         value = QVariant(t, (void*)0);
2897         argv[0] = value.data();
2898     }
2899     QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty,
2900                           idx + mobj->propertyOffset(), argv);
2901
2902     if (status != -1)
2903         return value;
2904     if (t != QMetaType::QVariant && argv[0] != value.data())
2905         // pointer or reference
2906         return QVariant((QVariant::Type)t, argv[0]);
2907     return value;
2908 }
2909
2910 /*!
2911     Writes \a value as the property's value to the given \a object. Returns
2912     true if the write succeeded; otherwise returns false.
2913
2914     \sa read(), reset(), isWritable()
2915 */
2916 bool QMetaProperty::write(QObject *object, const QVariant &value) const
2917 {
2918     if (!object || !isWritable())
2919         return false;
2920
2921     QVariant v = value;
2922     uint t = QVariant::Invalid;
2923     if (isEnumType()) {
2924         if (v.type() == QVariant::String) {
2925             bool ok;
2926             if (isFlagType())
2927                 v = QVariant(menum.keysToValue(value.toByteArray(), &ok));
2928             else
2929                 v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
2930             if (!ok)
2931                 return false;
2932         } else if (v.type() != QVariant::Int && v.type() != QVariant::UInt) {
2933             int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
2934             if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())
2935                 return false;
2936             v = QVariant(*reinterpret_cast<const int *>(v.constData()));
2937         }
2938         v.convert(QVariant::Int);
2939     } else {
2940         int handle = priv(mobj->d.data)->propertyData + 3*idx;
2941         const char *typeName = 0;
2942         if (priv(mobj->d.data)->revision >= 7) {
2943             uint typeInfo = mobj->d.data[handle + 1];
2944             if (!(typeInfo & IsUnresolvedType))
2945                 t = typeInfo;
2946             else {
2947                 typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask);
2948                 t = QMetaType::type(typeName);
2949             }
2950         } else {
2951             uint flags = mobj->d.data[handle + 2];
2952             t = flags >> 24;
2953             typeName = legacyString(mobj, mobj->d.data[handle + 1]);
2954         }
2955         if (t == QVariant::Invalid) {
2956             const char *typeName = rawStringData(mobj, mobj->d.data[handle + 1]);
2957             const char *vtypeName = value.typeName();
2958             if (vtypeName && strcmp(typeName, vtypeName) == 0)
2959                 t = value.userType();
2960             else
2961                 t = QVariant::nameToType(typeName);
2962         }
2963         if (t == QVariant::Invalid)
2964             return false;
2965         if (t != QMetaType::QVariant && t != (uint)value.userType() && (t < QMetaType::User && !v.convert((QVariant::Type)t)))
2966             return false;
2967     }
2968
2969     // the status variable is changed by qt_metacall to indicate what it did
2970     // this feature is currently only used by QtDBus and should not be depended
2971     // upon. Don't change it without looking into QDBusAbstractInterface first
2972     // -1 (unchanged): normal qt_metacall, result stored in argv[0]
2973     // changed: result stored directly in value, return the value of status
2974     int status = -1;
2975     // the flags variable is used by the declarative module to implement
2976     // interception of property writes.
2977     int flags = 0;
2978     void *argv[] = { 0, &v, &status, &flags };
2979     if (t == QMetaType::QVariant)
2980         argv[0] = &v;
2981     else
2982         argv[0] = v.data();
2983     QMetaObject::metacall(object, QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv);
2984     return status;
2985 }
2986
2987 /*!
2988     Resets the property for the given \a object with a reset method.
2989     Returns true if the reset worked; otherwise returns false.
2990
2991     Reset methods are optional; only a few properties support them.
2992
2993     \sa read(), write()
2994 */
2995 bool QMetaProperty::reset(QObject *object) const
2996 {
2997     if (!object || !mobj || !isResettable())
2998         return false;
2999     void *argv[] = { 0 };
3000     QMetaObject::metacall(object, QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv);
3001     return true;
3002 }
3003
3004 /*!
3005     Returns true if this property can be reset to a default value; otherwise
3006     returns false.
3007
3008     \sa reset()
3009 */
3010 bool QMetaProperty::isResettable() const
3011 {
3012     if (!mobj)
3013         return false;
3014     int flags = mobj->d.data[handle + 2];
3015     return flags & Resettable;
3016 }
3017
3018 /*!
3019     Returns true if this property is readable; otherwise returns false.
3020
3021     \sa isWritable(), read(), isValid()
3022  */
3023 bool QMetaProperty::isReadable() const
3024 {
3025     if (!mobj)
3026         return false;
3027     int flags = mobj->d.data[handle + 2];
3028     return flags & Readable;
3029 }
3030
3031 /*!
3032     Returns true if this property has a corresponding change notify signal;
3033     otherwise returns false.
3034
3035     \sa notifySignal()
3036  */
3037 bool QMetaProperty::hasNotifySignal() const
3038 {
3039     if (!mobj)
3040         return false;
3041     int flags = mobj->d.data[handle + 2];
3042     return flags & Notify;
3043 }
3044
3045 /*!
3046     \since 4.5
3047
3048     Returns the QMetaMethod instance of the property change notifying signal if
3049     one was specified, otherwise returns an invalid QMetaMethod.
3050
3051     \sa hasNotifySignal()
3052  */
3053 QMetaMethod QMetaProperty::notifySignal() const
3054 {
3055     int id = notifySignalIndex();
3056     if (id != -1)
3057         return mobj->method(id); 
3058     else
3059         return QMetaMethod();
3060 }
3061
3062 /*!
3063     \since 4.6
3064
3065     Returns the index of the property change notifying signal if one was 
3066     specified, otherwise returns -1.
3067
3068     \sa hasNotifySignal()
3069  */
3070 int QMetaProperty::notifySignalIndex() const
3071 {
3072     if (hasNotifySignal()) {
3073         int offset = priv(mobj->d.data)->propertyData +
3074                      priv(mobj->d.data)->propertyCount * 3 + idx;
3075         return mobj->d.data[offset] + mobj->methodOffset();
3076     } else {
3077         return -1;
3078     }
3079 }
3080
3081 /*!
3082     \internal
3083
3084     Returns the property revision if one was
3085     specified by REVISION, otherwise returns 0.
3086  */
3087 int QMetaProperty::revision() const
3088 {
3089     if (!mobj)
3090         return 0;
3091     int flags = mobj->d.data[handle + 2];
3092     if (flags & Revisioned) {
3093         int offset = priv(mobj->d.data)->propertyData +
3094                      priv(mobj->d.data)->propertyCount * 3 + idx;
3095         // Revision data is placed after NOTIFY data, if present.
3096         // Iterate through properties to discover whether we have NOTIFY signals.
3097         for (int i = 0; i < priv(mobj->d.data)->propertyCount; ++i) {
3098             int handle = priv(mobj->d.data)->propertyData + 3*i;
3099             if (mobj->d.data[handle + 2] & Notify) {
3100                 offset += priv(mobj->d.data)->propertyCount;
3101                 break;
3102             }
3103         }
3104         return mobj->d.data[offset];
3105     } else {
3106         return 0;
3107     }
3108 }
3109
3110 /*!
3111     Returns true if this property is writable; otherwise returns
3112     false.
3113
3114     \sa isReadable(), write()
3115  */
3116 bool QMetaProperty::isWritable() const
3117 {
3118     if (!mobj)
3119         return false;
3120     int flags = mobj->d.data[handle + 2];
3121     return flags & Writable;
3122 }
3123
3124
3125 /*!
3126     Returns true if this property is designable for the given \a object;
3127     otherwise returns false.
3128
3129     If no \a object is given, the function returns false if the
3130     \c{Q_PROPERTY()}'s \c DESIGNABLE attribute is false; otherwise
3131     returns true (if the attribute is true or is a function or expression).
3132
3133     \sa isScriptable(), isStored()
3134 */
3135 bool QMetaProperty::isDesignable(const QObject *object) const
3136 {
3137     if (!mobj)
3138         return false;
3139     int flags = mobj->d.data[handle + 2];
3140     bool b = flags & Designable;
3141     if (object) {
3142         void *argv[] = { &b };
3143         QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyDesignable,
3144                               idx + mobj->propertyOffset(), argv);
3145     }
3146     return b;
3147
3148
3149 }
3150
3151 /*!
3152     Returns true if the property is scriptable for the given \a object;
3153     otherwise returns false.
3154
3155     If no \a object is given, the function returns false if the
3156     \c{Q_PROPERTY()}'s \c SCRIPTABLE attribute is false; otherwise returns
3157     true (if the attribute is true or is a function or expression).
3158
3159     \sa isDesignable(), isStored()
3160 */
3161 bool QMetaProperty::isScriptable(const QObject *object) const
3162 {
3163     if (!mobj)
3164         return false;
3165     int flags = mobj->d.data[handle + 2];
3166     bool b = flags & Scriptable;
3167     if (object) {
3168         void *argv[] = { &b };
3169         QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyScriptable,
3170                               idx + mobj->propertyOffset(), argv);
3171     }
3172     return b;
3173 }
3174
3175 /*!
3176     Returns true if the property is stored for \a object; otherwise returns
3177     false.
3178
3179     If no \a object is given, the function returns false if the
3180     \c{Q_PROPERTY()}'s \c STORED attribute is false; otherwise returns
3181     true (if the attribute is true or is a function or expression).
3182
3183     \sa isDesignable(), isScriptable()
3184 */
3185 bool QMetaProperty::isStored(const QObject *object) const
3186 {
3187     if (!mobj)
3188         return false;
3189     int flags = mobj->d.data[handle + 2];
3190     bool b = flags & Stored;
3191     if (object) {
3192         void *argv[] = { &b };
3193         QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyStored,
3194                               idx + mobj->propertyOffset(), argv);
3195     }
3196     return b;
3197 }
3198
3199 /*!
3200     Returns true if this property is designated as the \c USER
3201     property, i.e., the one that the user can edit for \a object or
3202     that is significant in some other way.  Otherwise it returns
3203     false. e.g., the \c text property is the \c USER editable property
3204     of a QLineEdit.
3205
3206     If \a object is null, the function returns false if the \c
3207     {Q_PROPERTY()}'s \c USER attribute is false. Otherwise it returns
3208     true.
3209
3210     \sa QMetaObject::userProperty(), isDesignable(), isScriptable()
3211 */
3212 bool QMetaProperty::isUser(const QObject *object) const
3213 {
3214     if (!mobj)
3215         return false;
3216     int flags = mobj->d.data[handle + 2];
3217     bool b = flags & User;
3218     if (object) {
3219         void *argv[] = { &b };
3220         QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyUser,
3221                               idx + mobj->propertyOffset(), argv);
3222     }
3223     return b;
3224 }
3225
3226 /*!
3227     \since 4.6
3228     Returns true if the property is constant; otherwise returns false.
3229
3230     A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute
3231     is set.
3232 */
3233 bool QMetaProperty::isConstant() const
3234 {
3235     if (!mobj)
3236         return false;
3237     int flags = mobj->d.data[handle + 2];
3238     return flags & Constant;
3239 }
3240
3241 /*!
3242     \since 4.6
3243     Returns true if the property is final; otherwise returns false.
3244
3245     A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute
3246     is set.
3247 */
3248 bool QMetaProperty::isFinal() const
3249 {
3250     if (!mobj)
3251         return false;
3252     int flags = mobj->d.data[handle + 2];
3253     return flags & Final;
3254 }
3255
3256 /*!
3257     \obsolete
3258
3259     Returns true if the property is editable for the given \a object;
3260     otherwise returns false.
3261
3262     If no \a object is given, the function returns false if the
3263     \c{Q_PROPERTY()}'s \c EDITABLE attribute is false; otherwise returns
3264     true (if the attribute is true or is a function or expression).
3265
3266     \sa isDesignable(), isScriptable(), isStored()
3267 */
3268 bool QMetaProperty::isEditable(const QObject *object) const
3269 {
3270     if (!mobj)
3271         return false;
3272     int flags = mobj->d.data[handle + 2];
3273     bool b = flags & Editable;
3274     if (object) {
3275         void *argv[] = { &b };
3276         QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyEditable,
3277                               idx + mobj->propertyOffset(), argv);
3278     }
3279     return b;
3280 }
3281
3282 /*!
3283     \class QMetaClassInfo
3284
3285     \brief The QMetaClassInfo class provides additional information
3286     about a class.
3287
3288     \ingroup objectmodel
3289
3290     Class information items are simple \e{name}--\e{value} pairs that
3291     are specified using Q_CLASSINFO() in the source code. The
3292     information can be retrieved using name() and value(). For example:
3293
3294     \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 5
3295
3296     This mechanism is free for you to use in your Qt applications. Qt
3297     doesn't use it for any of its classes.
3298
3299     \sa QMetaObject
3300 */
3301
3302
3303 /*!
3304     \fn QMetaClassInfo::QMetaClassInfo()
3305     \internal
3306 */
3307
3308 /*!
3309     \fn const QMetaObject *QMetaClassInfo::enclosingMetaObject() const
3310     \internal
3311 */
3312
3313 /*!
3314     Returns the name of this item.
3315
3316     \sa value()
3317 */
3318 const char *QMetaClassInfo::name() const
3319 {
3320     if (!mobj)
3321         return 0;
3322     return rawStringData(mobj, mobj->d.data[handle]);
3323 }
3324
3325 /*!
3326     Returns the value of this item.
3327
3328     \sa name()
3329 */
3330 const char* QMetaClassInfo::value() const
3331 {
3332     if (!mobj)
3333         return 0;
3334     return rawStringData(mobj, mobj->d.data[handle + 1]);
3335 }
3336
3337 /*!
3338     \macro QGenericArgument Q_ARG(Type, const Type &value)
3339     \relates QMetaObject
3340
3341     This macro takes a \a Type and a \a value of that type and
3342     returns a \l QGenericArgument object that can be passed to
3343     QMetaObject::invokeMethod().
3344
3345     \sa Q_RETURN_ARG()
3346 */
3347
3348 /*!
3349     \macro QGenericReturnArgument Q_RETURN_ARG(Type, Type &value)
3350     \relates QMetaObject
3351
3352     This macro takes a \a Type and a non-const reference to a \a
3353     value of that type and returns a QGenericReturnArgument object
3354     that can be passed to QMetaObject::invokeMethod().
3355
3356     \sa Q_ARG()
3357 */
3358
3359 /*!
3360     \class QGenericArgument
3361
3362     \brief The QGenericArgument class is an internal helper class for
3363     marshalling arguments.
3364
3365     This class should never be used directly. Please use the \l Q_ARG()
3366     macro instead.
3367
3368     \sa Q_ARG(), QMetaObject::invokeMethod(),  QGenericReturnArgument
3369 */
3370
3371 /*!
3372     \fn QGenericArgument::QGenericArgument(const char *name, const void *data)
3373
3374     Constructs a QGenericArgument object with the given \a name and \a data.
3375 */
3376
3377 /*!
3378     \fn QGenericArgument::data () const
3379
3380     Returns the data set in the constructor.
3381 */
3382
3383 /*!
3384     \fn QGenericArgument::name () const
3385
3386     Returns the name set in the constructor.
3387 */
3388
3389 /*!
3390     \class QGenericReturnArgument
3391
3392     \brief The QGenericReturnArgument class is an internal helper class for
3393     marshalling arguments.
3394
3395     This class should never be used directly. Please use the
3396     Q_RETURN_ARG() macro instead.
3397
3398     \sa Q_RETURN_ARG(), QMetaObject::invokeMethod(), QGenericArgument
3399 */
3400
3401 /*!
3402     \fn QGenericReturnArgument::QGenericReturnArgument(const char *name, void *data)
3403
3404     Constructs a QGenericReturnArgument object with the given \a name
3405     and \a data.
3406 */
3407
3408 /*! \internal
3409     If the local_method_index is a cloned method, return the index of the original.
3410
3411     Example: if the index of "destroyed()" is passed, the index of "destroyed(QObject*)" is returned
3412  */
3413 int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index)
3414 {
3415     Q_ASSERT(local_method_index < get(mobj)->methodCount);
3416     int handle = get(mobj)->methodData + 5 * local_method_index;
3417     while (mobj->d.data[handle + 4] & MethodCloned) {
3418         Q_ASSERT(local_method_index > 0);
3419         handle -= 5;
3420         local_method_index--;
3421     }
3422     return local_method_index;
3423 }
3424
3425 /*!
3426     \internal
3427
3428     Returns the parameter type names extracted from the given \a signature.
3429 */
3430 QList<QByteArray> QMetaObjectPrivate::parameterTypeNamesFromSignature(const char *signature)
3431 {
3432     QList<QByteArray> list;
3433     while (*signature && *signature != '(')
3434         ++signature;
3435     while (*signature && *signature != ')' && *++signature != ')') {
3436         const char *begin = signature;
3437         int level = 0;
3438         while (*signature && (level > 0 || *signature != ',') && *signature != ')') {
3439             if (*signature == '<')
3440                 ++level;
3441             else if (*signature == '>')
3442                 --level;
3443             ++signature;
3444         }
3445         list += QByteArray(begin, signature - begin);
3446     }
3447     return list;
3448 }
3449
3450 QT_END_NAMESPACE