source: trunk/src/corelib/kernel/qmetaobject.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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