aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-06-11 01:01:10 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-06-11 11:28:44 +0200
commit10e3b24c02cd1c22c7df0f350f229625e13faeae (patch)
treee9f02181e47156e9c8652e0c5dba15bbdcb97e5a /src/qml/qml
parent8733a8762c2db473d3a39d1f01c09156c04e3772 (diff)
parentac402fa6d99eeb519a9cc23b028358dfb6df4d82 (diff)
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts: src/qml/jsruntime/qv4value_p.h src/qml/qml/qqmlmetatype.cpp src/qml/qml/qqmltypewrapper.cpp src/quick/items/qquicktableview.cpp Change-Id: I684f8e01a711580512848bf1253f39b39fcbf4c7
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqml.h9
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp9
-rw-r--r--src/qml/qml/qqmlcomponent.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp4
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp43
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h2
6 files changed, 56 insertions, 13 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 7b3f89e943..f84a1b2109 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -608,9 +608,12 @@ Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versi
template<typename T>
QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
{
- QObject *mutableObj = const_cast<QObject *>(obj);
- return qmlAttachedPropertiesObject(
- mutableObj, qmlAttachedPropertiesFunction(mutableObj, &T::staticMetaObject), create);
+ // We don't need a concrete object to resolve the function. As T is a C++ type, it and all its
+ // super types should be registered as CppType (or not at all). We only need the object and its
+ // QML engine to resolve composite types. Therefore, the function is actually a static property
+ // of the C++ type system and we can cache it here for improved performance on further lookups.
+ static const auto func = qmlAttachedPropertiesFunction(nullptr, &T::staticMetaObject);
+ return qmlAttachedPropertiesObject(const_cast<QObject *>(obj), func, create);
}
inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 1b7a433a84..facd79d211 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -76,7 +76,7 @@ void QQmlApplicationEnginePrivate::init()
&QCoreApplication::exit, Qt::QueuedConnection);
#if QT_CONFIG(translation)
QTranslator* qtTranslator = new QTranslator;
- if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath), QLatin1String(".qm")))
QCoreApplication::installTranslator(qtTranslator);
translators << qtTranslator;
#endif
@@ -90,10 +90,10 @@ void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile)
if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc"))
return;
- QFileInfo fi(rootFile.toLocalFile());
+ QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(rootFile));
QTranslator *translator = new QTranslator;
- if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"))) {
+ if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"), QLatin1String(".qm"))) {
QCoreApplication::installTranslator(translator);
translators << translator;
} else {
@@ -180,6 +180,9 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
\list
\li Connecting Qt.quit() to QCoreApplication::quit()
\li Automatically loads translation files from an i18n directory adjacent to the main QML file.
+ \list
+ \li Translation files must have "qml_" prefix e.g. qml_ja_JP.qm.
+ \endlist
\li Automatically sets an incubation controller if the scene contains a QQuickWindow.
\li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all
QML files and assets.
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 04debc0615..89b632f87b 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1206,7 +1206,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
\js
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready)
- component.createObject(parent, {"x": 100, "y": 100});
+ component.createObject(parent, {x: 100, y: 100});
\endjs
Dynamically created instances can be deleted with the \c destroy() method.
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index a5b92d14f7..c6858780a1 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1193,7 +1193,8 @@ QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVe
void QQmlMetaType::unregisterType(int typeIndex)
{
QQmlMetaTypeDataPtr data;
- if (const QQmlTypePrivate *d = data->types.value(typeIndex).priv()) {
+ const QQmlType type = data->types.value(typeIndex);
+ if (const QQmlTypePrivate *d = type.priv()) {
removeQQmlTypePrivate(data->idToType, d);
removeQQmlTypePrivate(data->nameToType, d);
removeQQmlTypePrivate(data->urlToType, d);
@@ -1203,6 +1204,7 @@ void QQmlMetaType::unregisterType(int typeIndex)
module->remove(d);
data->clearPropertyCachesForMinorVersion(typeIndex);
data->types[typeIndex] = QQmlType();
+ data->undeletableTypes.remove(type);
}
}
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 9db089c330..57c4eec879 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -454,16 +454,16 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
if (!includeEnums || !name->startsWithUpper()) {
QQmlData *ddata = QQmlData::get(qobjectSingleton, false);
if (ddata && ddata->propertyCache) {
- ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext);
if (property) {
- lookup->qobjectLookup.ic = This->internalClass();
- lookup->qobjectLookup.staticQObject = static_cast<Heap::QObjectWrapper *>(val->heapObject());
+ ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
+ lookup->qobjectLookup.qmlTypeIc = This->internalClass();
+ lookup->qobjectLookup.ic = val->objectValue()->internalClass();
lookup->qobjectLookup.propertyCache = ddata->propertyCache;
lookup->qobjectLookup.propertyCache->addref();
lookup->qobjectLookup.propertyData = property;
- lookup->getter = QV4::QObjectWrapper::lookupGetter;
- return lookup->getter(lookup, engine, *This);
+ lookup->getter = QQmlTypeWrapper::lookupSingletonProperty;
+ return lookup->getter(lookup, engine, *object);
}
// Fall through to base implementation
}
@@ -485,6 +485,39 @@ bool QQmlTypeWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine
return Object::virtualResolveLookupSetter(object, engine, lookup, value);
}
+ReturnedValue QQmlTypeWrapper::lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &object)
+{
+ const auto revertLookup = [l, engine, &object]() {
+ l->qobjectLookup.propertyCache->release();
+ l->qobjectLookup.propertyCache = nullptr;
+ l->getter = Lookup::getterGeneric;
+ return Lookup::getterGeneric(l, engine, object);
+ };
+
+ // we can safely cast to a QV4::Object here. If object is something else,
+ // the internal class won't match
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (!o || o->internalClass != l->qobjectLookup.qmlTypeIc)
+ return revertLookup();
+
+ Heap::QQmlTypeWrapper *This = static_cast<Heap::QQmlTypeWrapper *>(o);
+
+ QQmlType type = This->type();
+ if (!type.isValid())
+ return revertLookup();
+
+ if (!type.isQObjectSingleton() && !type.isCompositeSingleton())
+ return revertLookup();
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine->qmlEngine());
+ QObject *qobjectSingleton = e->singletonInstance<QObject *>(type);
+ Q_ASSERT(qobjectSingleton);
+
+ Scope scope(engine);
+ ScopedValue obj(scope, QV4::QObjectWrapper::wrap(engine, qobjectSingleton));
+ return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup);
+}
+
void Heap::QQmlScopedEnumWrapper::destroy()
{
QQmlType::derefHandle(typePrivate);
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index c797a4ac10..6b51f421b3 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -114,6 +114,8 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object
static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value);
+ static ReturnedValue lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &base);
+
protected:
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);