aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-04-07 11:50:39 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-04-28 11:46:03 +0200
commitc2de5643cd4f1b8d8b10e2bb62fdf95f12fdd9e3 (patch)
tree55cfa6610c91315d5ae6cbbf2c961fb2fbfcabd8
parent1029b2b9f3d0ff88c0900fbfec2fac873aa6bcd4 (diff)
Register value types declaratively
For now this has the effect of adding them to the .qmltypes files. In the future, the registration shall actually add additional value types you can declare as properties in QML. Change-Id: Ifee5a8ec054f35cc7bd07eb992a136730be68da7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqml.h4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp22
-rw-r--r--src/qml/qml/qqmlprivate.h8
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h28
-rw-r--r--src/qml/types/qqmlmodelindexvaluetype_p.h10
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.cpp5
-rw-r--r--src/qmltyperegistrar/qmltypesclassdescription.h1
-rw-r--r--src/qmltyperegistrar/qmltypescreator.cpp5
-rw-r--r--src/quick/util/qquickvaluetypes_p.h72
9 files changed, 121 insertions, 34 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 252e4a5baf..4957c12036 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -77,6 +77,10 @@
#define QML_NAMED_ELEMENT(NAME) \
Q_CLASSINFO("QML.Element", #NAME)
+#define QML_VALUE_TYPE(NAME) \
+ Q_CLASSINFO("QML.Element", #NAME) \
+ QML_UNCREATABLE("Value types cannot be created.")
+
#define QML_UNCREATABLE(REASON) \
Q_CLASSINFO("QML.Creatable", "false") \
Q_CLASSINFO("QML.UncreatableReason", REASON)
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 51931ccb6c..4587ac3cc8 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -366,10 +366,12 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
// NOTE: caller must hold a QMutexLocker on "data"
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
- const char *uri, const QString &typeName, QTypeRevision version)
+ const char *uri, const QString &typeName, QTypeRevision version,
+ QMetaType::TypeFlags flags)
{
if (!typeName.isEmpty()) {
- if (typeName.at(0).isLower()) {
+ if (typeName.at(0).isLower()
+ && !(flags & (QMetaType::PointerToGadget | QMetaType::IsGadget))) {
QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName));
return false;
@@ -453,8 +455,10 @@ QQmlType QQmlMetaType::registerType(const QQmlPrivate::RegisterType &type)
QQmlMetaTypeDataPtr data;
QString elementName = QString::fromUtf8(type.elementName);
- if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version))
+ if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
+ QMetaType(type.typeId).flags())) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
@@ -473,8 +477,10 @@ QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingleto
QQmlMetaTypeDataPtr data;
QString typeName = QString::fromUtf8(type.typeName);
- if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version))
+ if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
+ QMetaType(type.typeId).flags())) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
@@ -496,7 +502,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri,
- typeName, type.version)) {
+ typeName, type.version, {})) {
return QQmlType();
}
@@ -521,8 +527,10 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.version))
+ if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName,
+ type.version, {})) {
return QQmlType();
+ }
QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
addTypeToData(priv, data);
@@ -814,7 +822,7 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
const QQmlType::RegistrationType registrationType = isCompositeSingleton
? QQmlType::CompositeSingletonType
: QQmlType::CompositeType;
- if (checkRegistration(registrationType, data, nullptr, typeName, version)) {
+ if (checkRegistration(registrationType, data, nullptr, typeName, version, {})) {
auto *priv = new QQmlTypePrivate(registrationType);
priv->setName(QString(), typeName);
priv->version = version;
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 79969caa56..c5c524c27a 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -534,9 +534,9 @@ namespace QQmlPrivate
if (qstrcmp(elementName, "anonymous") == 0)
return nullptr;
- if (!elementName || elementName[0] < 'A' || elementName[0] > 'Z') {
- qWarning() << "Missing or unusable QML.Element class info \"" << elementName << "\""
- << "for" << metaObject->className();
+ if (!elementName) {
+ qWarning().nospace() << "Missing QML.Element class info \"" << elementName << "\""
+ << " for " << metaObject->className();
}
return elementName;
@@ -561,7 +561,7 @@ namespace QQmlPrivate
};
template<class T>
- struct QmlResolved<T, QmlVoidT<typename T::QmlForeignType>>
+ struct QmlResolved<T, QmlVoidT<decltype(T::QmlForeignType::staticMetaObject)>>
{
using Type = typename T::QmlForeignType;
};
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 0b38c746d6..056baf87d0 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -133,6 +133,10 @@ struct QQmlPointFValueType
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_GADGET
+ QML_VALUE_TYPE(point)
+ QML_FOREIGN(QPointF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -147,6 +151,10 @@ struct QQmlPointValueType
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QPoint)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int x() const;
int y() const;
@@ -160,6 +168,10 @@ struct QQmlSizeFValueType
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
Q_GADGET
+ QML_VALUE_TYPE(size)
+ QML_FOREIGN(QSizeF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal width() const;
@@ -174,6 +186,10 @@ struct QQmlSizeValueType
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QSize)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int width() const;
int height() const;
@@ -193,6 +209,10 @@ struct QQmlRectFValueType
Q_PROPERTY(qreal top READ top DESIGNABLE false FINAL)
Q_PROPERTY(qreal bottom READ bottom DESIGNABLE false FINAL)
Q_GADGET
+ QML_VALUE_TYPE(rect)
+ QML_FOREIGN(QRectF)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
Q_INVOKABLE QString toString() const;
qreal x() const;
@@ -223,6 +243,10 @@ struct QQmlRectValueType
Q_PROPERTY(int top READ top DESIGNABLE false FINAL)
Q_PROPERTY(int bottom READ bottom DESIGNABLE false FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QRect)
+ QML_ADDED_IN_VERSION(2, 0)
+
public:
int x() const;
int y() const;
@@ -302,6 +326,10 @@ struct QQmlPropertyValueType
Q_PROPERTY(QObject *object READ object CONSTANT FINAL)
Q_PROPERTY(QString name READ name CONSTANT FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QQmlProperty)
+ QML_ADDED_IN_VERSION(2, 15)
+
public:
QObject *object() const;
QString name() const;
diff --git a/src/qml/types/qqmlmodelindexvaluetype_p.h b/src/qml/types/qqmlmodelindexvaluetype_p.h
index f5b1699574..59c33bf5af 100644
--- a/src/qml/types/qqmlmodelindexvaluetype_p.h
+++ b/src/qml/types/qqmlmodelindexvaluetype_p.h
@@ -53,6 +53,7 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qitemselectionmodel.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -67,6 +68,9 @@ struct QQmlModelIndexValueType
Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT FINAL)
Q_PROPERTY(quint64 internalId READ internalId CONSTANT FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QModelIndex)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const
@@ -97,6 +101,9 @@ struct QQmlPersistentModelIndexValueType
Q_PROPERTY(QAbstractItemModel *model READ model FINAL)
Q_PROPERTY(quint64 internalId READ internalId FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QPersistentModelIndex)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const
@@ -130,6 +137,9 @@ struct QQmlItemSelectionRangeValueType
Q_PROPERTY(bool empty READ isEmpty FINAL)
Q_PROPERTY(QAbstractItemModel *model READ model FINAL)
Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QItemSelectionRange)
+ QML_ADDED_IN_VERSION(2, 0)
public:
Q_INVOKABLE QString toString() const;
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp
index 94f06a81ee..2214758f38 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.cpp
+++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp
@@ -117,6 +117,9 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
else if (foreignName == QLatin1String("QML.Attached"))
collectAttached(foreignValue, types, foreign, defaultRevision);
}
+ } else {
+ // The foreign type does not have a meta object: We only override the name.
+ className = value;
}
} else if (name == QLatin1String("QML.Root")) {
isRootClass = true;
@@ -173,6 +176,8 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef,
revisions.erase(end, revisions.end());
resolvedClass = classDef;
+ if (className.isEmpty() && mode == TopLevel)
+ className = classDef->value(QLatin1String("qualifiedClassName")).toString();
// If it's not a QObject, it's not creatable
isCreatable = isCreatable && classDef->value(QLatin1String("object")).toBool();
diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h
index abe68d42ed..ed4ba49592 100644
--- a/src/qmltyperegistrar/qmltypesclassdescription.h
+++ b/src/qmltyperegistrar/qmltypesclassdescription.h
@@ -39,6 +39,7 @@ struct QmlTypesClassDescription
{
const QJsonObject *resolvedClass = nullptr;
QString file;
+ QString className;
QString elementName;
QString defaultProp;
QString superClass;
diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp
index 1bccbc36d8..a9885b03fa 100644
--- a/src/qmltyperegistrar/qmltypescreator.cpp
+++ b/src/qmltyperegistrar/qmltypescreator.cpp
@@ -48,10 +48,7 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle
{
if (!collector.file.isEmpty())
m_qml.writeScriptBinding(QLatin1String("file"), enquote(collector.file));
- m_qml.writeScriptBinding(
- QLatin1String("name"),
- enquote(collector.resolvedClass->value(
- QLatin1String("qualifiedClassName")).toString()));
+ m_qml.writeScriptBinding(QLatin1String("name"), enquote(collector.className));
if (!collector.defaultProp.isEmpty())
m_qml.writeScriptBinding(QLatin1String("defaultProperty"), enquote(collector.defaultProp));
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 6ddb51b5de..a94f4ac6a7 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -87,6 +87,10 @@ class QQuickColorValueType
Q_PROPERTY(qreal hslLightness READ hslLightness WRITE setHslLightness FINAL)
Q_PROPERTY(bool valid READ isValid)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QColor)
+ QML_VALUE_TYPE(color)
+
public:
Q_INVOKABLE QString toString() const;
@@ -124,6 +128,10 @@ class QQuickVector2DValueType
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector2D)
+ QML_VALUE_TYPE(vector2d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -152,6 +160,10 @@ class QQuickVector3DValueType
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector3D)
+ QML_VALUE_TYPE(vector3d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -185,6 +197,10 @@ class QQuickVector4DValueType
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_PROPERTY(qreal w READ w WRITE setW FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QVector4D)
+ QML_VALUE_TYPE(vector4d)
+
public:
Q_INVOKABLE QString toString() const;
@@ -219,6 +235,10 @@ class QQuickQuaternionValueType
Q_PROPERTY(qreal y READ y WRITE setY)
Q_PROPERTY(qreal z READ z WRITE setZ)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QQuaternion)
+ QML_VALUE_TYPE(quaternion)
+
public:
Q_INVOKABLE QString toString() const;
@@ -252,6 +272,10 @@ class QQuickMatrix4x4ValueType
Q_PROPERTY(qreal m43 READ m43 WRITE setM43 FINAL)
Q_PROPERTY(qreal m44 READ m44 WRITE setM44 FINAL)
Q_GADGET
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_FOREIGN(QMatrix4x4)
+ QML_VALUE_TYPE(matrix4x4)
+
public:
qreal m11() const { return v(0, 0); }
qreal m12() const { return v(0, 1); }
@@ -312,28 +336,10 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QMatrix4x4 &m) const;
};
-class QQuickFontValueType
+class QQuickFontEnums
{
- QFont v;
Q_GADGET
- Q_PROPERTY(QString family READ family WRITE setFamily FINAL)
- Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL)
- Q_PROPERTY(bool bold READ bold WRITE setBold FINAL)
- Q_PROPERTY(int weight READ weight WRITE setWeight FINAL)
- Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL)
- Q_PROPERTY(bool underline READ underline WRITE setUnderline FINAL)
- Q_PROPERTY(bool overline READ overline WRITE setOverline FINAL)
- Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout FINAL)
- Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize FINAL)
- Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize FINAL)
- Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization FINAL)
- Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing FINAL)
- Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing FINAL)
- Q_PROPERTY(HintingPreference hintingPreference READ hintingPreference WRITE setHintingPreference FINAL)
- Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
- Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
-
QML_NAMED_ELEMENT(Font)
QML_ADDED_IN_VERSION(2, 0)
QML_UNCREATABLE("Element is not creatable.")
@@ -363,7 +369,35 @@ public:
PreferFullHinting = QFont::PreferFullHinting
};
Q_ENUM(HintingPreference)
+};
+
+class QQuickFontValueType : public QQuickFontEnums
+{
+ QFont v;
+ Q_GADGET
+ Q_PROPERTY(QString family READ family WRITE setFamily FINAL)
+ Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL)
+ Q_PROPERTY(bool bold READ bold WRITE setBold FINAL)
+ Q_PROPERTY(int weight READ weight WRITE setWeight FINAL)
+ Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL)
+ Q_PROPERTY(bool underline READ underline WRITE setUnderline FINAL)
+ Q_PROPERTY(bool overline READ overline WRITE setOverline FINAL)
+ Q_PROPERTY(bool strikeout READ strikeout WRITE setStrikeout FINAL)
+ Q_PROPERTY(qreal pointSize READ pointSize WRITE setPointSize FINAL)
+ Q_PROPERTY(int pixelSize READ pixelSize WRITE setPixelSize FINAL)
+ Q_PROPERTY(Capitalization capitalization READ capitalization WRITE setCapitalization FINAL)
+ Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing FINAL)
+ Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing FINAL)
+ Q_PROPERTY(HintingPreference hintingPreference READ hintingPreference WRITE setHintingPreference FINAL)
+ Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
+ Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
+
+ QML_VALUE_TYPE(font)
+ QML_FOREIGN(QFont)
+ QML_ADDED_IN_VERSION(2, 0)
+
+public:
Q_INVOKABLE QString toString() const;
QString family() const;