aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp33
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h46
-rw-r--r--src/qml/qml/qqml.cpp43
-rw-r--r--src/qml/qml/qqml.h33
-rw-r--r--src/qml/qml/qqmlmetatype.cpp6
-rw-r--r--src/qml/qml/qqmlprivate.h46
7 files changed, 165 insertions, 44 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index fe34207ddc..b09f874ef3 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -709,8 +709,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
static_cast<VariantPrototype *>(variantPrototype())->init();
#if QT_CONFIG(qml_sequence_object)
- static const bool registered = QV4::SequencePrototype::registerDefaultTypes();
- Q_UNUSED(registered);
sequencePrototype()->cast<SequencePrototype>()->init();
#endif
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 5c7f8289f2..73fa2385fd 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -37,7 +37,6 @@
**
****************************************************************************/
-#include <QtQml/qqml.h>
#include <QtCore/qsequentialiterable.h>
#include "qv4sequenceobject_p.h"
@@ -51,10 +50,6 @@
#include "qv4objectiterator_p.h"
#include <private/qqmlmetatype_p.h>
#include <private/qqmltype_p_p.h>
-#if QT_CONFIG(qml_itemmodel)
-#include <private/qqmlmodelindexvaluetype_p.h>
-#include <QtCore/qabstractitemmodel.h>
-#endif
#include <algorithm>
@@ -581,34 +576,6 @@ namespace QV4 {
DEFINE_OBJECT_VTABLE(QV4Sequence);
}
-
-template<typename SequenceType>
-void registerSequenceType()
-{
- qRegisterMetaType<SequenceType>();
- qmlRegisterAnonymousSequentialContainer<SequenceType>("QML", 1);
-}
-
-bool SequencePrototype::registerDefaultTypes()
-{
- registerSequenceType<std::vector<int>>();
- registerSequenceType<std::vector<qreal>>();
- registerSequenceType<std::vector<bool>>();
- registerSequenceType<QList<int>>();
- registerSequenceType<QList<qreal>>();
- registerSequenceType<QList<bool>>();
- registerSequenceType<QStringList>();
- registerSequenceType<std::vector<QString>>();
- registerSequenceType<QList<QUrl>>();
- registerSequenceType<std::vector<QUrl>>();
-#if QT_CONFIG(qml_itemmodel)
- registerSequenceType<QModelIndexList>();
- registerSequenceType<std::vector<QModelIndex>>();
- registerSequenceType<QItemSelection>();
-#endif
- return true;
-}
-
void SequencePrototype::init()
{
defineDefaultProperty(QStringLiteral("sort"), method_sort, 1);
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 6229a4b5ec..9143430872 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -53,12 +53,18 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
+#include <QtQml/qqml.h>
#include "qv4value_p.h"
#include "qv4object_p.h"
#include "qv4context_p.h"
#include "qv4string_p.h"
+#if QT_CONFIG(qml_itemmodel)
+#include <private/qqmlmodelindexvaluetype_p.h>
+#include <QtCore/qabstractitemmodel.h>
+#endif
+
QT_REQUIRE_CONFIG(qml_sequence_object);
QT_BEGIN_NAMESPACE
@@ -68,7 +74,6 @@ namespace QV4 {
struct Q_QML_PRIVATE_EXPORT SequencePrototype : public QV4::Object
{
V4_PROTOTYPE(arrayPrototype)
- static bool registerDefaultTypes();
void init();
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
@@ -84,6 +89,45 @@ struct Q_QML_PRIVATE_EXPORT SequencePrototype : public QV4::Object
}
+#define QT_DECLARE_SEQUENTIAL_CONTAINER(LOCAL, FOREIGN, VALUE) \
+ struct LOCAL \
+ { \
+ Q_GADGET \
+ QML_ANONYMOUS \
+ QML_SEQUENTIAL_CONTAINER(VALUE) \
+ QML_FOREIGN(FOREIGN) \
+ QML_ADDED_IN_VERSION(2, 0) \
+ }
+
+// We use the original QT_COORD_TYPE name because that will match up with relevant other
+// types in plugins.qmltypes (if you use either float or double, that is; otherwise you're
+// on your own).
+#ifdef QT_COORD_TYPE
+QT_DECLARE_SEQUENTIAL_CONTAINER(QStdRealVectorForeign, std::vector<qreal>, QT_COORD_TYPE);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QRealListForeign, QList<qreal>, QT_COORD_TYPE);
+#else
+QT_DECLARE_SEQUENTIAL_CONTAINER(QRealStdVectorForeign, std::vector<qreal>, double);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QRealListForeign, QList<qreal>, double);
+#endif
+
+QT_DECLARE_SEQUENTIAL_CONTAINER(QIntStdVectorForeign, std::vector<int>, int);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QBoolStdVectorForeign, std::vector<bool>, bool);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QStringStdVectorForeign, std::vector<QString>, QString);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QUrlStdVectorForeign, std::vector<QUrl>, QUrl);
+
+QT_DECLARE_SEQUENTIAL_CONTAINER(QIntListForeign, QList<int>, int);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QBoolListForeign, QList<bool>, bool);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QStringListForeign, QStringList, QString);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QUrlListForeign, QList<QUrl>, QUrl);
+
+#if QT_CONFIG(qml_itemmodel)
+QT_DECLARE_SEQUENTIAL_CONTAINER(QModelIndexListForeign, QModelIndexList, QModelIndex);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QModelIndexStdVectorForeign, std::vector<QModelIndex>, QModelIndex);
+QT_DECLARE_SEQUENTIAL_CONTAINER(QItemSelectionForeign, QItemSelection, QItemSelectionRange);
+#endif
+
+#undef QT_DECLARE_SEQUENTIAL_CONTAINER
+
QT_END_NAMESPACE
#endif // QV4SEQUENCEWRAPPER_P_H
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 20608a60e4..40e629284b 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -421,6 +421,48 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
}
break;
}
+ case SequentialContainerAndRevisionsRegistration: {
+ const RegisterSequentialContainerAndRevisions &type
+ = *reinterpret_cast<RegisterSequentialContainerAndRevisions *>(data);
+ const char *elementName = classElementName(type.classInfoMetaObject);
+ RegisterSequentialContainer revisionRegistration = {
+ 0,
+ type.uri,
+ type.version,
+ elementName,
+ type.typeId,
+ type.metaSequence,
+ QTypeRevision()
+ };
+
+ const QTypeRevision added = revisionClassInfo(
+ type.classInfoMetaObject, "QML.AddedInVersion",
+ QTypeRevision::fromMinorVersion(0));
+ const QTypeRevision removed = revisionClassInfo(
+ type.classInfoMetaObject, "QML.RemovedInVersion");
+
+ QVector<QTypeRevision> revisions = { added };
+ uniqueRevisions(&revisions, type.version, added);
+
+ for (QTypeRevision revision : qAsConst(revisions)) {
+ if (revision < added)
+ continue;
+ if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
+ break;
+
+ // When removed, we still add revisions, but anonymous ones
+ if (removed.isValid() && !(revision < removed))
+ revisionRegistration.typeName = nullptr;
+ else
+ revisionRegistration.typeName = elementName;
+
+ assignVersions(&revisionRegistration, revision, type.version);
+ const int id = qmlregister(SequentialContainerRegistration, &revisionRegistration);
+ if (type.qmlTypeIds)
+ type.qmlTypeIds->append(id);
+ }
+ break;
+ }
case TypeRegistration:
dtype = QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data));
break;
@@ -472,6 +514,7 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
break;
case TypeAndRevisionsRegistration:
case SingletonAndRevisionsRegistration:
+ case SequentialContainerAndRevisionsRegistration:
// Currently unnecessary. We'd need a special data structure to hold
// URI + majorVersion and then we'd iterate the minor versions, look up the
// associated QQmlType objects by uri/elementName/major/minor and qmlunregister
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 75f7ae5f06..7f0c81c514 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -94,6 +94,14 @@
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
+#define QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) \
+ Q_CLASSINFO("QML.Sequence", #VALUE_TYPE) \
+ using QmlSequenceValueType = VALUE_TYPE; \
+ enum class QmlIsSequence {yes = true}; \
+ template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlSequence; \
+ template<typename T, typename... Args> \
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor, QList<int> *);
+
#define QML_ADDED_IN_MINOR_VERSION(VERSION) \
Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION))
@@ -792,17 +800,18 @@ inline int qmlRegisterAnonymousSequentialContainer(const char *uri, int versionM
QTypeRevision::fromMajorVersion(versionMajor),
nullptr,
QMetaType::fromType<Container>(),
- QMetaSequence::fromContainer<Container>()
+ QMetaSequence::fromContainer<Container>(),
+ QTypeRevision::zero()
};
return QQmlPrivate::qmlregister(QQmlPrivate::SequentialContainerRegistration, &type);
}
-template<class T, class Resolved, class Extended, bool Singleton, bool Interface>
+template<class T, class Resolved, class Extended, bool Singleton, bool Interface, bool Sequence>
struct QmlTypeAndRevisionsRegistration;
template<class T, class Resolved, class Extended>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
const QMetaObject *extension)
{
@@ -812,8 +821,19 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
}
};
+template<class T, class Resolved>
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, false, true> {
+ static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
+ const QMetaObject *)
+ {
+ QQmlPrivate::qmlRegisterSequenceAndRevisions<Resolved>(
+ uri, versionMajor, QQmlPrivate::StaticMetaObject<T>::staticMetaObject(),
+ qmlTypeIds);
+ }
+};
+
template<class T, class Resolved, class Extended>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
const QMetaObject *extension)
{
@@ -824,7 +844,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, true, false> {
};
template<class T, class Resolved>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor, QList<int> *qmlTypeIds,
const QMetaObject *)
{
@@ -845,7 +865,8 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor, QList<int>
T, typename QQmlPrivate::QmlResolved<T>::Type,
typename QQmlPrivate::QmlExtended<T>::Type,
QQmlPrivate::QmlSingleton<T>::Value,
- QQmlPrivate::QmlInterface<T>::Value>
+ QQmlPrivate::QmlInterface<T>::Value,
+ QQmlPrivate::QmlSequence<T>::Value>
::registerTypeAndRevisions(uri, versionMajor, qmlTypeIds,
QQmlPrivate::QmlExtendedNamespace<T>::metaObject());
qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor, qmlTypeIds);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index e59ebc97eb..9dea173127 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -667,7 +667,8 @@ QQmlType QQmlMetaType::registerSequentialContainer(
QQmlMetaTypeDataPtr data;
- if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(),
+ const QString typeName = QString::fromUtf8(container.typeName);
+ if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, typeName,
container.version, {})) {
return QQmlType();
}
@@ -675,8 +676,9 @@ QQmlType QQmlMetaType::registerSequentialContainer(
QQmlTypePrivate *priv = new QQmlTypePrivate(QQmlType::SequentialContainerType);
data->registerType(priv);
- priv->setName(QString::fromUtf8(container.uri), QString());
+ priv->setName(QString::fromUtf8(container.uri), typeName);
priv->version = container.version;
+ priv->revision = container.revision;
priv->typeId = container.typeId;
*priv->extraData.ld = container.metaSequence;
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 19072f0751..feee3f8686 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -574,6 +574,19 @@ namespace QQmlPrivate
const char *typeName;
QMetaType typeId;
QMetaSequence metaSequence;
+ QTypeRevision revision;
+ };
+
+ struct RegisterSequentialContainerAndRevisions {
+ int structVersion;
+ const char *uri;
+ QTypeRevision version;
+
+ const QMetaObject *classInfoMetaObject;
+ QMetaType typeId;
+ QMetaSequence metaSequence;
+
+ QVector<int> *qmlTypeIds;
};
struct AOTCompiledFunction {
@@ -605,6 +618,7 @@ namespace QQmlPrivate
TypeAndRevisionsRegistration = 7,
SingletonAndRevisionsRegistration = 8,
SequentialContainerRegistration = 9,
+ SequentialContainerAndRevisionsRegistration = 10,
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
@@ -717,6 +731,20 @@ namespace QQmlPrivate
};
template<class T, class = std::void_t<>>
+ struct QmlSequence
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlSequence<T, std::void_t<typename T::QmlIsSequence>>
+ {
+ Q_STATIC_ASSERT((std::is_same_v<typename T::QmlSequenceValueType,
+ typename QmlResolved<T>::Type::value_type>));
+ static constexpr bool Value = bool(T::QmlIsSequence::yes);
+ };
+
+ template<class T, class = std::void_t<>>
struct QmlInterface
{
static constexpr bool Value = false;
@@ -823,6 +851,24 @@ namespace QQmlPrivate
qmlregister(TypeAndRevisionsRegistration, &type);
}
+ template<typename T>
+ void qmlRegisterSequenceAndRevisions(const char *uri, int versionMajor,
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds)
+ {
+ RegisterSequentialContainerAndRevisions type = {
+ 0,
+ uri,
+ QTypeRevision::fromMajorVersion(versionMajor),
+ classInfoMetaObject,
+ QMetaType::fromType<T>(),
+ QMetaSequence::fromContainer<T>(),
+ qmlTypeIds
+ };
+
+ qmlregister(SequentialContainerAndRevisionsRegistration, &type);
+ }
+
template<>
void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject,