1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QQML_H
41 #define QQML_H
42 
43 #include <QtQml/qqmlprivate.h>
44 
45 #include <QtCore/qbytearray.h>
46 #include <QtCore/qmetaobject.h>
47 
48 #define QML_VERSION     0x020000
49 #define QML_VERSION_STR "2.0"
50 
51 #define QML_PRIVATE_NAMESPACE \
52     QT_PREPEND_NAMESPACE(QQmlPrivate)
53 
54 #define QML_REGISTER_TYPES_AND_REVISIONS \
55     QT_PREPEND_NAMESPACE(qmlRegisterTypesAndRevisions)
56 
57 #define QML_DECLARE_TYPE(TYPE) \
58     Q_DECLARE_METATYPE(TYPE *) \
59     Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
60 
61 #define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \
62     Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
63 
64 #define QML_DECLARE_INTERFACE(INTERFACE) \
65     QML_DECLARE_TYPE(INTERFACE)
66 
67 #define QML_DECLARE_INTERFACE_HASMETATYPE(INTERFACE) \
68     QML_DECLARE_TYPE_HASMETATYPE(INTERFACE)
69 
70 #define QML_ELEMENT \
71     Q_CLASSINFO("QML.Element", "auto")
72 
73 #define QML_ANONYMOUS \
74     Q_CLASSINFO("QML.Element", "anonymous")
75 
76 #define QML_NAMED_ELEMENT(NAME) \
77     Q_CLASSINFO("QML.Element", #NAME)
78 
79 #define QML_UNCREATABLE(REASON) \
80     Q_CLASSINFO("QML.Creatable", "false") \
81     Q_CLASSINFO("QML.UncreatableReason", REASON)
82 
83 #define QML_SINGLETON \
84     Q_CLASSINFO("QML.Singleton", "true") \
85     enum class QmlIsSingleton {yes = true}; \
86     template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSingleton; \
87     template<typename T, typename... Args> \
88     friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
89 
90 #define QML_ADDED_IN_MINOR_VERSION(VERSION) \
91     Q_CLASSINFO("QML.AddedInMinorVersion", #VERSION)
92 
93 #define QML_REMOVED_IN_MINOR_VERSION(VERSION) \
94     Q_CLASSINFO("QML.RemovedInMinorVersion", #VERSION)
95 
96 #define QML_ATTACHED(ATTACHED_TYPE) \
97     Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \
98     using QmlAttachedType = ATTACHED_TYPE; \
99     template<class, class, bool> friend struct QML_PRIVATE_NAMESPACE::QmlAttached; \
100     template<class> friend struct QML_PRIVATE_NAMESPACE::QmlAttachedAccessor;
101 
102 #define QML_EXTENDED(EXTENDED_TYPE) \
103     Q_CLASSINFO("QML.Extended", #EXTENDED_TYPE) \
104     using QmlExtendedType = EXTENDED_TYPE; \
105     template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlExtended; \
106     template<typename T, typename... Args> \
107     friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
108 
109 #define QML_FOREIGN(FOREIGN_TYPE) \
110     Q_CLASSINFO("QML.Foreign", #FOREIGN_TYPE) \
111     using QmlForeignType = FOREIGN_TYPE; \
112     template<class, class> friend struct QML_PRIVATE_NAMESPACE::QmlResolved; \
113     template<typename T, typename... Args> \
114     friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
115 
116 #define QML_INTERFACE \
117     Q_CLASSINFO("QML.Element", "anonymous") \
118     enum class QmlIsInterface {yes = true}; \
119     template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
120     template<typename T, typename... Args> \
121     friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
122 
123 #define QML_UNAVAILABLE \
124     QML_FOREIGN(QQmlTypeNotAvailable)
125 
126 enum { /* TYPEINFO flags */
127     QML_HAS_ATTACHED_PROPERTIES = 0x01
128 };
129 
130 #define QML_DECLARE_TYPEINFO(TYPE, FLAGS) \
131 QT_BEGIN_NAMESPACE \
132 template <> \
133 class QQmlTypeInfo<TYPE > \
134 { \
135 public: \
136     enum { \
137         hasAttachedProperties = (((FLAGS) & QML_HAS_ATTACHED_PROPERTIES) == QML_HAS_ATTACHED_PROPERTIES) \
138     }; \
139 }; \
140 QT_END_NAMESPACE
141 
142 QT_BEGIN_NAMESPACE
143 
144 void Q_QML_EXPORT qmlClearTypeRegistrations();
145 
146 template<class T>
147 QQmlCustomParser *qmlCreateCustomParser();
148 
149 template<typename T>
qmlRegisterAnonymousType(const char * uri,int versionMajor)150 int qmlRegisterAnonymousType(const char *uri, int versionMajor)
151 {
152     QML_GETTYPENAMES
153 
154     QQmlPrivate::RegisterType type = {
155         0,
156 
157         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
158         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
159         0,
160         nullptr,
161         QString(),
162 
163         uri, versionMajor, 0, nullptr, &T::staticMetaObject,
164 
165         QQmlPrivate::attachedPropertiesFunc<T>(),
166         QQmlPrivate::attachedPropertiesMetaObject<T>(),
167 
168         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
169         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
170         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
171 
172         nullptr, nullptr,
173 
174         nullptr,
175         0
176     };
177 
178     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
179 }
180 
181 #if QT_DEPRECATED_SINCE(5, 14)
182 template<typename T>
qmlRegisterType()183 QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
184 {
185     return qmlRegisterAnonymousType<T>("", 1);
186 }
187 #endif
188 
189 int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor,
190                                              const char *qmlName, const QString& message);
191 
192 template<typename T>
qmlRegisterUncreatableType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,const QString & reason)193 int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
194 {
195     QML_GETTYPENAMES
196 
197     QQmlPrivate::RegisterType type = {
198         0,
199 
200         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
201         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
202         0,
203         nullptr,
204         reason,
205 
206         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
207 
208         QQmlPrivate::attachedPropertiesFunc<T>(),
209         QQmlPrivate::attachedPropertiesMetaObject<T>(),
210 
211         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
212         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
213         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
214 
215         nullptr, nullptr,
216 
217         nullptr,
218         0
219     };
220 
221     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
222 }
223 
224 template<typename T, int metaObjectRevision>
qmlRegisterUncreatableType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,const QString & reason)225 int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
226 {
227     QML_GETTYPENAMES
228 
229     QQmlPrivate::RegisterType type = {
230         1,
231 
232         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
233         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
234         0,
235         nullptr,
236         reason,
237 
238         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
239 
240         QQmlPrivate::attachedPropertiesFunc<T>(),
241         QQmlPrivate::attachedPropertiesMetaObject<T>(),
242 
243         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
244         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
245         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
246 
247         nullptr, nullptr,
248 
249         nullptr,
250         metaObjectRevision
251     };
252 
253     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
254 }
255 
256 template<typename T, typename E>
qmlRegisterExtendedUncreatableType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,const QString & reason)257 int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
258 {
259     QML_GETTYPENAMES
260 
261     QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
262     const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
263     if (!attached) {
264         attached = QQmlPrivate::attachedPropertiesFunc<T>();
265         attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
266     }
267 
268     QQmlPrivate::RegisterType type = {
269         0,
270 
271         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
272         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
273         0,
274         nullptr,
275         reason,
276 
277         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
278 
279         attached,
280         attachedMetaObject,
281 
282         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
283         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
284         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
285 
286         QQmlPrivate::createParent<E>, &E::staticMetaObject,
287 
288         nullptr,
289         0
290     };
291 
292     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
293 }
294 
295 template<typename T, typename E, int metaObjectRevision>
qmlRegisterExtendedUncreatableType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,const QString & reason)296 int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
297 {
298     QML_GETTYPENAMES
299 
300     QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
301     const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
302     if (!attached) {
303         attached = QQmlPrivate::attachedPropertiesFunc<T>();
304         attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
305     }
306 
307     QQmlPrivate::RegisterType type = {
308         1,
309 
310         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
311         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
312         0,
313         nullptr,
314         reason,
315 
316         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
317 
318         attached,
319         attachedMetaObject,
320 
321         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
322         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
323         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
324 
325         QQmlPrivate::createParent<E>, &E::staticMetaObject,
326 
327         nullptr,
328         metaObjectRevision
329     };
330 
331     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
332 }
333 
334 Q_QML_EXPORT int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason);
335 
336 template<typename T>
qmlRegisterType(const char * uri,int versionMajor,int versionMinor,const char * qmlName)337 int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
338 {
339     QML_GETTYPENAMES
340 
341     QQmlPrivate::RegisterType type = {
342         0,
343 
344         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
345         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
346         sizeof(T), QQmlPrivate::createInto<T>,
347         QString(),
348 
349         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
350 
351         QQmlPrivate::attachedPropertiesFunc<T>(),
352         QQmlPrivate::attachedPropertiesMetaObject<T>(),
353 
354         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
355         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
356         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
357 
358         nullptr, nullptr,
359 
360         nullptr,
361         0
362     };
363 
364     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
365 }
366 
367 template<typename T, int metaObjectRevision>
qmlRegisterType(const char * uri,int versionMajor,int versionMinor,const char * qmlName)368 int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
369 {
370     QML_GETTYPENAMES
371 
372     QQmlPrivate::RegisterType type = {
373         1,
374 
375         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
376         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
377         sizeof(T), QQmlPrivate::createInto<T>,
378         QString(),
379 
380         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
381 
382         QQmlPrivate::attachedPropertiesFunc<T>(),
383         QQmlPrivate::attachedPropertiesMetaObject<T>(),
384 
385         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
386         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
387         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
388 
389         nullptr, nullptr,
390 
391         nullptr,
392         metaObjectRevision
393     };
394 
395     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
396 }
397 
398 template<typename T, int metaObjectRevision>
qmlRegisterRevision(const char * uri,int versionMajor,int versionMinor)399 int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
400 {
401     QML_GETTYPENAMES
402 
403     QQmlPrivate::RegisterType type = {
404         1,
405 
406         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
407         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
408         sizeof(T), QQmlPrivate::createInto<T>,
409         QString(),
410 
411         uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject,
412 
413         QQmlPrivate::attachedPropertiesFunc<T>(),
414         QQmlPrivate::attachedPropertiesMetaObject<T>(),
415 
416         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
417         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
418         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
419 
420         nullptr, nullptr,
421 
422         nullptr,
423         metaObjectRevision
424     };
425 
426     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
427 }
428 
429 template<typename T, typename E>
qmlRegisterExtendedType(const char * uri,int versionMajor)430 int qmlRegisterExtendedType(const char *uri, int versionMajor)
431 {
432     QML_GETTYPENAMES
433 
434     QQmlPrivate::RegisterType type = {
435         0,
436 
437         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
438         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
439         0,
440         nullptr,
441         QString(),
442 
443         uri, versionMajor, 0, nullptr, &T::staticMetaObject,
444 
445         QQmlPrivate::attachedPropertiesFunc<T>(),
446         QQmlPrivate::attachedPropertiesMetaObject<T>(),
447 
448         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
449         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
450         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
451 
452         QQmlPrivate::createParent<E>, &E::staticMetaObject,
453 
454         nullptr,
455         0
456     };
457 
458     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
459 }
460 
461 #if QT_DEPRECATED_SINCE(5, 15)
462 template<typename T, typename E>
463 QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterExtendedType(uri, versionMajor) instead")
qmlRegisterExtendedType()464 int qmlRegisterExtendedType()
465 {
466     return qmlRegisterExtendedType<T, E>("", 0);
467 }
468 #endif
469 
470 template<typename T, typename E>
qmlRegisterExtendedType(const char * uri,int versionMajor,int versionMinor,const char * qmlName)471 int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
472                             const char *qmlName)
473 {
474     QML_GETTYPENAMES
475 
476     QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
477     const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
478     if (!attached) {
479         attached = QQmlPrivate::attachedPropertiesFunc<T>();
480         attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
481     }
482 
483     QQmlPrivate::RegisterType type = {
484         0,
485 
486         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
487         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
488         sizeof(T), QQmlPrivate::createInto<T>,
489         QString(),
490 
491         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
492 
493         attached,
494         attachedMetaObject,
495 
496         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
497         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
498         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
499 
500         QQmlPrivate::createParent<E>, &E::staticMetaObject,
501 
502         nullptr,
503         0
504     };
505 
506     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
507 }
508 
509 #if QT_DEPRECATED_SINCE(5, 15)
510 template<typename T>
511 QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterInterface(uri, versionMajor) instead")
qmlRegisterInterface(const char * typeName)512 int qmlRegisterInterface(const char *typeName)
513 {
514     QByteArray name(typeName);
515 
516     QByteArray pointerName(name + '*');
517     QByteArray listName("QQmlListProperty<" + name + '>');
518 
519     QQmlPrivate::RegisterInterface qmlInterface = {
520         1,
521 
522         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
523         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
524 
525         qobject_interface_iid<T *>(),
526         "",
527         0
528     };
529 
530     return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
531 }
532 #endif
533 
534 template<typename T>
qmlRegisterInterface(const char * uri,int versionMajor)535 int qmlRegisterInterface(const char *uri, int versionMajor)
536 {
537     QML_GETTYPENAMES
538 
539     QQmlPrivate::RegisterInterface qmlInterface = {
540         1,
541         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
542         qRegisterNormalizedMetaType<QQmlListProperty<T>>(listName.constData()),
543         qobject_interface_iid<T *>(),
544 
545         uri,
546         versionMajor
547     };
548 
549     return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
550 }
551 
552 template<typename T>
qmlRegisterCustomType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,QQmlCustomParser * parser)553 int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
554                           const char *qmlName, QQmlCustomParser *parser)
555 {
556     QML_GETTYPENAMES
557 
558     QQmlPrivate::RegisterType type = {
559         0,
560 
561         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
562         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
563         sizeof(T), QQmlPrivate::createInto<T>,
564         QString(),
565 
566         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
567 
568         QQmlPrivate::attachedPropertiesFunc<T>(),
569         QQmlPrivate::attachedPropertiesMetaObject<T>(),
570 
571         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
572         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
573         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
574 
575         nullptr, nullptr,
576 
577         parser,
578         0
579     };
580 
581     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
582 }
583 
584 template<typename T, int metaObjectRevision>
qmlRegisterCustomType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,QQmlCustomParser * parser)585 int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
586                           const char *qmlName, QQmlCustomParser *parser)
587 {
588     QML_GETTYPENAMES
589 
590     QQmlPrivate::RegisterType type = {
591         1,
592 
593         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
594         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
595         sizeof(T), QQmlPrivate::createInto<T>,
596         QString(),
597 
598         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
599 
600         QQmlPrivate::attachedPropertiesFunc<T>(),
601         QQmlPrivate::attachedPropertiesMetaObject<T>(),
602 
603         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
604         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
605         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
606 
607         nullptr, nullptr,
608 
609         parser,
610         metaObjectRevision
611     };
612 
613     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
614 }
615 
616 template<typename T, typename E>
qmlRegisterCustomExtendedType(const char * uri,int versionMajor,int versionMinor,const char * qmlName,QQmlCustomParser * parser)617 int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int versionMinor,
618                           const char *qmlName, QQmlCustomParser *parser)
619 {
620     QML_GETTYPENAMES
621 
622     QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
623     const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
624     if (!attached) {
625         attached = QQmlPrivate::attachedPropertiesFunc<T>();
626         attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
627     }
628 
629     QQmlPrivate::RegisterType type = {
630         0,
631 
632         qRegisterNormalizedMetaType<T *>(pointerName.constData()),
633         qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
634         sizeof(T), QQmlPrivate::createInto<T>,
635         QString(),
636 
637         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
638 
639         attached,
640         attachedMetaObject,
641 
642         QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
643         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
644         QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
645 
646         QQmlPrivate::createParent<E>, &E::staticMetaObject,
647 
648         parser,
649         0
650     };
651 
652     return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
653 }
654 
655 class QQmlContext;
656 class QQmlEngine;
657 class QJSValue;
658 class QJSEngine;
659 
660 #ifndef Q_QDOC
661 namespace QtQml {
662 #endif
663     // declared in namespace to avoid symbol conflicts with QtDeclarative
664     Q_QML_EXPORT void qmlExecuteDeferred(QObject *);
665     Q_QML_EXPORT QQmlContext *qmlContext(const QObject *);
666     Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *);
667 #if QT_DEPRECATED_SINCE(5, 14)
668     Q_QML_EXPORT QT_DEPRECATED_VERSION_X_5_14("Use qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc, bool")
669     QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true);
670     Q_QML_EXPORT QT_DEPRECATED_VERSION_X_5_14("Use qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc, bool")
671     QObject *qmlAttachedPropertiesObject(
672             int *, const QObject *, const QMetaObject *, bool create);
673 #endif
674     Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *,
675                                                                           const QMetaObject *);
676     Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func,
677                                                       bool create = true);
678 #ifndef Q_QDOC
679 }
680 
681 QT_WARNING_PUSH
682 QT_WARNING_DISABLE_CLANG("-Wheader-hygiene")
683 
684 // This is necessary to allow for QtQuick1 and QtQuick2 scenes in a single application.
685 using namespace QtQml;
686 
687 QT_WARNING_POP
688 
689 #endif // Q_QDOC
690 
691 //The C++ version of protected namespaces in qmldir
692 Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
693 Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor);
694 
695 template<typename T>
696 QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
697 {
698     // We don't need a concrete object to resolve the function. As T is a C++ type, it and all its
699     // super types should be registered as CppType (or not at all). We only need the object and its
700     // QML engine to resolve composite types. Therefore, the function is actually a static property
701     // of the C++ type system and we can cache it here for improved performance on further lookups.
702     static const auto func = qmlAttachedPropertiesFunction(nullptr, &T::staticMetaObject);
703     return qmlAttachedPropertiesObject(const_cast<QObject *>(obj), func, create);
704 }
705 
qmlRegisterSingletonType(const char * uri,int versionMajor,int versionMinor,const char * typeName,QJSValue (* callback)(QQmlEngine *,QJSEngine *))706 inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
707                                 QJSValue (*callback)(QQmlEngine *, QJSEngine *))
708 {
709     QQmlPrivate::RegisterSingletonType api = {
710         0,
711 
712         uri, versionMajor, versionMinor, typeName,
713 
714         callback, nullptr, nullptr, 0, 0, {}
715     };
716 
717     return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
718 }
719 
720 enum { QmlCurrentSingletonTypeRegistrationVersion = 3 };
721 template <typename T>
qmlRegisterSingletonType(const char * uri,int versionMajor,int versionMinor,const char * typeName,QObject * (* callback)(QQmlEngine *,QJSEngine *))722 inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
723                                 QObject *(*callback)(QQmlEngine *, QJSEngine *))
724 {
725     QML_GETTYPENAMES
726 
727     QQmlPrivate::RegisterSingletonType api = {
728         QmlCurrentSingletonTypeRegistrationVersion,
729 
730         uri, versionMajor, versionMinor, typeName,
731 
732         nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
733     };
734 
735     return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
736 }
737 
738 #ifdef Q_QDOC
739 template <typename T>
qmlRegisterSingletonType(const char * uri,int versionMajor,int versionMinor,const char * typeName,std::function<QObject * (QQmlEngine *,QJSEngine *)> callback)740 int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback)
741 #else
742 template <typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value
743                                                  && !std::is_convertible<F, QObject *(*)(QQmlEngine *, QJSEngine *)>::value, void>::type* = nullptr>
744 inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
745                                     F&& callback)
746 #endif
747 {
748 
749     QML_GETTYPENAMES
750 
751     QQmlPrivate::RegisterSingletonType api = {
752         QmlCurrentSingletonTypeRegistrationVersion,
753 
754         uri, versionMajor, versionMinor, typeName,
755 
756         nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
757     };
758 
759     return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
760 }
761 
762 #ifdef Q_QDOC
763 int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject)
764 #else
765 template<typename T>
766 inline auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor,
767                                          const char *typeName, T *cppObject) -> typename std::enable_if<std::is_base_of<QObject, T>::value, int>::type
768 #endif
769 {
770     QQmlPrivate::RegisterSingletonFunctor registrationFunctor;
771     registrationFunctor.m_object = cppObject;
772     return qmlRegisterSingletonType<T>(uri, versionMajor, versionMinor, typeName, registrationFunctor);
773 }
774 
qmlRegisterSingletonType(const QUrl & url,const char * uri,int versionMajor,int versionMinor,const char * qmlName)775 inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
776 {
777     if (url.isRelative()) {
778         // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
779         qWarning("qmlRegisterSingletonType requires absolute URLs.");
780         return 0;
781     }
782 
783     QQmlPrivate::RegisterCompositeSingletonType type = {
784         url,
785         uri,
786         versionMajor,
787         versionMinor,
788         qmlName
789     };
790 
791     return QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &type);
792 }
793 
qmlRegisterType(const QUrl & url,const char * uri,int versionMajor,int versionMinor,const char * qmlName)794 inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
795 {
796     if (url.isRelative()) {
797         // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
798         qWarning("qmlRegisterType requires absolute URLs.");
799         return 0;
800     }
801 
802     QQmlPrivate::RegisterCompositeType type = {
803         url,
804         uri,
805         versionMajor,
806         versionMinor,
807         qmlName
808     };
809 
810     return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type);
811 }
812 
813 template<class T, class Resolved, class Extended, bool Singleton, bool Interface>
814 struct QmlTypeAndRevisionsRegistration;
815 
816 template<class T, class Resolved, class Extended>
817 struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
818     static void registerTypeAndRevisions(const char *uri, int versionMajor)
819     {
820         QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
821                     uri, versionMajor, &T::staticMetaObject);
822     }
823 };
824 
825 template<class T, class Resolved>
826 struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true, false> {
827     static void registerTypeAndRevisions(const char *uri, int versionMajor)
828     {
829         QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved>(
830                     uri, versionMajor, &T::staticMetaObject);
831     }
832 };
833 
834 template<class T, class Resolved>
835 struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> {
836     static void registerTypeAndRevisions(const char *uri, int versionMajor)
837     {
838         qmlRegisterInterface<Resolved>(uri, versionMajor);
839     }
840 };
841 
842 template<typename T = void, typename... Args>
843 void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor);
844 
845 template<typename T, typename... Args>
846 void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor)
847 {
848     QmlTypeAndRevisionsRegistration<
849             T, typename QQmlPrivate::QmlResolved<T>::Type,
850             typename QQmlPrivate::QmlExtended<T>::Type,
851             QQmlPrivate::QmlSingleton<T>::Value,
852             QQmlPrivate::QmlInterface<T>::Value>
853             ::registerTypeAndRevisions(uri, versionMajor);
854     qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor);
855 }
856 
857 template<>
858 inline void qmlRegisterTypesAndRevisions<>(const char *, int) {}
859 
860 inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
861                                              const char *uri, int versionMajor)
862 {
863     QQmlPrivate::RegisterTypeAndRevisions type = {
864         0,
865         0,
866         0,
867         0,
868         nullptr,
869 
870         uri,
871         versionMajor,
872 
873         metaObject,
874         metaObject,
875 
876         nullptr,
877         nullptr,
878 
879         -1,
880         -1,
881         -1,
882 
883         nullptr,
884         nullptr,
885 
886         &qmlCreateCustomParser<void>
887     };
888 
889     qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type);
890 }
891 
892 int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
893 
894 QT_END_NAMESPACE
895 
896 QML_DECLARE_TYPE(QObject)
897 Q_DECLARE_METATYPE(QVariant)
898 
899 #endif // QQML_H
900