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