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