diff options
Diffstat (limited to 'src/qml/qml/qqml.h')
-rw-r--r-- | src/qml/qml/qqml.h | 752 |
1 files changed, 519 insertions, 233 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index ebf4817b4a..3e6441bfa7 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -1,58 +1,23 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QQML_H #define QQML_H #include <QtQml/qqmlprivate.h> -#include <QtQml/qqmlparserstatus.h> -#include <QtQml/qqmlpropertyvaluesource.h> -#include <QtQml/qqmllist.h> +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlregistration.h> #include <QtCore/qbytearray.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qmetacontainer.h> +#include <QtCore/qversionnumber.h> #define QML_VERSION 0x020000 #define QML_VERSION_STR "2.0" #define QML_DECLARE_TYPE(TYPE) \ - Q_DECLARE_METATYPE(TYPE *) \ + Q_DECLARE_METATYPE(TYPE*) \ Q_DECLARE_METATYPE(QQmlListProperty<TYPE>) #define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \ @@ -82,40 +47,25 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE - -class QQmlPropertyValueInterceptor; - -#define QML_GETTYPENAMES \ - const char *className = T::staticMetaObject.className(); \ - const int nameLen = int(strlen(className)); \ - QVarLengthArray<char,48> pointerName(nameLen+2); \ - memcpy(pointerName.data(), className, size_t(nameLen)); \ - pointerName[nameLen] = '*'; \ - pointerName[nameLen+1] = '\0'; \ - const int listLen = int(strlen("QQmlListProperty<")); \ - QVarLengthArray<char,64> listName(listLen + nameLen + 2); \ - memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \ - memcpy(listName.data()+listLen, className, size_t(nameLen)); \ - listName[listLen+nameLen] = '>'; \ - listName[listLen+nameLen+1] = '\0'; - void Q_QML_EXPORT qmlClearTypeRegistrations(); +template<class T> +QQmlCustomParser *qmlCreateCustomParser(); + template<typename T> -int qmlRegisterType() +int qmlRegisterAnonymousType(const char *uri, int versionMajor) { - QML_GETTYPENAMES - QQmlPrivate::RegisterType type = { + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - 0, - nullptr, + nullptr, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - nullptr, 0, 0, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -127,29 +77,88 @@ int qmlRegisterType() nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); +} + +//! \internal +template<typename T, int metaObjectRevisionMinor> +int qmlRegisterAnonymousType(const char *uri, int versionMajor) +{ + QQmlPrivate::RegisterType type = { + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + 0, + nullptr, + nullptr, + QString(), + QQmlPrivate::ValueType<T, void>::create, + + uri, + QTypeRevision::fromVersion(versionMajor, 0), + nullptr, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + + QQmlPrivate::attachedPropertiesFunc<T>(), + QQmlPrivate::attachedPropertiesMetaObject<T>(), + + QQmlPrivate::StaticCastSelector<T, QQmlParserStatus>::cast(), + QQmlPrivate::StaticCastSelector<T, QQmlPropertyValueSource>::cast(), + QQmlPrivate::StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(), + + nullptr, + nullptr, + + nullptr, + QTypeRevision::fromMinorVersion(metaObjectRevisionMinor), + QQmlPrivate::StaticCastSelector<T, QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } -int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message); +//! \internal +template<typename T> +void qmlRegisterAnonymousTypesAndRevisions(const char *uri, int versionMajor) +{ + // Anonymous types are not creatable, no need to warn about missing acceptable constructors. + QQmlPrivate::qmlRegisterTypeAndRevisions<T, void>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), nullptr, + nullptr, true); +} + +class QQmlTypeNotAvailable : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(TypeNotAvailable) + QML_ADDED_IN_VERSION(2, 15) + QML_UNCREATABLE("Type not available.") +}; + +int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, + const char *qmlName, const QString &message); template<typename T> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) { - QML_GETTYPENAMES - QQmlPrivate::RegisterType type = { - 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, nullptr, + nullptr, reason, + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -161,7 +170,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -170,18 +181,18 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin template<typename T, int metaObjectRevision> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) { - QML_GETTYPENAMES - QQmlPrivate::RegisterType type = { - 1, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, nullptr, + nullptr, reason, + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -193,7 +204,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -202,8 +215,6 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin template<typename T, typename E> int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) { - QML_GETTYPENAMES - QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>(); const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>(); if (!attached) { @@ -212,15 +223,17 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve } QQmlPrivate::RegisterType type = { + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - 0, + nullptr, nullptr, reason, + QQmlPrivate::ValueType<T, E>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), attached, attachedMetaObject, @@ -229,10 +242,12 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), - QQmlPrivate::createParent<E>, &E::staticMetaObject, + QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(), nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -241,8 +256,6 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve template<typename T, typename E, int metaObjectRevision> int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) { - QML_GETTYPENAMES - QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>(); const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>(); if (!attached) { @@ -251,15 +264,17 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve } QQmlPrivate::RegisterType type = { - 1, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, nullptr, + nullptr, reason, + QQmlPrivate::ValueType<T, E>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), attached, attachedMetaObject, @@ -268,10 +283,12 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), - QQmlPrivate::createParent<E>, &E::staticMetaObject, + QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(), nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -282,17 +299,20 @@ Q_QML_EXPORT int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaO template<typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an abstract type with qmlRegisterType. " + "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?"); QQmlPrivate::RegisterType type = { - 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -304,7 +324,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -313,17 +335,20 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c template<typename T, int metaObjectRevision> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an abstract type with qmlRegisterType. " + "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?"); QQmlPrivate::RegisterType type = { - 1, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -335,7 +360,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -344,17 +371,16 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c template<typename T, int metaObjectRevision> int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) { - QML_GETTYPENAMES - QQmlPrivate::RegisterType type = { - 1, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), nullptr, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -366,28 +392,36 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } - template<typename T, typename E> -int qmlRegisterExtendedType() +int qmlRegisterExtendedType(const char *uri, int versionMajor) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an extension to an abstract type with qmlRegisterExtendedType."); - QQmlPrivate::RegisterType type = { - 0, + static_assert(!std::is_abstract_v<E>, + "It is not possible to register an abstract type with qmlRegisterExtendedType. " + "Maybe you wanted qmlRegisterExtendedUncreatableType?"); - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), + QQmlPrivate::RegisterType type = { + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), 0, nullptr, + nullptr, QString(), + QQmlPrivate::ValueType<T, E>::create, - nullptr, 0, 0, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -396,10 +430,12 @@ int qmlRegisterExtendedType() QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), - QQmlPrivate::createParent<E>, &E::staticMetaObject, + QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(), nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -409,7 +445,12 @@ template<typename T, typename E> int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an extension to an abstract type with qmlRegisterExtendedType."); + + static_assert(!std::is_abstract_v<E>, + "It is not possible to register an abstract type with qmlRegisterExtendedType. " + "Maybe you wanted qmlRegisterExtendedUncreatableType?"); QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>(); const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>(); @@ -419,14 +460,15 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, } QQmlPrivate::RegisterType type = { - 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, E>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), attached, attachedMetaObject, @@ -435,30 +477,30 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), - QQmlPrivate::createParent<E>, &E::staticMetaObject, + QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(), nullptr, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } template<typename T> -int qmlRegisterInterface(const char *typeName) +int qmlRegisterInterface(const char *uri, int versionMajor) { - QByteArray name(typeName); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); - QQmlPrivate::RegisterInterface qmlInterface = { 0, + // An interface is not a QObject itself but is typically casted to one. + // Therefore, we still want the pointer. + QMetaType::fromType<T *>(), + QMetaType::fromType<QQmlListProperty<T> >(), + qobject_interface_iid<T *>(), - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - - qobject_interface_iid<T *>() + uri, + QTypeRevision::fromVersion(versionMajor, 0) }; return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface); @@ -468,17 +510,20 @@ template<typename T> int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, QQmlCustomParser *parser) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an abstract type with qmlRegisterCustomType. " + "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?"); QQmlPrivate::RegisterType type = { - 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -490,7 +535,9 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -500,17 +547,20 @@ template<typename T, int metaObjectRevision> int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, QQmlCustomParser *parser) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an abstract type with qmlRegisterCustomType. " + "Maybe you wanted qmlRegisterUncreatableType or qmlRegisterInterface?"); QQmlPrivate::RegisterType type = { - 1, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, void>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -522,7 +572,9 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -532,7 +584,11 @@ template<typename T, typename E> int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, QQmlCustomParser *parser) { - QML_GETTYPENAMES + static_assert(!std::is_abstract_v<T>, + "It is not possible to register an extension to an abstract type with qmlRegisterCustomExtendedType."); + + static_assert(!std::is_abstract_v<E>, + "It is not possible to register an abstract type with qmlRegisterCustomExtendedType."); QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>(); const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>(); @@ -542,14 +598,15 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version } QQmlPrivate::RegisterType type = { - 0, - - qRegisterNormalizedMetaType<T *>(pointerName.constData()), - qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), - sizeof(T), QQmlPrivate::createInto<T>, + QQmlPrivate::RegisterType::CurrentVersion, + QQmlPrivate::QmlMetaType<T>::self(), + QQmlPrivate::QmlMetaType<T>::list(), + sizeof(T), QQmlPrivate::Constructors<T>::createInto, nullptr, QString(), + QQmlPrivate::ValueType<T, E>::create, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), attached, attachedMetaObject, @@ -558,10 +615,12 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), - QQmlPrivate::createParent<E>, &E::staticMetaObject, + QQmlPrivate::ExtendedType<E>::createParent, QQmlPrivate::ExtendedType<E>::staticMetaObject(), parser, - 0 + QTypeRevision::zero(), + QQmlPrivate::StaticCastSelector<T,QQmlFinalizerHook>::cast(), + QQmlPrivate::ValueTypeCreationMethod::None, }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -572,36 +631,34 @@ class QQmlEngine; class QJSValue; class QJSEngine; -#ifndef Q_QDOC -namespace QtQml { -#endif - // declared in namespace to avoid symbol conflicts with QtDeclarative - Q_QML_EXPORT void qmlExecuteDeferred(QObject *); - Q_QML_EXPORT QQmlContext *qmlContext(const QObject *); - Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *); - Q_QML_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true); - Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *, const QObject *, - const QMetaObject *, bool create); - Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *, - const QMetaObject *); - Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func, - bool create = true); -#ifndef Q_QDOC -} -#endif - -QT_WARNING_PUSH -QT_WARNING_DISABLE_CLANG("-Wheader-hygiene") - -// This is necessary to allow for QtQuick1 and QtQuick2 scenes in a single application. -using namespace QtQml; - -QT_WARNING_POP +Q_QML_EXPORT void qmlExecuteDeferred(QObject *); +Q_QML_EXPORT QQmlContext *qmlContext(const QObject *); +Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *); +Q_QML_EXPORT QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *, + const QMetaObject *); +Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(QObject *, QQmlAttachedPropertiesFunc func, + bool create = true); +Q_QML_EXPORT QObject *qmlExtendedObject(QObject *); //The C++ version of protected namespaces in qmldir Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion); Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor); +enum QQmlModuleImportSpecialVersions: int { + QQmlModuleImportModuleAny = -1, + QQmlModuleImportLatest = -1, + QQmlModuleImportAuto = -2 +}; + +Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int moduleMajor, + const char *import, + int importMajor = QQmlModuleImportLatest, + int importMinor = QQmlModuleImportLatest); +Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int moduleMajor, + const char *import, + int importMajor = QQmlModuleImportLatest, + int importMinor = QQmlModuleImportLatest); + template<typename T> QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) { @@ -613,40 +670,72 @@ QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) return qmlAttachedPropertiesObject(const_cast<QObject *>(obj), func, create); } -Q_QML_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor); - -inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, - QJSValue (*callback)(QQmlEngine *, QJSEngine *)) +#ifdef Q_QDOC +int qmlRegisterSingletonType( + const char *uri, int versionMajor, int versionMinor, const char *typeName, + std::function<QJSValue(QQmlEngine *, QJSEngine *)> callback) +#else +template<typename F, typename std::enable_if<std::is_convertible<F, std::function<QJSValue(QQmlEngine *, QJSEngine *)>>::value, void>::type* = nullptr> +int qmlRegisterSingletonType( + const char *uri, int versionMajor, int versionMinor, const char *typeName, F &&callback) +#endif { QQmlPrivate::RegisterSingletonType api = { 0, - - uri, versionMajor, versionMinor, typeName, - - callback, nullptr, nullptr, 0, 0 + uri, + QTypeRevision::fromVersion(versionMajor, versionMinor), + typeName, + std::forward<F>(callback), + nullptr, + nullptr, + QMetaType(), + nullptr, nullptr, + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } -enum { QmlCurrentSingletonTypeRegistrationVersion = 2 }; +#ifdef Q_QDOC template <typename T> -inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, - QObject *(*callback)(QQmlEngine *, QJSEngine *)) +int qmlRegisterSingletonType( + const char *uri, int versionMajor, int versionMinor, const char *typeName, + std::function<QObject *(QQmlEngine *, QJSEngine *)> callback) +#else +template<typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value, void>::type* = nullptr> +int qmlRegisterSingletonType( + const char *uri, int versionMajor, int versionMinor, const char *typeName, F &&callback) +#endif { - QML_GETTYPENAMES - QQmlPrivate::RegisterSingletonType api = { - QmlCurrentSingletonTypeRegistrationVersion, - - uri, versionMajor, versionMinor, typeName, - - nullptr, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0 + 0, + uri, + QTypeRevision::fromVersion(versionMajor, versionMinor), + typeName, + nullptr, + std::forward<F>(callback), + QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + QQmlPrivate::QmlMetaType<T>::self(), + nullptr, nullptr, + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } +#ifdef Q_QDOC +int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject) +#else +template<typename T> +inline auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, + const char *typeName, T *cppObject) -> typename std::enable_if<std::is_base_of<QObject, T>::value, int>::type +#endif +{ + QQmlPrivate::SingletonInstanceFunctor registrationFunctor; + registrationFunctor.m_object = cppObject; + return qmlRegisterSingletonType<T>(uri, versionMajor, versionMinor, typeName, registrationFunctor); +} + inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName) { if (url.isRelative()) { @@ -656,10 +745,10 @@ inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versio } QQmlPrivate::RegisterCompositeSingletonType type = { + 0, url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; @@ -675,21 +764,218 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i } QQmlPrivate::RegisterCompositeType type = { + 0, url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type); } +template<typename Container> +inline int qmlRegisterAnonymousSequentialContainer(const char *uri, int versionMajor) +{ + static_assert(!std::is_abstract_v<Container>, + "It is not possible to register an abstract container with qmlRegisterAnonymousSequentialContainer."); + + QQmlPrivate::RegisterSequentialContainer type = { + 0, + uri, + QTypeRevision::fromMajorVersion(versionMajor), + nullptr, + QMetaType::fromType<Container>(), + QMetaSequence::fromContainer<Container>(), + QTypeRevision::zero() + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::SequentialContainerRegistration, &type); +} + +template<class T, class Resolved, class Extended, bool Singleton, bool Interface, bool Sequence, bool Uncreatable> +struct QmlTypeAndRevisionsRegistration; + +template<class T, class Resolved, class Extended> +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false, false> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *extension) + { +#if QT_DEPRECATED_SINCE(6, 4) + // ### Qt7: Remove the warnings, and leave only the static asserts below. + if constexpr (!QQmlPrivate::QmlMetaType<Resolved>::hasAcceptableCtors()) { + QQmlPrivate::qmlRegistrationWarning(QQmlPrivate::UnconstructibleType, + QMetaType::fromType<Resolved>()); + } + + if constexpr (!std::is_base_of_v<QObject, Resolved> + && QQmlTypeInfo<T>::hasAttachedProperties) { + QQmlPrivate::qmlRegistrationWarning(QQmlPrivate::NonQObjectWithAtached, + QMetaType::fromType<Resolved>()); + } +#else + static_assert(QQmlPrivate::QmlMetaType<Resolved>::hasAcceptableCtors(), + "This type is neither a default constructible QObject, nor a default- " + "and copy-constructible Q_GADGET, nor marked as uncreatable.\n" + "You should not use it as a QML type."); + static_assert(std::is_base_of_v<QObject, Resolved> + || !QQmlTypeInfo<Resolved>::hasAttachedProperties); +#endif + QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds, extension); + } +}; + +template<class T, class Resolved, class Extended> +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false, true> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *extension) + { +#if QT_DEPRECATED_SINCE(6, 4) + // ### Qt7: Remove the warning, and leave only the static assert below. + if constexpr (!std::is_base_of_v<QObject, Resolved> + && QQmlTypeInfo<Resolved>::hasAttachedProperties) { + QQmlPrivate::qmlRegistrationWarning(QQmlPrivate::NonQObjectWithAtached, + QMetaType::fromType<Resolved>()); + } +#else + static_assert(std::is_base_of_v<QObject, Resolved> + || !QQmlTypeInfo<Resolved>::hasAttachedProperties); +#endif + QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds, extension); + } +}; + +template<class T, class Resolved> +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, false, true, true> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *) + { + // Sequences have to be anonymous for now, which implies uncreatable. + QQmlPrivate::qmlRegisterSequenceAndRevisions<Resolved>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds); + } +}; + +template<class T, class Resolved, class Extended> +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false, false> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *extension) + { +#if QT_DEPRECATED_SINCE(6, 4) + // ### Qt7: Remove the warning, and leave only the static assert below. + if constexpr (QQmlPrivate::singletonConstructionMode<Resolved, T>() + == QQmlPrivate::SingletonConstructionMode::None) { + QQmlPrivate::qmlRegistrationWarning(QQmlPrivate::UnconstructibleSingleton, + QMetaType::fromType<Resolved>()); + } +#else + static_assert(QQmlPrivate::singletonConstructionMode<Resolved, T>() + != QQmlPrivate::SingletonConstructionMode::None, + "A singleton needs either a default constructor or, when adding a default " + "constructor is infeasible, a public static " + "create(QQmlEngine *, QJSEngine *) method"); +#endif + + QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended, T>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds, extension); + } +}; + +template<class T, class Resolved, class Extended> +struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false, true> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *extension) + { + // An uncreatable singleton makes little sense? OK, you can still use the enums. + QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved, Extended, T>( + uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(), + qmlTypeIds, extension); + } +}; + +template<class T, class Resolved> +struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false, false> { + static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds, + const QMetaObject *) + { + const int id = qmlRegisterInterface<Resolved>(uri, versionMajor); + if (qmlTypeIds) + qmlTypeIds->append(id); + } +}; + +template<typename... T> +void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds) +{ + (QmlTypeAndRevisionsRegistration< + T, typename QQmlPrivate::QmlResolved<T>::Type, + typename QQmlPrivate::QmlExtended<T>::Type, + QQmlPrivate::QmlSingleton<T>::Value, + QQmlPrivate::QmlInterface<T>::Value, + QQmlPrivate::QmlSequence<T>::Value, + QQmlPrivate::QmlUncreatable<T>::Value || QQmlPrivate::QmlAnonymous<T>::Value> + ::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds, + QQmlPrivate::QmlExtendedNamespace<T>::metaObject()), ...); +} + +inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject, + const char *uri, int versionMajor, + QList<int> *qmlTypeIds, + const QMetaObject *classInfoMetaObject, + const QMetaObject *extensionMetaObject) +{ + QQmlPrivate::RegisterTypeAndRevisions type = { + 3, + QMetaType(), + QMetaType(), + 0, + nullptr, + nullptr, + nullptr, + + uri, + QTypeRevision::fromMajorVersion(versionMajor), + + metaObject, + (classInfoMetaObject ? classInfoMetaObject : metaObject), + + nullptr, + nullptr, + + -1, + -1, + -1, + + nullptr, + extensionMetaObject, + + &qmlCreateCustomParser<void>, + qmlTypeIds, + -1, + false, + QMetaSequence() + }; + + qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type); +} + +inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject, + const char *uri, int versionMajor, + QList<int> *qmlTypeIds = nullptr, + const QMetaObject *classInfoMetaObject = nullptr) +{ + qmlRegisterNamespaceAndRevisions(metaObject, uri, versionMajor, qmlTypeIds, + classInfoMetaObject, nullptr); +} + int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName); QT_END_NAMESPACE -QML_DECLARE_TYPE(QObject) -Q_DECLARE_METATYPE(QVariant) - #endif // QQML_H |