summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-09-12 18:30:04 +0300
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-09-12 18:30:04 +0300
commit5f2a598a9134167a0da2efcbf1249fc167ae3750 (patch)
treef821e0e2871afcaedf84d4a245eb5d15f5c816ea
parentaa705010da0f658b78c1155babce7091ae44529a (diff)
parentf14549a54bb8daeffae48108a7e76d521523f04f (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.7' into tqtc/lts-5.15-opensourcev5.15.7-lts-lgpl
-rw-r--r--.qmake.conf2
-rw-r--r--src/remoteobjects/qremoteobjectsource.cpp33
-rw-r--r--tests/auto/qml/usertypes/data/MyType.qml5
-rw-r--r--tests/auto/qml/usertypes/data/composite.qml7
-rw-r--r--tests/auto/qml/usertypes/tst_usertypes.cpp12
5 files changed, 49 insertions, 10 deletions
diff --git a/.qmake.conf b/.qmake.conf
index df72b25..f1a6b2b 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -4,6 +4,6 @@ CONFIG += qt_example_installs
DEFINES += QT_NO_JAVA_STYLE_ITERATORS
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.15.6
+MODULE_VERSION = 5.15.7
QTRO_SOURCE_TREE = $$PWD
diff --git a/src/remoteobjects/qremoteobjectsource.cpp b/src/remoteobjects/qremoteobjectsource.cpp
index 49f1e1d..a16884c 100644
--- a/src/remoteobjects/qremoteobjectsource.cpp
+++ b/src/remoteobjects/qremoteobjectsource.cpp
@@ -113,7 +113,10 @@ QRemoteObjectSourceBase::QRemoteObjectSourceBase(QObject *obj, Private *d, const
if (QMetaType::typeFlags(property.userType()).testFlag(QMetaType::PointerToQObject)) {
auto propertyMeta = QMetaType::metaObjectForType(property.userType());
QObject *child = property.read(m_object).value<QObject *>();
- if (propertyMeta->inherits(&QAbstractItemModel::staticMetaObject)) {
+ const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
+ if (!meta)
+ continue;
+ if (meta->inherits(&QAbstractItemModel::staticMetaObject)) {
const auto modelInfo = api->m_models.at(modelIndex++);
QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(child);
QAbstractItemAdapterSourceAPI<QAbstractItemModel, QAbstractItemModelSourceAdapter> *modelApi =
@@ -455,13 +458,20 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
const int propCount = metaObject->propertyCount();
const int propOffset = metaObject->propertyOffset();
m_properties.reserve(propCount-propOffset);
- int i = 0;
- for (i = propOffset; i < propCount; ++i) {
+ QSet<int> invalidSignals;
+ for (int i = propOffset; i < propCount; ++i) {
const QMetaProperty property = metaObject->property(i);
if (QMetaType::typeFlags(property.userType()).testFlag(QMetaType::PointerToQObject)) {
auto propertyMeta = QMetaType::metaObjectForType(property.userType());
QObject *child = property.read(object).value<QObject *>();
- if (propertyMeta->inherits(&QAbstractItemModel::staticMetaObject)) {
+ const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
+ if (!meta) {
+ const int notifyIndex = metaObject->property(i).notifySignalIndex();
+ if (notifyIndex != -1)
+ invalidSignals << notifyIndex;
+ continue;
+ }
+ if (meta->inherits(&QAbstractItemModel::staticMetaObject)) {
const QByteArray name = QByteArray::fromRawData(property.name(),
qstrlen(property.name()));
const QByteArray infoName = name.toUpper() + QByteArrayLiteral("_ROLES");
@@ -475,12 +485,15 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
QString::fromLatin1(property.name()),
roleInfo});
} else {
- const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
QString typeName = QtRemoteObjects::getTypeNameAndMetaobjectFromClassInfo(meta);
if (typeName.isNull()) {
- typeName = QString::fromLatin1(propertyMeta->className());
+ typeName = QString::fromLatin1(meta->className());
+ if (typeName.contains(QLatin1String("QQuick")))
+ typeName.remove(QLatin1String("QQuick"));
+ else if (int index = typeName.indexOf(QLatin1String("_QMLTYPE_")))
+ typeName.truncate(index);
// TODO better way to ensure we have consistent typenames between source/replicas?
- if (typeName.endsWith(QLatin1String("Source")))
+ else if (typeName.endsWith(QLatin1String("Source")))
typeName.chop(6);
}
@@ -499,11 +512,13 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
}
const int methodCount = metaObject->methodCount();
const int methodOffset = metaObject->methodOffset();
- for (i = methodOffset; i < methodCount; ++i) {
+ for (int i = methodOffset; i < methodCount; ++i) {
const QMetaMethod mm = metaObject->method(i);
const QMetaMethod::MethodType m = mm.methodType();
if (m == QMetaMethod::Signal) {
- if (m_signals.indexOf(i) >= 0) //Already added as a property notifier
+ if (m_signals.indexOf(i) >= 0) // Already added as a property notifier
+ continue;
+ if (invalidSignals.contains(i)) // QObject with no metatype
continue;
m_signals << i;
} else if (m == QMetaMethod::Slot || m == QMetaMethod::Method)
diff --git a/tests/auto/qml/usertypes/data/MyType.qml b/tests/auto/qml/usertypes/data/MyType.qml
new file mode 100644
index 0000000..7061c2c
--- /dev/null
+++ b/tests/auto/qml/usertypes/data/MyType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int value: 39
+}
diff --git a/tests/auto/qml/usertypes/data/composite.qml b/tests/auto/qml/usertypes/data/composite.qml
new file mode 100644
index 0000000..b8defd3
--- /dev/null
+++ b/tests/auto/qml/usertypes/data/composite.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+QtObject {
+ property QtObject myTypeOk: MyType {} // this works
+ property MyType myType: MyType {} // this crashes
+ property MyType myType2 // this crashes (ensure solution works with null object)
+}
diff --git a/tests/auto/qml/usertypes/tst_usertypes.cpp b/tests/auto/qml/usertypes/tst_usertypes.cpp
index 355d545..4c25153 100644
--- a/tests/auto/qml/usertypes/tst_usertypes.cpp
+++ b/tests/auto/qml/usertypes/tst_usertypes.cpp
@@ -65,6 +65,7 @@ private Q_SLOTS:
void watcherInQml();
void hostInQml();
void twoReplicas();
+ void remoteCompositeType();
};
tst_usertypes::tst_usertypes()
@@ -293,6 +294,17 @@ void tst_usertypes::twoReplicas()
QTRY_COMPARE_WITH_TIMEOUT(obj->property("result2").value<int>(), 7, 500);
}
+void tst_usertypes::remoteCompositeType()
+{
+ QQmlEngine e;
+ QQmlComponent c(&e, SRCDIR "data/composite.qml");
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(obj);
+
+ QRemoteObjectRegistryHost host(QUrl("local:remoteCompositeType"));
+ host.enableRemoting(obj.data(), "composite");
+}
+
QTEST_MAIN(tst_usertypes)
#include "tst_usertypes.moc"