Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/kernel/qmetaobject.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||
2 | ** | - | ||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||
4 | ** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> | - | ||||||
5 | ** Contact: https://www.qt.io/licensing/ | - | ||||||
6 | ** | - | ||||||
7 | ** This file is part of the QtCore module of the Qt Toolkit. | - | ||||||
8 | ** | - | ||||||
9 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||
10 | ** Commercial License Usage | - | ||||||
11 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||
12 | ** accordance with the commercial license agreement provided with the | - | ||||||
13 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||
14 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||
15 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||
16 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||
17 | ** | - | ||||||
18 | ** GNU Lesser General Public License Usage | - | ||||||
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||
20 | ** General Public License version 3 as published by the Free Software | - | ||||||
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||
22 | ** packaging of this file. Please review the following information to | - | ||||||
23 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||
25 | ** | - | ||||||
26 | ** GNU General Public License Usage | - | ||||||
27 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||
28 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||
29 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||
30 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||
32 | ** included in the packaging of this file. Please review the following | - | ||||||
33 | ** information to ensure the GNU General Public License requirements will | - | ||||||
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||
36 | ** | - | ||||||
37 | ** $QT_END_LICENSE$ | - | ||||||
38 | ** | - | ||||||
39 | ****************************************************************************/ | - | ||||||
40 | - | |||||||
41 | #include "qmetaobject.h" | - | ||||||
42 | #include "qmetatype.h" | - | ||||||
43 | #include "qobject.h" | - | ||||||
44 | #include "qmetaobject_p.h" | - | ||||||
45 | - | |||||||
46 | #include <qcoreapplication.h> | - | ||||||
47 | #include <qcoreevent.h> | - | ||||||
48 | #include <qdatastream.h> | - | ||||||
49 | #include <qstringlist.h> | - | ||||||
50 | #include <qthread.h> | - | ||||||
51 | #include <qvariant.h> | - | ||||||
52 | #include <qdebug.h> | - | ||||||
53 | #include <qsemaphore.h> | - | ||||||
54 | - | |||||||
55 | #include "private/qobject_p.h" | - | ||||||
56 | #include "private/qmetaobject_p.h" | - | ||||||
57 | - | |||||||
58 | // for normalizeTypeInternal | - | ||||||
59 | #include "private/qmetaobject_moc_p.h" | - | ||||||
60 | - | |||||||
61 | #include <ctype.h> | - | ||||||
62 | - | |||||||
63 | QT_BEGIN_NAMESPACE | - | ||||||
64 | - | |||||||
65 | /*! | - | ||||||
66 | \class QMetaObject | - | ||||||
67 | \inmodule QtCore | - | ||||||
68 | - | |||||||
69 | \brief The QMetaObject class contains meta-information about Qt | - | ||||||
70 | objects. | - | ||||||
71 | - | |||||||
72 | \ingroup objectmodel | - | ||||||
73 | - | |||||||
74 | The Qt \l{Meta-Object System} in Qt is responsible for the | - | ||||||
75 | signals and slots inter-object communication mechanism, runtime | - | ||||||
76 | type information, and the Qt property system. A single | - | ||||||
77 | QMetaObject instance is created for each QObject subclass that is | - | ||||||
78 | used in an application, and this instance stores all the | - | ||||||
79 | meta-information for the QObject subclass. This object is | - | ||||||
80 | available as QObject::metaObject(). | - | ||||||
81 | - | |||||||
82 | This class is not normally required for application programming, | - | ||||||
83 | but it is useful if you write meta-applications, such as scripting | - | ||||||
84 | engines or GUI builders. | - | ||||||
85 | - | |||||||
86 | The functions you are most likely to find useful are these: | - | ||||||
87 | \list | - | ||||||
88 | \li className() returns the name of a class. | - | ||||||
89 | \li superClass() returns the superclass's meta-object. | - | ||||||
90 | \li method() and methodCount() provide information | - | ||||||
91 | about a class's meta-methods (signals, slots and other | - | ||||||
92 | \l{Q_INVOKABLE}{invokable} member functions). | - | ||||||
93 | \li enumerator() and enumeratorCount() and provide information about | - | ||||||
94 | a class's enumerators. | - | ||||||
95 | \li propertyCount() and property() provide information about a | - | ||||||
96 | class's properties. | - | ||||||
97 | \li constructor() and constructorCount() provide information | - | ||||||
98 | about a class's meta-constructors. | - | ||||||
99 | \endlist | - | ||||||
100 | - | |||||||
101 | The index functions indexOfConstructor(), indexOfMethod(), | - | ||||||
102 | indexOfEnumerator(), and indexOfProperty() map names of constructors, | - | ||||||
103 | member functions, enumerators, or properties to indexes in the | - | ||||||
104 | meta-object. For example, Qt uses indexOfMethod() internally when you | - | ||||||
105 | connect a signal to a slot. | - | ||||||
106 | - | |||||||
107 | Classes can also have a list of \e{name}--\e{value} pairs of | - | ||||||
108 | additional class information, stored in QMetaClassInfo objects. | - | ||||||
109 | The number of pairs is returned by classInfoCount(), single pairs | - | ||||||
110 | are returned by classInfo(), and you can search for pairs with | - | ||||||
111 | indexOfClassInfo(). | - | ||||||
112 | - | |||||||
113 | \sa QMetaClassInfo, QMetaEnum, QMetaMethod, QMetaProperty, QMetaType, | - | ||||||
114 | {Meta-Object System} | - | ||||||
115 | */ | - | ||||||
116 | - | |||||||
117 | /*! | - | ||||||
118 | \enum QMetaObject::Call | - | ||||||
119 | - | |||||||
120 | \internal | - | ||||||
121 | - | |||||||
122 | \value InvokeSlot | - | ||||||
123 | \value EmitSignal | - | ||||||
124 | \value ReadProperty | - | ||||||
125 | \value WriteProperty | - | ||||||
126 | \value ResetProperty | - | ||||||
127 | \value QueryPropertyDesignable | - | ||||||
128 | \value QueryPropertyScriptable | - | ||||||
129 | \value QueryPropertyStored | - | ||||||
130 | \value QueryPropertyEditable | - | ||||||
131 | \value QueryPropertyUser | - | ||||||
132 | \value CreateInstance | - | ||||||
133 | */ | - | ||||||
134 | - | |||||||
135 | /*! | - | ||||||
136 | \enum QMetaMethod::Access | - | ||||||
137 | - | |||||||
138 | This enum describes the access level of a method, following the conventions used in C++. | - | ||||||
139 | - | |||||||
140 | \value Private | - | ||||||
141 | \value Protected | - | ||||||
142 | \value Public | - | ||||||
143 | */ | - | ||||||
144 | - | |||||||
145 | static inline const QMetaObjectPrivate *priv(const uint* data) | - | ||||||
146 | { return reinterpret_cast<const QMetaObjectPrivate*>(data); } | - | ||||||
147 | - | |||||||
148 | static inline const QByteArray stringData(const QMetaObject *mo, int index) | - | ||||||
149 | { | - | ||||||
150 | Q_ASSERT(priv(mo->d.data)->revision >= 7); | - | ||||||
151 | const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) }; | - | ||||||
152 | Q_ASSERT(data.ptr->ref.isStatic()); | - | ||||||
153 | Q_ASSERT(data.ptr->alloc == 0); | - | ||||||
154 | Q_ASSERT(data.ptr->capacityReserved == 0); | - | ||||||
155 | Q_ASSERT(data.ptr->size >= 0); | - | ||||||
156 | return data; | - | ||||||
157 | } | - | ||||||
158 | - | |||||||
159 | static inline const char *rawStringData(const QMetaObject *mo, int index) | - | ||||||
160 | { | - | ||||||
161 | return stringData(mo, index).data(); | - | ||||||
162 | } | - | ||||||
163 | - | |||||||
164 | static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo) | - | ||||||
165 | { | - | ||||||
166 | if (typeInfo & IsUnresolvedType) { | - | ||||||
167 | return stringData(mo, typeInfo & TypeNameIndexMask); | - | ||||||
168 | } else { | - | ||||||
169 | // ### Use the QMetaType::typeName() that returns QByteArray | - | ||||||
170 | const char *t = QMetaType::typeName(typeInfo); | - | ||||||
171 | return QByteArray::fromRawData(t, qstrlen(t)); | - | ||||||
172 | } | - | ||||||
173 | } | - | ||||||
174 | - | |||||||
175 | static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo) | - | ||||||
176 | { | - | ||||||
177 | return typeNameFromTypeInfo(mo, typeInfo).constData(); | - | ||||||
178 | } | - | ||||||
179 | - | |||||||
180 | static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo) | - | ||||||
181 | { | - | ||||||
182 | if (!(typeInfo & IsUnresolvedType)) | - | ||||||
183 | return typeInfo; | - | ||||||
184 | return QMetaType::type(stringData(mo, typeInfo & TypeNameIndexMask)); | - | ||||||
185 | } | - | ||||||
186 | - | |||||||
187 | class QMetaMethodPrivate : public QMetaMethod | - | ||||||
188 | { | - | ||||||
189 | public: | - | ||||||
190 | static const QMetaMethodPrivate *get(const QMetaMethod *q) | - | ||||||
191 | { return static_cast<const QMetaMethodPrivate *>(q); } | - | ||||||
192 | - | |||||||
193 | inline QByteArray signature() const; | - | ||||||
194 | inline QByteArray name() const; | - | ||||||
195 | inline int typesDataIndex() const; | - | ||||||
196 | inline const char *rawReturnTypeName() const; | - | ||||||
197 | inline int returnType() const; | - | ||||||
198 | inline int parameterCount() const; | - | ||||||
199 | inline int parametersDataIndex() const; | - | ||||||
200 | inline uint parameterTypeInfo(int index) const; | - | ||||||
201 | inline int parameterType(int index) const; | - | ||||||
202 | inline void getParameterTypes(int *types) const; | - | ||||||
203 | inline QList<QByteArray> parameterTypes() const; | - | ||||||
204 | inline QList<QByteArray> parameterNames() const; | - | ||||||
205 | inline QByteArray tag() const; | - | ||||||
206 | inline int ownMethodIndex() const; | - | ||||||
207 | - | |||||||
208 | private: | - | ||||||
209 | QMetaMethodPrivate(); | - | ||||||
210 | }; | - | ||||||
211 | - | |||||||
212 | /*! | - | ||||||
213 | \since 4.5 | - | ||||||
214 | - | |||||||
215 | Constructs a new instance of this class. You can pass up to ten arguments | - | ||||||
216 | (\a val0, \a val1, \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, | - | ||||||
217 | \a val8, and \a val9) to the constructor. Returns the new object, or 0 if | - | ||||||
218 | no suitable constructor is available. | - | ||||||
219 | - | |||||||
220 | Note that only constructors that are declared with the Q_INVOKABLE | - | ||||||
221 | modifier are made available through the meta-object system. | - | ||||||
222 | - | |||||||
223 | \sa Q_ARG(), constructor() | - | ||||||
224 | */ | - | ||||||
225 | QObject *QMetaObject::newInstance(QGenericArgument val0, | - | ||||||
226 | QGenericArgument val1, | - | ||||||
227 | QGenericArgument val2, | - | ||||||
228 | QGenericArgument val3, | - | ||||||
229 | QGenericArgument val4, | - | ||||||
230 | QGenericArgument val5, | - | ||||||
231 | QGenericArgument val6, | - | ||||||
232 | QGenericArgument val7, | - | ||||||
233 | QGenericArgument val8, | - | ||||||
234 | QGenericArgument val9) const | - | ||||||
235 | { | - | ||||||
236 | QByteArray constructorName = className(); | - | ||||||
237 | { | - | ||||||
238 | int idx = constructorName.lastIndexOf(':'); | - | ||||||
239 | if (idx != -1) | - | ||||||
240 | constructorName.remove(0, idx+1); // remove qualified part | - | ||||||
241 | } | - | ||||||
242 | QVarLengthArray<char, 512> sig; | - | ||||||
243 | sig.append(constructorName.constData(), constructorName.length()); | - | ||||||
244 | sig.append('('); | - | ||||||
245 | - | |||||||
246 | enum { MaximumParamCount = 10 }; | - | ||||||
247 | const char *typeNames[] = {val0.name(), val1.name(), val2.name(), val3.name(), val4.name(), | - | ||||||
248 | val5.name(), val6.name(), val7.name(), val8.name(), val9.name()}; | - | ||||||
249 | - | |||||||
250 | int paramCount; | - | ||||||
251 | for (paramCount = 0; paramCount < MaximumParamCount; ++paramCount) { | - | ||||||
252 | int len = qstrlen(typeNames[paramCount]); | - | ||||||
253 | if (len <= 0) | - | ||||||
254 | break; | - | ||||||
255 | sig.append(typeNames[paramCount], len); | - | ||||||
256 | sig.append(','); | - | ||||||
257 | } | - | ||||||
258 | if (paramCount == 0) | - | ||||||
259 | sig.append(')'); // no parameters | - | ||||||
260 | else | - | ||||||
261 | sig[sig.size() - 1] = ')'; | - | ||||||
262 | sig.append('\0'); | - | ||||||
263 | - | |||||||
264 | int idx = indexOfConstructor(sig.constData()); | - | ||||||
265 | if (idx < 0) { | - | ||||||
266 | QByteArray norm = QMetaObject::normalizedSignature(sig.constData()); | - | ||||||
267 | idx = indexOfConstructor(norm.constData()); | - | ||||||
268 | } | - | ||||||
269 | if (idx < 0) | - | ||||||
270 | return 0; | - | ||||||
271 | - | |||||||
272 | QObject *returnValue = 0; | - | ||||||
273 | void *param[] = {&returnValue, val0.data(), val1.data(), val2.data(), val3.data(), val4.data(), | - | ||||||
274 | val5.data(), val6.data(), val7.data(), val8.data(), val9.data()}; | - | ||||||
275 | - | |||||||
276 | if (static_metacall(CreateInstance, idx, param) >= 0) | - | ||||||
277 | return 0; | - | ||||||
278 | return returnValue; | - | ||||||
279 | } | - | ||||||
280 | - | |||||||
281 | /*! | - | ||||||
282 | \internal | - | ||||||
283 | */ | - | ||||||
284 | int QMetaObject::static_metacall(Call cl, int idx, void **argv) const | - | ||||||
285 | { | - | ||||||
286 | Q_ASSERT(priv(d.data)->revision >= 6); | - | ||||||
287 | if (!d.static_metacall) | - | ||||||
288 | return 0; | - | ||||||
289 | d.static_metacall(0, cl, idx, argv); | - | ||||||
290 | return -1; | - | ||||||
291 | } | - | ||||||
292 | - | |||||||
293 | /*! | - | ||||||
294 | \internal | - | ||||||
295 | */ | - | ||||||
296 | int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv) | - | ||||||
297 | { | - | ||||||
298 | if (object->d_ptr->metaObject) | - | ||||||
299 | return object->d_ptr->metaObject->metaCall(object, cl, idx, argv); | - | ||||||
300 | else | - | ||||||
301 | return object->qt_metacall(cl, idx, argv); | - | ||||||
302 | } | - | ||||||
303 | - | |||||||
304 | static inline const char *objectClassName(const QMetaObject *m) | - | ||||||
305 | { | - | ||||||
306 | return rawStringData(m, priv(m->d.data)->className); | - | ||||||
307 | } | - | ||||||
308 | - | |||||||
309 | /*! | - | ||||||
310 | Returns the class name. | - | ||||||
311 | - | |||||||
312 | \sa superClass() | - | ||||||
313 | */ | - | ||||||
314 | const char *QMetaObject::className() const | - | ||||||
315 | { | - | ||||||
316 | return objectClassName(this); | - | ||||||
317 | } | - | ||||||
318 | - | |||||||
319 | /*! | - | ||||||
320 | \fn QMetaObject *QMetaObject::superClass() const | - | ||||||
321 | - | |||||||
322 | Returns the meta-object of the superclass, or 0 if there is no | - | ||||||
323 | such object. | - | ||||||
324 | - | |||||||
325 | \sa className() | - | ||||||
326 | */ | - | ||||||
327 | - | |||||||
QObject */*! | ||||||||
329 | Returns \c true if the class described by this QMetaObject inherits | - | ||||||
330 | the type described by \a metaObject; otherwise returns false. | - | ||||||
331 | - | |||||||
332 | A type is considered to inherit itself. | - | ||||||
333 | - | |||||||
334 | \since 5.7 | - | ||||||
335 | */ | - | ||||||
336 | bool QMetaObject::castinherits(QObjectconst QMetaObject *objmetaObject) const { | - | ||||||
if (obj)Q_DECL_NOEXCEPT | ||||||||
337 | { | - | ||||||
338 | const QMetaObject *m = obj->metaObject();this; | - | ||||||
339 | do { | - | ||||||
340 | if (mmetaObject == thism)
| 10998745-11516969 | ||||||
341 | return objtrue; executed 10998745 times by 545 tests: return true; Executed by:
| 10998745 | ||||||
342 | } while ((m = m->d.superdata)); executed 11516969 times by 264 tests: end of block Executed by:
| 1036800-11516969 | ||||||
343 | }return 0false; executed 1036800 times by 215 tests: return false; Executed by:
| 1036800 | ||||||
344 | } | - | ||||||
345 | - | |||||||
346 | /*! | - | ||||||
347 | \internal | - | ||||||
348 | - | |||||||
349 | Returns \a obj if object \a obj inherits from this | - | ||||||
350 | meta-object; otherwise returns 0. | - | ||||||
351 | */ | - | ||||||
constQObject *QMetaObject::cast(constQObject *obj) const | ||||||||
353 | { | - | ||||||
354 | if// ### Qt 6: inline | - | ||||||
355 | executed 12063925 times by 655 tests: return const_cast<QObject*>(cast(const_cast<const QObject*>(obj) {)));return const_cast<QObject*>(cast(const_cast<const QObject*>(obj))); Executed by:
executed 12063925 times by 655 tests: return const_cast<QObject*>(cast(const_cast<const QObject*>(obj))); Executed by:
| 12063925 | ||||||
356 | } | - | ||||||
357 | - | |||||||
358 | /*! | - | ||||||
359 | \internal | - | ||||||
360 | - | |||||||
361 | Returns \a obj if object \a obj inherits from this | - | ||||||
362 | meta-object; otherwise returns 0. | - | ||||||
363 | */ | - | ||||||
364 | const QObject *QMetaObject::cast(const QObject *m =obj) const | - | ||||||
365 | { | - | ||||||
366 | return (obj && executed 12338177 times by 655 tests: obj->metaObject();return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| 12338177 | ||||||
do { executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
if executed 12338177 times by 655 tests: ()->inherits(m ==this)return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
return executed 12338177 times by 655 tests: )) ? obj ;return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
} while ((m = m->d.superdata)); executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
} executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
return 0 executed 12338177 times by 655 tests: : nullptr;return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
executed 12338177 times by 655 tests: return (obj && obj->metaObject()->inherits(this)) ? obj : nullptr; Executed by:
| ||||||||
367 | } | - | ||||||
368 | - | |||||||
369 | #ifndef QT_NO_TRANSLATION | - | ||||||
370 | /*! | - | ||||||
371 | \internal | - | ||||||
372 | */ | - | ||||||
373 | QString QMetaObject::tr(const char *s, const char *c, int n) const | - | ||||||
374 | { | - | ||||||
375 | return QCoreApplication::translate(objectClassName(this), s, c, n); | - | ||||||
376 | } | - | ||||||
377 | #endif // QT_NO_TRANSLATION | - | ||||||
378 | - | |||||||
379 | /*! | - | ||||||
380 | Returns the method offset for this class; i.e. the index position | - | ||||||
381 | of this class's first member function. | - | ||||||
382 | - | |||||||
383 | The offset is the sum of all the methods in the class's | - | ||||||
384 | superclasses (which is always positive since QObject has the | - | ||||||
385 | deleteLater() slot and a destroyed() signal). | - | ||||||
386 | - | |||||||
387 | \sa method(), methodCount(), indexOfMethod() | - | ||||||
388 | */ | - | ||||||
389 | int QMetaObject::methodOffset() const | - | ||||||
390 | { | - | ||||||
391 | int offset = 0; | - | ||||||
392 | const QMetaObject *m = d.superdata; | - | ||||||
393 | while (m) { | - | ||||||
394 | offset += priv(m->d.data)->methodCount; | - | ||||||
395 | m = m->d.superdata; | - | ||||||
396 | } | - | ||||||
397 | return offset; | - | ||||||
398 | } | - | ||||||
399 | - | |||||||
400 | - | |||||||
401 | /*! | - | ||||||
402 | Returns the enumerator offset for this class; i.e. the index | - | ||||||
403 | position of this class's first enumerator. | - | ||||||
404 | - | |||||||
405 | If the class has no superclasses with enumerators, the offset is | - | ||||||
406 | 0; otherwise the offset is the sum of all the enumerators in the | - | ||||||
407 | class's superclasses. | - | ||||||
408 | - | |||||||
409 | \sa enumerator(), enumeratorCount(), indexOfEnumerator() | - | ||||||
410 | */ | - | ||||||
411 | int QMetaObject::enumeratorOffset() const | - | ||||||
412 | { | - | ||||||
413 | int offset = 0; | - | ||||||
414 | const QMetaObject *m = d.superdata; | - | ||||||
415 | while (m) { | - | ||||||
416 | offset += priv(m->d.data)->enumeratorCount; | - | ||||||
417 | m = m->d.superdata; | - | ||||||
418 | } | - | ||||||
419 | return offset; | - | ||||||
420 | } | - | ||||||
421 | - | |||||||
422 | /*! | - | ||||||
423 | Returns the property offset for this class; i.e. the index | - | ||||||
424 | position of this class's first property. | - | ||||||
425 | - | |||||||
426 | The offset is the sum of all the properties in the class's | - | ||||||
427 | superclasses (which is always positive since QObject has the | - | ||||||
428 | name() property). | - | ||||||
429 | - | |||||||
430 | \sa property(), propertyCount(), indexOfProperty() | - | ||||||
431 | */ | - | ||||||
432 | int QMetaObject::propertyOffset() const | - | ||||||
433 | { | - | ||||||
434 | int offset = 0; | - | ||||||
435 | const QMetaObject *m = d.superdata; | - | ||||||
436 | while (m) { | - | ||||||
437 | offset += priv(m->d.data)->propertyCount; | - | ||||||
438 | m = m->d.superdata; | - | ||||||
439 | } | - | ||||||
440 | return offset; | - | ||||||
441 | } | - | ||||||
442 | - | |||||||
443 | /*! | - | ||||||
444 | Returns the class information offset for this class; i.e. the | - | ||||||
445 | index position of this class's first class information item. | - | ||||||
446 | - | |||||||
447 | If the class has no superclasses with class information, the | - | ||||||
448 | offset is 0; otherwise the offset is the sum of all the class | - | ||||||
449 | information items in the class's superclasses. | - | ||||||
450 | - | |||||||
451 | \sa classInfo(), classInfoCount(), indexOfClassInfo() | - | ||||||
452 | */ | - | ||||||
453 | int QMetaObject::classInfoOffset() const | - | ||||||
454 | { | - | ||||||
455 | int offset = 0; | - | ||||||
456 | const QMetaObject *m = d.superdata; | - | ||||||
457 | while (m) { | - | ||||||
458 | offset += priv(m->d.data)->classInfoCount; | - | ||||||
459 | m = m->d.superdata; | - | ||||||
460 | } | - | ||||||
461 | return offset; | - | ||||||
462 | } | - | ||||||
463 | - | |||||||
464 | /*! | - | ||||||
465 | \since 4.5 | - | ||||||
466 | - | |||||||
467 | Returns the number of constructors in this class. | - | ||||||
468 | - | |||||||
469 | \sa constructor(), indexOfConstructor() | - | ||||||
470 | */ | - | ||||||
471 | int QMetaObject::constructorCount() const | - | ||||||
472 | { | - | ||||||
473 | Q_ASSERT(priv(d.data)->revision >= 2); | - | ||||||
474 | return priv(d.data)->constructorCount; | - | ||||||
475 | } | - | ||||||
476 | - | |||||||
477 | /*! | - | ||||||
478 | Returns the number of methods in this class, including the number of | - | ||||||
479 | methods provided by each base class. These include signals and slots | - | ||||||
480 | as well as normal member functions. | - | ||||||
481 | - | |||||||
482 | Use code like the following to obtain a QStringList containing the methods | - | ||||||
483 | specific to a given class: | - | ||||||
484 | - | |||||||
485 | \snippet code/src_corelib_kernel_qmetaobject.cpp methodCount | - | ||||||
486 | - | |||||||
487 | \sa method(), methodOffset(), indexOfMethod() | - | ||||||
488 | */ | - | ||||||
489 | int QMetaObject::methodCount() const | - | ||||||
490 | { | - | ||||||
491 | int n = priv(d.data)->methodCount; | - | ||||||
492 | const QMetaObject *m = d.superdata; | - | ||||||
493 | while (m) { | - | ||||||
494 | n += priv(m->d.data)->methodCount; | - | ||||||
495 | m = m->d.superdata; | - | ||||||
496 | } | - | ||||||
497 | return n; | - | ||||||
498 | } | - | ||||||
499 | - | |||||||
500 | /*! | - | ||||||
501 | Returns the number of enumerators in this class. | - | ||||||
502 | - | |||||||
503 | \sa enumerator(), enumeratorOffset(), indexOfEnumerator() | - | ||||||
504 | */ | - | ||||||
505 | int QMetaObject::enumeratorCount() const | - | ||||||
506 | { | - | ||||||
507 | int n = priv(d.data)->enumeratorCount; | - | ||||||
508 | const QMetaObject *m = d.superdata; | - | ||||||
509 | while (m) { | - | ||||||
510 | n += priv(m->d.data)->enumeratorCount; | - | ||||||
511 | m = m->d.superdata; | - | ||||||
512 | } | - | ||||||
513 | return n; | - | ||||||
514 | } | - | ||||||
515 | - | |||||||
516 | /*! | - | ||||||
517 | Returns the number of properties in this class, including the number of | - | ||||||
518 | properties provided by each base class. | - | ||||||
519 | - | |||||||
520 | Use code like the following to obtain a QStringList containing the properties | - | ||||||
521 | specific to a given class: | - | ||||||
522 | - | |||||||
523 | \snippet code/src_corelib_kernel_qmetaobject.cpp propertyCount | - | ||||||
524 | - | |||||||
525 | \sa property(), propertyOffset(), indexOfProperty() | - | ||||||
526 | */ | - | ||||||
527 | int QMetaObject::propertyCount() const | - | ||||||
528 | { | - | ||||||
529 | int n = priv(d.data)->propertyCount; | - | ||||||
530 | const QMetaObject *m = d.superdata; | - | ||||||
531 | while (m) { | - | ||||||
532 | n += priv(m->d.data)->propertyCount; | - | ||||||
533 | m = m->d.superdata; | - | ||||||
534 | } | - | ||||||
535 | return n; | - | ||||||
536 | } | - | ||||||
537 | - | |||||||
538 | /*! | - | ||||||
539 | Returns the number of items of class information in this class. | - | ||||||
540 | - | |||||||
541 | \sa classInfo(), classInfoOffset(), indexOfClassInfo() | - | ||||||
542 | */ | - | ||||||
543 | int QMetaObject::classInfoCount() const | - | ||||||
544 | { | - | ||||||
545 | int n = priv(d.data)->classInfoCount; | - | ||||||
546 | const QMetaObject *m = d.superdata; | - | ||||||
547 | while (m) { | - | ||||||
548 | n += priv(m->d.data)->classInfoCount; | - | ||||||
549 | m = m->d.superdata; | - | ||||||
550 | } | - | ||||||
551 | return n; | - | ||||||
552 | } | - | ||||||
553 | - | |||||||
554 | // Returns \c true if the method defined by the given meta-object&handle | - | ||||||
555 | // matches the given name, argument count and argument types, otherwise | - | ||||||
556 | // returns \c false. | - | ||||||
557 | static bool methodMatch(const QMetaObject *m, int handle, | - | ||||||
558 | const QByteArray &name, int argc, | - | ||||||
559 | const QArgumentType *types) | - | ||||||
560 | { | - | ||||||
561 | Q_ASSERT(priv(m->d.data)->revision >= 7); | - | ||||||
562 | if (int(m->d.data[handle + 1]) != argc) | - | ||||||
563 | return false; | - | ||||||
564 | - | |||||||
565 | if (stringData(m, m->d.data[handle]) != name) | - | ||||||
566 | return false; | - | ||||||
567 | - | |||||||
568 | int paramsIndex = m->d.data[handle + 2] + 1; | - | ||||||
569 | for (int i = 0; i < argc; ++i) { | - | ||||||
570 | uint typeInfo = m->d.data[paramsIndex + i]; | - | ||||||
571 | if (types[i].type()) { | - | ||||||
572 | if (types[i].type() != typeFromTypeInfo(m, typeInfo)) | - | ||||||
573 | return false; | - | ||||||
574 | } else { | - | ||||||
575 | if (types[i].name() != typeNameFromTypeInfo(m, typeInfo)) | - | ||||||
576 | return false; | - | ||||||
577 | } | - | ||||||
578 | } | - | ||||||
579 | - | |||||||
580 | return true; | - | ||||||
581 | } | - | ||||||
582 | - | |||||||
583 | /** | - | ||||||
584 | * \internal | - | ||||||
585 | * helper function for indexOf{Method,Slot,Signal}, returns the relative index of the method within | - | ||||||
586 | * the baseObject | - | ||||||
587 | * \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything. | - | ||||||
588 | */ | - | ||||||
589 | template<int MethodType> | - | ||||||
590 | static inline int indexOfMethodRelative(const QMetaObject **baseObject, | - | ||||||
591 | const QByteArray &name, int argc, | - | ||||||
592 | const QArgumentType *types) | - | ||||||
593 | { | - | ||||||
594 | for (const QMetaObject *m = *baseObject; m; m = m->d.superdata) { | - | ||||||
595 | Q_ASSERT(priv(m->d.data)->revision >= 7); | - | ||||||
596 | int i = (MethodType == MethodSignal) | - | ||||||
597 | ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1); | - | ||||||
598 | const int end = (MethodType == MethodSlot) | - | ||||||
599 | ? (priv(m->d.data)->signalCount) : 0; | - | ||||||
600 | - | |||||||
601 | for (; i >= end; --i) { | - | ||||||
602 | int handle = priv(m->d.data)->methodData + 5*i; | - | ||||||
603 | if (methodMatch(m, handle, name, argc, types)) { | - | ||||||
604 | *baseObject = m; | - | ||||||
605 | return i; | - | ||||||
606 | } | - | ||||||
607 | } | - | ||||||
608 | } | - | ||||||
609 | return -1; | - | ||||||
610 | } | - | ||||||
611 | - | |||||||
612 | - | |||||||
613 | /*! | - | ||||||
614 | \since 4.5 | - | ||||||
615 | - | |||||||
616 | Finds \a constructor and returns its index; otherwise returns -1. | - | ||||||
617 | - | |||||||
618 | Note that the \a constructor has to be in normalized form, as returned | - | ||||||
619 | by normalizedSignature(). | - | ||||||
620 | - | |||||||
621 | \sa constructor(), constructorCount(), normalizedSignature() | - | ||||||
622 | */ | - | ||||||
623 | int QMetaObject::indexOfConstructor(const char *constructor) const | - | ||||||
624 | { | - | ||||||
625 | Q_ASSERT(priv(d.data)->revision >= 7); | - | ||||||
626 | QArgumentTypeArray types; | - | ||||||
627 | QByteArray name = QMetaObjectPrivate::decodeMethodSignature(constructor, types); | - | ||||||
628 | return QMetaObjectPrivate::indexOfConstructor(this, name, types.size(), types.constData()); | - | ||||||
629 | } | - | ||||||
630 | - | |||||||
631 | /*! | - | ||||||
632 | Finds \a method and returns its index; otherwise returns -1. | - | ||||||
633 | - | |||||||
634 | Note that the \a method has to be in normalized form, as returned | - | ||||||
635 | by normalizedSignature(). | - | ||||||
636 | - | |||||||
637 | \sa method(), methodCount(), methodOffset(), normalizedSignature() | - | ||||||
638 | */ | - | ||||||
639 | int QMetaObject::indexOfMethod(const char *method) const | - | ||||||
640 | { | - | ||||||
641 | const QMetaObject *m = this; | - | ||||||
642 | int i; | - | ||||||
643 | Q_ASSERT(priv(m->d.data)->revision >= 7); | - | ||||||
644 | QArgumentTypeArray types; | - | ||||||
645 | QByteArray name = QMetaObjectPrivate::decodeMethodSignature(method, types); | - | ||||||
646 | i = indexOfMethodRelative<0>(&m, name, types.size(), types.constData()); | - | ||||||
647 | if (i >= 0) | - | ||||||
648 | i += m->methodOffset(); | - | ||||||
649 | return i; | - | ||||||
650 | } | - | ||||||
651 | - | |||||||
652 | // Parses a string of comma-separated types into QArgumentTypes. | - | ||||||
653 | // No normalization of the type names is performed. | - | ||||||
654 | static void argumentTypesFromString(const char *str, const char *end, | - | ||||||
655 | QArgumentTypeArray &types) | - | ||||||
656 | { | - | ||||||
657 | Q_ASSERT(str <= end); | - | ||||||
658 | while (str != end) { | - | ||||||
659 | if (!types.isEmpty()) | - | ||||||
660 | ++str; // Skip comma | - | ||||||
661 | const char *begin = str; | - | ||||||
662 | int level = 0; | - | ||||||
663 | while (str != end && (level > 0 || *str != ',')) { | - | ||||||
664 | if (*str == '<') | - | ||||||
665 | ++level; | - | ||||||
666 | else if (*str == '>') | - | ||||||
667 | --level; | - | ||||||
668 | ++str; | - | ||||||
669 | } | - | ||||||
670 | types += QArgumentType(QByteArray(begin, str - begin)); | - | ||||||
671 | } | - | ||||||
672 | } | - | ||||||
673 | - | |||||||
674 | // Given a method \a signature (e.g. "foo(int,double)"), this function | - | ||||||
675 | // populates the argument \a types array and returns the method name. | - | ||||||
676 | QByteArray QMetaObjectPrivate::decodeMethodSignature( | - | ||||||
677 | const char *signature, QArgumentTypeArray &types) | - | ||||||
678 | { | - | ||||||
679 | Q_ASSERT(signature != 0); | - | ||||||
680 | const char *lparens = strchr(signature, '('); | - | ||||||
681 | if (!lparens) | - | ||||||
682 | return QByteArray(); | - | ||||||
683 | const char *rparens = strrchr(lparens + 1, ')'); | - | ||||||
684 | if (!rparens || *(rparens+1)) | - | ||||||
685 | return QByteArray(); | - | ||||||
686 | int nameLength = lparens - signature; | - | ||||||
687 | argumentTypesFromString(lparens + 1, rparens, types); | - | ||||||
688 | return QByteArray::fromRawData(signature, nameLength); | - | ||||||
689 | } | - | ||||||
690 | - | |||||||
691 | /*! | - | ||||||
692 | Finds \a signal and returns its index; otherwise returns -1. | - | ||||||
693 | - | |||||||
694 | This is the same as indexOfMethod(), except that it will return | - | ||||||
695 | -1 if the method exists but isn't a signal. | - | ||||||
696 | - | |||||||
697 | Note that the \a signal has to be in normalized form, as returned | - | ||||||
698 | by normalizedSignature(). | - | ||||||
699 | - | |||||||
700 | \sa indexOfMethod(), normalizedSignature(), method(), methodCount(), methodOffset() | - | ||||||
701 | */ | - | ||||||
702 | int QMetaObject::indexOfSignal(const char *signal) const | - | ||||||
703 | { | - | ||||||
704 | const QMetaObject *m = this; | - | ||||||
705 | int i; | - | ||||||
706 | Q_ASSERT(priv(m->d.data)->revision >= 7); | - | ||||||
707 | QArgumentTypeArray types; | - | ||||||
708 | QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signal, types); | - | ||||||
709 | i = QMetaObjectPrivate::indexOfSignalRelative(&m, name, types.size(), types.constData()); | - | ||||||
710 | if (i >= 0) | - | ||||||
711 | i += m->methodOffset(); | - | ||||||
712 | return i; | - | ||||||
713 | } | - | ||||||
714 | - | |||||||
715 | /*! | - | ||||||
716 | \internal | - | ||||||
717 | Same as QMetaObject::indexOfSignal, but the result is the local offset to the base object. | - | ||||||
718 | - | |||||||
719 | \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found | - | ||||||
720 | */ | - | ||||||
721 | int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, | - | ||||||
722 | const QByteArray &name, int argc, | - | ||||||
723 | const QArgumentType *types) | - | ||||||
724 | { | - | ||||||
725 | int i = indexOfMethodRelative<MethodSignal>(baseObject, name, argc, types); | - | ||||||
726 | #ifndef QT_NO_DEBUG | - | ||||||
727 | const QMetaObject *m = *baseObject; | - | ||||||
728 | if (i >= 0 && m && m->d.superdata) { | - | ||||||
729 | int conflict = indexOfMethod(m->d.superdata, name, argc, types); | - | ||||||
730 | if (conflict >= 0) { | - | ||||||
731 | QMetaMethod conflictMethod = m->d.superdata->method(conflict); | - | ||||||
732 | qWarning("QMetaObject::indexOfSignal: signal %s from %s redefined in %s", | - | ||||||
733 | conflictMethod.methodSignature().constData(), | - | ||||||
734 | objectClassName(m->d.superdata), objectClassName(m)); | - | ||||||
735 | } | - | ||||||
736 | } | - | ||||||
737 | #endif | - | ||||||
738 | return i; | - | ||||||
739 | } | - | ||||||
740 | - | |||||||
741 | /*! | - | ||||||
742 | Finds \a slot and returns its index; otherwise returns -1. | - | ||||||
743 | - | |||||||
744 | This is the same as indexOfMethod(), except that it will return | - | ||||||
745 | -1 if the method exists but isn't a slot. | - | ||||||
746 | - | |||||||
747 | \sa indexOfMethod(), method(), methodCount(), methodOffset() | - | ||||||
748 | */ | - | ||||||
749 | int QMetaObject::indexOfSlot(const char *slot) const | - | ||||||
750 | { | - | ||||||
751 | const QMetaObject *m = this; | - | ||||||
752 | int i; | - | ||||||
753 | Q_ASSERT(priv(m->d.data)->revision >= 7); | - | ||||||
754 | QArgumentTypeArray types; | - | ||||||
755 | QByteArray name = QMetaObjectPrivate::decodeMethodSignature(slot, types); | - | ||||||
756 | i = QMetaObjectPrivate::indexOfSlotRelative(&m, name, types.size(), types.constData()); | - | ||||||
757 | if (i >= 0) | - | ||||||
758 | i += m->methodOffset(); | - | ||||||
759 | return i; | - | ||||||
760 | } | - | ||||||
761 | - | |||||||
762 | // same as indexOfSignalRelative but for slots. | - | ||||||
763 | int QMetaObjectPrivate::indexOfSlotRelative(const QMetaObject **m, | - | ||||||
764 | const QByteArray &name, int argc, | - | ||||||
765 | const QArgumentType *types) | - | ||||||
766 | { | - | ||||||
767 | return indexOfMethodRelative<MethodSlot>(m, name, argc, types); | - | ||||||
768 | } | - | ||||||
769 | - | |||||||
770 | int QMetaObjectPrivate::indexOfSignal(const QMetaObject *m, const QByteArray &name, | - | ||||||
771 | int argc, const QArgumentType *types) | - | ||||||
772 | { | - | ||||||
773 | int i = indexOfSignalRelative(&m, name, argc, types); | - | ||||||
774 | if (i >= 0) | - | ||||||
775 | i += m->methodOffset(); | - | ||||||
776 | return i; | - | ||||||
777 | } | - | ||||||
778 | - | |||||||
779 | int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m, const QByteArray &name, | - | ||||||
780 | int argc, const QArgumentType *types) | - | ||||||
781 | { | - | ||||||
782 | int i = indexOfSlotRelative(&m, name, argc, types); | - | ||||||
783 | if (i >= 0) | - | ||||||
784 | i += m->methodOffset(); | - | ||||||
785 | return i; | - | ||||||
786 | } | - | ||||||
787 | - | |||||||
788 | int QMetaObjectPrivate::indexOfMethod(const QMetaObject *m, const QByteArray &name, | - | ||||||
789 | int argc, const QArgumentType *types) | - | ||||||
790 | { | - | ||||||
791 | int i = indexOfMethodRelative<0>(&m, name, argc, types); | - | ||||||
792 | if (i >= 0) | - | ||||||
793 | i += m->methodOffset(); | - | ||||||
794 | return i; | - | ||||||
795 | } | - | ||||||
796 | - | |||||||
797 | int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArray &name, | - | ||||||
798 | int argc, const QArgumentType *types) | - | ||||||
799 | { | - | ||||||
800 | for (int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) { | - | ||||||
801 | int handle = priv(m->d.data)->constructorData + 5*i; | - | ||||||
802 | if (methodMatch(m, handle, name, argc, types)) | - | ||||||
803 | return i; | - | ||||||
804 | } | - | ||||||
805 | return -1; | - | ||||||
806 | } | - | ||||||
807 | - | |||||||
808 | /*! | - | ||||||
809 | \internal | - | ||||||
810 | \since 5.0 | - | ||||||
811 | - | |||||||
812 | Returns the signal offset for the class \a m; i.e., the index position | - | ||||||
813 | of the class's first signal. | - | ||||||
814 | - | |||||||
815 | Similar to QMetaObject::methodOffset(), but non-signal methods are | - | ||||||
816 | excluded. | - | ||||||
817 | */ | - | ||||||
818 | int QMetaObjectPrivate::signalOffset(const QMetaObject *m) | - | ||||||
819 | { | - | ||||||
820 | Q_ASSERT(m != 0); | - | ||||||
821 | int offset = 0; | - | ||||||
822 | for (m = m->d.superdata; m; m = m->d.superdata) | - | ||||||
823 | offset += priv(m->d.data)->signalCount; | - | ||||||
824 | return offset; | - | ||||||
825 | } | - | ||||||
826 | - | |||||||
827 | /*! | - | ||||||
828 | \internal | - | ||||||
829 | \since 5.0 | - | ||||||
830 | - | |||||||
831 | Returns the number of signals for the class \a m, including the signals | - | ||||||
832 | for the base class. | - | ||||||
833 | - | |||||||
834 | Similar to QMetaObject::methodCount(), but non-signal methods are | - | ||||||
835 | excluded. | - | ||||||
836 | */ | - | ||||||
837 | int QMetaObjectPrivate::absoluteSignalCount(const QMetaObject *m) | - | ||||||
838 | { | - | ||||||
839 | Q_ASSERT(m != 0); | - | ||||||
840 | int n = priv(m->d.data)->signalCount; | - | ||||||
841 | for (m = m->d.superdata; m; m = m->d.superdata) | - | ||||||
842 | n += priv(m->d.data)->signalCount; | - | ||||||
843 | return n; | - | ||||||
844 | } | - | ||||||
845 | - | |||||||
846 | /*! | - | ||||||
847 | \internal | - | ||||||
848 | \since 5.0 | - | ||||||
849 | - | |||||||
850 | Returns the index of the signal method \a m. | - | ||||||
851 | - | |||||||
852 | Similar to QMetaMethod::methodIndex(), but non-signal methods are | - | ||||||
853 | excluded. | - | ||||||
854 | */ | - | ||||||
855 | int QMetaObjectPrivate::signalIndex(const QMetaMethod &m) | - | ||||||
856 | { | - | ||||||
857 | if (!m.mobj) | - | ||||||
858 | return -1; | - | ||||||
859 | return QMetaMethodPrivate::get(&m)->ownMethodIndex() + signalOffset(m.mobj); | - | ||||||
860 | } | - | ||||||
861 | - | |||||||
862 | /*! | - | ||||||
863 | \internal | - | ||||||
864 | \since 5.0 | - | ||||||
865 | - | |||||||
866 | Returns the signal for the given meta-object \a m at \a signal_index. | - | ||||||
867 | - | |||||||
868 | It it different from QMetaObject::method(); the index should not include | - | ||||||
869 | non-signal methods. | - | ||||||
870 | */ | - | ||||||
871 | QMetaMethod QMetaObjectPrivate::signal(const QMetaObject *m, int signal_index) | - | ||||||
872 | { | - | ||||||
873 | QMetaMethod result; | - | ||||||
874 | if (signal_index < 0) | - | ||||||
875 | return result; | - | ||||||
876 | Q_ASSERT(m != 0); | - | ||||||
877 | int i = signal_index; | - | ||||||
878 | i -= signalOffset(m); | - | ||||||
879 | if (i < 0 && m->d.superdata) | - | ||||||
880 | return signal(m->d.superdata, signal_index); | - | ||||||
881 | - | |||||||
882 | if (i >= 0 && i < priv(m->d.data)->signalCount) { | - | ||||||
883 | result.mobj = m; | - | ||||||
884 | result.handle = priv(m->d.data)->methodData + 5*i; | - | ||||||
885 | } | - | ||||||
886 | return result; | - | ||||||
887 | } | - | ||||||
888 | - | |||||||
889 | /*! | - | ||||||
890 | \internal | - | ||||||
891 | - | |||||||
892 | Returns \c true if the \a signalTypes and \a methodTypes are | - | ||||||
893 | compatible; otherwise returns \c false. | - | ||||||
894 | */ | - | ||||||
895 | bool QMetaObjectPrivate::checkConnectArgs(int signalArgc, const QArgumentType *signalTypes, | - | ||||||
896 | int methodArgc, const QArgumentType *methodTypes) | - | ||||||
897 | { | - | ||||||
898 | if (signalArgc < methodArgc) | - | ||||||
899 | return false; | - | ||||||
900 | for (int i = 0; i < methodArgc; ++i) { | - | ||||||
901 | if (signalTypes[i] != methodTypes[i]) | - | ||||||
902 | return false; | - | ||||||
903 | } | - | ||||||
904 | return true; | - | ||||||
905 | } | - | ||||||
906 | - | |||||||
907 | /*! | - | ||||||
908 | \internal | - | ||||||
909 | - | |||||||
910 | Returns \c true if the \a signal and \a method arguments are | - | ||||||
911 | compatible; otherwise returns \c false. | - | ||||||
912 | */ | - | ||||||
913 | bool QMetaObjectPrivate::checkConnectArgs(const QMetaMethodPrivate *signal, | - | ||||||
914 | const QMetaMethodPrivate *method) | - | ||||||
915 | { | - | ||||||
916 | if (signal->methodType() != QMetaMethod::Signal) | - | ||||||
917 | return false; | - | ||||||
918 | if (signal->parameterCount() < method->parameterCount()) | - | ||||||
919 | return false; | - | ||||||
920 | const QMetaObject *smeta = signal->enclosingMetaObject(); | - | ||||||
921 | const QMetaObject *rmeta = method->enclosingMetaObject(); | - | ||||||
922 | for (int i = 0; i < method->parameterCount(); ++i) { | - | ||||||
923 | uint sourceTypeInfo = signal->parameterTypeInfo(i); | - | ||||||
924 | uint targetTypeInfo = method->parameterTypeInfo(i); | - | ||||||
925 | if ((sourceTypeInfo & IsUnresolvedType) | - | ||||||
926 | || (targetTypeInfo & IsUnresolvedType)) { | - | ||||||
927 | QByteArray sourceName = typeNameFromTypeInfo(smeta, sourceTypeInfo); | - | ||||||
928 | QByteArray targetName = typeNameFromTypeInfo(rmeta, targetTypeInfo); | - | ||||||
929 | if (sourceName != targetName) | - | ||||||
930 | return false; | - | ||||||
931 | } else { | - | ||||||
932 | int sourceType = typeFromTypeInfo(smeta, sourceTypeInfo); | - | ||||||
933 | int targetType = typeFromTypeInfo(rmeta, targetTypeInfo); | - | ||||||
934 | if (sourceType != targetType) | - | ||||||
935 | return false; | - | ||||||
936 | } | - | ||||||
937 | } | - | ||||||
938 | return true; | - | ||||||
939 | } | - | ||||||
940 | - | |||||||
941 | static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, const char *name) | - | ||||||
942 | { | - | ||||||
943 | while (self) { | - | ||||||
944 | if (strcmp(objectClassName(self), name) == 0) | - | ||||||
945 | return self; | - | ||||||
946 | if (self->d.relatedMetaObjects) { | - | ||||||
947 | Q_ASSERT(priv(self->d.data)->revision >= 2); | - | ||||||
948 | const QMetaObject * const *e = self->d.relatedMetaObjects; | - | ||||||
949 | if (e) { | - | ||||||
950 | while (*e) { | - | ||||||
951 | if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name)) | - | ||||||
952 | return m; | - | ||||||
953 | ++e; | - | ||||||
954 | } | - | ||||||
955 | } | - | ||||||
956 | } | - | ||||||
957 | self = self->d.superdata; | - | ||||||
958 | } | - | ||||||
959 | return self; | - | ||||||
960 | } | - | ||||||
961 | - | |||||||
962 | /*! | - | ||||||
963 | Finds enumerator \a name and returns its index; otherwise returns | - | ||||||
964 | -1. | - | ||||||
965 | - | |||||||
966 | \sa enumerator(), enumeratorCount(), enumeratorOffset() | - | ||||||
967 | */ | - | ||||||
968 | int QMetaObject::indexOfEnumerator(const char *name) const | - | ||||||
969 | { | - | ||||||
970 | const QMetaObject *m = this; | - | ||||||
971 | while (m) { | - | ||||||
972 | const QMetaObjectPrivate *d = priv(m->d.data); | - | ||||||
973 | for (int i = d->enumeratorCount - 1; i >= 0; --i) { | - | ||||||
974 | const char *prop = rawStringData(m, m->d.data[d->enumeratorData + 4*i]); | - | ||||||
975 | if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { | - | ||||||
976 | i += m->enumeratorOffset(); | - | ||||||
977 | return i; | - | ||||||
978 | } | - | ||||||
979 | } | - | ||||||
980 | m = m->d.superdata; | - | ||||||
981 | } | - | ||||||
982 | return -1; | - | ||||||
983 | } | - | ||||||
984 | - | |||||||
985 | /*! | - | ||||||
986 | Finds property \a name and returns its index; otherwise returns | - | ||||||
987 | -1. | - | ||||||
988 | - | |||||||
989 | \sa property(), propertyCount(), propertyOffset() | - | ||||||
990 | */ | - | ||||||
991 | int QMetaObject::indexOfProperty(const char *name) const | - | ||||||
992 | { | - | ||||||
993 | const QMetaObject *m = this; | - | ||||||
994 | while (m) { | - | ||||||
995 | const QMetaObjectPrivate *d = priv(m->d.data); | - | ||||||
996 | for (int i = d->propertyCount-1; i >= 0; --i) { | - | ||||||
997 | const char *prop = rawStringData(m, m->d.data[d->propertyData + 3*i]); | - | ||||||
998 | if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { | - | ||||||
999 | i += m->propertyOffset(); | - | ||||||
1000 | return i; | - | ||||||
1001 | } | - | ||||||
1002 | } | - | ||||||
1003 | m = m->d.superdata; | - | ||||||
1004 | } | - | ||||||
1005 | - | |||||||
1006 | Q_ASSERT(priv(this->d.data)->revision >= 3); | - | ||||||
1007 | if (priv(this->d.data)->flags & DynamicMetaObject) { | - | ||||||
1008 | QAbstractDynamicMetaObject *me = | - | ||||||
1009 | const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this)); | - | ||||||
1010 | - | |||||||
1011 | return me->createProperty(name, 0); | - | ||||||
1012 | } | - | ||||||
1013 | - | |||||||
1014 | return -1; | - | ||||||
1015 | } | - | ||||||
1016 | - | |||||||
1017 | /*! | - | ||||||
1018 | Finds class information item \a name and returns its index; | - | ||||||
1019 | otherwise returns -1. | - | ||||||
1020 | - | |||||||
1021 | \sa classInfo(), classInfoCount(), classInfoOffset() | - | ||||||
1022 | */ | - | ||||||
1023 | int QMetaObject::indexOfClassInfo(const char *name) const | - | ||||||
1024 | { | - | ||||||
1025 | int i = -1; | - | ||||||
1026 | const QMetaObject *m = this; | - | ||||||
1027 | while (m && i < 0) { | - | ||||||
1028 | for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i) | - | ||||||
1029 | if (strcmp(name, rawStringData(m, m->d.data[priv(m->d.data)->classInfoData + 2*i])) == 0) { | - | ||||||
1030 | i += m->classInfoOffset(); | - | ||||||
1031 | break; | - | ||||||
1032 | } | - | ||||||
1033 | m = m->d.superdata; | - | ||||||
1034 | } | - | ||||||
1035 | return i; | - | ||||||
1036 | } | - | ||||||
1037 | - | |||||||
1038 | /*! | - | ||||||
1039 | \since 4.5 | - | ||||||
1040 | - | |||||||
1041 | Returns the meta-data for the constructor with the given \a index. | - | ||||||
1042 | - | |||||||
1043 | \sa constructorCount(), newInstance() | - | ||||||
1044 | */ | - | ||||||
1045 | QMetaMethod QMetaObject::constructor(int index) const | - | ||||||
1046 | { | - | ||||||
1047 | int i = index; | - | ||||||
1048 | QMetaMethod result; | - | ||||||
1049 | Q_ASSERT(priv(d.data)->revision >= 2); | - | ||||||
1050 | if (i >= 0 && i < priv(d.data)->constructorCount) { | - | ||||||
1051 | result.mobj = this; | - | ||||||
1052 | result.handle = priv(d.data)->constructorData + 5*i; | - | ||||||
1053 | } | - | ||||||
1054 | return result; | - | ||||||
1055 | } | - | ||||||
1056 | - | |||||||
1057 | /*! | - | ||||||
1058 | Returns the meta-data for the method with the given \a index. | - | ||||||
1059 | - | |||||||
1060 | \sa methodCount(), methodOffset(), indexOfMethod() | - | ||||||
1061 | */ | - | ||||||
1062 | QMetaMethod QMetaObject::method(int index) const | - | ||||||
1063 | { | - | ||||||
1064 | int i = index; | - | ||||||
1065 | i -= methodOffset(); | - | ||||||
1066 | if (i < 0 && d.superdata) | - | ||||||
1067 | return d.superdata->method(index); | - | ||||||
1068 | - | |||||||
1069 | QMetaMethod result; | - | ||||||
1070 | if (i >= 0 && i < priv(d.data)->methodCount) { | - | ||||||
1071 | result.mobj = this; | - | ||||||
1072 | result.handle = priv(d.data)->methodData + 5*i; | - | ||||||
1073 | } | - | ||||||
1074 | return result; | - | ||||||
1075 | } | - | ||||||
1076 | - | |||||||
1077 | /*! | - | ||||||
1078 | Returns the meta-data for the enumerator with the given \a index. | - | ||||||
1079 | - | |||||||
1080 | \sa enumeratorCount(), enumeratorOffset(), indexOfEnumerator() | - | ||||||
1081 | */ | - | ||||||
1082 | QMetaEnum QMetaObject::enumerator(int index) const | - | ||||||
1083 | { | - | ||||||
1084 | int i = index; | - | ||||||
1085 | i -= enumeratorOffset(); | - | ||||||
1086 | if (i < 0 && d.superdata) | - | ||||||
1087 | return d.superdata->enumerator(index); | - | ||||||
1088 | - | |||||||
1089 | QMetaEnum result; | - | ||||||
1090 | if (i >= 0 && i < priv(d.data)->enumeratorCount) { | - | ||||||
1091 | result.mobj = this; | - | ||||||
1092 | result.handle = priv(d.data)->enumeratorData + 4*i; | - | ||||||
1093 | } | - | ||||||
1094 | return result; | - | ||||||
1095 | } | - | ||||||
1096 | - | |||||||
1097 | /*! | - | ||||||
1098 | Returns the meta-data for the property with the given \a index. | - | ||||||
1099 | If no such property exists, a null QMetaProperty is returned. | - | ||||||
1100 | - | |||||||
1101 | \sa propertyCount(), propertyOffset(), indexOfProperty() | - | ||||||
1102 | */ | - | ||||||
1103 | QMetaProperty QMetaObject::property(int index) const | - | ||||||
1104 | { | - | ||||||
1105 | int i = index; | - | ||||||
1106 | i -= propertyOffset(); | - | ||||||
1107 | if (i < 0 && d.superdata) | - | ||||||
1108 | return d.superdata->property(index); | - | ||||||
1109 | - | |||||||
1110 | QMetaProperty result; | - | ||||||
1111 | if (i >= 0 && i < priv(d.data)->propertyCount) { | - | ||||||
1112 | int handle = priv(d.data)->propertyData + 3*i; | - | ||||||
1113 | int flags = d.data[handle + 2]; | - | ||||||
1114 | result.mobj = this; | - | ||||||
1115 | result.handle = handle; | - | ||||||
1116 | result.idx = i; | - | ||||||
1117 | - | |||||||
1118 | if (flags & EnumOrFlag) { | - | ||||||
1119 | const char *type = rawTypeNameFromTypeInfo(this, d.data[handle + 1]); | - | ||||||
1120 | result.menum = enumerator(indexOfEnumerator(type)); | - | ||||||
1121 | if (!result.menum.isValid()) { | - | ||||||
1122 | const char *enum_name = type; | - | ||||||
1123 | const char *scope_name = objectClassName(this); | - | ||||||
1124 | char *scope_buffer = 0; | - | ||||||
1125 | - | |||||||
1126 | const char *colon = strrchr(enum_name, ':'); | - | ||||||
1127 | // ':' will always appear in pairs | - | ||||||
1128 | Q_ASSERT(colon <= enum_name || *(colon-1) == ':'); | - | ||||||
1129 | if (colon > enum_name) { | - | ||||||
1130 | int len = colon-enum_name-1; | - | ||||||
1131 | scope_buffer = (char *)malloc(len+1); | - | ||||||
1132 | memcpy(scope_buffer, enum_name, len); | - | ||||||
1133 | scope_buffer[len] = '\0'; | - | ||||||
1134 | scope_name = scope_buffer; | - | ||||||
1135 | enum_name = colon+1; | - | ||||||
1136 | } | - | ||||||
1137 | - | |||||||
1138 | const QMetaObject *scope = 0; | - | ||||||
1139 | if (qstrcmp(scope_name, "Qt") == 0) | - | ||||||
1140 | scope = &QObject::staticQtMetaObject; | - | ||||||
1141 | else | - | ||||||
1142 | scope = QMetaObject_findMetaObject(this, scope_name); | - | ||||||
1143 | if (scope) | - | ||||||
1144 | result.menum = scope->enumerator(scope->indexOfEnumerator(enum_name)); | - | ||||||
1145 | if (scope_buffer) | - | ||||||
1146 | free(scope_buffer); | - | ||||||
1147 | } | - | ||||||
1148 | } | - | ||||||
1149 | } | - | ||||||
1150 | return result; | - | ||||||
1151 | } | - | ||||||
1152 | - | |||||||
1153 | /*! | - | ||||||
1154 | \since 4.2 | - | ||||||
1155 | - | |||||||
1156 | Returns the property that has the \c USER flag set to true. | - | ||||||
1157 | - | |||||||
1158 | \sa QMetaProperty::isUser() | - | ||||||
1159 | */ | - | ||||||
1160 | QMetaProperty QMetaObject::userProperty() const | - | ||||||
1161 | { | - | ||||||
1162 | const int propCount = propertyCount(); | - | ||||||
1163 | for (int i = propCount - 1; i >= 0; --i) { | - | ||||||
1164 | const QMetaProperty prop = property(i); | - | ||||||
1165 | if (prop.isUser()) | - | ||||||
1166 | return prop; | - | ||||||
1167 | } | - | ||||||
1168 | return QMetaProperty(); | - | ||||||
1169 | } | - | ||||||
1170 | - | |||||||
1171 | /*! | - | ||||||
1172 | Returns the meta-data for the item of class information with the | - | ||||||
1173 | given \a index. | - | ||||||
1174 | - | |||||||
1175 | Example: | - | ||||||
1176 | - | |||||||
1177 | \snippet code/src_corelib_kernel_qmetaobject.cpp 0 | - | ||||||
1178 | - | |||||||
1179 | \sa classInfoCount(), classInfoOffset(), indexOfClassInfo() | - | ||||||
1180 | */ | - | ||||||
1181 | QMetaClassInfo QMetaObject::classInfo(int index) const | - | ||||||
1182 | { | - | ||||||
1183 | int i = index; | - | ||||||
1184 | i -= classInfoOffset(); | - | ||||||
1185 | if (i < 0 && d.superdata) | - | ||||||
1186 | return d.superdata->classInfo(index); | - | ||||||
1187 | - | |||||||
1188 | QMetaClassInfo result; | - | ||||||
1189 | if (i >= 0 && i < priv(d.data)->classInfoCount) { | - | ||||||
1190 | result.mobj = this; | - | ||||||
1191 | result.handle = priv(d.data)->classInfoData + 2*i; | - | ||||||
1192 | } | - | ||||||
1193 | return result; | - | ||||||
1194 | } | - | ||||||
1195 | - | |||||||
1196 | /*! | - | ||||||
1197 | Returns \c true if the \a signal and \a method arguments are | - | ||||||
1198 | compatible; otherwise returns \c false. | - | ||||||
1199 | - | |||||||
1200 | Both \a signal and \a method are expected to be normalized. | - | ||||||
1201 | - | |||||||
1202 | \sa normalizedSignature() | - | ||||||
1203 | */ | - | ||||||
1204 | bool QMetaObject::checkConnectArgs(const char *signal, const char *method) | - | ||||||
1205 | { | - | ||||||
1206 | const char *s1 = signal; | - | ||||||
1207 | const char *s2 = method; | - | ||||||
1208 | while (*s1++ != '(') { } // scan to first '(' | - | ||||||
1209 | while (*s2++ != '(') { } | - | ||||||
1210 | if (*s2 == ')' || qstrcmp(s1,s2) == 0) // method has no args or | - | ||||||
1211 | return true; // exact match | - | ||||||
1212 | int s1len = qstrlen(s1); | - | ||||||
1213 | int s2len = qstrlen(s2); | - | ||||||
1214 | if (s2len < s1len && strncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',') | - | ||||||
1215 | return true; // method has less args | - | ||||||
1216 | return false; | - | ||||||
1217 | } | - | ||||||
1218 | - | |||||||
1219 | /*! | - | ||||||
1220 | \since 5.0 | - | ||||||
1221 | \overload | - | ||||||
1222 | - | |||||||
1223 | Returns \c true if the \a signal and \a method arguments are | - | ||||||
1224 | compatible; otherwise returns \c false. | - | ||||||
1225 | */ | - | ||||||
1226 | bool QMetaObject::checkConnectArgs(const QMetaMethod &signal, | - | ||||||
1227 | const QMetaMethod &method) | - | ||||||
1228 | { | - | ||||||
1229 | return QMetaObjectPrivate::checkConnectArgs( | - | ||||||
1230 | QMetaMethodPrivate::get(&signal), | - | ||||||
1231 | QMetaMethodPrivate::get(&method)); | - | ||||||
1232 | } | - | ||||||
1233 | - | |||||||
1234 | static void qRemoveWhitespace(const char *s, char *d) | - | ||||||
1235 | { | - | ||||||
1236 | char last = 0; | - | ||||||
1237 | while (*s && is_space(*s)) | - | ||||||
1238 | s++; | - | ||||||
1239 | while (*s) { | - | ||||||
1240 | while (*s && !is_space(*s)) | - | ||||||
1241 | last = *d++ = *s++; | - | ||||||
1242 | while (*s && is_space(*s)) | - | ||||||
1243 | s++; | - | ||||||
1244 | if (*s && ((is_ident_char(*s) && is_ident_char(last)) | - | ||||||
1245 | || ((*s == ':') && (last == '<')))) { | - | ||||||
1246 | last = *d++ = ' '; | - | ||||||
1247 | } | - | ||||||
1248 | } | - | ||||||
1249 | *d = '\0'; | - | ||||||
1250 | } | - | ||||||
1251 | - | |||||||
1252 | static char *qNormalizeType(char *d, int &templdepth, QByteArray &result) | - | ||||||
1253 | { | - | ||||||
1254 | const char *t = d; | - | ||||||
1255 | while (*d && (templdepth | - | ||||||
1256 | || (*d != ',' && *d != ')'))) { | - | ||||||
1257 | if (*d == '<') | - | ||||||
1258 | ++templdepth; | - | ||||||
1259 | if (*d == '>') | - | ||||||
1260 | --templdepth; | - | ||||||
1261 | ++d; | - | ||||||
1262 | } | - | ||||||
1263 | // "void" should only be removed if this is part of a signature that has | - | ||||||
1264 | // an explicit void argument; e.g., "void foo(void)" --> "void foo()" | - | ||||||
1265 | if (strncmp("void)", t, d - t + 1) != 0) | - | ||||||
1266 | result += normalizeTypeInternal(t, d); | - | ||||||
1267 | - | |||||||
1268 | return d; | - | ||||||
1269 | } | - | ||||||
1270 | - | |||||||
1271 | - | |||||||
1272 | /*! | - | ||||||
1273 | \since 4.2 | - | ||||||
1274 | - | |||||||
1275 | Normalizes a \a type. | - | ||||||
1276 | - | |||||||
1277 | See QMetaObject::normalizedSignature() for a description on how | - | ||||||
1278 | Qt normalizes. | - | ||||||
1279 | - | |||||||
1280 | Example: | - | ||||||
1281 | - | |||||||
1282 | \snippet code/src_corelib_kernel_qmetaobject.cpp 1 | - | ||||||
1283 | - | |||||||
1284 | \sa normalizedSignature() | - | ||||||
1285 | */ | - | ||||||
1286 | QByteArray QMetaObject::normalizedType(const char *type) | - | ||||||
1287 | { | - | ||||||
1288 | QByteArray result; | - | ||||||
1289 | - | |||||||
1290 | if (!type || !*type) | - | ||||||
1291 | return result; | - | ||||||
1292 | - | |||||||
1293 | QVarLengthArray<char> stackbuf(qstrlen(type) + 1); | - | ||||||
1294 | qRemoveWhitespace(type, stackbuf.data()); | - | ||||||
1295 | int templdepth = 0; | - | ||||||
1296 | qNormalizeType(stackbuf.data(), templdepth, result); | - | ||||||
1297 | - | |||||||
1298 | return result; | - | ||||||
1299 | } | - | ||||||
1300 | - | |||||||
1301 | /*! | - | ||||||
1302 | Normalizes the signature of the given \a method. | - | ||||||
1303 | - | |||||||
1304 | Qt uses normalized signatures to decide whether two given signals | - | ||||||
1305 | and slots are compatible. Normalization reduces whitespace to a | - | ||||||
1306 | minimum, moves 'const' to the front where appropriate, removes | - | ||||||
1307 | 'const' from value types and replaces const references with | - | ||||||
1308 | values. | - | ||||||
1309 | - | |||||||
1310 | \sa checkConnectArgs(), normalizedType() | - | ||||||
1311 | */ | - | ||||||
1312 | QByteArray QMetaObject::normalizedSignature(const char *method) | - | ||||||
1313 | { | - | ||||||
1314 | QByteArray result; | - | ||||||
1315 | if (!method || !*method) | - | ||||||
1316 | return result; | - | ||||||
1317 | int len = int(strlen(method)); | - | ||||||
1318 | QVarLengthArray<char> stackbuf(len + 1); | - | ||||||
1319 | char *d = stackbuf.data(); | - | ||||||
1320 | qRemoveWhitespace(method, d); | - | ||||||
1321 | - | |||||||
1322 | result.reserve(len); | - | ||||||
1323 | - | |||||||
1324 | int argdepth = 0; | - | ||||||
1325 | int templdepth = 0; | - | ||||||
1326 | while (*d) { | - | ||||||
1327 | if (argdepth == 1) { | - | ||||||
1328 | d = qNormalizeType(d, templdepth, result); | - | ||||||
1329 | if (!*d) //most likely an invalid signature. | - | ||||||
1330 | break; | - | ||||||
1331 | } | - | ||||||
1332 | if (*d == '(') | - | ||||||
1333 | ++argdepth; | - | ||||||
1334 | if (*d == ')') | - | ||||||
1335 | --argdepth; | - | ||||||
1336 | result += *d++; | - | ||||||
1337 | } | - | ||||||
1338 | - | |||||||
1339 | return result; | - | ||||||
1340 | } | - | ||||||
1341 | - | |||||||
1342 | enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value | - | ||||||
1343 | - | |||||||
1344 | /*! | - | ||||||
1345 | Returns the signatures of all methods whose name matches \a nonExistentMember, | - | ||||||
1346 | or an empty QByteArray if there are no matches. | - | ||||||
1347 | */ | - | ||||||
1348 | static inline QByteArray findMethodCandidates(const QMetaObject *metaObject, const char *nonExistentMember) | - | ||||||
1349 | { | - | ||||||
1350 | QByteArray candidateMessage; | - | ||||||
1351 | // Prevent full string comparison in every iteration. | - | ||||||
1352 | const QByteArray memberByteArray = nonExistentMember; | - | ||||||
1353 | for (int i = 0; i < metaObject->methodCount(); ++i) {
| 10-244 | ||||||
1354 | const QMetaMethod method = metaObject->method(i); | - | ||||||
1355 | if (method.name() == memberByteArray)
| 4-240 | ||||||
1356 | candidateMessage .append(+= " " + method.methodSignature() + '\n');; executed 4 times by 1 test: candidateMessage += " " + method.methodSignature() + '\n'; Executed by:
| 4 | ||||||
1357 | } executed 244 times by 2 tests: end of block Executed by:
| 244 | ||||||
1358 | if (!candidateMessage.isEmpty()) {
| 4-6 | ||||||
1359 | candidateMessage.prepend("\nCandidates are:\n"); | - | ||||||
1360 | candidateMessage.chop(1); | - | ||||||
1361 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||
1362 | return candidateMessage; executed 10 times by 2 tests: return candidateMessage; Executed by:
| 10 | ||||||
1363 | } | - | ||||||
1364 | - | |||||||
1365 | /*! | - | ||||||
1366 | Invokes the \a member (a signal or a slot name) on the object \a | - | ||||||
1367 | obj. Returns \c true if the member could be invoked. Returns \c false | - | ||||||
1368 | if there is no such member or the parameters did not match. | - | ||||||
1369 | - | |||||||
1370 | The invocation can be either synchronous or asynchronous, | - | ||||||
1371 | depending on \a type: | - | ||||||
1372 | - | |||||||
1373 | \list | - | ||||||
1374 | \li If \a type is Qt::DirectConnection, the member will be invoked immediately. | - | ||||||
1375 | - | |||||||
1376 | \li If \a type is Qt::QueuedConnection, | - | ||||||
1377 | a QEvent will be sent and the member is invoked as soon as the application | - | ||||||
1378 | enters the main event loop. | - | ||||||
1379 | - | |||||||
1380 | \li If \a type is Qt::BlockingQueuedConnection, the method will be invoked in | - | ||||||
1381 | the same way as for Qt::QueuedConnection, except that the current thread | - | ||||||
1382 | will block until the event is delivered. Using this connection type to | - | ||||||
1383 | communicate between objects in the same thread will lead to deadlocks. | - | ||||||
1384 | - | |||||||
1385 | \li If \a type is Qt::AutoConnection, the member is invoked | - | ||||||
1386 | synchronously if \a obj lives in the same thread as the | - | ||||||
1387 | caller; otherwise it will invoke the member asynchronously. | - | ||||||
1388 | \endlist | - | ||||||
1389 | - | |||||||
1390 | The return value of the \a member function call is placed in \a | - | ||||||
1391 | ret. If the invocation is asynchronous, the return value cannot | - | ||||||
1392 | be evaluated. You can pass up to ten arguments (\a val0, \a val1, | - | ||||||
1393 | \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, \a val8, | - | ||||||
1394 | and \a val9) to the \a member function. | - | ||||||
1395 | - | |||||||
1396 | QGenericArgument and QGenericReturnArgument are internal | - | ||||||
1397 | helper classes. Because signals and slots can be dynamically | - | ||||||
1398 | invoked, you must enclose the arguments using the Q_ARG() and | - | ||||||
1399 | Q_RETURN_ARG() macros. Q_ARG() takes a type name and a | - | ||||||
1400 | const reference of that type; Q_RETURN_ARG() takes a type name | - | ||||||
1401 | and a non-const reference. | - | ||||||
1402 | - | |||||||
1403 | You only need to pass the name of the signal or slot to this function, | - | ||||||
1404 | not the entire signature. For example, to asynchronously invoke | - | ||||||
1405 | the \l{QThread::quit()}{quit()} slot on a | - | ||||||
1406 | QThread, use the following code: | - | ||||||
1407 | - | |||||||
1408 | \snippet code/src_corelib_kernel_qmetaobject.cpp 2 | - | ||||||
1409 | - | |||||||
1410 | With asynchronous method invocations, the parameters must be of | - | ||||||
1411 | types that are known to Qt's meta-object system, because Qt needs | - | ||||||
1412 | to copy the arguments to store them in an event behind the | - | ||||||
1413 | scenes. If you try to use a queued connection and get the error | - | ||||||
1414 | message | - | ||||||
1415 | - | |||||||
1416 | \snippet code/src_corelib_kernel_qmetaobject.cpp 3 | - | ||||||
1417 | - | |||||||
1418 | call qRegisterMetaType() to register the data type before you | - | ||||||
1419 | call invokeMethod(). | - | ||||||
1420 | - | |||||||
1421 | To synchronously invoke the \c compute(QString, int, double) slot on | - | ||||||
1422 | some arbitrary object \c obj retrieve its return value: | - | ||||||
1423 | - | |||||||
1424 | \snippet code/src_corelib_kernel_qmetaobject.cpp 4 | - | ||||||
1425 | - | |||||||
1426 | If the "compute" slot does not take exactly one QString, one int | - | ||||||
1427 | and one double in the specified order, the call will fail. | - | ||||||
1428 | - | |||||||
1429 | \sa Q_ARG(), Q_RETURN_ARG(), qRegisterMetaType(), QMetaMethod::invoke() | - | ||||||
1430 | */ | - | ||||||
1431 | bool QMetaObject::invokeMethod(QObject *obj, | - | ||||||
1432 | const char *member, | - | ||||||
1433 | Qt::ConnectionType type, | - | ||||||
1434 | QGenericReturnArgument ret, | - | ||||||
1435 | QGenericArgument val0, | - | ||||||
1436 | QGenericArgument val1, | - | ||||||
1437 | QGenericArgument val2, | - | ||||||
1438 | QGenericArgument val3, | - | ||||||
1439 | QGenericArgument val4, | - | ||||||
1440 | QGenericArgument val5, | - | ||||||
1441 | QGenericArgument val6, | - | ||||||
1442 | QGenericArgument val7, | - | ||||||
1443 | QGenericArgument val8, | - | ||||||
1444 | QGenericArgument val9) | - | ||||||
1445 | { | - | ||||||
1446 | if (!obj) | - | ||||||
1447 | return false; | - | ||||||
1448 | - | |||||||
1449 | QVarLengthArray<char, 512> sig; | - | ||||||
1450 | int len = qstrlen(member); | - | ||||||
1451 | if (len <= 0) | - | ||||||
1452 | return false; | - | ||||||
1453 | sig.append(member, len); | - | ||||||
1454 | sig.append('('); | - | ||||||
1455 | - | |||||||
1456 | const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(), | - | ||||||
1457 | val4.name(), val5.name(), val6.name(), val7.name(), val8.name(), | - | ||||||
1458 | val9.name()}; | - | ||||||
1459 | - | |||||||
1460 | int paramCount; | - | ||||||
1461 | for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) { | - | ||||||
1462 | len = qstrlen(typeNames[paramCount]); | - | ||||||
1463 | if (len <= 0) | - | ||||||
1464 | break; | - | ||||||
1465 | sig.append(typeNames[paramCount], len); | - | ||||||
1466 | sig.append(','); | - | ||||||
1467 | } | - | ||||||
1468 | if (paramCount == 1) | - | ||||||
1469 | sig.append(')'); // no parameters | - | ||||||
1470 | else | - | ||||||
1471 | sig[sig.size() - 1] = ')'; | - | ||||||
1472 | sig.append('\0'); | - | ||||||
1473 | - | |||||||
1474 | const QMetaObject *meta = obj->metaObject(); | - | ||||||
1475 | int idx = meta->indexOfMethod(sig.constData()); | - | ||||||
1476 | if (idx < 0) { | - | ||||||
1477 | QByteArray norm = QMetaObject::normalizedSignature(sig.constData()); | - | ||||||
1478 | idx = meta->indexOfMethod(norm.constData()); | - | ||||||
1479 | } | - | ||||||
1480 | - | |||||||
1481 | if (idx < 0 || idx >= meta->methodCount()) { | - | ||||||
1482 | // This method doesn't belong to us; print out a nice warning with candidates. | - | ||||||
1483 | qWarning("QMetaObject::invokeMethod: No such method %s::%s%s", | - | ||||||
1484 | meta->className(), sig.constData(), findMethodCandidates(meta, member).constData()); | - | ||||||
1485 | return false; | - | ||||||
1486 | } | - | ||||||
1487 | QMetaMethod method = meta->method(idx); | - | ||||||
1488 | return method.invoke(obj, type, ret, | - | ||||||
1489 | val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); | - | ||||||
1490 | } | - | ||||||
1491 | - | |||||||
1492 | /*! \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member, | - | ||||||
1493 | QGenericReturnArgument ret, | - | ||||||
1494 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
1495 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
1496 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
1497 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
1498 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
1499 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
1500 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
1501 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
1502 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
1503 | QGenericArgument val9 = QGenericArgument()); | - | ||||||
1504 | \overload invokeMethod() | - | ||||||
1505 | - | |||||||
1506 | This overload always invokes the member using the connection type Qt::AutoConnection. | - | ||||||
1507 | */ | - | ||||||
1508 | - | |||||||
1509 | /*! \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member, | - | ||||||
1510 | Qt::ConnectionType type, | - | ||||||
1511 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
1512 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
1513 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
1514 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
1515 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
1516 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
1517 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
1518 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
1519 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
1520 | QGenericArgument val9 = QGenericArgument()) | - | ||||||
1521 | - | |||||||
1522 | \overload invokeMethod() | - | ||||||
1523 | - | |||||||
1524 | This overload can be used if the return value of the member is of no interest. | - | ||||||
1525 | */ | - | ||||||
1526 | - | |||||||
1527 | /*! | - | ||||||
1528 | \fn bool QMetaObject::invokeMethod(QObject *obj, const char *member, | - | ||||||
1529 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
1530 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
1531 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
1532 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
1533 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
1534 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
1535 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
1536 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
1537 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
1538 | QGenericArgument val9 = QGenericArgument()) | - | ||||||
1539 | - | |||||||
1540 | \overload invokeMethod() | - | ||||||
1541 | - | |||||||
1542 | This overload invokes the member using the connection type Qt::AutoConnection and | - | ||||||
1543 | ignores return values. | - | ||||||
1544 | */ | - | ||||||
1545 | - | |||||||
1546 | /*! | - | ||||||
1547 | \fn QMetaObject::Connection::Connection(const Connection &other) | - | ||||||
1548 | - | |||||||
1549 | Constructs a copy of \a other. | - | ||||||
1550 | */ | - | ||||||
1551 | - | |||||||
1552 | /*! | - | ||||||
1553 | \fn QMetaObject::Connection::Connection &operator=(const Connection &other) | - | ||||||
1554 | - | |||||||
1555 | Assigns \a other to this connection and returns a reference to this connection. | - | ||||||
1556 | */ | - | ||||||
1557 | - | |||||||
1558 | /*! | - | ||||||
1559 | \fn QMetaObject::Connection &QMetaObject::Connection::operator=(Connection &&other) | - | ||||||
1560 | - | |||||||
1561 | Move-assigns \a other to this object, and returns a reference. | - | ||||||
1562 | */ | - | ||||||
1563 | /*! | - | ||||||
1564 | \fn QMetaObject::Connection::Connection(Connection &&o) | - | ||||||
1565 | - | |||||||
1566 | Move-constructs a Connection instance, making it point to the same object | - | ||||||
1567 | that \a o was pointing to. | - | ||||||
1568 | */ | - | ||||||
1569 | - | |||||||
1570 | /*! | - | ||||||
1571 | \class QMetaMethod | - | ||||||
1572 | \inmodule QtCore | - | ||||||
1573 | - | |||||||
1574 | \brief The QMetaMethod class provides meta-data about a member | - | ||||||
1575 | function. | - | ||||||
1576 | - | |||||||
1577 | \ingroup objectmodel | - | ||||||
1578 | - | |||||||
1579 | A QMetaMethod has a methodType(), a methodSignature(), a list of | - | ||||||
1580 | parameterTypes() and parameterNames(), a return typeName(), a | - | ||||||
1581 | tag(), and an access() specifier. You can use invoke() to invoke | - | ||||||
1582 | the method on an arbitrary QObject. | - | ||||||
1583 | - | |||||||
1584 | \sa QMetaObject, QMetaEnum, QMetaProperty, {Qt's Property System} | - | ||||||
1585 | */ | - | ||||||
1586 | - | |||||||
1587 | /*! | - | ||||||
1588 | \enum QMetaMethod::Attributes | - | ||||||
1589 | - | |||||||
1590 | \internal | - | ||||||
1591 | - | |||||||
1592 | \value Compatibility | - | ||||||
1593 | \value Cloned | - | ||||||
1594 | \value Scriptable | - | ||||||
1595 | */ | - | ||||||
1596 | - | |||||||
1597 | /*! | - | ||||||
1598 | \fn bool QMetaMethod::isValid() const | - | ||||||
1599 | \since 5.0 | - | ||||||
1600 | - | |||||||
1601 | Returns \c true if this method is valid (can be introspected and | - | ||||||
1602 | invoked), otherwise returns \c false. | - | ||||||
1603 | */ | - | ||||||
1604 | - | |||||||
1605 | /*! \fn bool operator==(const QMetaMethod &m1, const QMetaMethod &m2) | - | ||||||
1606 | \since 5.0 | - | ||||||
1607 | \relates QMetaMethod | - | ||||||
1608 | \overload | - | ||||||
1609 | - | |||||||
1610 | Returns \c true if method \a m1 is equal to method \a m2, | - | ||||||
1611 | otherwise returns \c false. | - | ||||||
1612 | */ | - | ||||||
1613 | - | |||||||
1614 | /*! \fn bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2) | - | ||||||
1615 | \since 5.0 | - | ||||||
1616 | \relates QMetaMethod | - | ||||||
1617 | \overload | - | ||||||
1618 | - | |||||||
1619 | Returns \c true if method \a m1 is not equal to method \a m2, | - | ||||||
1620 | otherwise returns \c false. | - | ||||||
1621 | */ | - | ||||||
1622 | - | |||||||
1623 | /*! | - | ||||||
1624 | \fn const QMetaObject *QMetaMethod::enclosingMetaObject() const | - | ||||||
1625 | \internal | - | ||||||
1626 | */ | - | ||||||
1627 | - | |||||||
1628 | /*! | - | ||||||
1629 | \enum QMetaMethod::MethodType | - | ||||||
1630 | - | |||||||
1631 | \value Method The function is a plain member function. | - | ||||||
1632 | \value Signal The function is a signal. | - | ||||||
1633 | \value Slot The function is a slot. | - | ||||||
1634 | \value Constructor The function is a constructor. | - | ||||||
1635 | */ | - | ||||||
1636 | - | |||||||
1637 | /*! | - | ||||||
1638 | \fn QMetaMethod::QMetaMethod() | - | ||||||
1639 | \internal | - | ||||||
1640 | */ | - | ||||||
1641 | - | |||||||
1642 | /*! | - | ||||||
1643 | \macro Q_METAMETHOD_INVOKE_MAX_ARGS | - | ||||||
1644 | \relates QMetaMethod | - | ||||||
1645 | - | |||||||
1646 | Equals maximum number of arguments available for | - | ||||||
1647 | execution of the method via QMetaMethod::invoke() | - | ||||||
1648 | */ | - | ||||||
1649 | - | |||||||
1650 | QByteArray QMetaMethodPrivate::signature() const | - | ||||||
1651 | { | - | ||||||
1652 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1653 | QByteArray result; | - | ||||||
1654 | result.reserve(256); | - | ||||||
1655 | result += name(); | - | ||||||
1656 | result += '('; | - | ||||||
1657 | QList<QByteArray> argTypes = parameterTypes(); | - | ||||||
1658 | for (int i = 0; i < argTypes.size(); ++i) { | - | ||||||
1659 | if (i) | - | ||||||
1660 | result += ','; | - | ||||||
1661 | result += argTypes.at(i); | - | ||||||
1662 | } | - | ||||||
1663 | result += ')'; | - | ||||||
1664 | return result; | - | ||||||
1665 | } | - | ||||||
1666 | - | |||||||
1667 | QByteArray QMetaMethodPrivate::name() const | - | ||||||
1668 | { | - | ||||||
1669 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1670 | return stringData(mobj, mobj->d.data[handle]); | - | ||||||
1671 | } | - | ||||||
1672 | - | |||||||
1673 | int QMetaMethodPrivate::typesDataIndex() const | - | ||||||
1674 | { | - | ||||||
1675 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1676 | return mobj->d.data[handle + 2]; | - | ||||||
1677 | } | - | ||||||
1678 | - | |||||||
1679 | const char *QMetaMethodPrivate::rawReturnTypeName() const | - | ||||||
1680 | { | - | ||||||
1681 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1682 | uint typeInfo = mobj->d.data[typesDataIndex()]; | - | ||||||
1683 | if (typeInfo & IsUnresolvedType) | - | ||||||
1684 | return rawStringData(mobj, typeInfo & TypeNameIndexMask); | - | ||||||
1685 | else | - | ||||||
1686 | return QMetaType::typeName(typeInfo); | - | ||||||
1687 | } | - | ||||||
1688 | - | |||||||
1689 | int QMetaMethodPrivate::returnType() const | - | ||||||
1690 | { | - | ||||||
1691 | return parameterType(-1); | - | ||||||
1692 | } | - | ||||||
1693 | - | |||||||
1694 | int QMetaMethodPrivate::parameterCount() const | - | ||||||
1695 | { | - | ||||||
1696 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1697 | return mobj->d.data[handle + 1]; | - | ||||||
1698 | } | - | ||||||
1699 | - | |||||||
1700 | int QMetaMethodPrivate::parametersDataIndex() const | - | ||||||
1701 | { | - | ||||||
1702 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1703 | return typesDataIndex() + 1; | - | ||||||
1704 | } | - | ||||||
1705 | - | |||||||
1706 | uint QMetaMethodPrivate::parameterTypeInfo(int index) const | - | ||||||
1707 | { | - | ||||||
1708 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1709 | return mobj->d.data[parametersDataIndex() + index]; | - | ||||||
1710 | } | - | ||||||
1711 | - | |||||||
1712 | int QMetaMethodPrivate::parameterType(int index) const | - | ||||||
1713 | { | - | ||||||
1714 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1715 | return typeFromTypeInfo(mobj, parameterTypeInfo(index)); | - | ||||||
1716 | } | - | ||||||
1717 | - | |||||||
1718 | void QMetaMethodPrivate::getParameterTypes(int *types) const | - | ||||||
1719 | { | - | ||||||
1720 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1721 | int dataIndex = parametersDataIndex(); | - | ||||||
1722 | int argc = parameterCount(); | - | ||||||
1723 | for (int i = 0; i < argc; ++i) { | - | ||||||
1724 | int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]); | - | ||||||
1725 | *(types++) = id; | - | ||||||
1726 | } | - | ||||||
1727 | } | - | ||||||
1728 | - | |||||||
1729 | QList<QByteArray> QMetaMethodPrivate::parameterTypes() const | - | ||||||
1730 | { | - | ||||||
1731 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1732 | int argc = parameterCount(); | - | ||||||
1733 | QList<QByteArray> list; | - | ||||||
1734 | list.reserve(argc); | - | ||||||
1735 | int paramsIndex = parametersDataIndex(); | - | ||||||
1736 | for (int i = 0; i < argc; ++i) | - | ||||||
1737 | list += typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]); | - | ||||||
1738 | return list; | - | ||||||
1739 | } | - | ||||||
1740 | - | |||||||
1741 | QList<QByteArray> QMetaMethodPrivate::parameterNames() const | - | ||||||
1742 | { | - | ||||||
1743 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1744 | int argc = parameterCount(); | - | ||||||
1745 | QList<QByteArray> list; | - | ||||||
1746 | list.reserve(argc); | - | ||||||
1747 | int namesIndex = parametersDataIndex() + argc; | - | ||||||
1748 | for (int i = 0; i < argc; ++i) | - | ||||||
1749 | list += stringData(mobj, mobj->d.data[namesIndex + i]); | - | ||||||
1750 | return list; | - | ||||||
1751 | } | - | ||||||
1752 | - | |||||||
1753 | QByteArray QMetaMethodPrivate::tag() const | - | ||||||
1754 | { | - | ||||||
1755 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
1756 | return stringData(mobj, mobj->d.data[handle + 3]); | - | ||||||
1757 | } | - | ||||||
1758 | - | |||||||
1759 | int QMetaMethodPrivate::ownMethodIndex() const | - | ||||||
1760 | { | - | ||||||
1761 | // recompute the methodIndex by reversing the arithmetic in QMetaObject::property() | - | ||||||
1762 | return (handle - priv(mobj->d.data)->methodData) / 5; | - | ||||||
1763 | } | - | ||||||
1764 | - | |||||||
1765 | /*! | - | ||||||
1766 | \since 5.0 | - | ||||||
1767 | - | |||||||
1768 | Returns the signature of this method (e.g., | - | ||||||
1769 | \c{setValue(double)}). | - | ||||||
1770 | - | |||||||
1771 | \sa parameterTypes(), parameterNames() | - | ||||||
1772 | */ | - | ||||||
1773 | QByteArray QMetaMethod::methodSignature() const | - | ||||||
1774 | { | - | ||||||
1775 | if (!mobj) | - | ||||||
1776 | return QByteArray(); | - | ||||||
1777 | return QMetaMethodPrivate::get(this)->signature(); | - | ||||||
1778 | } | - | ||||||
1779 | - | |||||||
1780 | /*! | - | ||||||
1781 | \since 5.0 | - | ||||||
1782 | - | |||||||
1783 | Returns the name of this method. | - | ||||||
1784 | - | |||||||
1785 | \sa methodSignature(), parameterCount() | - | ||||||
1786 | */ | - | ||||||
1787 | QByteArray QMetaMethod::name() const | - | ||||||
1788 | { | - | ||||||
1789 | if (!mobj) | - | ||||||
1790 | return QByteArray(); | - | ||||||
1791 | return QMetaMethodPrivate::get(this)->name(); | - | ||||||
1792 | } | - | ||||||
1793 | - | |||||||
1794 | /*! | - | ||||||
1795 | \since 5.0 | - | ||||||
1796 | - | |||||||
1797 | Returns the return type of this method. | - | ||||||
1798 | - | |||||||
1799 | The return value is one of the types that are registered | - | ||||||
1800 | with QMetaType, or QMetaType::UnknownType if the type is not registered. | - | ||||||
1801 | - | |||||||
1802 | \sa parameterType(), QMetaType, typeName() | - | ||||||
1803 | */ | - | ||||||
1804 | int QMetaMethod::returnType() const | - | ||||||
1805 | { | - | ||||||
1806 | if (!mobj) | - | ||||||
1807 | return QMetaType::UnknownType; | - | ||||||
1808 | return QMetaMethodPrivate::get(this)->returnType(); | - | ||||||
1809 | } | - | ||||||
1810 | - | |||||||
1811 | /*! | - | ||||||
1812 | \since 5.0 | - | ||||||
1813 | - | |||||||
1814 | Returns the number of parameters of this method. | - | ||||||
1815 | - | |||||||
1816 | \sa parameterType(), parameterNames() | - | ||||||
1817 | */ | - | ||||||
1818 | int QMetaMethod::parameterCount() const | - | ||||||
1819 | { | - | ||||||
1820 | if (!mobj) | - | ||||||
1821 | return 0; | - | ||||||
1822 | return QMetaMethodPrivate::get(this)->parameterCount(); | - | ||||||
1823 | } | - | ||||||
1824 | - | |||||||
1825 | /*! | - | ||||||
1826 | \since 5.0 | - | ||||||
1827 | - | |||||||
1828 | Returns the type of the parameter at the given \a index. | - | ||||||
1829 | - | |||||||
1830 | The return value is one of the types that are registered | - | ||||||
1831 | with QMetaType, or QMetaType::UnknownType if the type is not registered. | - | ||||||
1832 | - | |||||||
1833 | \sa parameterCount(), returnType(), QMetaType | - | ||||||
1834 | */ | - | ||||||
1835 | int QMetaMethod::parameterType(int index) const | - | ||||||
1836 | { | - | ||||||
1837 | if (!mobj || index < 0) | - | ||||||
1838 | return QMetaType::UnknownType; | - | ||||||
1839 | if (index >= QMetaMethodPrivate::get(this)->parameterCount()) | - | ||||||
1840 | return QMetaType::UnknownType; | - | ||||||
1841 | - | |||||||
1842 | int type = QMetaMethodPrivate::get(this)->parameterType(index); | - | ||||||
1843 | if (type != QMetaType::UnknownType) | - | ||||||
1844 | return type; | - | ||||||
1845 | - | |||||||
1846 | void *argv[] = { &type, &index }; | - | ||||||
1847 | mobj->static_metacall(QMetaObject::RegisterMethodArgumentMetaType, QMetaMethodPrivate::get(this)->ownMethodIndex(), argv); | - | ||||||
1848 | if (type != -1) | - | ||||||
1849 | return type; | - | ||||||
1850 | return QMetaType::UnknownType; | - | ||||||
1851 | } | - | ||||||
1852 | - | |||||||
1853 | /*! | - | ||||||
1854 | \since 5.0 | - | ||||||
1855 | \internal | - | ||||||
1856 | - | |||||||
1857 | Gets the parameter \a types of this method. The storage | - | ||||||
1858 | for \a types must be able to hold parameterCount() items. | - | ||||||
1859 | - | |||||||
1860 | \sa parameterCount(), returnType(), parameterType() | - | ||||||
1861 | */ | - | ||||||
1862 | void QMetaMethod::getParameterTypes(int *types) const | - | ||||||
1863 | { | - | ||||||
1864 | if (!mobj) | - | ||||||
1865 | return; | - | ||||||
1866 | QMetaMethodPrivate::get(this)->getParameterTypes(types); | - | ||||||
1867 | } | - | ||||||
1868 | - | |||||||
1869 | /*! | - | ||||||
1870 | Returns a list of parameter types. | - | ||||||
1871 | - | |||||||
1872 | \sa parameterNames(), methodSignature() | - | ||||||
1873 | */ | - | ||||||
1874 | QList<QByteArray> QMetaMethod::parameterTypes() const | - | ||||||
1875 | { | - | ||||||
1876 | if (!mobj) | - | ||||||
1877 | return QList<QByteArray>(); | - | ||||||
1878 | return QMetaMethodPrivate::get(this)->parameterTypes(); | - | ||||||
1879 | } | - | ||||||
1880 | - | |||||||
1881 | /*! | - | ||||||
1882 | Returns a list of parameter names. | - | ||||||
1883 | - | |||||||
1884 | \sa parameterTypes(), methodSignature() | - | ||||||
1885 | */ | - | ||||||
1886 | QList<QByteArray> QMetaMethod::parameterNames() const | - | ||||||
1887 | { | - | ||||||
1888 | QList<QByteArray> list; | - | ||||||
1889 | if (!mobj) | - | ||||||
1890 | return list; | - | ||||||
1891 | return QMetaMethodPrivate::get(this)->parameterNames(); | - | ||||||
1892 | } | - | ||||||
1893 | - | |||||||
1894 | - | |||||||
1895 | /*! | - | ||||||
1896 | Returns the return type name of this method. | - | ||||||
1897 | - | |||||||
1898 | \sa returnType(), QMetaType::type() | - | ||||||
1899 | */ | - | ||||||
1900 | const char *QMetaMethod::typeName() const | - | ||||||
1901 | { | - | ||||||
1902 | if (!mobj) | - | ||||||
1903 | return 0; | - | ||||||
1904 | return QMetaMethodPrivate::get(this)->rawReturnTypeName(); | - | ||||||
1905 | } | - | ||||||
1906 | - | |||||||
1907 | /*! | - | ||||||
1908 | Returns the tag associated with this method. | - | ||||||
1909 | - | |||||||
1910 | Tags are special macros recognized by \c moc that make it | - | ||||||
1911 | possible to add extra information about a method. | - | ||||||
1912 | - | |||||||
1913 | Tag information can be added in the following | - | ||||||
1914 | way in the function declaration: | - | ||||||
1915 | - | |||||||
1916 | \code | - | ||||||
1917 | // In the class MainWindow declaration | - | ||||||
1918 | #ifndef Q_MOC_RUN | - | ||||||
1919 | // define the tag text as empty, so the compiler doesn't see it | - | ||||||
1920 | # define MY_CUSTOM_TAG | - | ||||||
1921 | #endif | - | ||||||
1922 | ... | - | ||||||
1923 | private slots: | - | ||||||
1924 | MY_CUSTOM_TAG void testFunc(); | - | ||||||
1925 | \endcode | - | ||||||
1926 | - | |||||||
1927 | and the information can be accessed by using: | - | ||||||
1928 | - | |||||||
1929 | \code | - | ||||||
1930 | MainWindow win; | - | ||||||
1931 | win.show(); | - | ||||||
1932 | - | |||||||
1933 | int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); | - | ||||||
1934 | QMetaMethod mm = win.metaObject()->method(functionIndex); | - | ||||||
1935 | qDebug() << mm.tag(); // prints MY_CUSTOM_TAG | - | ||||||
1936 | \endcode | - | ||||||
1937 | - | |||||||
1938 | For the moment, \c moc will extract and record all tags, but it will not | - | ||||||
1939 | handle any of them specially. You can use the tags to annotate your methods | - | ||||||
1940 | differently, and treat them according to the specific needs of your | - | ||||||
1941 | application. | - | ||||||
1942 | - | |||||||
1943 | \note Since Qt 5.0, \c moc expands preprocessor macros, so it is necessary | - | ||||||
1944 | to surround the definition with \c #ifndef \c Q_MOC_RUN, as shown in the | - | ||||||
1945 | example above. This was not required in Qt 4. The code as shown above works | - | ||||||
1946 | with Qt 4 too. | - | ||||||
1947 | */ | - | ||||||
1948 | const char *QMetaMethod::tag() const | - | ||||||
1949 | { | - | ||||||
1950 | if (!mobj) | - | ||||||
1951 | return 0; | - | ||||||
1952 | return QMetaMethodPrivate::get(this)->tag().constData(); | - | ||||||
1953 | } | - | ||||||
1954 | - | |||||||
1955 | - | |||||||
1956 | /*! | - | ||||||
1957 | \internal | - | ||||||
1958 | */ | - | ||||||
1959 | int QMetaMethod::attributes() const | - | ||||||
1960 | { | - | ||||||
1961 | if (!mobj) | - | ||||||
1962 | return false; | - | ||||||
1963 | return ((mobj->d.data[handle + 4])>>4); | - | ||||||
1964 | } | - | ||||||
1965 | - | |||||||
1966 | /*! | - | ||||||
1967 | \since 4.6 | - | ||||||
1968 | - | |||||||
1969 | Returns this method's index. | - | ||||||
1970 | */ | - | ||||||
1971 | int QMetaMethod::methodIndex() const | - | ||||||
1972 | { | - | ||||||
1973 | if (!mobj) | - | ||||||
1974 | return -1; | - | ||||||
1975 | return QMetaMethodPrivate::get(this)->ownMethodIndex() + mobj->methodOffset(); | - | ||||||
1976 | } | - | ||||||
1977 | - | |||||||
1978 | // This method has been around for a while, but the documentation was marked \internal until 5.1 | - | ||||||
1979 | /*! | - | ||||||
1980 | \since 5.1 | - | ||||||
1981 | Returns the method revision if one was | - | ||||||
1982 | specified by Q_REVISION, otherwise returns 0. | - | ||||||
1983 | */ | - | ||||||
1984 | int QMetaMethod::revision() const | - | ||||||
1985 | { | - | ||||||
1986 | if (!mobj) | - | ||||||
1987 | return 0; | - | ||||||
1988 | if ((QMetaMethod::Access)(mobj->d.data[handle + 4] & MethodRevisioned)) { | - | ||||||
1989 | int offset = priv(mobj->d.data)->methodData | - | ||||||
1990 | + priv(mobj->d.data)->methodCount * 5 | - | ||||||
1991 | + QMetaMethodPrivate::get(this)->ownMethodIndex(); | - | ||||||
1992 | return mobj->d.data[offset]; | - | ||||||
1993 | } | - | ||||||
1994 | return 0; | - | ||||||
1995 | } | - | ||||||
1996 | - | |||||||
1997 | /*! | - | ||||||
1998 | Returns the access specification of this method (private, | - | ||||||
1999 | protected, or public). | - | ||||||
2000 | - | |||||||
2001 | \note Signals are always public, but you should regard that as an | - | ||||||
2002 | implementation detail. It is almost always a bad idea to emit a signal from | - | ||||||
2003 | outside its class. | - | ||||||
2004 | - | |||||||
2005 | \sa methodType() | - | ||||||
2006 | */ | - | ||||||
2007 | QMetaMethod::Access QMetaMethod::access() const | - | ||||||
2008 | { | - | ||||||
2009 | if (!mobj) | - | ||||||
2010 | return Private; | - | ||||||
2011 | return (QMetaMethod::Access)(mobj->d.data[handle + 4] & AccessMask); | - | ||||||
2012 | } | - | ||||||
2013 | - | |||||||
2014 | /*! | - | ||||||
2015 | Returns the type of this method (signal, slot, or method). | - | ||||||
2016 | - | |||||||
2017 | \sa access() | - | ||||||
2018 | */ | - | ||||||
2019 | QMetaMethod::MethodType QMetaMethod::methodType() const | - | ||||||
2020 | { | - | ||||||
2021 | if (!mobj) | - | ||||||
2022 | return QMetaMethod::Method; | - | ||||||
2023 | return (QMetaMethod::MethodType)((mobj->d.data[handle + 4] & MethodTypeMask)>>2); | - | ||||||
2024 | } | - | ||||||
2025 | - | |||||||
2026 | /*! | - | ||||||
2027 | \fn QMetaMethod QMetaMethod::fromSignal(PointerToMemberFunction signal) | - | ||||||
2028 | \since 5.0 | - | ||||||
2029 | - | |||||||
2030 | Returns the meta-method that corresponds to the given \a signal, or an | - | ||||||
2031 | invalid QMetaMethod if \a signal is not a signal of the class. | - | ||||||
2032 | - | |||||||
2033 | Example: | - | ||||||
2034 | - | |||||||
2035 | \snippet code/src_corelib_kernel_qmetaobject.cpp 9 | - | ||||||
2036 | */ | - | ||||||
2037 | - | |||||||
2038 | /*! | - | ||||||
2039 | \internal | - | ||||||
2040 | - | |||||||
2041 | Implementation of the fromSignal() function. | - | ||||||
2042 | - | |||||||
2043 | \a metaObject is the class's meta-object | - | ||||||
2044 | \a signal is a pointer to a pointer to a member signal of the class | - | ||||||
2045 | */ | - | ||||||
2046 | QMetaMethod QMetaMethod::fromSignalImpl(const QMetaObject *metaObject, void **signal) | - | ||||||
2047 | { | - | ||||||
2048 | int i = -1; | - | ||||||
2049 | void *args[] = { &i, signal }; | - | ||||||
2050 | QMetaMethod result; | - | ||||||
2051 | for (const QMetaObject *m = metaObject; m; m = m->d.superdata) { | - | ||||||
2052 | m->static_metacall(QMetaObject::IndexOfMethod, 0, args); | - | ||||||
2053 | if (i >= 0) { | - | ||||||
2054 | result.mobj = m; | - | ||||||
2055 | result.handle = priv(m->d.data)->methodData + 5*i; | - | ||||||
2056 | break; | - | ||||||
2057 | } | - | ||||||
2058 | } | - | ||||||
2059 | return result; | - | ||||||
2060 | } | - | ||||||
2061 | - | |||||||
2062 | /*! | - | ||||||
2063 | Invokes this method on the object \a object. Returns \c true if the member could be invoked. | - | ||||||
2064 | Returns \c false if there is no such member or the parameters did not match. | - | ||||||
2065 | - | |||||||
2066 | The invocation can be either synchronous or asynchronous, depending on the | - | ||||||
2067 | \a connectionType: | - | ||||||
2068 | - | |||||||
2069 | \list | - | ||||||
2070 | \li If \a connectionType is Qt::DirectConnection, the member will be invoked immediately. | - | ||||||
2071 | - | |||||||
2072 | \li If \a connectionType is Qt::QueuedConnection, | - | ||||||
2073 | a QEvent will be posted and the member is invoked as soon as the application | - | ||||||
2074 | enters the main event loop. | - | ||||||
2075 | - | |||||||
2076 | \li If \a connectionType is Qt::AutoConnection, the member is invoked | - | ||||||
2077 | synchronously if \a object lives in the same thread as the | - | ||||||
2078 | caller; otherwise it will invoke the member asynchronously. | - | ||||||
2079 | \endlist | - | ||||||
2080 | - | |||||||
2081 | The return value of this method call is placed in \a | - | ||||||
2082 | returnValue. If the invocation is asynchronous, the return value cannot | - | ||||||
2083 | be evaluated. You can pass up to ten arguments (\a val0, \a val1, | - | ||||||
2084 | \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, \a val8, | - | ||||||
2085 | and \a val9) to this method call. | - | ||||||
2086 | - | |||||||
2087 | QGenericArgument and QGenericReturnArgument are internal | - | ||||||
2088 | helper classes. Because signals and slots can be dynamically | - | ||||||
2089 | invoked, you must enclose the arguments using the Q_ARG() and | - | ||||||
2090 | Q_RETURN_ARG() macros. Q_ARG() takes a type name and a | - | ||||||
2091 | const reference of that type; Q_RETURN_ARG() takes a type name | - | ||||||
2092 | and a non-const reference. | - | ||||||
2093 | - | |||||||
2094 | To asynchronously invoke the | - | ||||||
2095 | \l{QPushButton::animateClick()}{animateClick()} slot on a | - | ||||||
2096 | QPushButton: | - | ||||||
2097 | - | |||||||
2098 | \snippet code/src_corelib_kernel_qmetaobject.cpp 6 | - | ||||||
2099 | - | |||||||
2100 | With asynchronous method invocations, the parameters must be of | - | ||||||
2101 | types that are known to Qt's meta-object system, because Qt needs | - | ||||||
2102 | to copy the arguments to store them in an event behind the | - | ||||||
2103 | scenes. If you try to use a queued connection and get the error | - | ||||||
2104 | message | - | ||||||
2105 | - | |||||||
2106 | \snippet code/src_corelib_kernel_qmetaobject.cpp 7 | - | ||||||
2107 | - | |||||||
2108 | call qRegisterMetaType() to register the data type before you | - | ||||||
2109 | call QMetaMethod::invoke(). | - | ||||||
2110 | - | |||||||
2111 | To synchronously invoke the \c compute(QString, int, double) slot on | - | ||||||
2112 | some arbitrary object \c obj retrieve its return value: | - | ||||||
2113 | - | |||||||
2114 | \snippet code/src_corelib_kernel_qmetaobject.cpp 8 | - | ||||||
2115 | - | |||||||
2116 | QMetaObject::normalizedSignature() is used here to ensure that the format | - | ||||||
2117 | of the signature is what invoke() expects. E.g. extra whitespace is | - | ||||||
2118 | removed. | - | ||||||
2119 | - | |||||||
2120 | If the "compute" slot does not take exactly one QString, one int | - | ||||||
2121 | and one double in the specified order, the call will fail. | - | ||||||
2122 | - | |||||||
2123 | \warning this method will not test the validity of the arguments: \a object | - | ||||||
2124 | must be an instance of the class of the QMetaObject of which this QMetaMethod | - | ||||||
2125 | has been constructed with. The arguments must have the same type as the ones | - | ||||||
2126 | expected by the method, else, the behaviour is undefined. | - | ||||||
2127 | - | |||||||
2128 | \sa Q_ARG(), Q_RETURN_ARG(), qRegisterMetaType(), QMetaObject::invokeMethod() | - | ||||||
2129 | */ | - | ||||||
2130 | bool QMetaMethod::invoke(QObject *object, | - | ||||||
2131 | Qt::ConnectionType connectionType, | - | ||||||
2132 | QGenericReturnArgument returnValue, | - | ||||||
2133 | QGenericArgument val0, | - | ||||||
2134 | QGenericArgument val1, | - | ||||||
2135 | QGenericArgument val2, | - | ||||||
2136 | QGenericArgument val3, | - | ||||||
2137 | QGenericArgument val4, | - | ||||||
2138 | QGenericArgument val5, | - | ||||||
2139 | QGenericArgument val6, | - | ||||||
2140 | QGenericArgument val7, | - | ||||||
2141 | QGenericArgument val8, | - | ||||||
2142 | QGenericArgument val9) const | - | ||||||
2143 | { | - | ||||||
2144 | if (!object || !mobj) | - | ||||||
2145 | return false; | - | ||||||
2146 | - | |||||||
2147 | Q_ASSERT(mobj->cast(object)); | - | ||||||
2148 | - | |||||||
2149 | // check return type | - | ||||||
2150 | if (returnValue.data()) { | - | ||||||
2151 | const char *retType = typeName(); | - | ||||||
2152 | if (qstrcmp(returnValue.name(), retType) != 0) { | - | ||||||
2153 | // normalize the return value as well | - | ||||||
2154 | QByteArray normalized = QMetaObject::normalizedType(returnValue.name()); | - | ||||||
2155 | if (qstrcmp(normalized.constData(), retType) != 0) { | - | ||||||
2156 | // String comparison failed, try compare the metatype. | - | ||||||
2157 | int t = returnType(); | - | ||||||
2158 | if (t == QMetaType::UnknownType || t != QMetaType::type(normalized)) | - | ||||||
2159 | return false; | - | ||||||
2160 | } | - | ||||||
2161 | } | - | ||||||
2162 | } | - | ||||||
2163 | - | |||||||
2164 | // check argument count (we don't allow invoking a method if given too few arguments) | - | ||||||
2165 | const char *typeNames[] = { | - | ||||||
2166 | returnValue.name(), | - | ||||||
2167 | val0.name(), | - | ||||||
2168 | val1.name(), | - | ||||||
2169 | val2.name(), | - | ||||||
2170 | val3.name(), | - | ||||||
2171 | val4.name(), | - | ||||||
2172 | val5.name(), | - | ||||||
2173 | val6.name(), | - | ||||||
2174 | val7.name(), | - | ||||||
2175 | val8.name(), | - | ||||||
2176 | val9.name() | - | ||||||
2177 | }; | - | ||||||
2178 | int paramCount; | - | ||||||
2179 | for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) { | - | ||||||
2180 | if (qstrlen(typeNames[paramCount]) <= 0) | - | ||||||
2181 | break; | - | ||||||
2182 | } | - | ||||||
2183 | if (paramCount <= QMetaMethodPrivate::get(this)->parameterCount()) | - | ||||||
2184 | return false; | - | ||||||
2185 | - | |||||||
2186 | // check connection type | - | ||||||
2187 | QThread *currentThread = QThread::currentThread(); | - | ||||||
2188 | QThread *objectThread = object->thread(); | - | ||||||
2189 | if (connectionType == Qt::AutoConnection) { | - | ||||||
2190 | connectionType = currentThread == objectThread | - | ||||||
2191 | ? Qt::DirectConnection | - | ||||||
2192 | : Qt::QueuedConnection; | - | ||||||
2193 | } | - | ||||||
2194 | - | |||||||
2195 | #ifdef QT_NO_THREAD | - | ||||||
2196 | if (connectionType == Qt::BlockingQueuedConnection) { | - | ||||||
2197 | connectionType = Qt::DirectConnection; | - | ||||||
2198 | } | - | ||||||
2199 | #endif | - | ||||||
2200 | - | |||||||
2201 | // invoke! | - | ||||||
2202 | void *param[] = { | - | ||||||
2203 | returnValue.data(), | - | ||||||
2204 | val0.data(), | - | ||||||
2205 | val1.data(), | - | ||||||
2206 | val2.data(), | - | ||||||
2207 | val3.data(), | - | ||||||
2208 | val4.data(), | - | ||||||
2209 | val5.data(), | - | ||||||
2210 | val6.data(), | - | ||||||
2211 | val7.data(), | - | ||||||
2212 | val8.data(), | - | ||||||
2213 | val9.data() | - | ||||||
2214 | }; | - | ||||||
2215 | int idx_relative = QMetaMethodPrivate::get(this)->ownMethodIndex(); | - | ||||||
2216 | int idx_offset = mobj->methodOffset(); | - | ||||||
2217 | Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6); | - | ||||||
2218 | QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall; | - | ||||||
2219 | - | |||||||
2220 | if (connectionType == Qt::DirectConnection) { | - | ||||||
2221 | if (callFunction) { | - | ||||||
2222 | callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param); | - | ||||||
2223 | return true; | - | ||||||
2224 | } else { | - | ||||||
2225 | return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) < 0; | - | ||||||
2226 | } | - | ||||||
2227 | } else if (connectionType == Qt::QueuedConnection) { | - | ||||||
2228 | if (returnValue.data()) { | - | ||||||
2229 | qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in " | - | ||||||
2230 | "queued connections"); | - | ||||||
2231 | return false; | - | ||||||
2232 | } | - | ||||||
2233 | - | |||||||
2234 | int nargs = 1; // include return type | - | ||||||
2235 | void **args = (void **) malloc(paramCount * sizeof(void *)); | - | ||||||
2236 | Q_CHECK_PTR(args); | - | ||||||
2237 | int *types = (int *) malloc(paramCount * sizeof(int)); | - | ||||||
2238 | Q_CHECK_PTR(types); | - | ||||||
2239 | types[0] = 0; // return type | - | ||||||
2240 | args[0] = 0; | - | ||||||
2241 | - | |||||||
2242 | for (int i = 1; i < paramCount; ++i) { | - | ||||||
2243 | types[i] = QMetaType::type(typeNames[i]); | - | ||||||
2244 | if (types[i] != QMetaType::UnknownType) { | - | ||||||
2245 | args[i] = QMetaType::create(types[i], param[i]); | - | ||||||
2246 | ++nargs; | - | ||||||
2247 | } else if (param[i]) { | - | ||||||
2248 | // Try to register the type and try again before reporting an error. | - | ||||||
2249 | void *argv[] = { &types[i], &i }; | - | ||||||
2250 | QMetaObject::metacall(object, QMetaObject::RegisterMethodArgumentMetaType, | - | ||||||
2251 | idx_relative + idx_offset, argv); | - | ||||||
2252 | if (types[i] == -1) { | - | ||||||
2253 | qWarning("QMetaMethod::invoke: Unable to handle unregistered datatype '%s'", | - | ||||||
2254 | typeNames[i]); | - | ||||||
2255 | for (int x = 1; x < i; ++x) { | - | ||||||
2256 | if (types[x] && args[x]) | - | ||||||
2257 | QMetaType::destroy(types[x], args[x]); | - | ||||||
2258 | } | - | ||||||
2259 | free(types); | - | ||||||
2260 | free(args); | - | ||||||
2261 | return false; | - | ||||||
2262 | } | - | ||||||
2263 | } | - | ||||||
2264 | } | - | ||||||
2265 | - | |||||||
2266 | QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction, | - | ||||||
2267 | 0, -1, nargs, types, args)); | - | ||||||
2268 | } else { // blocking queued connection | - | ||||||
2269 | #ifndef QT_NO_THREAD | - | ||||||
2270 | if (currentThread == objectThread) { | - | ||||||
2271 | qWarning("QMetaMethod::invoke: Dead lock detected in " | - | ||||||
2272 | "BlockingQueuedConnection: Receiver is %s(%p)", | - | ||||||
2273 | mobj->className(), object); | - | ||||||
2274 | } | - | ||||||
2275 | - | |||||||
2276 | QSemaphore semaphore; | - | ||||||
2277 | QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction, | - | ||||||
2278 | 0, -1, 0, 0, param, &semaphore)); | - | ||||||
2279 | semaphore.acquire(); | - | ||||||
2280 | #endif // QT_NO_THREAD | - | ||||||
2281 | } | - | ||||||
2282 | return true; | - | ||||||
2283 | } | - | ||||||
2284 | - | |||||||
2285 | /*! \fn bool QMetaMethod::invoke(QObject *object, | - | ||||||
2286 | QGenericReturnArgument returnValue, | - | ||||||
2287 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
2288 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
2289 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
2290 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
2291 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
2292 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
2293 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
2294 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
2295 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
2296 | QGenericArgument val9 = QGenericArgument()) const | - | ||||||
2297 | \overload invoke() | - | ||||||
2298 | - | |||||||
2299 | This overload always invokes this method using the connection type Qt::AutoConnection. | - | ||||||
2300 | */ | - | ||||||
2301 | - | |||||||
2302 | /*! \fn bool QMetaMethod::invoke(QObject *object, | - | ||||||
2303 | Qt::ConnectionType connectionType, | - | ||||||
2304 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
2305 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
2306 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
2307 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
2308 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
2309 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
2310 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
2311 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
2312 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
2313 | QGenericArgument val9 = QGenericArgument()) const | - | ||||||
2314 | - | |||||||
2315 | \overload invoke() | - | ||||||
2316 | - | |||||||
2317 | This overload can be used if the return value of the member is of no interest. | - | ||||||
2318 | */ | - | ||||||
2319 | - | |||||||
2320 | /*! | - | ||||||
2321 | \fn bool QMetaMethod::invoke(QObject *object, | - | ||||||
2322 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
2323 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
2324 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
2325 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
2326 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
2327 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
2328 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
2329 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
2330 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
2331 | QGenericArgument val9 = QGenericArgument()) const | - | ||||||
2332 | - | |||||||
2333 | \overload invoke() | - | ||||||
2334 | - | |||||||
2335 | This overload invokes this method using the | - | ||||||
2336 | connection type Qt::AutoConnection and ignores return values. | - | ||||||
2337 | */ | - | ||||||
2338 | - | |||||||
2339 | /*! | - | ||||||
2340 | \since 5.5 | - | ||||||
2341 | - | |||||||
2342 | Invokes this method on a Q_GADGET. Returns \c true if the member could be invoked. | - | ||||||
2343 | Returns \c false if there is no such member or the parameters did not match. | - | ||||||
2344 | - | |||||||
2345 | The pointer \a gadget must point to an instance of the gadget class. | - | ||||||
2346 | - | |||||||
2347 | The invocation is always synchronous. | - | ||||||
2348 | - | |||||||
2349 | The return value of this method call is placed in \a | - | ||||||
2350 | returnValue. You can pass up to ten arguments (\a val0, \a val1, | - | ||||||
2351 | \a val2, \a val3, \a val4, \a val5, \a val6, \a val7, \a val8, | - | ||||||
2352 | and \a val9) to this method call. | - | ||||||
2353 | - | |||||||
2354 | \warning this method will not test the validity of the arguments: \a gadget | - | ||||||
2355 | must be an instance of the class of the QMetaObject of which this QMetaMethod | - | ||||||
2356 | has been constructed with. The arguments must have the same type as the ones | - | ||||||
2357 | expected by the method, else, the behavior is undefined. | - | ||||||
2358 | - | |||||||
2359 | \sa Q_ARG(), Q_RETURN_ARG(), qRegisterMetaType(), QMetaObject::invokeMethod() | - | ||||||
2360 | */ | - | ||||||
2361 | bool QMetaMethod::invokeOnGadget(void* gadget, QGenericReturnArgument returnValue, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9) const | - | ||||||
2362 | { | - | ||||||
2363 | if (!gadget || !mobj) | - | ||||||
2364 | return false; | - | ||||||
2365 | - | |||||||
2366 | // check return type | - | ||||||
2367 | if (returnValue.data()) { | - | ||||||
2368 | const char *retType = typeName(); | - | ||||||
2369 | if (qstrcmp(returnValue.name(), retType) != 0) { | - | ||||||
2370 | // normalize the return value as well | - | ||||||
2371 | QByteArray normalized = QMetaObject::normalizedType(returnValue.name()); | - | ||||||
2372 | if (qstrcmp(normalized.constData(), retType) != 0) { | - | ||||||
2373 | // String comparison failed, try compare the metatype. | - | ||||||
2374 | int t = returnType(); | - | ||||||
2375 | if (t == QMetaType::UnknownType || t != QMetaType::type(normalized)) | - | ||||||
2376 | return false; | - | ||||||
2377 | } | - | ||||||
2378 | } | - | ||||||
2379 | } | - | ||||||
2380 | - | |||||||
2381 | // check argument count (we don't allow invoking a method if given too few arguments) | - | ||||||
2382 | const char *typeNames[] = { | - | ||||||
2383 | returnValue.name(), | - | ||||||
2384 | val0.name(), | - | ||||||
2385 | val1.name(), | - | ||||||
2386 | val2.name(), | - | ||||||
2387 | val3.name(), | - | ||||||
2388 | val4.name(), | - | ||||||
2389 | val5.name(), | - | ||||||
2390 | val6.name(), | - | ||||||
2391 | val7.name(), | - | ||||||
2392 | val8.name(), | - | ||||||
2393 | val9.name() | - | ||||||
2394 | }; | - | ||||||
2395 | int paramCount; | - | ||||||
2396 | for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) { | - | ||||||
2397 | if (qstrlen(typeNames[paramCount]) <= 0) | - | ||||||
2398 | break; | - | ||||||
2399 | } | - | ||||||
2400 | if (paramCount <= QMetaMethodPrivate::get(this)->parameterCount()) | - | ||||||
2401 | return false; | - | ||||||
2402 | - | |||||||
2403 | // invoke! | - | ||||||
2404 | void *param[] = { | - | ||||||
2405 | returnValue.data(), | - | ||||||
2406 | val0.data(), | - | ||||||
2407 | val1.data(), | - | ||||||
2408 | val2.data(), | - | ||||||
2409 | val3.data(), | - | ||||||
2410 | val4.data(), | - | ||||||
2411 | val5.data(), | - | ||||||
2412 | val6.data(), | - | ||||||
2413 | val7.data(), | - | ||||||
2414 | val8.data(), | - | ||||||
2415 | val9.data() | - | ||||||
2416 | }; | - | ||||||
2417 | int idx_relative = QMetaMethodPrivate::get(this)->ownMethodIndex(); | - | ||||||
2418 | Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6); | - | ||||||
2419 | QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall; | - | ||||||
2420 | if (!callFunction) | - | ||||||
2421 | return false; | - | ||||||
2422 | callFunction(reinterpret_cast<QObject*>(gadget), QMetaObject::InvokeMetaMethod, idx_relative, param); | - | ||||||
2423 | return true; | - | ||||||
2424 | } | - | ||||||
2425 | - | |||||||
2426 | /*! | - | ||||||
2427 | \fn bool QMetaMethod::invokeOnGadget(void *gadget, | - | ||||||
2428 | QGenericArgument val0 = QGenericArgument(0), | - | ||||||
2429 | QGenericArgument val1 = QGenericArgument(), | - | ||||||
2430 | QGenericArgument val2 = QGenericArgument(), | - | ||||||
2431 | QGenericArgument val3 = QGenericArgument(), | - | ||||||
2432 | QGenericArgument val4 = QGenericArgument(), | - | ||||||
2433 | QGenericArgument val5 = QGenericArgument(), | - | ||||||
2434 | QGenericArgument val6 = QGenericArgument(), | - | ||||||
2435 | QGenericArgument val7 = QGenericArgument(), | - | ||||||
2436 | QGenericArgument val8 = QGenericArgument(), | - | ||||||
2437 | QGenericArgument val9 = QGenericArgument()) const | - | ||||||
2438 | - | |||||||
2439 | \overload | - | ||||||
2440 | \since 5.5 | - | ||||||
2441 | - | |||||||
2442 | This overload invokes this method for a \a gadget and ignores return values. | - | ||||||
2443 | */ | - | ||||||
2444 | - | |||||||
2445 | /*! | - | ||||||
2446 | \class QMetaEnum | - | ||||||
2447 | \inmodule QtCore | - | ||||||
2448 | \brief The QMetaEnum class provides meta-data about an enumerator. | - | ||||||
2449 | - | |||||||
2450 | \ingroup objectmodel | - | ||||||
2451 | - | |||||||
2452 | Use name() for the enumerator's name. The enumerator's keys (names | - | ||||||
2453 | of each enumerated item) are returned by key(); use keyCount() to find | - | ||||||
2454 | the number of keys. isFlag() returns whether the enumerator is | - | ||||||
2455 | meant to be used as a flag, meaning that its values can be combined | - | ||||||
2456 | using the OR operator. | - | ||||||
2457 | - | |||||||
2458 | The conversion functions keyToValue(), valueToKey(), keysToValue(), | - | ||||||
2459 | and valueToKeys() allow conversion between the integer | - | ||||||
2460 | representation of an enumeration or set value and its literal | - | ||||||
2461 | representation. The scope() function returns the class scope this | - | ||||||
2462 | enumerator was declared in. | - | ||||||
2463 | - | |||||||
2464 | \sa QMetaObject, QMetaMethod, QMetaProperty | - | ||||||
2465 | */ | - | ||||||
2466 | - | |||||||
2467 | /*! | - | ||||||
2468 | \fn bool QMetaEnum::isValid() const | - | ||||||
2469 | - | |||||||
2470 | Returns \c true if this enum is valid (has a name); otherwise returns | - | ||||||
2471 | false. | - | ||||||
2472 | - | |||||||
2473 | \sa name() | - | ||||||
2474 | */ | - | ||||||
2475 | - | |||||||
2476 | /*! | - | ||||||
2477 | \fn const QMetaObject *QMetaEnum::enclosingMetaObject() const | - | ||||||
2478 | \internal | - | ||||||
2479 | */ | - | ||||||
2480 | - | |||||||
2481 | - | |||||||
2482 | /*! | - | ||||||
2483 | \fn QMetaEnum::QMetaEnum() | - | ||||||
2484 | \internal | - | ||||||
2485 | */ | - | ||||||
2486 | - | |||||||
2487 | /*! | - | ||||||
2488 | Returns the name of the enumerator (without the scope). | - | ||||||
2489 | - | |||||||
2490 | For example, the Qt::AlignmentFlag enumeration has \c | - | ||||||
2491 | AlignmentFlag as the name and \l Qt as the scope. | - | ||||||
2492 | - | |||||||
2493 | \sa isValid(), scope() | - | ||||||
2494 | */ | - | ||||||
2495 | const char *QMetaEnum::name() const | - | ||||||
2496 | { | - | ||||||
2497 | if (!mobj) | - | ||||||
2498 | return 0; | - | ||||||
2499 | return rawStringData(mobj, mobj->d.data[handle]); | - | ||||||
2500 | } | - | ||||||
2501 | - | |||||||
2502 | /*! | - | ||||||
2503 | Returns the number of keys. | - | ||||||
2504 | - | |||||||
2505 | \sa key() | - | ||||||
2506 | */ | - | ||||||
2507 | int QMetaEnum::keyCount() const | - | ||||||
2508 | { | - | ||||||
2509 | if (!mobj) | - | ||||||
2510 | return 0; | - | ||||||
2511 | return mobj->d.data[handle + 2]; | - | ||||||
2512 | } | - | ||||||
2513 | - | |||||||
2514 | - | |||||||
2515 | /*! | - | ||||||
2516 | Returns the key with the given \a index, or 0 if no such key exists. | - | ||||||
2517 | - | |||||||
2518 | \sa keyCount(), value(), valueToKey() | - | ||||||
2519 | */ | - | ||||||
2520 | const char *QMetaEnum::key(int index) const | - | ||||||
2521 | { | - | ||||||
2522 | if (!mobj) | - | ||||||
2523 | return 0; | - | ||||||
2524 | int count = mobj->d.data[handle + 2]; | - | ||||||
2525 | int data = mobj->d.data[handle + 3]; | - | ||||||
2526 | if (index >= 0 && index < count) | - | ||||||
2527 | return rawStringData(mobj, mobj->d.data[data + 2*index]); | - | ||||||
2528 | return 0; | - | ||||||
2529 | } | - | ||||||
2530 | - | |||||||
2531 | /*! | - | ||||||
2532 | Returns the value with the given \a index; or returns -1 if there | - | ||||||
2533 | is no such value. | - | ||||||
2534 | - | |||||||
2535 | \sa keyCount(), key(), keyToValue() | - | ||||||
2536 | */ | - | ||||||
2537 | int QMetaEnum::value(int index) const | - | ||||||
2538 | { | - | ||||||
2539 | if (!mobj) | - | ||||||
2540 | return 0; | - | ||||||
2541 | int count = mobj->d.data[handle + 2]; | - | ||||||
2542 | int data = mobj->d.data[handle + 3]; | - | ||||||
2543 | if (index >= 0 && index < count) | - | ||||||
2544 | return mobj->d.data[data + 2*index + 1]; | - | ||||||
2545 | return -1; | - | ||||||
2546 | } | - | ||||||
2547 | - | |||||||
2548 | - | |||||||
2549 | /*! | - | ||||||
2550 | Returns \c true if this enumerator is used as a flag; otherwise returns | - | ||||||
2551 | false. | - | ||||||
2552 | - | |||||||
2553 | When used as flags, enumerators can be combined using the OR | - | ||||||
2554 | operator. | - | ||||||
2555 | - | |||||||
2556 | \sa keysToValue(), valueToKeys() | - | ||||||
2557 | */ | - | ||||||
2558 | bool QMetaEnum::isFlag() const | - | ||||||
2559 | { | - | ||||||
2560 | return mobj && mobj->d.data[handle + 1]; | - | ||||||
2561 | } | - | ||||||
2562 | - | |||||||
2563 | - | |||||||
2564 | /*! | - | ||||||
2565 | Returns the scope this enumerator was declared in. | - | ||||||
2566 | - | |||||||
2567 | For example, the Qt::AlignmentFlag enumeration has \c Qt as | - | ||||||
2568 | the scope and \c AlignmentFlag as the name. | - | ||||||
2569 | - | |||||||
2570 | \sa name() | - | ||||||
2571 | */ | - | ||||||
2572 | const char *QMetaEnum::scope() const | - | ||||||
2573 | { | - | ||||||
2574 | return mobj ? objectClassName(mobj) : 0; | - | ||||||
2575 | } | - | ||||||
2576 | - | |||||||
2577 | /*! | - | ||||||
2578 | Returns the integer value of the given enumeration \a key, or -1 | - | ||||||
2579 | if \a key is not defined. | - | ||||||
2580 | - | |||||||
2581 | If \a key is not defined, *\a{ok} is set to false; otherwise | - | ||||||
2582 | *\a{ok} is set to true. | - | ||||||
2583 | - | |||||||
2584 | For flag types, use keysToValue(). | - | ||||||
2585 | - | |||||||
2586 | \sa valueToKey(), isFlag(), keysToValue() | - | ||||||
2587 | */ | - | ||||||
2588 | int QMetaEnum::keyToValue(const char *key, bool *ok) const | - | ||||||
2589 | { | - | ||||||
2590 | if (ok != 0) | - | ||||||
2591 | *ok = false; | - | ||||||
2592 | if (!mobj || !key) | - | ||||||
2593 | return -1; | - | ||||||
2594 | uint scope = 0; | - | ||||||
2595 | const char *qualified_key = key; | - | ||||||
2596 | const char *s = key + qstrlen(key); | - | ||||||
2597 | while (s > key && *s != ':') | - | ||||||
2598 | --s; | - | ||||||
2599 | if (s > key && *(s-1)==':') { | - | ||||||
2600 | scope = s - key - 1; | - | ||||||
2601 | key += scope + 2; | - | ||||||
2602 | } | - | ||||||
2603 | int count = mobj->d.data[handle + 2]; | - | ||||||
2604 | int data = mobj->d.data[handle + 3]; | - | ||||||
2605 | for (int i = 0; i < count; ++i) { | - | ||||||
2606 | const QByteArray className = stringData(mobj, priv(mobj->d.data)->className); | - | ||||||
2607 | if ((!scope || (className.size() == int(scope) && strncmp(qualified_key, className.constData(), scope) == 0)) | - | ||||||
2608 | && strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) { | - | ||||||
2609 | if (ok != 0) | - | ||||||
2610 | *ok = true; | - | ||||||
2611 | return mobj->d.data[data + 2*i + 1]; | - | ||||||
2612 | } | - | ||||||
2613 | } | - | ||||||
2614 | return -1; | - | ||||||
2615 | } | - | ||||||
2616 | - | |||||||
2617 | /*! | - | ||||||
2618 | Returns the string that is used as the name of the given | - | ||||||
2619 | enumeration \a value, or 0 if \a value is not defined. | - | ||||||
2620 | - | |||||||
2621 | For flag types, use valueToKeys(). | - | ||||||
2622 | - | |||||||
2623 | \sa isFlag(), valueToKeys() | - | ||||||
2624 | */ | - | ||||||
2625 | const char* QMetaEnum::valueToKey(int value) const | - | ||||||
2626 | { | - | ||||||
2627 | if (!mobj) | - | ||||||
2628 | return 0; | - | ||||||
2629 | int count = mobj->d.data[handle + 2]; | - | ||||||
2630 | int data = mobj->d.data[handle + 3]; | - | ||||||
2631 | for (int i = 0; i < count; ++i) | - | ||||||
2632 | if (value == (int)mobj->d.data[data + 2*i + 1]) | - | ||||||
2633 | return rawStringData(mobj, mobj->d.data[data + 2*i]); | - | ||||||
2634 | return 0; | - | ||||||
2635 | } | - | ||||||
2636 | - | |||||||
2637 | /*! | - | ||||||
2638 | Returns the value derived from combining together the values of | - | ||||||
2639 | the \a keys using the OR operator, or -1 if \a keys is not | - | ||||||
2640 | defined. Note that the strings in \a keys must be '|'-separated. | - | ||||||
2641 | - | |||||||
2642 | If \a keys is not defined, *\a{ok} is set to false; otherwise | - | ||||||
2643 | *\a{ok} is set to true. | - | ||||||
2644 | - | |||||||
2645 | \sa isFlag(), valueToKey(), valueToKeys() | - | ||||||
2646 | */ | - | ||||||
2647 | int QMetaEnum::keysToValue(const char *keys, bool *ok) const | - | ||||||
2648 | { | - | ||||||
2649 | if (ok != 0) | - | ||||||
2650 | *ok = false; | - | ||||||
2651 | if (!mobj || !keys) | - | ||||||
2652 | return -1; | - | ||||||
2653 | if (ok != 0) | - | ||||||
2654 | *ok = true; | - | ||||||
2655 | QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|')); | - | ||||||
2656 | if (l.isEmpty()) | - | ||||||
2657 | return 0; | - | ||||||
2658 | //#### TODO write proper code, do not use QStringList | - | ||||||
2659 | int value = 0; | - | ||||||
2660 | int count = mobj->d.data[handle + 2]; | - | ||||||
2661 | int data = mobj->d.data[handle + 3]; | - | ||||||
2662 | for (int li = 0; li < l.size(); ++li) { | - | ||||||
2663 | QString trimmed = l.at(li).trimmed(); | - | ||||||
2664 | QByteArray qualified_key = trimmed.toLatin1(); | - | ||||||
2665 | const char *key = qualified_key.constData(); | - | ||||||
2666 | uint scope = 0; | - | ||||||
2667 | const char *s = key + qstrlen(key); | - | ||||||
2668 | while (s > key && *s != ':') | - | ||||||
2669 | --s; | - | ||||||
2670 | if (s > key && *(s-1)==':') { | - | ||||||
2671 | scope = s - key - 1; | - | ||||||
2672 | key += scope + 2; | - | ||||||
2673 | } | - | ||||||
2674 | int i; | - | ||||||
2675 | for (i = count-1; i >= 0; --i) { | - | ||||||
2676 | const QByteArray className = stringData(mobj, priv(mobj->d.data)->className); | - | ||||||
2677 | if ((!scope || (className.size() == int(scope) && strncmp(qualified_key.constData(), className.constData(), scope) == 0)) | - | ||||||
2678 | && strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) { | - | ||||||
2679 | value |= mobj->d.data[data + 2*i + 1]; | - | ||||||
2680 | break; | - | ||||||
2681 | } | - | ||||||
2682 | } | - | ||||||
2683 | if (i < 0) { | - | ||||||
2684 | if (ok != 0) | - | ||||||
2685 | *ok = false; | - | ||||||
2686 | value |= -1; | - | ||||||
2687 | } | - | ||||||
2688 | } | - | ||||||
2689 | return value; | - | ||||||
2690 | } | - | ||||||
2691 | - | |||||||
2692 | /*! | - | ||||||
2693 | Returns a byte array of '|'-separated keys that represents the | - | ||||||
2694 | given \a value. | - | ||||||
2695 | - | |||||||
2696 | \sa isFlag(), valueToKey(), keysToValue() | - | ||||||
2697 | */ | - | ||||||
2698 | QByteArray QMetaEnum::valueToKeys(int value) const | - | ||||||
2699 | { | - | ||||||
2700 | QByteArray keys; | - | ||||||
2701 | if (!mobj) | - | ||||||
2702 | return keys; | - | ||||||
2703 | int count = mobj->d.data[handle + 2]; | - | ||||||
2704 | int data = mobj->d.data[handle + 3]; | - | ||||||
2705 | int v = value; | - | ||||||
2706 | // reverse iterate to ensure values like Qt::Dialog=0x2|Qt::Window are processed first. | - | ||||||
2707 | for (int i = count - 1; i >= 0; --i) { | - | ||||||
2708 | int k = mobj->d.data[data + 2*i + 1]; | - | ||||||
2709 | if ((k != 0 && (v & k) == k ) || (k == value)) { | - | ||||||
2710 | v = v & ~k; | - | ||||||
2711 | if (!keys.isEmpty()) | - | ||||||
2712 | keys.prepend('|'); | - | ||||||
2713 | keys.prepend(stringData(mobj, mobj->d.data[data + 2*i])); | - | ||||||
2714 | } | - | ||||||
2715 | } | - | ||||||
2716 | return keys; | - | ||||||
2717 | } | - | ||||||
2718 | - | |||||||
2719 | /*! | - | ||||||
2720 | \fn QMetaEnum QMetaEnum::fromType() | - | ||||||
2721 | \since 5.5 | - | ||||||
2722 | - | |||||||
2723 | Returns the QMetaEnum corresponding to the type in the template parameter. | - | ||||||
2724 | The enum needs to be declared with Q_ENUM. | - | ||||||
2725 | */ | - | ||||||
2726 | - | |||||||
2727 | static QByteArray qualifiedName(const QMetaEnum &e) | - | ||||||
2728 | { | - | ||||||
2729 | return QByteArray(e.scope()) + "::" + e.name(); | - | ||||||
2730 | } | - | ||||||
2731 | - | |||||||
2732 | /*! | - | ||||||
2733 | \class QMetaProperty | - | ||||||
2734 | \inmodule QtCore | - | ||||||
2735 | \brief The QMetaProperty class provides meta-data about a property. | - | ||||||
2736 | - | |||||||
2737 | \ingroup objectmodel | - | ||||||
2738 | - | |||||||
2739 | Property meta-data is obtained from an object's meta-object. See | - | ||||||
2740 | QMetaObject::property() and QMetaObject::propertyCount() for | - | ||||||
2741 | details. | - | ||||||
2742 | - | |||||||
2743 | \section1 Property Meta-Data | - | ||||||
2744 | - | |||||||
2745 | A property has a name() and a type(), as well as various | - | ||||||
2746 | attributes that specify its behavior: isReadable(), isWritable(), | - | ||||||
2747 | isDesignable(), isScriptable(), revision(), and isStored(). | - | ||||||
2748 | - | |||||||
2749 | If the property is an enumeration, isEnumType() returns \c true; if the | - | ||||||
2750 | property is an enumeration that is also a flag (i.e. its values | - | ||||||
2751 | can be combined using the OR operator), isEnumType() and | - | ||||||
2752 | isFlagType() both return true. The enumerator for these types is | - | ||||||
2753 | available from enumerator(). | - | ||||||
2754 | - | |||||||
2755 | The property's values are set and retrieved with read(), write(), | - | ||||||
2756 | and reset(); they can also be changed through QObject's set and get | - | ||||||
2757 | functions. See QObject::setProperty() and QObject::property() for | - | ||||||
2758 | details. | - | ||||||
2759 | - | |||||||
2760 | \section1 Copying and Assignment | - | ||||||
2761 | - | |||||||
2762 | QMetaProperty objects can be copied by value. However, each copy will | - | ||||||
2763 | refer to the same underlying property meta-data. | - | ||||||
2764 | - | |||||||
2765 | \sa QMetaObject, QMetaEnum, QMetaMethod, {Qt's Property System} | - | ||||||
2766 | */ | - | ||||||
2767 | - | |||||||
2768 | /*! | - | ||||||
2769 | \fn bool QMetaProperty::isValid() const | - | ||||||
2770 | - | |||||||
2771 | Returns \c true if this property is valid (readable); otherwise | - | ||||||
2772 | returns \c false. | - | ||||||
2773 | - | |||||||
2774 | \sa isReadable() | - | ||||||
2775 | */ | - | ||||||
2776 | - | |||||||
2777 | /*! | - | ||||||
2778 | \fn const QMetaObject *QMetaProperty::enclosingMetaObject() const | - | ||||||
2779 | \internal | - | ||||||
2780 | */ | - | ||||||
2781 | - | |||||||
2782 | /*! | - | ||||||
2783 | \internal | - | ||||||
2784 | */ | - | ||||||
2785 | QMetaProperty::QMetaProperty() | - | ||||||
2786 | : mobj(0), handle(0), idx(0) | - | ||||||
2787 | { | - | ||||||
2788 | } | - | ||||||
2789 | - | |||||||
2790 | - | |||||||
2791 | /*! | - | ||||||
2792 | Returns this property's name. | - | ||||||
2793 | - | |||||||
2794 | \sa type(), typeName() | - | ||||||
2795 | */ | - | ||||||
2796 | const char *QMetaProperty::name() const | - | ||||||
2797 | { | - | ||||||
2798 | if (!mobj) | - | ||||||
2799 | return 0; | - | ||||||
2800 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2801 | return rawStringData(mobj, mobj->d.data[handle]); | - | ||||||
2802 | } | - | ||||||
2803 | - | |||||||
2804 | /*! | - | ||||||
2805 | Returns the name of this property's type. | - | ||||||
2806 | - | |||||||
2807 | \sa type(), name() | - | ||||||
2808 | */ | - | ||||||
2809 | const char *QMetaProperty::typeName() const | - | ||||||
2810 | { | - | ||||||
2811 | if (!mobj) | - | ||||||
2812 | return 0; | - | ||||||
2813 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2814 | return rawTypeNameFromTypeInfo(mobj, mobj->d.data[handle + 1]); | - | ||||||
2815 | } | - | ||||||
2816 | - | |||||||
2817 | /*! | - | ||||||
2818 | Returns this property's type. The return value is one | - | ||||||
2819 | of the values of the QVariant::Type enumeration. | - | ||||||
2820 | - | |||||||
2821 | \sa userType(), typeName(), name() | - | ||||||
2822 | */ | - | ||||||
2823 | QVariant::Type QMetaProperty::type() const | - | ||||||
2824 | { | - | ||||||
2825 | if (!mobj) | - | ||||||
2826 | return QVariant::Invalid; | - | ||||||
2827 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2828 | - | |||||||
2829 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
2830 | uint type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]); | - | ||||||
2831 | if (type >= QMetaType::User) | - | ||||||
2832 | return QVariant::UserType; | - | ||||||
2833 | if (type != QMetaType::UnknownType) | - | ||||||
2834 | return QVariant::Type(type); | - | ||||||
2835 | if (isEnumType()) { | - | ||||||
2836 | int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); | - | ||||||
2837 | if (enumMetaTypeId == QMetaType::UnknownType) | - | ||||||
2838 | return QVariant::Int; | - | ||||||
2839 | } | - | ||||||
2840 | #ifdef QT_COORD_TYPE | - | ||||||
2841 | // qreal metatype must be resolved at runtime. | - | ||||||
2842 | if (strcmp(typeName(), "qreal") == 0) | - | ||||||
2843 | return QVariant::Type(qMetaTypeId<qreal>()); | - | ||||||
2844 | #endif | - | ||||||
2845 | - | |||||||
2846 | return QVariant::UserType; | - | ||||||
2847 | } | - | ||||||
2848 | - | |||||||
2849 | /*! | - | ||||||
2850 | \since 4.2 | - | ||||||
2851 | - | |||||||
2852 | Returns this property's user type. The return value is one | - | ||||||
2853 | of the values that are registered with QMetaType, or QMetaType::UnknownType if | - | ||||||
2854 | the type is not registered. | - | ||||||
2855 | - | |||||||
2856 | \sa type(), QMetaType, typeName() | - | ||||||
2857 | */ | - | ||||||
2858 | int QMetaProperty::userType() const | - | ||||||
2859 | { | - | ||||||
2860 | if (!mobj) | - | ||||||
2861 | return QMetaType::UnknownType; | - | ||||||
2862 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
2863 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2864 | int type = typeFromTypeInfo(mobj, mobj->d.data[handle + 1]); | - | ||||||
2865 | if (type != QMetaType::UnknownType) | - | ||||||
2866 | return type; | - | ||||||
2867 | if (isEnumType()) { | - | ||||||
2868 | type = QMetaType::type(qualifiedName(menum)); | - | ||||||
2869 | if (type == QMetaType::UnknownType) { | - | ||||||
2870 | type = registerPropertyType(); | - | ||||||
2871 | if (type == QMetaType::UnknownType) | - | ||||||
2872 | return QVariant::Int; // Match behavior of QMetaType::type() | - | ||||||
2873 | } | - | ||||||
2874 | return type; | - | ||||||
2875 | } | - | ||||||
2876 | type = QMetaType::type(typeName()); | - | ||||||
2877 | if (type != QMetaType::UnknownType) | - | ||||||
2878 | return type; | - | ||||||
2879 | return registerPropertyType(); | - | ||||||
2880 | } | - | ||||||
2881 | - | |||||||
2882 | /*! | - | ||||||
2883 | \since 4.6 | - | ||||||
2884 | - | |||||||
2885 | Returns this property's index. | - | ||||||
2886 | */ | - | ||||||
2887 | int QMetaProperty::propertyIndex() const | - | ||||||
2888 | { | - | ||||||
2889 | if (!mobj) | - | ||||||
2890 | return -1; | - | ||||||
2891 | return idx + mobj->propertyOffset(); | - | ||||||
2892 | } | - | ||||||
2893 | - | |||||||
2894 | /*! | - | ||||||
2895 | Returns \c true if the property's type is an enumeration value that | - | ||||||
2896 | is used as a flag; otherwise returns \c false. | - | ||||||
2897 | - | |||||||
2898 | Flags can be combined using the OR operator. A flag type is | - | ||||||
2899 | implicitly also an enum type. | - | ||||||
2900 | - | |||||||
2901 | \sa isEnumType(), enumerator(), QMetaEnum::isFlag() | - | ||||||
2902 | */ | - | ||||||
2903 | - | |||||||
2904 | bool QMetaProperty::isFlagType() const | - | ||||||
2905 | { | - | ||||||
2906 | return isEnumType() && menum.isFlag(); | - | ||||||
2907 | } | - | ||||||
2908 | - | |||||||
2909 | /*! | - | ||||||
2910 | Returns \c true if the property's type is an enumeration value; | - | ||||||
2911 | otherwise returns \c false. | - | ||||||
2912 | - | |||||||
2913 | \sa enumerator(), isFlagType() | - | ||||||
2914 | */ | - | ||||||
2915 | bool QMetaProperty::isEnumType() const | - | ||||||
2916 | { | - | ||||||
2917 | if (!mobj) | - | ||||||
2918 | return false; | - | ||||||
2919 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2920 | int flags = mobj->d.data[handle + 2]; | - | ||||||
2921 | return (flags & EnumOrFlag) && menum.name(); | - | ||||||
2922 | } | - | ||||||
2923 | - | |||||||
2924 | /*! | - | ||||||
2925 | \internal | - | ||||||
2926 | - | |||||||
2927 | Returns \c true if the property has a C++ setter function that | - | ||||||
2928 | follows Qt's standard "name" / "setName" pattern. Designer and uic | - | ||||||
2929 | query hasStdCppSet() in order to avoid expensive | - | ||||||
2930 | QObject::setProperty() calls. All properties in Qt [should] follow | - | ||||||
2931 | this pattern. | - | ||||||
2932 | */ | - | ||||||
2933 | bool QMetaProperty::hasStdCppSet() const | - | ||||||
2934 | { | - | ||||||
2935 | if (!mobj) | - | ||||||
2936 | return false; | - | ||||||
2937 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2938 | int flags = mobj->d.data[handle + 2]; | - | ||||||
2939 | return (flags & StdCppSet); | - | ||||||
2940 | } | - | ||||||
2941 | - | |||||||
2942 | /*! | - | ||||||
2943 | \internal | - | ||||||
2944 | Executes metacall with QMetaObject::RegisterPropertyMetaType flag. | - | ||||||
2945 | Returns id of registered type or QMetaType::UnknownType if a type | - | ||||||
2946 | could not be registered for any reason. | - | ||||||
2947 | */ | - | ||||||
2948 | int QMetaProperty::registerPropertyType() const | - | ||||||
2949 | { | - | ||||||
2950 | int registerResult = -1; | - | ||||||
2951 | void *argv[] = { ®isterResult }; | - | ||||||
2952 | mobj->static_metacall(QMetaObject::RegisterPropertyMetaType, idx, argv); | - | ||||||
2953 | return registerResult == -1 ? QMetaType::UnknownType : registerResult; | - | ||||||
2954 | } | - | ||||||
2955 | - | |||||||
2956 | /*! | - | ||||||
2957 | Returns the enumerator if this property's type is an enumerator | - | ||||||
2958 | type; otherwise the returned value is undefined. | - | ||||||
2959 | - | |||||||
2960 | \sa isEnumType(), isFlagType() | - | ||||||
2961 | */ | - | ||||||
2962 | QMetaEnum QMetaProperty::enumerator() const | - | ||||||
2963 | { | - | ||||||
2964 | return menum; | - | ||||||
2965 | } | - | ||||||
2966 | - | |||||||
2967 | /*! | - | ||||||
2968 | Reads the property's value from the given \a object. Returns the value | - | ||||||
2969 | if it was able to read it; otherwise returns an invalid variant. | - | ||||||
2970 | - | |||||||
2971 | \sa write(), reset(), isReadable() | - | ||||||
2972 | */ | - | ||||||
2973 | QVariant QMetaProperty::read(const QObject *object) const | - | ||||||
2974 | { | - | ||||||
2975 | if (!object || !mobj) | - | ||||||
2976 | return QVariant(); | - | ||||||
2977 | - | |||||||
2978 | uint t = QVariant::Int; | - | ||||||
2979 | if (isEnumType()) { | - | ||||||
2980 | /* | - | ||||||
2981 | try to create a QVariant that can be converted to this enum | - | ||||||
2982 | type (only works if the enum has already been registered | - | ||||||
2983 | with QMetaType) | - | ||||||
2984 | */ | - | ||||||
2985 | int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); | - | ||||||
2986 | if (enumMetaTypeId != QMetaType::UnknownType) | - | ||||||
2987 | t = enumMetaTypeId; | - | ||||||
2988 | } else { | - | ||||||
2989 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
2990 | const char *typeName = 0; | - | ||||||
2991 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
2992 | uint typeInfo = mobj->d.data[handle + 1]; | - | ||||||
2993 | if (!(typeInfo & IsUnresolvedType)) | - | ||||||
2994 | t = typeInfo; | - | ||||||
2995 | else { | - | ||||||
2996 | typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask); | - | ||||||
2997 | t = QMetaType::type(typeName); | - | ||||||
2998 | } | - | ||||||
2999 | if (t == QMetaType::UnknownType) { | - | ||||||
3000 | // Try to register the type and try again before reporting an error. | - | ||||||
3001 | t = registerPropertyType(); | - | ||||||
3002 | if (t == QMetaType::UnknownType) { | - | ||||||
3003 | qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property '%s::%s'", typeName, mobj->className(), name()); | - | ||||||
3004 | return QVariant(); | - | ||||||
3005 | } | - | ||||||
3006 | } | - | ||||||
3007 | } | - | ||||||
3008 | - | |||||||
3009 | // the status variable is changed by qt_metacall to indicate what it did | - | ||||||
3010 | // this feature is currently only used by Qt D-Bus and should not be depended | - | ||||||
3011 | // upon. Don't change it without looking into QDBusAbstractInterface first | - | ||||||
3012 | // -1 (unchanged): normal qt_metacall, result stored in argv[0] | - | ||||||
3013 | // changed: result stored directly in value | - | ||||||
3014 | int status = -1; | - | ||||||
3015 | QVariant value; | - | ||||||
3016 | void *argv[] = { 0, &value, &status }; | - | ||||||
3017 | if (t == QMetaType::QVariant) { | - | ||||||
3018 | argv[0] = &value; | - | ||||||
3019 | } else { | - | ||||||
3020 | value = QVariant(t, (void*)0); | - | ||||||
3021 | argv[0] = value.data(); | - | ||||||
3022 | } | - | ||||||
3023 | if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) { | - | ||||||
3024 | mobj->d.static_metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty, idx, argv); | - | ||||||
3025 | } else { | - | ||||||
3026 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty, | - | ||||||
3027 | idx + mobj->propertyOffset(), argv); | - | ||||||
3028 | } | - | ||||||
3029 | - | |||||||
3030 | if (status != -1) | - | ||||||
3031 | return value; | - | ||||||
3032 | if (t != QMetaType::QVariant && argv[0] != value.data()) | - | ||||||
3033 | // pointer or reference | - | ||||||
3034 | return QVariant((QVariant::Type)t, argv[0]); | - | ||||||
3035 | return value; | - | ||||||
3036 | } | - | ||||||
3037 | - | |||||||
3038 | /*! | - | ||||||
3039 | Writes \a value as the property's value to the given \a object. Returns | - | ||||||
3040 | true if the write succeeded; otherwise returns \c false. | - | ||||||
3041 | - | |||||||
3042 | If \a value is not of the same type type as the property, a conversion | - | ||||||
3043 | is attempted. An empty QVariant() is equivalent to a call to reset() | - | ||||||
3044 | if this property is resetable, or setting a default-constructed object | - | ||||||
3045 | otherwise. | - | ||||||
3046 | - | |||||||
3047 | \sa read(), reset(), isWritable() | - | ||||||
3048 | */ | - | ||||||
3049 | bool QMetaProperty::write(QObject *object, const QVariant &value) const | - | ||||||
3050 | { | - | ||||||
3051 | if (!object || !isWritable()) | - | ||||||
3052 | return false; | - | ||||||
3053 | - | |||||||
3054 | QVariant v = value; | - | ||||||
3055 | uint t = QVariant::Invalid; | - | ||||||
3056 | if (isEnumType()) { | - | ||||||
3057 | if (v.type() == QVariant::String) { | - | ||||||
3058 | bool ok; | - | ||||||
3059 | if (isFlagType()) | - | ||||||
3060 | v = QVariant(menum.keysToValue(value.toByteArray(), &ok)); | - | ||||||
3061 | else | - | ||||||
3062 | v = QVariant(menum.keyToValue(value.toByteArray(), &ok)); | - | ||||||
3063 | if (!ok) | - | ||||||
3064 | return false; | - | ||||||
3065 | } else if (v.type() != QVariant::Int && v.type() != QVariant::UInt) { | - | ||||||
3066 | int enumMetaTypeId = QMetaType::type(qualifiedName(menum)); | - | ||||||
3067 | if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData()) | - | ||||||
3068 | return false; | - | ||||||
3069 | v = QVariant(*reinterpret_cast<const int *>(v.constData())); | - | ||||||
3070 | } | - | ||||||
3071 | v.convert(QVariant::Int); | - | ||||||
3072 | } else { | - | ||||||
3073 | int handle = priv(mobj->d.data)->propertyData + 3*idx; | - | ||||||
3074 | const char *typeName = 0; | - | ||||||
3075 | Q_ASSERT(priv(mobj->d.data)->revision >= 7); | - | ||||||
3076 | uint typeInfo = mobj->d.data[handle + 1]; | - | ||||||
3077 | if (!(typeInfo & IsUnresolvedType)) | - | ||||||
3078 | t = typeInfo; | - | ||||||
3079 | else { | - | ||||||
3080 | typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask); | - | ||||||
3081 | t = QMetaType::type(typeName); | - | ||||||
3082 | if (t == QMetaType::UnknownType) | - | ||||||
3083 | t = registerPropertyType(); | - | ||||||
3084 | if (t == QMetaType::UnknownType) | - | ||||||
3085 | return false; | - | ||||||
3086 | } | - | ||||||
3087 | if (t != QMetaType::QVariant && int(t) != value.userType()) { | - | ||||||
3088 | if (!value.isValid()) { | - | ||||||
3089 | if (isResettable()) | - | ||||||
3090 | return reset(object); | - | ||||||
3091 | v = QVariant(t, 0); | - | ||||||
3092 | } else if (!v.convert(t)) { | - | ||||||
3093 | return false; | - | ||||||
3094 | } | - | ||||||
3095 | } | - | ||||||
3096 | } | - | ||||||
3097 | - | |||||||
3098 | // the status variable is changed by qt_metacall to indicate what it did | - | ||||||
3099 | // this feature is currently only used by Qt D-Bus and should not be depended | - | ||||||
3100 | // upon. Don't change it without looking into QDBusAbstractInterface first | - | ||||||
3101 | // -1 (unchanged): normal qt_metacall, result stored in argv[0] | - | ||||||
3102 | // changed: result stored directly in value, return the value of status | - | ||||||
3103 | int status = -1; | - | ||||||
3104 | // the flags variable is used by the declarative module to implement | - | ||||||
3105 | // interception of property writes. | - | ||||||
3106 | int flags = 0; | - | ||||||
3107 | void *argv[] = { 0, &v, &status, &flags }; | - | ||||||
3108 | if (t == QMetaType::QVariant) | - | ||||||
3109 | argv[0] = &v; | - | ||||||
3110 | else | - | ||||||
3111 | argv[0] = v.data(); | - | ||||||
3112 | if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) | - | ||||||
3113 | mobj->d.static_metacall(object, QMetaObject::WriteProperty, idx, argv); | - | ||||||
3114 | else | - | ||||||
3115 | QMetaObject::metacall(object, QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv); | - | ||||||
3116 | - | |||||||
3117 | return status; | - | ||||||
3118 | } | - | ||||||
3119 | - | |||||||
3120 | /*! | - | ||||||
3121 | Resets the property for the given \a object with a reset method. | - | ||||||
3122 | Returns \c true if the reset worked; otherwise returns \c false. | - | ||||||
3123 | - | |||||||
3124 | Reset methods are optional; only a few properties support them. | - | ||||||
3125 | - | |||||||
3126 | \sa read(), write() | - | ||||||
3127 | */ | - | ||||||
3128 | bool QMetaProperty::reset(QObject *object) const | - | ||||||
3129 | { | - | ||||||
3130 | if (!object || !mobj || !isResettable()) | - | ||||||
3131 | return false; | - | ||||||
3132 | void *argv[] = { 0 }; | - | ||||||
3133 | if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) | - | ||||||
3134 | mobj->d.static_metacall(object, QMetaObject::ResetProperty, idx, argv); | - | ||||||
3135 | else | - | ||||||
3136 | QMetaObject::metacall(object, QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv); | - | ||||||
3137 | return true; | - | ||||||
3138 | } | - | ||||||
3139 | /*! | - | ||||||
3140 | \since 5.5 | - | ||||||
3141 | - | |||||||
3142 | Reads the property's value from the given \a gadget. Returns the value | - | ||||||
3143 | if it was able to read it; otherwise returns an invalid variant. | - | ||||||
3144 | - | |||||||
3145 | This function should only be used if this is a property of a Q_GADGET | - | ||||||
3146 | */ | - | ||||||
3147 | QVariant QMetaProperty::readOnGadget(const void *gadget) const | - | ||||||
3148 | { | - | ||||||
3149 | Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall); | - | ||||||
3150 | return read(reinterpret_cast<const QObject*>(gadget)); | - | ||||||
3151 | } | - | ||||||
3152 | - | |||||||
3153 | /*! | - | ||||||
3154 | \since 5.5 | - | ||||||
3155 | - | |||||||
3156 | Writes \a value as the property's value to the given \a gadget. Returns | - | ||||||
3157 | true if the write succeeded; otherwise returns \c false. | - | ||||||
3158 | - | |||||||
3159 | This function should only be used if this is a property of a Q_GADGET | - | ||||||
3160 | */ | - | ||||||
3161 | bool QMetaProperty::writeOnGadget(void *gadget, const QVariant &value) const | - | ||||||
3162 | { | - | ||||||
3163 | Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall); | - | ||||||
3164 | return write(reinterpret_cast<QObject*>(gadget), value); | - | ||||||
3165 | } | - | ||||||
3166 | - | |||||||
3167 | /*! | - | ||||||
3168 | \since 5.5 | - | ||||||
3169 | - | |||||||
3170 | Resets the property for the given \a gadget with a reset method. | - | ||||||
3171 | Returns \c true if the reset worked; otherwise returns \c false. | - | ||||||
3172 | - | |||||||
3173 | Reset methods are optional; only a few properties support them. | - | ||||||
3174 | - | |||||||
3175 | This function should only be used if this is a property of a Q_GADGET | - | ||||||
3176 | */ | - | ||||||
3177 | bool QMetaProperty::resetOnGadget(void *gadget) const | - | ||||||
3178 | { | - | ||||||
3179 | Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall); | - | ||||||
3180 | return reset(reinterpret_cast<QObject*>(gadget)); | - | ||||||
3181 | } | - | ||||||
3182 | - | |||||||
3183 | /*! | - | ||||||
3184 | Returns \c true if this property can be reset to a default value; otherwise | - | ||||||
3185 | returns \c false. | - | ||||||
3186 | - | |||||||
3187 | \sa reset() | - | ||||||
3188 | */ | - | ||||||
3189 | bool QMetaProperty::isResettable() const | - | ||||||
3190 | { | - | ||||||
3191 | if (!mobj) | - | ||||||
3192 | return false; | - | ||||||
3193 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3194 | return flags & Resettable; | - | ||||||
3195 | } | - | ||||||
3196 | - | |||||||
3197 | /*! | - | ||||||
3198 | Returns \c true if this property is readable; otherwise returns \c false. | - | ||||||
3199 | - | |||||||
3200 | \sa isWritable(), read(), isValid() | - | ||||||
3201 | */ | - | ||||||
3202 | bool QMetaProperty::isReadable() const | - | ||||||
3203 | { | - | ||||||
3204 | if (!mobj) | - | ||||||
3205 | return false; | - | ||||||
3206 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3207 | return flags & Readable; | - | ||||||
3208 | } | - | ||||||
3209 | - | |||||||
3210 | /*! | - | ||||||
3211 | Returns \c true if this property has a corresponding change notify signal; | - | ||||||
3212 | otherwise returns \c false. | - | ||||||
3213 | - | |||||||
3214 | \sa notifySignal() | - | ||||||
3215 | */ | - | ||||||
3216 | bool QMetaProperty::hasNotifySignal() const | - | ||||||
3217 | { | - | ||||||
3218 | if (!mobj) | - | ||||||
3219 | return false; | - | ||||||
3220 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3221 | return flags & Notify; | - | ||||||
3222 | } | - | ||||||
3223 | - | |||||||
3224 | /*! | - | ||||||
3225 | \since 4.5 | - | ||||||
3226 | - | |||||||
3227 | Returns the QMetaMethod instance of the property change notifying signal if | - | ||||||
3228 | one was specified, otherwise returns an invalid QMetaMethod. | - | ||||||
3229 | - | |||||||
3230 | \sa hasNotifySignal() | - | ||||||
3231 | */ | - | ||||||
3232 | QMetaMethod QMetaProperty::notifySignal() const | - | ||||||
3233 | { | - | ||||||
3234 | int id = notifySignalIndex(); | - | ||||||
3235 | if (id != -1) | - | ||||||
3236 | return mobj->method(id); | - | ||||||
3237 | else | - | ||||||
3238 | return QMetaMethod(); | - | ||||||
3239 | } | - | ||||||
3240 | - | |||||||
3241 | /*! | - | ||||||
3242 | \since 4.6 | - | ||||||
3243 | - | |||||||
3244 | Returns the index of the property change notifying signal if one was | - | ||||||
3245 | specified, otherwise returns -1. | - | ||||||
3246 | - | |||||||
3247 | \sa hasNotifySignal() | - | ||||||
3248 | */ | - | ||||||
3249 | int QMetaProperty::notifySignalIndex() const | - | ||||||
3250 | { | - | ||||||
3251 | if (hasNotifySignal()) { | - | ||||||
3252 | int offset = priv(mobj->d.data)->propertyData + | - | ||||||
3253 | priv(mobj->d.data)->propertyCount * 3 + idx; | - | ||||||
3254 | return mobj->d.data[offset] + mobj->methodOffset(); | - | ||||||
3255 | } else { | - | ||||||
3256 | return -1; | - | ||||||
3257 | } | - | ||||||
3258 | } | - | ||||||
3259 | - | |||||||
3260 | // This method has been around for a while, but the documentation was marked \internal until 5.1 | - | ||||||
3261 | /*! | - | ||||||
3262 | \since 5.1 | - | ||||||
3263 | - | |||||||
3264 | Returns the property revision if one was | - | ||||||
3265 | specified by REVISION, otherwise returns 0. | - | ||||||
3266 | */ | - | ||||||
3267 | int QMetaProperty::revision() const | - | ||||||
3268 | { | - | ||||||
3269 | if (!mobj) | - | ||||||
3270 | return 0; | - | ||||||
3271 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3272 | if (flags & Revisioned) { | - | ||||||
3273 | int offset = priv(mobj->d.data)->propertyData + | - | ||||||
3274 | priv(mobj->d.data)->propertyCount * 3 + idx; | - | ||||||
3275 | // Revision data is placed after NOTIFY data, if present. | - | ||||||
3276 | // Iterate through properties to discover whether we have NOTIFY signals. | - | ||||||
3277 | for (int i = 0; i < priv(mobj->d.data)->propertyCount; ++i) { | - | ||||||
3278 | int handle = priv(mobj->d.data)->propertyData + 3*i; | - | ||||||
3279 | if (mobj->d.data[handle + 2] & Notify) { | - | ||||||
3280 | offset += priv(mobj->d.data)->propertyCount; | - | ||||||
3281 | break; | - | ||||||
3282 | } | - | ||||||
3283 | } | - | ||||||
3284 | return mobj->d.data[offset]; | - | ||||||
3285 | } else { | - | ||||||
3286 | return 0; | - | ||||||
3287 | } | - | ||||||
3288 | } | - | ||||||
3289 | - | |||||||
3290 | /*! | - | ||||||
3291 | Returns \c true if this property is writable; otherwise returns | - | ||||||
3292 | false. | - | ||||||
3293 | - | |||||||
3294 | \sa isReadable(), write() | - | ||||||
3295 | */ | - | ||||||
3296 | bool QMetaProperty::isWritable() const | - | ||||||
3297 | { | - | ||||||
3298 | if (!mobj) | - | ||||||
3299 | return false; | - | ||||||
3300 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3301 | return flags & Writable; | - | ||||||
3302 | } | - | ||||||
3303 | - | |||||||
3304 | - | |||||||
3305 | /*! | - | ||||||
3306 | Returns \c true if this property is designable for the given \a object; | - | ||||||
3307 | otherwise returns \c false. | - | ||||||
3308 | - | |||||||
3309 | If no \a object is given, the function returns \c false if the | - | ||||||
3310 | \c{Q_PROPERTY()}'s \c DESIGNABLE attribute is false; otherwise | - | ||||||
3311 | returns \c true (if the attribute is true or is a function or expression). | - | ||||||
3312 | - | |||||||
3313 | \sa isScriptable(), isStored() | - | ||||||
3314 | */ | - | ||||||
3315 | bool QMetaProperty::isDesignable(const QObject *object) const | - | ||||||
3316 | { | - | ||||||
3317 | if (!mobj) | - | ||||||
3318 | return false; | - | ||||||
3319 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3320 | bool b = flags & Designable; | - | ||||||
3321 | if (object) { | - | ||||||
3322 | void *argv[] = { &b }; | - | ||||||
3323 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyDesignable, | - | ||||||
3324 | idx + mobj->propertyOffset(), argv); | - | ||||||
3325 | } | - | ||||||
3326 | return b; | - | ||||||
3327 | - | |||||||
3328 | - | |||||||
3329 | } | - | ||||||
3330 | - | |||||||
3331 | /*! | - | ||||||
3332 | Returns \c true if the property is scriptable for the given \a object; | - | ||||||
3333 | otherwise returns \c false. | - | ||||||
3334 | - | |||||||
3335 | If no \a object is given, the function returns \c false if the | - | ||||||
3336 | \c{Q_PROPERTY()}'s \c SCRIPTABLE attribute is false; otherwise returns | - | ||||||
3337 | true (if the attribute is true or is a function or expression). | - | ||||||
3338 | - | |||||||
3339 | \sa isDesignable(), isStored() | - | ||||||
3340 | */ | - | ||||||
3341 | bool QMetaProperty::isScriptable(const QObject *object) const | - | ||||||
3342 | { | - | ||||||
3343 | if (!mobj) | - | ||||||
3344 | return false; | - | ||||||
3345 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3346 | bool b = flags & Scriptable; | - | ||||||
3347 | if (object) { | - | ||||||
3348 | void *argv[] = { &b }; | - | ||||||
3349 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyScriptable, | - | ||||||
3350 | idx + mobj->propertyOffset(), argv); | - | ||||||
3351 | } | - | ||||||
3352 | return b; | - | ||||||
3353 | } | - | ||||||
3354 | - | |||||||
3355 | /*! | - | ||||||
3356 | Returns \c true if the property is stored for \a object; otherwise returns | - | ||||||
3357 | false. | - | ||||||
3358 | - | |||||||
3359 | If no \a object is given, the function returns \c false if the | - | ||||||
3360 | \c{Q_PROPERTY()}'s \c STORED attribute is false; otherwise returns | - | ||||||
3361 | true (if the attribute is true or is a function or expression). | - | ||||||
3362 | - | |||||||
3363 | \sa isDesignable(), isScriptable() | - | ||||||
3364 | */ | - | ||||||
3365 | bool QMetaProperty::isStored(const QObject *object) const | - | ||||||
3366 | { | - | ||||||
3367 | if (!mobj) | - | ||||||
3368 | return false; | - | ||||||
3369 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3370 | bool b = flags & Stored; | - | ||||||
3371 | if (object) { | - | ||||||
3372 | void *argv[] = { &b }; | - | ||||||
3373 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyStored, | - | ||||||
3374 | idx + mobj->propertyOffset(), argv); | - | ||||||
3375 | } | - | ||||||
3376 | return b; | - | ||||||
3377 | } | - | ||||||
3378 | - | |||||||
3379 | /*! | - | ||||||
3380 | Returns \c true if this property is designated as the \c USER | - | ||||||
3381 | property, i.e., the one that the user can edit for \a object or | - | ||||||
3382 | that is significant in some other way. Otherwise it returns | - | ||||||
3383 | false. e.g., the \c text property is the \c USER editable property | - | ||||||
3384 | of a QLineEdit. | - | ||||||
3385 | - | |||||||
3386 | If \a object is null, the function returns \c false if the \c | - | ||||||
3387 | {Q_PROPERTY()}'s \c USER attribute is false. Otherwise it returns | - | ||||||
3388 | true. | - | ||||||
3389 | - | |||||||
3390 | \sa QMetaObject::userProperty(), isDesignable(), isScriptable() | - | ||||||
3391 | */ | - | ||||||
3392 | bool QMetaProperty::isUser(const QObject *object) const | - | ||||||
3393 | { | - | ||||||
3394 | if (!mobj) | - | ||||||
3395 | return false; | - | ||||||
3396 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3397 | bool b = flags & User; | - | ||||||
3398 | if (object) { | - | ||||||
3399 | void *argv[] = { &b }; | - | ||||||
3400 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyUser, | - | ||||||
3401 | idx + mobj->propertyOffset(), argv); | - | ||||||
3402 | } | - | ||||||
3403 | return b; | - | ||||||
3404 | } | - | ||||||
3405 | - | |||||||
3406 | /*! | - | ||||||
3407 | \since 4.6 | - | ||||||
3408 | Returns \c true if the property is constant; otherwise returns \c false. | - | ||||||
3409 | - | |||||||
3410 | A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute | - | ||||||
3411 | is set. | - | ||||||
3412 | */ | - | ||||||
3413 | bool QMetaProperty::isConstant() const | - | ||||||
3414 | { | - | ||||||
3415 | if (!mobj) | - | ||||||
3416 | return false; | - | ||||||
3417 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3418 | return flags & Constant; | - | ||||||
3419 | } | - | ||||||
3420 | - | |||||||
3421 | /*! | - | ||||||
3422 | \since 4.6 | - | ||||||
3423 | Returns \c true if the property is final; otherwise returns \c false. | - | ||||||
3424 | - | |||||||
3425 | A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute | - | ||||||
3426 | is set. | - | ||||||
3427 | */ | - | ||||||
3428 | bool QMetaProperty::isFinal() const | - | ||||||
3429 | { | - | ||||||
3430 | if (!mobj) | - | ||||||
3431 | return false; | - | ||||||
3432 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3433 | return flags & Final; | - | ||||||
3434 | } | - | ||||||
3435 | - | |||||||
3436 | /*! | - | ||||||
3437 | \obsolete | - | ||||||
3438 | - | |||||||
3439 | Returns \c true if the property is editable for the given \a object; | - | ||||||
3440 | otherwise returns \c false. | - | ||||||
3441 | - | |||||||
3442 | If no \a object is given, the function returns \c false if the | - | ||||||
3443 | \c{Q_PROPERTY()}'s \c EDITABLE attribute is false; otherwise returns | - | ||||||
3444 | true (if the attribute is true or is a function or expression). | - | ||||||
3445 | - | |||||||
3446 | \sa isDesignable(), isScriptable(), isStored() | - | ||||||
3447 | */ | - | ||||||
3448 | bool QMetaProperty::isEditable(const QObject *object) const | - | ||||||
3449 | { | - | ||||||
3450 | if (!mobj) | - | ||||||
3451 | return false; | - | ||||||
3452 | int flags = mobj->d.data[handle + 2]; | - | ||||||
3453 | bool b = flags & Editable; | - | ||||||
3454 | if (object) { | - | ||||||
3455 | void *argv[] = { &b }; | - | ||||||
3456 | QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyEditable, | - | ||||||
3457 | idx + mobj->propertyOffset(), argv); | - | ||||||
3458 | } | - | ||||||
3459 | return b; | - | ||||||
3460 | } | - | ||||||
3461 | - | |||||||
3462 | /*! | - | ||||||
3463 | \class QMetaClassInfo | - | ||||||
3464 | \inmodule QtCore | - | ||||||
3465 | - | |||||||
3466 | \brief The QMetaClassInfo class provides additional information | - | ||||||
3467 | about a class. | - | ||||||
3468 | - | |||||||
3469 | \ingroup objectmodel | - | ||||||
3470 | - | |||||||
3471 | Class information items are simple \e{name}--\e{value} pairs that | - | ||||||
3472 | are specified using Q_CLASSINFO() in the source code. The | - | ||||||
3473 | information can be retrieved using name() and value(). For example: | - | ||||||
3474 | - | |||||||
3475 | \snippet code/src_corelib_kernel_qmetaobject.cpp 5 | - | ||||||
3476 | - | |||||||
3477 | This mechanism is free for you to use in your Qt applications. Qt | - | ||||||
3478 | doesn't use it for any of its classes. | - | ||||||
3479 | - | |||||||
3480 | \sa QMetaObject | - | ||||||
3481 | */ | - | ||||||
3482 | - | |||||||
3483 | - | |||||||
3484 | /*! | - | ||||||
3485 | \fn QMetaClassInfo::QMetaClassInfo() | - | ||||||
3486 | \internal | - | ||||||
3487 | */ | - | ||||||
3488 | - | |||||||
3489 | /*! | - | ||||||
3490 | \fn const QMetaObject *QMetaClassInfo::enclosingMetaObject() const | - | ||||||
3491 | \internal | - | ||||||
3492 | */ | - | ||||||
3493 | - | |||||||
3494 | /*! | - | ||||||
3495 | Returns the name of this item. | - | ||||||
3496 | - | |||||||
3497 | \sa value() | - | ||||||
3498 | */ | - | ||||||
3499 | const char *QMetaClassInfo::name() const | - | ||||||
3500 | { | - | ||||||
3501 | if (!mobj) | - | ||||||
3502 | return 0; | - | ||||||
3503 | return rawStringData(mobj, mobj->d.data[handle]); | - | ||||||
3504 | } | - | ||||||
3505 | - | |||||||
3506 | /*! | - | ||||||
3507 | Returns the value of this item. | - | ||||||
3508 | - | |||||||
3509 | \sa name() | - | ||||||
3510 | */ | - | ||||||
3511 | const char* QMetaClassInfo::value() const | - | ||||||
3512 | { | - | ||||||
3513 | if (!mobj) | - | ||||||
3514 | return 0; | - | ||||||
3515 | return rawStringData(mobj, mobj->d.data[handle + 1]); | - | ||||||
3516 | } | - | ||||||
3517 | - | |||||||
3518 | /*! | - | ||||||
3519 | \macro QGenericArgument Q_ARG(Type, const Type &value) | - | ||||||
3520 | \relates QMetaObject | - | ||||||
3521 | - | |||||||
3522 | This macro takes a \a Type and a \a value of that type and | - | ||||||
3523 | returns a \l QGenericArgument object that can be passed to | - | ||||||
3524 | QMetaObject::invokeMethod(). | - | ||||||
3525 | - | |||||||
3526 | \sa Q_RETURN_ARG() | - | ||||||
3527 | */ | - | ||||||
3528 | - | |||||||
3529 | /*! | - | ||||||
3530 | \macro QGenericReturnArgument Q_RETURN_ARG(Type, Type &value) | - | ||||||
3531 | \relates QMetaObject | - | ||||||
3532 | - | |||||||
3533 | This macro takes a \a Type and a non-const reference to a \a | - | ||||||
3534 | value of that type and returns a QGenericReturnArgument object | - | ||||||
3535 | that can be passed to QMetaObject::invokeMethod(). | - | ||||||
3536 | - | |||||||
3537 | \sa Q_ARG() | - | ||||||
3538 | */ | - | ||||||
3539 | - | |||||||
3540 | /*! | - | ||||||
3541 | \class QGenericArgument | - | ||||||
3542 | \inmodule QtCore | - | ||||||
3543 | - | |||||||
3544 | \brief The QGenericArgument class is an internal helper class for | - | ||||||
3545 | marshalling arguments. | - | ||||||
3546 | - | |||||||
3547 | This class should never be used directly. Please use the \l Q_ARG() | - | ||||||
3548 | macro instead. | - | ||||||
3549 | - | |||||||
3550 | \sa Q_ARG(), QMetaObject::invokeMethod(), QGenericReturnArgument | - | ||||||
3551 | */ | - | ||||||
3552 | - | |||||||
3553 | /*! | - | ||||||
3554 | \fn QGenericArgument::QGenericArgument(const char *name, const void *data) | - | ||||||
3555 | - | |||||||
3556 | Constructs a QGenericArgument object with the given \a name and \a data. | - | ||||||
3557 | */ | - | ||||||
3558 | - | |||||||
3559 | /*! | - | ||||||
3560 | \fn QGenericArgument::data () const | - | ||||||
3561 | - | |||||||
3562 | Returns the data set in the constructor. | - | ||||||
3563 | */ | - | ||||||
3564 | - | |||||||
3565 | /*! | - | ||||||
3566 | \fn QGenericArgument::name () const | - | ||||||
3567 | - | |||||||
3568 | Returns the name set in the constructor. | - | ||||||
3569 | */ | - | ||||||
3570 | - | |||||||
3571 | /*! | - | ||||||
3572 | \class QGenericReturnArgument | - | ||||||
3573 | \inmodule QtCore | - | ||||||
3574 | - | |||||||
3575 | \brief The QGenericReturnArgument class is an internal helper class for | - | ||||||
3576 | marshalling arguments. | - | ||||||
3577 | - | |||||||
3578 | This class should never be used directly. Please use the | - | ||||||
3579 | Q_RETURN_ARG() macro instead. | - | ||||||
3580 | - | |||||||
3581 | \sa Q_RETURN_ARG(), QMetaObject::invokeMethod(), QGenericArgument | - | ||||||
3582 | */ | - | ||||||
3583 | - | |||||||
3584 | /*! | - | ||||||
3585 | \fn QGenericReturnArgument::QGenericReturnArgument(const char *name, void *data) | - | ||||||
3586 | - | |||||||
3587 | Constructs a QGenericReturnArgument object with the given \a name | - | ||||||
3588 | and \a data. | - | ||||||
3589 | */ | - | ||||||
3590 | - | |||||||
3591 | /*! | - | ||||||
3592 | \internal | - | ||||||
3593 | If the local_method_index is a cloned method, return the index of the original. | - | ||||||
3594 | - | |||||||
3595 | Example: if the index of "destroyed()" is passed, the index of "destroyed(QObject*)" is returned | - | ||||||
3596 | */ | - | ||||||
3597 | int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index) | - | ||||||
3598 | { | - | ||||||
3599 | Q_ASSERT(local_method_index < get(mobj)->methodCount); | - | ||||||
3600 | int handle = get(mobj)->methodData + 5 * local_method_index; | - | ||||||
3601 | while (mobj->d.data[handle + 4] & MethodCloned) { | - | ||||||
3602 | Q_ASSERT(local_method_index > 0); | - | ||||||
3603 | handle -= 5; | - | ||||||
3604 | local_method_index--; | - | ||||||
3605 | } | - | ||||||
3606 | return local_method_index; | - | ||||||
3607 | } | - | ||||||
3608 | - | |||||||
3609 | /*! | - | ||||||
3610 | \internal | - | ||||||
3611 | - | |||||||
3612 | Returns the parameter type names extracted from the given \a signature. | - | ||||||
3613 | */ | - | ||||||
3614 | QList<QByteArray> QMetaObjectPrivate::parameterTypeNamesFromSignature(const char *signature) | - | ||||||
3615 | { | - | ||||||
3616 | QList<QByteArray> list; | - | ||||||
3617 | while (*signature && *signature != '(') | - | ||||||
3618 | ++signature; | - | ||||||
3619 | while (*signature && *signature != ')' && *++signature != ')') { | - | ||||||
3620 | const char *begin = signature; | - | ||||||
3621 | int level = 0; | - | ||||||
3622 | while (*signature && (level > 0 || *signature != ',') && *signature != ')') { | - | ||||||
3623 | if (*signature == '<') | - | ||||||
3624 | ++level; | - | ||||||
3625 | else if (*signature == '>') | - | ||||||
3626 | --level; | - | ||||||
3627 | ++signature; | - | ||||||
3628 | } | - | ||||||
3629 | list += QByteArray(begin, signature - begin); | - | ||||||
3630 | } | - | ||||||
3631 | return list; | - | ||||||
3632 | } | - | ||||||
3633 | - | |||||||
3634 | QT_END_NAMESPACE | - | ||||||
Source code | Switch to Preprocessed file |