1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQML_H
5#define QQML_H
6
7#include <QtQml/qqmlprivate.h>
8#include <QtQml/qjsvalue.h>
9#include <QtQml/qqmlregistration.h>
10
11#include <QtCore/qbytearray.h>
12#include <QtCore/qmetaobject.h>
13#include <QtCore/qmetacontainer.h>
14#include <QtCore/qversionnumber.h>
15
16#define QML_VERSION 0x020000
17#define QML_VERSION_STR "2.0"
18
19#define QML_DECLARE_TYPE(TYPE) \
20 Q_DECLARE_METATYPE(TYPE*) \
21 Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
22
23#define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \
24 Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
25
26#define QML_DECLARE_INTERFACE(INTERFACE) \
27 QML_DECLARE_TYPE(INTERFACE)
28
29#define QML_DECLARE_INTERFACE_HASMETATYPE(INTERFACE) \
30 QML_DECLARE_TYPE_HASMETATYPE(INTERFACE)
31
32enum { /* TYPEINFO flags */
33 QML_HAS_ATTACHED_PROPERTIES = 0x01
34};
35
36#define QML_DECLARE_TYPEINFO(TYPE, FLAGS) \
37QT_BEGIN_NAMESPACE \
38template <> \
39class QQmlTypeInfo<TYPE > \
40{ \
41public: \
42 enum { \
43 hasAttachedProperties = (((FLAGS) & QML_HAS_ATTACHED_PROPERTIES) == QML_HAS_ATTACHED_PROPERTIES) \
44 }; \
45}; \
46QT_END_NAMESPACE
47
48QT_BEGIN_NAMESPACE
49
50void Q_QML_EXPORT qmlClearTypeRegistrations();
51
52template<class T>
53QQmlCustomParser *qmlCreateCustomParser();
54
55template<typename T>
56int qmlRegisterAnonymousType(const char *uri, int versionMajor)
57{
58 QQmlPrivate::RegisterType type = {
59 QQmlPrivate::RegisterType::CurrentVersion,
60 QQmlPrivate::QmlMetaType<T>::self(),
61 QQmlPrivate::QmlMetaType<T>::list(),
62 0,
63 nullptr, nullptr,
64 QString(),
65 QQmlPrivate::ValueType<T, void>::create,
66
67 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: 0), nullptr,
68 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
69
70 QQmlPrivate::attachedPropertiesFunc<T>(),
71 QQmlPrivate::attachedPropertiesMetaObject<T>(),
72
73 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
74 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
75 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
76
77 nullptr, nullptr,
78
79 nullptr,
80 QTypeRevision::zero(),
81 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
82 QQmlPrivate::ValueTypeCreationMethod::None,
83 };
84
85 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
86}
87
88//! \internal
89template<typename T, int metaObjectRevisionMinor>
90int qmlRegisterAnonymousType(const char *uri, int versionMajor)
91{
92 QQmlPrivate::RegisterType type = {
93 QQmlPrivate::RegisterType::CurrentVersion,
94 QQmlPrivate::QmlMetaType<T>::self(),
95 QQmlPrivate::QmlMetaType<T>::list(),
96 0,
97 nullptr,
98 nullptr,
99 QString(),
100 QQmlPrivate::ValueType<T, void>::create,
101
102 uri,
103 QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: 0),
104 nullptr,
105 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
106
107 QQmlPrivate::attachedPropertiesFunc<T>(),
108 QQmlPrivate::attachedPropertiesMetaObject<T>(),
109
110 QQmlPrivate::StaticCastSelector<T, QQmlParserStatus>::cast(),
111 QQmlPrivate::StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
112 QQmlPrivate::StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
113
114 nullptr,
115 nullptr,
116
117 nullptr,
118 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevisionMinor),
119 QQmlPrivate::StaticCastSelector<T, QQmlFinalizerHook>::cast(),
120 QQmlPrivate::ValueTypeCreationMethod::None,
121 };
122
123 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
124}
125
126//! \internal
127template<typename T>
128void qmlRegisterAnonymousTypesAndRevisions(const char *uri, int versionMajor)
129{
130 // Anonymous types are not creatable, no need to warn about missing acceptable constructors.
131 QQmlPrivate::qmlRegisterTypeAndRevisions<T, void>(
132 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), nullptr,
133 nullptr, true);
134}
135
136class QQmlTypeNotAvailable : public QObject
137{
138 Q_OBJECT
139 QML_NAMED_ELEMENT(TypeNotAvailable)
140 QML_ADDED_IN_VERSION(2, 15)
141 QML_UNCREATABLE("Type not available.")
142};
143
144int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor,
145 const char *qmlName, const QString &message);
146
147template<typename T>
148int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
149{
150 QQmlPrivate::RegisterType type = {
151 QQmlPrivate::RegisterType::CurrentVersion,
152 QQmlPrivate::QmlMetaType<T>::self(),
153 QQmlPrivate::QmlMetaType<T>::list(),
154 0,
155 nullptr,
156 nullptr,
157 reason,
158 QQmlPrivate::ValueType<T, void>::create,
159
160 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
161 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
162
163 QQmlPrivate::attachedPropertiesFunc<T>(),
164 QQmlPrivate::attachedPropertiesMetaObject<T>(),
165
166 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
167 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
168 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
169
170 nullptr, nullptr,
171
172 nullptr,
173 QTypeRevision::zero(),
174 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
175 QQmlPrivate::ValueTypeCreationMethod::None,
176 };
177
178 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
179}
180
181template<typename T, int metaObjectRevision>
182int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
183{
184 QQmlPrivate::RegisterType type = {
185 QQmlPrivate::RegisterType::CurrentVersion,
186 QQmlPrivate::QmlMetaType<T>::self(),
187 QQmlPrivate::QmlMetaType<T>::list(),
188 0,
189 nullptr,
190 nullptr,
191 reason,
192 QQmlPrivate::ValueType<T, void>::create,
193
194 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
195 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
196
197 QQmlPrivate::attachedPropertiesFunc<T>(),
198 QQmlPrivate::attachedPropertiesMetaObject<T>(),
199
200 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
201 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
202 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
203
204 nullptr, nullptr,
205
206 nullptr,
207 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevision),
208 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
209 QQmlPrivate::ValueTypeCreationMethod::None,
210 };
211
212 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
213}
214
215template<typename T, typename E>
216int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
217{
218 QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
219 const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
220 if (!attached) {
221 attached = QQmlPrivate::attachedPropertiesFunc<T>();
222 attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
223 }
224
225 QQmlPrivate::RegisterType type = {
226 QQmlPrivate::RegisterType::CurrentVersion,
227 QQmlPrivate::QmlMetaType<T>::self(),
228 QQmlPrivate::QmlMetaType<T>::list(),
229 0,
230 nullptr,
231 nullptr,
232 reason,
233 QQmlPrivate::ValueType<T, E>::create,
234
235 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
236 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
237
238 attached,
239 attachedMetaObject,
240
241 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
242 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
243 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
244
245 QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(),
246
247 nullptr,
248 QTypeRevision::zero(),
249 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
250 QQmlPrivate::ValueTypeCreationMethod::None,
251 };
252
253 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
254}
255
256template<typename T, typename E, int metaObjectRevision>
257int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
258{
259 QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
260 const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
261 if (!attached) {
262 attached = QQmlPrivate::attachedPropertiesFunc<T>();
263 attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
264 }
265
266 QQmlPrivate::RegisterType type = {
267 QQmlPrivate::RegisterType::CurrentVersion,
268 QQmlPrivate::QmlMetaType<T>::self(),
269 QQmlPrivate::QmlMetaType<T>::list(),
270 0,
271 nullptr,
272 nullptr,
273 reason,
274 QQmlPrivate::ValueType<T, E>::create,
275
276 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
277 QQmlPrivate::StaticMetaObject<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::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(),
287
288 nullptr,
289 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevision),
290 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
291 QQmlPrivate::ValueTypeCreationMethod::None,
292 };
293
294 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
295}
296
297Q_QML_EXPORT int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason);
298
299template<typename T>
300int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
301{
302 static_assert(!std::is_abstract_v<T>,
303 "It is not possible to register an abstract type with qmlRegisterType. "
304 "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?");
305
306 QQmlPrivate::RegisterType type = {
307 QQmlPrivate::RegisterType::CurrentVersion,
308 QQmlPrivate::QmlMetaType<T>::self(),
309 QQmlPrivate::QmlMetaType<T>::list(),
310 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
311 QString(),
312 QQmlPrivate::ValueType<T, void>::create,
313
314 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
315 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
316
317 QQmlPrivate::attachedPropertiesFunc<T>(),
318 QQmlPrivate::attachedPropertiesMetaObject<T>(),
319
320 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
321 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
322 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
323
324 nullptr, nullptr,
325
326 nullptr,
327 QTypeRevision::zero(),
328 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
329 QQmlPrivate::ValueTypeCreationMethod::None,
330 };
331
332 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
333}
334
335template<typename T, int metaObjectRevision>
336int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
337{
338 static_assert(!std::is_abstract_v<T>,
339 "It is not possible to register an abstract type with qmlRegisterType. "
340 "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?");
341
342 QQmlPrivate::RegisterType type = {
343 QQmlPrivate::RegisterType::CurrentVersion,
344 QQmlPrivate::QmlMetaType<T>::self(),
345 QQmlPrivate::QmlMetaType<T>::list(),
346 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
347 QString(),
348 QQmlPrivate::ValueType<T, void>::create,
349
350 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
351 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
352
353 QQmlPrivate::attachedPropertiesFunc<T>(),
354 QQmlPrivate::attachedPropertiesMetaObject<T>(),
355
356 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
357 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
358 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
359
360 nullptr, nullptr,
361
362 nullptr,
363 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevision),
364 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
365 QQmlPrivate::ValueTypeCreationMethod::None,
366 };
367
368 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
369}
370
371template<typename T, int metaObjectRevision>
372int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
373{
374 QQmlPrivate::RegisterType type = {
375 QQmlPrivate::RegisterType::CurrentVersion,
376 QQmlPrivate::QmlMetaType<T>::self(),
377 QQmlPrivate::QmlMetaType<T>::list(),
378 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
379 QString(),
380 QQmlPrivate::ValueType<T, void>::create,
381
382 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), nullptr,
383 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
384
385 QQmlPrivate::attachedPropertiesFunc<T>(),
386 QQmlPrivate::attachedPropertiesMetaObject<T>(),
387
388 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
389 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
390 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
391
392 nullptr, nullptr,
393
394 nullptr,
395 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevision),
396 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
397 QQmlPrivate::ValueTypeCreationMethod::None,
398 };
399
400 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
401}
402
403template<typename T, typename E>
404int qmlRegisterExtendedType(const char *uri, int versionMajor)
405{
406 static_assert(!std::is_abstract_v<T>,
407 "It is not possible to register an extension to an abstract type with qmlRegisterExtendedType.");
408
409 static_assert(!std::is_abstract_v<E>,
410 "It is not possible to register an abstract type with qmlRegisterExtendedType. "
411 "Maybe you wanted qmlRegisterExtendedUncreatableType?");
412
413 QQmlPrivate::RegisterType type = {
414 QQmlPrivate::RegisterType::CurrentVersion,
415 QQmlPrivate::QmlMetaType<T>::self(),
416 QQmlPrivate::QmlMetaType<T>::list(),
417 0,
418 nullptr,
419 nullptr,
420 QString(),
421 QQmlPrivate::ValueType<T, E>::create,
422
423 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: 0), nullptr,
424 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
425
426 QQmlPrivate::attachedPropertiesFunc<T>(),
427 QQmlPrivate::attachedPropertiesMetaObject<T>(),
428
429 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
430 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
431 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
432
433 QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(),
434
435 nullptr,
436 QTypeRevision::zero(),
437 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
438 QQmlPrivate::ValueTypeCreationMethod::None,
439 };
440
441 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
442}
443
444template<typename T, typename E>
445int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
446 const char *qmlName)
447{
448 static_assert(!std::is_abstract_v<T>,
449 "It is not possible to register an extension to an abstract type with qmlRegisterExtendedType.");
450
451 static_assert(!std::is_abstract_v<E>,
452 "It is not possible to register an abstract type with qmlRegisterExtendedType. "
453 "Maybe you wanted qmlRegisterExtendedUncreatableType?");
454
455 QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
456 const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
457 if (!attached) {
458 attached = QQmlPrivate::attachedPropertiesFunc<T>();
459 attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
460 }
461
462 QQmlPrivate::RegisterType type = {
463 QQmlPrivate::RegisterType::CurrentVersion,
464 QQmlPrivate::QmlMetaType<T>::self(),
465 QQmlPrivate::QmlMetaType<T>::list(),
466 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
467 QString(),
468 QQmlPrivate::ValueType<T, E>::create,
469
470 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
471 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
472
473 attached,
474 attachedMetaObject,
475
476 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
477 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
478 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
479
480 QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(),
481
482 nullptr,
483 QTypeRevision::zero(),
484 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
485 QQmlPrivate::ValueTypeCreationMethod::None,
486 };
487
488 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
489}
490
491template<typename T>
492int qmlRegisterInterface(const char *uri, int versionMajor)
493{
494 QQmlPrivate::RegisterInterface qmlInterface = {
495 0,
496 // An interface is not a QObject itself but is typically casted to one.
497 // Therefore, we still want the pointer.
498 QMetaType::fromType<T *>(),
499 QMetaType::fromType<QQmlListProperty<T> >(),
500 qobject_interface_iid<T *>(),
501
502 uri,
503 QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: 0)
504 };
505
506 return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
507}
508
509template<typename T>
510int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
511 const char *qmlName, QQmlCustomParser *parser)
512{
513 static_assert(!std::is_abstract_v<T>,
514 "It is not possible to register an abstract type with qmlRegisterCustomType. "
515 "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?");
516
517 QQmlPrivate::RegisterType type = {
518 QQmlPrivate::RegisterType::CurrentVersion,
519 QQmlPrivate::QmlMetaType<T>::self(),
520 QQmlPrivate::QmlMetaType<T>::list(),
521 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
522 QString(),
523 QQmlPrivate::ValueType<T, void>::create,
524
525 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
526 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
527
528 QQmlPrivate::attachedPropertiesFunc<T>(),
529 QQmlPrivate::attachedPropertiesMetaObject<T>(),
530
531 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
532 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
533 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
534
535 nullptr, nullptr,
536
537 parser,
538 QTypeRevision::zero(),
539 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
540 QQmlPrivate::ValueTypeCreationMethod::None,
541 };
542
543 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
544}
545
546template<typename T, int metaObjectRevision>
547int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
548 const char *qmlName, QQmlCustomParser *parser)
549{
550 static_assert(!std::is_abstract_v<T>,
551 "It is not possible to register an abstract type with qmlRegisterCustomType. "
552 "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?");
553
554 QQmlPrivate::RegisterType type = {
555 QQmlPrivate::RegisterType::CurrentVersion,
556 QQmlPrivate::QmlMetaType<T>::self(),
557 QQmlPrivate::QmlMetaType<T>::list(),
558 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
559 QString(),
560 QQmlPrivate::ValueType<T, void>::create,
561
562 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
563 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
564
565 QQmlPrivate::attachedPropertiesFunc<T>(),
566 QQmlPrivate::attachedPropertiesMetaObject<T>(),
567
568 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
569 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
570 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
571
572 nullptr, nullptr,
573
574 parser,
575 QTypeRevision::fromMinorVersion(minorVersion: metaObjectRevision),
576 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
577 QQmlPrivate::ValueTypeCreationMethod::None,
578 };
579
580 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
581}
582
583template<typename T, typename E>
584int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int versionMinor,
585 const char *qmlName, QQmlCustomParser *parser)
586{
587 static_assert(!std::is_abstract_v<T>,
588 "It is not possible to register an extension to an abstract type with qmlRegisterCustomExtendedType.");
589
590 static_assert(!std::is_abstract_v<E>,
591 "It is not possible to register an abstract type with qmlRegisterCustomExtendedType.");
592
593 QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
594 const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
595 if (!attached) {
596 attached = QQmlPrivate::attachedPropertiesFunc<T>();
597 attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
598 }
599
600 QQmlPrivate::RegisterType type = {
601 QQmlPrivate::RegisterType::CurrentVersion,
602 QQmlPrivate::QmlMetaType<T>::self(),
603 QQmlPrivate::QmlMetaType<T>::list(),
604 sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr,
605 QString(),
606 QQmlPrivate::ValueType<T, E>::create,
607
608 uri, QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), qmlName,
609 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
610
611 attached,
612 attachedMetaObject,
613
614 QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
615 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
616 QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
617
618 QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(),
619
620 parser,
621 QTypeRevision::zero(),
622 QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(),
623 QQmlPrivate::ValueTypeCreationMethod::None,
624 };
625
626 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
627}
628
629class QQmlContext;
630class QQmlEngine;
631class QJSValue;
632class QJSEngine;
633
634Q_QML_EXPORT void qmlExecuteDeferred(QObject *);
635Q_QML_EXPORT QQmlContext *qmlContext(const QObject *);
636Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *);
637Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *,
638 const QMetaObject *);
639Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func,
640 bool create = true);
641Q_QML_EXPORT QObject *qmlExtendedObject(QObject *);
642
643//The C++ version of protected namespaces in qmldir
644Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
645Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor);
646
647enum QQmlModuleImportSpecialVersions: int {
648 QQmlModuleImportModuleAny = -1,
649 QQmlModuleImportLatest = -1,
650 QQmlModuleImportAuto = -2
651};
652
653Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int moduleMajor,
654 const char *import,
655 int importMajor = QQmlModuleImportLatest,
656 int importMinor = QQmlModuleImportLatest);
657Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int moduleMajor,
658 const char *import,
659 int importMajor = QQmlModuleImportLatest,
660 int importMinor = QQmlModuleImportLatest);
661
662template<typename T>
663QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
664{
665 // We don't need a concrete object to resolve the function. As T is a C++ type, it and all its
666 // super types should be registered as CppType (or not at all). We only need the object and its
667 // QML engine to resolve composite types. Therefore, the function is actually a static property
668 // of the C++ type system and we can cache it here for improved performance on further lookups.
669 static const auto func = qmlAttachedPropertiesFunction(nullptr, &T::staticMetaObject);
670 return qmlAttachedPropertiesObject(const_cast<QObject *>(obj), func, create);
671}
672
673inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
674 QJSValue (*callback)(QQmlEngine *, QJSEngine *))
675{
676 QQmlPrivate::RegisterSingletonType api = {
677 .structVersion: 0,
678
679 .uri: uri, .version: QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor), .typeName: typeName,
680
681 .scriptApi: callback,
682 .qObjectApi: nullptr, .instanceMetaObject: nullptr, .typeId: QMetaType(),
683 .extensionObjectCreate: nullptr, .extensionMetaObject: nullptr,
684 .revision: QTypeRevision::zero()
685 };
686
687 return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
688}
689
690template <typename T>
691inline int qmlRegisterSingletonType(
692 const char *uri, int versionMajor, int versionMinor, const char *typeName,
693 QObject *(*callback)(QQmlEngine *, QJSEngine *))
694{
695 QQmlPrivate::RegisterSingletonType api = {
696 0,
697 uri,
698 QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor),
699 typeName,
700 nullptr,
701 callback,
702 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
703 QQmlPrivate::QmlMetaType<T>::self(),
704 nullptr, nullptr,
705 QTypeRevision::zero()
706 };
707
708 return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
709}
710
711#ifdef Q_QDOC
712template <typename T>
713int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback)
714#else
715template <typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value
716 && !std::is_convertible<F, QObject *(*)(QQmlEngine *, QJSEngine *)>::value, void>::type* = nullptr>
717inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
718 F&& callback)
719#endif
720{
721 QQmlPrivate::RegisterSingletonType api = {
722 0,
723 uri,
724 QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor),
725 typeName,
726 nullptr,
727 callback,
728 QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
729 QQmlPrivate::QmlMetaType<T>::self(),
730 nullptr, nullptr,
731 QTypeRevision::zero()
732 };
733
734 return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
735}
736
737#ifdef Q_QDOC
738int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject)
739#else
740template<typename T>
741inline auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor,
742 const char *typeName, T *cppObject) -> typename std::enable_if<std::is_base_of<QObject, T>::value, int>::type
743#endif
744{
745 QQmlPrivate::SingletonInstanceFunctor registrationFunctor;
746 registrationFunctor.m_object = cppObject;
747 return qmlRegisterSingletonType<T>(uri, versionMajor, versionMinor, typeName, registrationFunctor);
748}
749
750inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
751{
752 if (url.isRelative()) {
753 // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
754 qWarning(msg: "qmlRegisterSingletonType requires absolute URLs.");
755 return 0;
756 }
757
758 QQmlPrivate::RegisterCompositeSingletonType type = {
759 .structVersion: 0,
760 .url: url,
761 .uri: uri,
762 .version: QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor),
763 .typeName: qmlName
764 };
765
766 return QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &type);
767}
768
769inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
770{
771 if (url.isRelative()) {
772 // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
773 qWarning(msg: "qmlRegisterType requires absolute URLs.");
774 return 0;
775 }
776
777 QQmlPrivate::RegisterCompositeType type = {
778 .structVersion: 0,
779 .url: url,
780 .uri: uri,
781 .version: QTypeRevision::fromVersion(majorVersion: versionMajor, minorVersion: versionMinor),
782 .typeName: qmlName
783 };
784
785 return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type);
786}
787
788template<typename Container>
789inline int qmlRegisterAnonymousSequentialContainer(const char *uri, int versionMajor)
790{
791 static_assert(!std::is_abstract_v<Container>,
792 "It is not possible to register an abstract container with qmlRegisterAnonymousSequentialContainer.");
793
794 QQmlPrivate::RegisterSequentialContainer type = {
795 0,
796 uri,
797 QTypeRevision::fromMajorVersion(majorVersion: versionMajor),
798 nullptr,
799 QMetaType::fromType<Container>(),
800 QMetaSequence::fromContainer<Container>(),
801 QTypeRevision::zero()
802 };
803
804 return QQmlPrivate::qmlregister(QQmlPrivate::SequentialContainerRegistration, &type);
805}
806
807template<class T, class Resolved, class Extended, bool Singleton, bool Interface, bool Sequence, bool Uncreatable>
808struct QmlTypeAndRevisionsRegistration;
809
810template<class T, class Resolved, class Extended>
811struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false, false> {
812 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
813 const QMetaObject *extension)
814 {
815#if QT_DEPRECATED_SINCE(6, 4)
816 // ### Qt7: Remove the warnings, and leave only the static asserts below.
817 if constexpr (!QQmlPrivate::QmlMetaType<Resolved>::hasAcceptableCtors()) {
818 QQmlPrivate::qmlRegistrationWarning(warning: QQmlPrivate::UnconstructibleType,
819 type: QMetaType::fromType<Resolved>());
820 }
821
822 if constexpr (!std::is_base_of_v<QObject, Resolved>
823 && QQmlTypeInfo<T>::hasAttachedProperties) {
824 QQmlPrivate::qmlRegistrationWarning(warning: QQmlPrivate::NonQObjectWithAtached,
825 type: QMetaType::fromType<Resolved>());
826 }
827#else
828 static_assert(QQmlPrivate::QmlMetaType<Resolved>::hasAcceptableCtors(),
829 "This type is neither a QObject, nor default- and copy-constructible, nor"
830 "uncreatable.\n"
831 "You should not use it as a QML type.");
832 static_assert(std::is_base_of_v<QObject, Resolved>
833 || !QQmlTypeInfo<Resolved>::hasAttachedProperties);
834#endif
835 QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
836 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
837 qmlTypeIds, extension);
838 }
839};
840
841template<class T, class Resolved, class Extended>
842struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false, true> {
843 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
844 const QMetaObject *extension)
845 {
846#if QT_DEPRECATED_SINCE(6, 4)
847 // ### Qt7: Remove the warning, and leave only the static assert below.
848 if constexpr (!std::is_base_of_v<QObject, Resolved>
849 && QQmlTypeInfo<Resolved>::hasAttachedProperties) {
850 QQmlPrivate::qmlRegistrationWarning(warning: QQmlPrivate::NonQObjectWithAtached,
851 type: QMetaType::fromType<Resolved>());
852 }
853#else
854 static_assert(std::is_base_of_v<QObject, Resolved>
855 || !QQmlTypeInfo<Resolved>::hasAttachedProperties);
856#endif
857 QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
858 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
859 qmlTypeIds, extension);
860 }
861};
862
863template<class T, class Resolved>
864struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, false, true, true> {
865 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
866 const QMetaObject *)
867 {
868 // Sequences have to be anonymous for now, which implies uncreatable.
869 QQmlPrivate::qmlRegisterSequenceAndRevisions<Resolved>(
870 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
871 qmlTypeIds);
872 }
873};
874
875template<class T, class Resolved, class Extended>
876struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false, false> {
877 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
878 const QMetaObject *extension)
879 {
880#if QT_DEPRECATED_SINCE(6, 4)
881 // ### Qt7: Remove the warning, and leave only the static assert below.
882 if constexpr (QQmlPrivate::singletonConstructionMode<Resolved, T>()
883 == QQmlPrivate::SingletonConstructionMode::None) {
884 QQmlPrivate::qmlRegistrationWarning(warning: QQmlPrivate::UnconstructibleSingleton,
885 type: QMetaType::fromType<Resolved>());
886 }
887#else
888 static_assert(QQmlPrivate::singletonConstructionMode<Resolved, T>()
889 != QQmlPrivate::SingletonConstructionMode::None,
890 "A singleton needs either a default constructor or, when adding a default "
891 "constructor is infeasible, a public static "
892 "create(QQmlEngine *, QJSEngine *) method");
893#endif
894
895 QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended, T>(
896 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
897 qmlTypeIds, extension);
898 }
899};
900
901template<class T, class Resolved, class Extended>
902struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false, true> {
903 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
904 const QMetaObject *extension)
905 {
906 // An uncreatable singleton makes little sense? OK, you can still use the enums.
907 QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended, T>(
908 uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
909 qmlTypeIds, extension);
910 }
911};
912
913template<class T, class Resolved>
914struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false, false> {
915 static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
916 const QMetaObject *)
917 {
918 const int id = qmlRegisterInterface<Resolved>(uri, versionMajor);
919 if (qmlTypeIds)
920 qmlTypeIds->append(t: id);
921 }
922};
923
924template<typename... T>
925void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds)
926{
927 (QmlTypeAndRevisionsRegistration<
928 T, typename QQmlPrivate::QmlResolved<T>::Type,
929 typename QQmlPrivate::QmlExtended<T>::Type,
930 QQmlPrivate::QmlSingleton<T>::Value,
931 QQmlPrivate::QmlInterface<T>::Value,
932 QQmlPrivate::QmlSequence<T>::Value,
933 QQmlPrivate::QmlUncreatable<T>::Value || QQmlPrivate::QmlAnonymous<T>::Value>
934 ::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds,
935 QQmlPrivate::QmlExtendedNamespace<T>::metaObject()), ...);
936}
937
938inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
939 const char *uri, int versionMajor,
940 QList<int> *qmlTypeIds,
941 const QMetaObject *classInfoMetaObject,
942 const QMetaObject *extensionMetaObject)
943{
944 QQmlPrivate::RegisterTypeAndRevisions type = {
945 .structVersion: 3,
946 .typeId: QMetaType(),
947 .listId: QMetaType(),
948 .objectSize: 0,
949 .create: nullptr,
950 .userdata: nullptr,
951 .createValueType: nullptr,
952
953 .uri: uri,
954 .version: QTypeRevision::fromMajorVersion(majorVersion: versionMajor),
955
956 .metaObject: metaObject,
957 .classInfoMetaObject: (classInfoMetaObject ? classInfoMetaObject : metaObject),
958
959 .attachedPropertiesFunction: nullptr,
960 .attachedPropertiesMetaObject: nullptr,
961
962 .parserStatusCast: -1,
963 .valueSourceCast: -1,
964 .valueInterceptorCast: -1,
965
966 .extensionObjectCreate: nullptr,
967 .extensionMetaObject: extensionMetaObject,
968
969 .customParserFactory: &qmlCreateCustomParser<void>,
970 .qmlTypeIds: qmlTypeIds,
971 .finalizerCast: -1,
972 .forceAnonymous: false,
973 .listMetaSequence: QMetaSequence()
974 };
975
976 qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type);
977}
978
979inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject,
980 const char *uri, int versionMajor,
981 QList<int> *qmlTypeIds = nullptr,
982 const QMetaObject *classInfoMetaObject = nullptr)
983{
984 qmlRegisterNamespaceAndRevisions(metaObject, uri, versionMajor, qmlTypeIds,
985 classInfoMetaObject, extensionMetaObject: nullptr);
986}
987
988int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
989
990QT_END_NAMESPACE
991
992#endif // QQML_H
993

source code of qtdeclarative/src/qml/qml/qqml.h