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