1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the QtCore module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** 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 have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia 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 |
|
---|
62 | QT_BEGIN_NAMESPACE
|
---|
63 |
|
---|
64 | /*!
|
---|
65 | \class QMetaObject
|
---|
66 |
|
---|
67 | \brief The QMetaObject class contains meta-information about Qt
|
---|
68 | objects.
|
---|
69 |
|
---|
70 | \ingroup objectmodel
|
---|
71 |
|
---|
72 | The Qt \l{Meta-Object System} in Qt is responsible for the
|
---|
73 | signals and slots inter-object communication mechanism, runtime
|
---|
74 | type information, and the Qt property system. A single
|
---|
75 | QMetaObject instance is created for each QObject subclass that is
|
---|
76 | used in an application, and this instance stores all the
|
---|
77 | meta-information for the QObject subclass. This object is
|
---|
78 | available as QObject::metaObject().
|
---|
79 |
|
---|
80 | This class is not normally required for application programming,
|
---|
81 | but it is useful if you write meta-applications, such as scripting
|
---|
82 | engines or GUI builders.
|
---|
83 |
|
---|
84 | The functions you are most likely to find useful are these:
|
---|
85 | \list
|
---|
86 | \o className() returns the name of a class.
|
---|
87 | \o superClass() returns the superclass's meta-object.
|
---|
88 | \o method() and methodCount() provide information
|
---|
89 | about a class's meta-methods (signals, slots and other
|
---|
90 | \l{Q_INVOKABLE}{invokable} member functions).
|
---|
91 | \o enumerator() and enumeratorCount() and provide information about
|
---|
92 | a class's enumerators.
|
---|
93 | \o propertyCount() and property() provide information about a
|
---|
94 | class's properties.
|
---|
95 | \o constructor() and constructorCount() provide information
|
---|
96 | about a class's meta-constructors.
|
---|
97 | \endlist
|
---|
98 |
|
---|
99 | The index functions indexOfConstructor(), indexOfMethod(),
|
---|
100 | indexOfEnumerator(), and indexOfProperty() map names of constructors,
|
---|
101 | member functions, enumerators, or properties to indexes in the
|
---|
102 | meta-object. For example, Qt uses indexOfMethod() internally when you
|
---|
103 | connect a signal to a slot.
|
---|
104 |
|
---|
105 | Classes can also have a list of \e{name}--\e{value} pairs of
|
---|
106 | additional class information, stored in QMetaClassInfo objects.
|
---|
107 | The number of pairs is returned by classInfoCount(), single pairs
|
---|
108 | are returned by classInfo(), and you can search for pairs with
|
---|
109 | indexOfClassInfo().
|
---|
110 |
|
---|
111 | \sa QMetaClassInfo, QMetaEnum, QMetaMethod, QMetaProperty, QMetaType,
|
---|
112 | {Meta-Object System}
|
---|
113 | */
|
---|
114 |
|
---|
115 | /*!
|
---|
116 | \enum QMetaObject::Call
|
---|
117 |
|
---|
118 | \internal
|
---|
119 |
|
---|
120 | \value InvokeSlot
|
---|
121 | \value EmitSignal
|
---|
122 | \value ReadProperty
|
---|
123 | \value WriteProperty
|
---|
124 | \value ResetProperty
|
---|
125 | \value QueryPropertyDesignable
|
---|
126 | \value QueryPropertyScriptable
|
---|
127 | \value QueryPropertyStored
|
---|
128 | \value QueryPropertyEditable
|
---|
129 | \value QueryPropertyUser
|
---|
130 | \value CreateInstance
|
---|
131 | */
|
---|
132 |
|
---|
133 | /*!
|
---|
134 | \enum QMetaMethod::Access
|
---|
135 |
|
---|
136 | This enum describes the access level of a method, following the conventions used in C++.
|
---|
137 |
|
---|
138 | \value Private
|
---|
139 | \value Protected
|
---|
140 | \value Public
|
---|
141 | */
|
---|
142 |
|
---|
143 | static inline const QMetaObjectPrivate *priv(const uint* data)
|
---|
144 | { return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
---|
145 |
|
---|
146 |
|
---|
147 | /*!
|
---|
148 | \since 4.5
|
---|
149 |
|
---|
150 | Constructs a new instance of this class. You can pass up to ten arguments
|
---|
151 | (\a val0, \a val1, \a val2, \a val3, \a val4, \a val5, \a val6, \a val7,
|
---|
152 | \a val8, and \a val9) to the constructor. Returns the new object, or 0 if
|
---|
153 | no suitable constructor is available.
|
---|
154 |
|
---|
155 | Note that only constructors that are declared with the Q_INVOKABLE
|
---|
156 | modifier are made available through the meta-object system.
|
---|
157 |
|
---|
158 | \sa Q_ARG(), constructor()
|
---|
159 | */
|
---|
160 | QObject *QMetaObject::newInstance(QGenericArgument val0,
|
---|
161 | QGenericArgument val1,
|
---|
162 | QGenericArgument val2,
|
---|
163 | QGenericArgument val3,
|
---|
164 | QGenericArgument val4,
|
---|
165 | QGenericArgument val5,
|
---|
166 | QGenericArgument val6,
|
---|
167 | QGenericArgument val7,
|
---|
168 | QGenericArgument val8,
|
---|
169 | QGenericArgument val9) const
|
---|
170 | {
|
---|
171 | QByteArray constructorName = className();
|
---|
172 | {
|
---|
173 | int idx = constructorName.lastIndexOf(':');
|
---|
174 | if (idx != -1)
|
---|
175 | constructorName.remove(0, idx+1); // remove qualified part
|
---|
176 | }
|
---|
177 | QVarLengthArray<char, 512> sig;
|
---|
178 | sig.append(constructorName.constData(), constructorName.length());
|
---|
179 | sig.append('(');
|
---|
180 |
|
---|
181 | enum { MaximumParamCount = 10 };
|
---|
182 | const char *typeNames[] = {val0.name(), val1.name(), val2.name(), val3.name(), val4.name(),
|
---|
183 | val5.name(), val6.name(), val7.name(), val8.name(), val9.name()};
|
---|
184 |
|
---|
185 | int paramCount;
|
---|
186 | for (paramCount = 0; paramCount < MaximumParamCount; ++paramCount) {
|
---|
187 | int len = qstrlen(typeNames[paramCount]);
|
---|
188 | if (len <= 0)
|
---|
189 | break;
|
---|
190 | sig.append(typeNames[paramCount], len);
|
---|
191 | sig.append(',');
|
---|
192 | }
|
---|
193 | if (paramCount == 0)
|
---|
194 | sig.append(')'); // no parameters
|
---|
195 | else
|
---|
196 | sig[sig.size() - 1] = ')';
|
---|
197 | sig.append('\0');
|
---|
198 |
|
---|
199 | int idx = indexOfConstructor(sig.constData());
|
---|
200 | if (idx < 0) {
|
---|
201 | QByteArray norm = QMetaObject::normalizedSignature(sig.constData());
|
---|
202 | idx = indexOfConstructor(norm.constData());
|
---|
203 | }
|
---|
204 | if (idx < 0)
|
---|
205 | return 0;
|
---|
206 |
|
---|
207 | QVariant ret(QMetaType::QObjectStar, (void*)0);
|
---|
208 | void *param[] = {ret.data(), val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
|
---|
209 | val5.data(), val6.data(), val7.data(), val8.data(), val9.data()};
|
---|
210 |
|
---|
211 | if (static_metacall(CreateInstance, idx, param) >= 0)
|
---|
212 | return 0;
|
---|
213 | return *reinterpret_cast<QObject**>(param[0]);
|
---|
214 | }
|
---|
215 |
|
---|
216 | /*!
|
---|
217 | \internal
|
---|
218 | */
|
---|
219 | int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
|
---|
220 | {
|
---|
221 | if (priv(d.data)->revision < 2)
|
---|
222 | return 0;
|
---|
223 | const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(d.extradata);
|
---|
224 | if (!extra || !extra->static_metacall)
|
---|
225 | return 0;
|
---|
226 | return extra->static_metacall(cl, idx, argv);
|
---|
227 | }
|
---|
228 |
|
---|
229 | /*!
|
---|
230 | \internal
|
---|
231 | */
|
---|
232 | int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv)
|
---|
233 | {
|
---|
234 | if (QMetaObject *mo = object->d_ptr->metaObject)
|
---|
235 | return static_cast<QAbstractDynamicMetaObject*>(mo)->metaCall(cl, idx, argv);
|
---|
236 | else
|
---|
237 | return object->qt_metacall(cl, idx, argv);
|
---|
238 | }
|
---|
239 |
|
---|
240 | /*!
|
---|
241 | \fn const char *QMetaObject::className() const
|
---|
242 |
|
---|
243 | Returns the class name.
|
---|
244 |
|
---|
245 | \sa superClass()
|
---|
246 | */
|
---|
247 |
|
---|
248 | /*!
|
---|
249 | \fn QMetaObject *QMetaObject::superClass() const
|
---|
250 |
|
---|
251 | Returns the meta-object of the superclass, or 0 if there is no
|
---|
252 | such object.
|
---|
253 |
|
---|
254 | \sa className()
|
---|
255 | */
|
---|
256 |
|
---|
257 | /*!
|
---|
258 | \internal
|
---|
259 |
|
---|
260 | Returns \a obj if object \a obj inherits from this
|
---|
261 | meta-object; otherwise returns 0.
|
---|
262 | */
|
---|
263 | QObject *QMetaObject::cast(QObject *obj) const
|
---|
264 | {
|
---|
265 | if (obj) {
|
---|
266 | const QMetaObject *m = obj->metaObject();
|
---|
267 | do {
|
---|
268 | if (m == this)
|
---|
269 | return const_cast<QObject*>(obj);
|
---|
270 | } while ((m = m->d.superdata));
|
---|
271 | }
|
---|
272 | return 0;
|
---|
273 | }
|
---|
274 |
|
---|
275 | #ifndef QT_NO_TRANSLATION
|
---|
276 | /*!
|
---|
277 | \internal
|
---|
278 | */
|
---|
279 | QString QMetaObject::tr(const char *s, const char *c) const
|
---|
280 | {
|
---|
281 | return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::CodecForTr);
|
---|
282 | }
|
---|
283 |
|
---|
284 | /*!
|
---|
285 | \internal
|
---|
286 | */
|
---|
287 | QString QMetaObject::tr(const char *s, const char *c, int n) const
|
---|
288 | {
|
---|
289 | return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::CodecForTr, n);
|
---|
290 | }
|
---|
291 |
|
---|
292 | /*!
|
---|
293 | \internal
|
---|
294 | */
|
---|
295 | QString QMetaObject::trUtf8(const char *s, const char *c) const
|
---|
296 | {
|
---|
297 | return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::UnicodeUTF8);
|
---|
298 | }
|
---|
299 |
|
---|
300 | /*!
|
---|
301 | \internal
|
---|
302 | */
|
---|
303 | QString QMetaObject::trUtf8(const char *s, const char *c, int n) const
|
---|
304 | {
|
---|
305 | return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::UnicodeUTF8, n);
|
---|
306 | }
|
---|
307 | #endif // QT_NO_TRANSLATION
|
---|
308 |
|
---|
309 | /*!
|
---|
310 | Returns the method offset for this class; i.e. the index position
|
---|
311 | of this class's first member function.
|
---|
312 |
|
---|
313 | The offset is the sum of all the methods in the class's
|
---|
314 | superclasses (which is always positive since QObject has the
|
---|
315 | deleteLater() slot and a destroyed() signal).
|
---|
316 |
|
---|
317 | \sa method(), methodCount(), indexOfMethod()
|
---|
318 | */
|
---|
319 | int QMetaObject::methodOffset() const
|
---|
320 | {
|
---|
321 | int offset = 0;
|
---|
322 | const QMetaObject *m = d.superdata;
|
---|
323 | while (m) {
|
---|
324 | offset += priv(m->d.data)->methodCount;
|
---|
325 | m = m->d.superdata;
|
---|
326 | }
|
---|
327 | return offset;
|
---|
328 | }
|
---|
329 |
|
---|
330 |
|
---|
331 | /*!
|
---|
332 | Returns the enumerator offset for this class; i.e. the index
|
---|
333 | position of this class's first enumerator.
|
---|
334 |
|
---|
335 | If the class has no superclasses with enumerators, the offset is
|
---|
336 | 0; otherwise the offset is the sum of all the enumerators in the
|
---|
337 | class's superclasses.
|
---|
338 |
|
---|
339 | \sa enumerator(), enumeratorCount(), indexOfEnumerator()
|
---|
340 | */
|
---|
341 | int QMetaObject::enumeratorOffset() const
|
---|
342 | {
|
---|
343 | int offset = 0;
|
---|
344 | const QMetaObject *m = d.superdata;
|
---|
345 | while (m) {
|
---|
346 | offset += priv(m->d.data)->enumeratorCount;
|
---|
347 | m = m->d.superdata;
|
---|
348 | }
|
---|
349 | return offset;
|
---|
350 | }
|
---|
351 |
|
---|
352 | /*!
|
---|
353 | Returns the property offset for this class; i.e. the index
|
---|
354 | position of this class's first property.
|
---|
355 |
|
---|
356 | The offset is the sum of all the properties in the class's
|
---|
357 | superclasses (which is always positive since QObject has the
|
---|
358 | name() property).
|
---|
359 |
|
---|
360 | \sa property(), propertyCount(), indexOfProperty()
|
---|
361 | */
|
---|
362 | int QMetaObject::propertyOffset() const
|
---|
363 | {
|
---|
364 | int offset = 0;
|
---|
365 | const QMetaObject *m = d.superdata;
|
---|
366 | while (m) {
|
---|
367 | offset += priv(m->d.data)->propertyCount;
|
---|
368 | m = m->d.superdata;
|
---|
369 | }
|
---|
370 | return offset;
|
---|
371 | }
|
---|
372 |
|
---|
373 | /*!
|
---|
374 | Returns the class information offset for this class; i.e. the
|
---|
375 | index position of this class's first class information item.
|
---|
376 |
|
---|
377 | If the class has no superclasses with class information, the
|
---|
378 | offset is 0; otherwise the offset is the sum of all the class
|
---|
379 | information items in the class's superclasses.
|
---|
380 |
|
---|
381 | \sa classInfo(), classInfoCount(), indexOfClassInfo()
|
---|
382 | */
|
---|
383 | int QMetaObject::classInfoOffset() const
|
---|
384 | {
|
---|
385 | int offset = 0;
|
---|
386 | const QMetaObject *m = d.superdata;
|
---|
387 | while (m) {
|
---|
388 | offset += priv(m->d.data)->classInfoCount;
|
---|
389 | m = m->d.superdata;
|
---|
390 | }
|
---|
391 | return offset;
|
---|
392 | }
|
---|
393 |
|
---|
394 | /*!
|
---|
395 | \since 4.5
|
---|
396 |
|
---|
397 | Returns the number of constructors in this class.
|
---|
398 |
|
---|
399 | \sa constructor(), indexOfConstructor()
|
---|
400 | */
|
---|
401 | int QMetaObject::constructorCount() const
|
---|
402 | {
|
---|
403 | if (priv(d.data)->revision < 2)
|
---|
404 | return 0;
|
---|
405 | return priv(d.data)->constructorCount;
|
---|
406 | }
|
---|
407 |
|
---|
408 | /*!
|
---|
409 | Returns the number of methods in this class, including the number of
|
---|
410 | properties provided by each base class. These include signals and slots
|
---|
411 | as well as normal member functions.
|
---|
412 |
|
---|
413 | Use code like the following to obtain a QStringList containing the methods
|
---|
414 | specific to a given class:
|
---|
415 |
|
---|
416 | \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp methodCount
|
---|
417 |
|
---|
418 | \sa method(), methodOffset(), indexOfMethod()
|
---|
419 | */
|
---|
420 | int QMetaObject::methodCount() const
|
---|
421 | {
|
---|
422 | int n = priv(d.data)->methodCount;
|
---|
423 | const QMetaObject *m = d.superdata;
|
---|
424 | while (m) {
|
---|
425 | n += priv(m->d.data)->methodCount;
|
---|
426 | m = m->d.superdata;
|
---|
427 | }
|
---|
428 | return n;
|
---|
429 | }
|
---|
430 |
|
---|
431 | /*!
|
---|
432 | Returns the number of enumerators in this class.
|
---|
433 |
|
---|
434 | \sa enumerator(), enumeratorOffset(), indexOfEnumerator()
|
---|
435 | */
|
---|
436 | int QMetaObject::enumeratorCount() const
|
---|
437 | {
|
---|
438 | int n = priv(d.data)->enumeratorCount;
|
---|
439 | const QMetaObject *m = d.superdata;
|
---|
440 | while (m) {
|
---|
441 | n += priv(m->d.data)->enumeratorCount;
|
---|
442 | m = m->d.superdata;
|
---|
443 | }
|
---|
444 | return n;
|
---|
445 | }
|
---|
446 |
|
---|
447 | /*!
|
---|
448 | Returns the number of properties in this class, including the number of
|
---|
449 | properties provided by each base class.
|
---|
450 |
|
---|
451 | Use code like the following to obtain a QStringList containing the properties
|
---|
452 | specific to a given class:
|
---|
453 |
|
---|
454 | \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp propertyCount
|
---|
455 |
|
---|
456 | \sa property(), propertyOffset(), indexOfProperty()
|
---|
457 | */
|
---|
458 | int QMetaObject::propertyCount() const
|
---|
459 | {
|
---|
460 | int n = priv(d.data)->propertyCount;
|
---|
461 | const QMetaObject *m = d.superdata;
|
---|
462 | while (m) {
|
---|
463 | n += priv(m->d.data)->propertyCount;
|
---|
464 | m = m->d.superdata;
|
---|
465 | }
|
---|
466 | return n;
|
---|
467 | }
|
---|
468 |
|
---|
469 | /*!
|
---|
470 | Returns the number of items of class information in this class.
|
---|
471 |
|
---|
472 | \sa classInfo(), classInfoOffset(), indexOfClassInfo()
|
---|
473 | */
|
---|
474 | int QMetaObject::classInfoCount() const
|
---|
475 | {
|
---|
476 | int n = priv(d.data)->classInfoCount;
|
---|
477 | const QMetaObject *m = d.superdata;
|
---|
478 | while (m) {
|
---|
479 | n += priv(m->d.data)->classInfoCount;
|
---|
480 | m = m->d.superdata;
|
---|
481 | }
|
---|
482 | return n;
|
---|
483 | }
|
---|
484 |
|
---|
485 | /*!
|
---|
486 | \since 4.5
|
---|
487 |
|
---|
488 | Finds \a constructor and returns its index; otherwise returns -1.
|
---|
489 |
|
---|
490 | Note that the \a constructor has to be in normalized form, as returned
|
---|
491 | by normalizedSignature().
|
---|
492 |
|
---|
493 | \sa constructor(), constructorCount(), normalizedSignature()
|
---|
494 | */
|
---|
495 | int QMetaObject::indexOfConstructor(const char *constructor) const
|
---|
496 | {
|
---|
497 | if (priv(d.data)->revision < 2)
|
---|
498 | return -1;
|
---|
499 | for (int i = priv(d.data)->constructorCount-1; i >= 0; --i) {
|
---|
500 | if (strcmp(constructor, d.stringdata
|
---|
501 | + d.data[priv(d.data)->constructorData + 5*i]) == 0) {
|
---|
502 | return i;
|
---|
503 | }
|
---|
504 | }
|
---|
505 | return -1;
|
---|
506 | }
|
---|
507 |
|
---|
508 | /*!
|
---|
509 | Finds \a method and returns its index; otherwise returns -1.
|
---|
510 |
|
---|
511 | Note that the \a method has to be in normalized form, as returned
|
---|
512 | by normalizedSignature().
|
---|
513 |
|
---|
514 | \sa method(), methodCount(), methodOffset(), normalizedSignature()
|
---|
515 | */
|
---|
516 | int QMetaObject::indexOfMethod(const char *method) const
|
---|
517 | {
|
---|
518 | int i = -1;
|
---|
519 | const QMetaObject *m = this;
|
---|
520 | while (m && i < 0) {
|
---|
521 | for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
|
---|
522 | if (strcmp(method, m->d.stringdata
|
---|
523 | + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
|
---|
524 | i += m->methodOffset();
|
---|
525 | break;
|
---|
526 | }
|
---|
527 | m = m->d.superdata;
|
---|
528 | }
|
---|
529 | return i;
|
---|
530 | }
|
---|
531 |
|
---|
532 | /*!
|
---|
533 | Finds \a signal and returns its index; otherwise returns -1.
|
---|
534 |
|
---|
535 | This is the same as indexOfMethod(), except that it will return
|
---|
536 | -1 if the method exists but isn't a signal.
|
---|
537 |
|
---|
538 | Note that the \a signal has to be in normalized form, as returned
|
---|
539 | by normalizedSignature().
|
---|
540 |
|
---|
541 | \sa indexOfMethod(), normalizedSignature(), method(), methodCount(), methodOffset()
|
---|
542 | */
|
---|
543 | int QMetaObject::indexOfSignal(const char *signal) const
|
---|
544 | {
|
---|
545 | const QMetaObject *m = this;
|
---|
546 | int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal);
|
---|
547 | if (i >= 0)
|
---|
548 | i += m->methodOffset();
|
---|
549 | return i;
|
---|
550 | }
|
---|
551 |
|
---|
552 | /*! \internal
|
---|
553 | Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object.
|
---|
554 |
|
---|
555 | \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
|
---|
556 | */
|
---|
557 | int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, const char *signal)
|
---|
558 | {
|
---|
559 | int i = -1;
|
---|
560 | while (*baseObject) {
|
---|
561 | const QMetaObject *const m = *baseObject;
|
---|
562 | for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
|
---|
563 | if ((m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodSignal
|
---|
564 | && strcmp(signal, m->d.stringdata
|
---|
565 | + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
|
---|
566 | break;
|
---|
567 | }
|
---|
568 | if (i >= 0)
|
---|
569 | break;
|
---|
570 | *baseObject = m->d.superdata;
|
---|
571 | }
|
---|
572 | #ifndef QT_NO_DEBUG
|
---|
573 | const QMetaObject *m = *baseObject;
|
---|
574 | if (i >= 0 && m && m->d.superdata) {
|
---|
575 | int conflict = m->d.superdata->indexOfMethod(signal);
|
---|
576 | if (conflict >= 0)
|
---|
577 | qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
|
---|
578 | signal, m->d.superdata->d.stringdata, m->d.stringdata);
|
---|
579 | }
|
---|
580 | #endif
|
---|
581 | return i;
|
---|
582 | }
|
---|
583 |
|
---|
584 |
|
---|
585 | /*!
|
---|
586 | Finds \a slot and returns its index; otherwise returns -1.
|
---|
587 |
|
---|
588 | This is the same as indexOfMethod(), except that it will return
|
---|
589 | -1 if the method exists but isn't a slot.
|
---|
590 |
|
---|
591 | \sa indexOfMethod(), method(), methodCount(), methodOffset()
|
---|
592 | */
|
---|
593 | int QMetaObject::indexOfSlot(const char *slot) const
|
---|
594 | {
|
---|
595 | int i = -1;
|
---|
596 | const QMetaObject *m = this;
|
---|
597 | while (m && i < 0) {
|
---|
598 | for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
|
---|
599 | if ((m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodSlot
|
---|
600 | && strcmp(slot, m->d.stringdata
|
---|
601 | + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
|
---|
602 | i += m->methodOffset();
|
---|
603 | break;
|
---|
604 | }
|
---|
605 | m = m->d.superdata;
|
---|
606 | }
|
---|
607 | return i;
|
---|
608 | }
|
---|
609 |
|
---|
610 | static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name)
|
---|
611 | {
|
---|
612 | while (self) {
|
---|
613 | if (strcmp(self->d.stringdata, name) == 0)
|
---|
614 | return self;
|
---|
615 | if (self->d.extradata) {
|
---|
616 | #ifdef Q_NO_DATA_RELOCATION
|
---|
617 | const QMetaObjectAccessor *e;
|
---|
618 | Q_ASSERT(priv(self->d.data)->revision >= 2);
|
---|
619 | #else
|
---|
620 | const QMetaObject **e;
|
---|
621 | if (priv(self->d.data)->revision < 2) {
|
---|
622 | e = (const QMetaObject**)(self->d.extradata);
|
---|
623 | } else
|
---|
624 | #endif
|
---|
625 | {
|
---|
626 | const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(self->d.extradata);
|
---|
627 | e = extra->objects;
|
---|
628 | }
|
---|
629 | if (e) {
|
---|
630 | while (*e) {
|
---|
631 | #ifdef Q_NO_DATA_RELOCATION
|
---|
632 | if (const QMetaObject *m =QMetaObject_findMetaObject(&((*e)()), name))
|
---|
633 | #else
|
---|
634 | if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
|
---|
635 | #endif
|
---|
636 | return m;
|
---|
637 | ++e;
|
---|
638 | }
|
---|
639 | }
|
---|
640 | }
|
---|
641 | self = self->d.superdata;
|
---|
642 | }
|
---|
643 | return self;
|
---|
644 | }
|
---|
645 |
|
---|
646 | /*!
|
---|
647 | Finds enumerator \a name and returns its index; otherwise returns
|
---|
648 | -1.
|
---|
649 |
|
---|
650 | \sa enumerator(), enumeratorCount(), enumeratorOffset()
|
---|
651 | */
|
---|
652 | int QMetaObject::indexOfEnumerator(const char *name) const
|
---|
653 | {
|
---|
654 | int i = -1;
|
---|
655 | const QMetaObject *m = this;
|
---|
656 | while (m && i < 0) {
|
---|
657 | for (i = priv(m->d.data)->enumeratorCount-1; i >= 0; --i)
|
---|
658 | if (strcmp(name, m->d.stringdata
|
---|
659 | + m->d.data[priv(m->d.data)->enumeratorData + 4*i]) == 0) {
|
---|
660 | i += m->enumeratorOffset();
|
---|
661 | break;
|
---|
662 | }
|
---|
663 | m = m->d.superdata;
|
---|
664 | }
|
---|
665 | return i;
|
---|
666 | }
|
---|
667 |
|
---|
668 | /*!
|
---|
669 | Finds property \a name and returns its index; otherwise returns
|
---|
670 | -1.
|
---|
671 |
|
---|
672 | \sa property(), propertyCount(), propertyOffset()
|
---|
673 | */
|
---|
674 | int QMetaObject::indexOfProperty(const char *name) const
|
---|
675 | {
|
---|
676 | int i = -1;
|
---|
677 | const QMetaObject *m = this;
|
---|
678 | while (m && i < 0) {
|
---|
679 | for (i = priv(m->d.data)->propertyCount-1; i >= 0; --i)
|
---|
680 | if (strcmp(name, m->d.stringdata
|
---|
681 | + m->d.data[priv(m->d.data)->propertyData + 3*i]) == 0) {
|
---|
682 | i += m->propertyOffset();
|
---|
683 | break;
|
---|
684 | }
|
---|
685 | m = m->d.superdata;
|
---|
686 | }
|
---|
687 |
|
---|
688 | if (i == -1 && priv(this->d.data)->revision >= 3 && (priv(this->d.data)->flags & DynamicMetaObject)){
|
---|
689 | QAbstractDynamicMetaObject *me =
|
---|
690 | const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this));
|
---|
691 |
|
---|
692 | i = me->createProperty(name, 0);
|
---|
693 | }
|
---|
694 |
|
---|
695 | return i;
|
---|
696 | }
|
---|
697 |
|
---|
698 | /*!
|
---|
699 | Finds class information item \a name and returns its index;
|
---|
700 | otherwise returns -1.
|
---|
701 |
|
---|
702 | \sa classInfo(), classInfoCount(), classInfoOffset()
|
---|
703 | */
|
---|
704 | int QMetaObject::indexOfClassInfo(const char *name) const
|
---|
705 | {
|
---|
706 | int i = -1;
|
---|
707 | const QMetaObject *m = this;
|
---|
708 | while (m && i < 0) {
|
---|
709 | for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i)
|
---|
710 | if (strcmp(name, m->d.stringdata
|
---|
711 | + m->d.data[priv(m->d.data)->classInfoData + 2*i]) == 0) {
|
---|
712 | i += m->classInfoOffset();
|
---|
713 | break;
|
---|
714 | }
|
---|
715 | m = m->d.superdata;
|
---|
716 | }
|
---|
717 | return i;
|
---|
718 | }
|
---|
719 |
|
---|
720 | /*!
|
---|
721 | \since 4.5
|
---|
722 |
|
---|
723 | Returns the meta-data for the constructor with the given \a index.
|
---|
724 |
|
---|
725 | \sa constructorCount(), newInstance()
|
---|
726 | */
|
---|
727 | QMetaMethod QMetaObject::constructor(int index) const
|
---|
728 | {
|
---|
729 | int i = index;
|
---|
730 | QMetaMethod result;
|
---|
731 | if (priv(d.data)->revision >= 2 && i >= 0 && i < priv(d.data)->constructorCount) {
|
---|
732 | result.mobj = this;
|
---|
733 | result.handle = priv(d.data)->constructorData + 5*i;
|
---|
734 | }
|
---|
735 | return result;
|
---|
736 | }
|
---|
737 |
|
---|
738 | /*!
|
---|
739 | Returns the meta-data for the method with the given \a index.
|
---|
740 |
|
---|
741 | \sa methodCount(), methodOffset(), indexOfMethod()
|
---|
742 | */
|
---|
743 | QMetaMethod QMetaObject::method(int index) const
|
---|
744 | {
|
---|
745 | int i = index;
|
---|
746 | i -= methodOffset();
|
---|
747 | if (i < 0 && d.superdata)
|
---|
748 | return d.superdata->method(index);
|
---|
749 |
|
---|
750 | QMetaMethod result;
|
---|
751 | if (i >= 0 && i < priv(d.data)->methodCount) {
|
---|
752 | result.mobj = this;
|
---|
753 | result.handle = priv(d.data)->methodData + 5*i;
|
---|
754 | }
|
---|
755 | return result;
|
---|
756 | }
|
---|
757 |
|
---|
758 | /*!
|
---|
759 | Returns the meta-data for the enumerator with the given \a index.
|
---|
760 |
|
---|
761 | \sa enumeratorCount(), enumeratorOffset(), indexOfEnumerator()
|
---|
762 | */
|
---|
763 | QMetaEnum QMetaObject::enumerator(int index) const
|
---|
764 | {
|
---|
765 | int i = index;
|
---|
766 | i -= enumeratorOffset();
|
---|
767 | if (i < 0 && d.superdata)
|
---|
768 | return d.superdata->enumerator(index);
|
---|
769 |
|
---|
770 | QMetaEnum result;
|
---|
771 | if (i >= 0 && i < priv(d.data)->enumeratorCount) {
|
---|
772 | result.mobj = this;
|
---|
773 | result.handle = priv(d.data)->enumeratorData + 4*i;
|
---|
774 | }
|
---|
775 | return result;
|
---|
776 | }
|
---|
777 |
|
---|
778 | /*!
|
---|
779 | Returns the meta-data for the property with the given \a index.
|
---|
780 | If no such property exists, a null QMetaProperty is returned.
|
---|
781 |
|
---|
782 | \sa propertyCount(), propertyOffset(), indexOfProperty()
|
---|
783 | */
|
---|
784 | QMetaProperty QMetaObject::property(int index) const
|
---|
785 | {
|
---|
786 | int i = index;
|
---|
787 | i -= propertyOffset();
|
---|
788 | if (i < 0 && d.superdata)
|
---|
789 | return d.superdata->property(index);
|
---|
790 |
|
---|
|
---|