From fa8cb43a7e90d1bf54c0dcc76ab41c537afc6e88 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 14 Feb 2020 17:13:30 +0100 Subject: Windows: Do look for d.dll as a fallback Do look for d.dll as name of the library, even if Qt was built in release mode. This mitigates the change we did in Qt 5.14.0, where we switched the way our MinGW builds are configured from -debug-and-release to -debug -force-debug-info. But it is also more consisten in how we handle the release build, and macOS dylib loading. Fixes: QTBUG-81021 Change-Id: I73cd11941d86a732b92a3479d47b6e83a839994f Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlimport.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 3bf8d807a9..a01b07c75c 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1859,8 +1859,11 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, static const QStringList suffixes = { # ifdef QT_DEBUG QLatin1String("d.dll"), // try a qmake-style debug build first -# endif QLatin1String(".dll") +#else + QLatin1String(".dll"), + QLatin1String("d.dll") // try a qmake-style debug build after +# endif }; #elif defined(Q_OS_DARWIN) static const QString prefix = QLatin1String("lib"); -- cgit v1.2.3 From 8ccc86d31933054edc02487d29328e109e4a1bc4 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 12 Feb 2020 13:49:43 +0100 Subject: Doc: Update documentation for "extending" example It referred to qmlRegisterType() even though we don't call it anymore. Change-Id: Ib07e4428d032e789d705156ddc4c9589fd797c65 Reviewed-by: Fabian Kosmale --- .../doc/src/cppintegration/extending-tutorial.qdoc | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index d587173e5a..458768bf18 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -103,11 +103,22 @@ functionality of an existing QObject-based class, it could inherit from that cla Alternatively, if we want to create a visual item that doesn't need to perform drawing operations with the QPainter API, we can just subclass QQuickItem. -The \c PieChart class defines the two properties, \c name and \c color, with the Q_PROPERTY macro, -and overrides QQuickPaintedItem::paint(). The class implementation in \c piechart.cpp -simply sets and returns the \c m_name and \c m_color values as appropriate, and -implements \c paint() to draw a simple pie chart. It also turns off the -QGraphicsItem::ItemHasNoContents flag to enable painting: +The \c PieChart class defines the two properties, \c name and \c color, with the +Q_PROPERTY macro, and overrides QQuickPaintedItem::paint(). The \c PieChart +class is registered using the QML_ELEMENT macro, to allow it to be used from +QML. If you don't register the class, \c app.qml won't be able to create a +\c PieChart. + +For the registration to take effect, the \c qmltypes option is added to +\c CONFIG in the project file and a \c QML_IMPORT_NAME and +\c QML_IMPORT_MAJOR_VERSION are given: + +\snippet tutorials/extending-qml/chapter1-basics/chapter1-basics.pro 0 + +The class implementation in \c piechart.cpp simply sets and returns the +\c m_name and \c m_color values as appropriate, and implements \c paint() to +draw a simple pie chart. It also turns off the QGraphicsItem::ItemHasNoContents +flag to enable painting: \snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 0 \dots 0 @@ -125,9 +136,7 @@ provided for various other \l {QML Basic Types}{basic types}; for example, a str like "640x480" can be automatically converted to a QSize value. We'll also create a C++ application that uses a QQuickView to run and -display \c app.qml. The application must register the \c PieChart type -using the qmlRegisterType() function, to allow it to be used from QML. If -you don't register the type, \c app.qml won't be able to create a \c PieChart. +display \c app.qml. Here is the application \c main.cpp: @@ -143,7 +152,7 @@ Now we can build and run the application: \image extending-tutorial-chapter1.png -\note You may see a warning \e {Expression ... depends on non-NOTIFYable properties: +\note You may see a warning \e {Expression ... depends on non-NOTIFYable properties: PieChart::name}. This happens because we add a binding to the writable \c name property, but haven't yet defined a notify signal for it. The QML engine therefore cannot update the binding if the \c name value changes. This is addressed in @@ -450,7 +459,7 @@ In this tutorial, we've shown the basic steps for creating a QML extension: \list \li Define new QML types by subclassing QObject and registering them with - qmlRegisterType() + QML_ELEMENT or QML_NAMED_ELEMENT() \li Add callable methods using \l Q_INVOKABLE or Qt slots, and connect to Qt signals with an \c onSignal syntax \li Add property bindings by defining \l{Qt's Property System}{NOTIFY} signals -- cgit v1.2.3 From 2eb5b3f5c5f32404b8cb4ebb1d65ed5d5781b9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Wed, 19 Feb 2020 15:10:36 +0100 Subject: Fix broken -no-qml-debug 4975a33ba9aa357ba2bca93e292b1fbcfb34c24e introduced QQmlDebugTranslationService. If -no-qml-debug is provided the dummy class misses "public:". qml/qqmlbinding.cpp:401:54: error: 'virtual void QQmlDebugTranslationService::foundTranslationBinding(QQmlTranslationBinding*, QObject*, QQmlContextData*)' is private within this context Change-Id: I0f4ebd4d935a17aa7a679d2d87d98d03b0e1fcbb Reviewed-by: Tim Jenssen --- src/qml/debugger/qqmldebugserviceinterfaces_p.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml') diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h index 644d9d6ba9..b259e047a1 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h +++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h @@ -105,6 +105,7 @@ class QDebugMessageService {}; class QQmlEngineControlService {}; class QQmlNativeDebugService {}; class QQmlDebugTranslationService { +public: virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};} virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *, QQmlContextData *) {} }; -- cgit v1.2.3 From d4f3445bb050bbc34f0e86832fca9b7047041c1e Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 18 Feb 2020 12:44:24 +0100 Subject: Avoid memory leaks for inline component types When a QQmlType is constructed from a QQmlTypePrivate, the latter's refcount is incremented. We decrement it again, as the QQmlType should be its sole owner. Change-Id: Id6ab618e06b49c10e3888c694113536caed7f058 Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlimport.cpp | 1 + src/qml/qml/qqmltype.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 80eafdf146..3a06e98b6b 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -724,6 +724,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt Q_ASSERT(ok); typePriv->extraData.id->url = QUrl(this->url); auto icType = QQmlType(typePriv); + typePriv->release(); return icType; }; if (containingType.isValid()) { diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 2b804c45a7..96a35b0fe9 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -946,7 +946,8 @@ int QQmlType::generatePlaceHolderICId() const void QQmlType::associateInlineComponent(const QString &name, int objectID, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType) { - auto priv = existingType.isValid() ? const_cast(existingType.d.data()) : new QQmlTypePrivate { RegistrationType::InlineComponentType } ; + bool const reuseExistingType = existingType.isValid(); + auto priv = reuseExistingType ? const_cast(existingType.d.data()) : new QQmlTypePrivate { RegistrationType::InlineComponentType } ; priv->setName( QString::fromUtf8(typeName()), name); auto icUrl = QUrl(sourceUrl()); icUrl.setFragment(QString::number(objectID)); @@ -958,6 +959,8 @@ void QQmlType::associateInlineComponent(const QString &name, int objectID, const d->namesToInlineComponentObjectIndex.insert(name, objectID); QQmlType icType(priv); d->objectIdToICType.insert(objectID, icType); + if (!reuseExistingType) + priv->release(); } void QQmlType::setPendingResolutionName(const QString &name) -- cgit v1.2.3 From add46fd9055088e6aa458f21558234e267eb60ca Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 18 Feb 2020 09:20:13 +0100 Subject: ResolvedList: attempt read from correct meta object Fixes: QTBUG-82171 Change-Id: If14b10d703aa1b69cd697024ada2fae0453103d7 Reviewed-by: Ulf Hermann Reviewed-by: Aleix Pol Gonzalez --- src/qml/qml/qqmlvmemetaobject.cpp | 47 ++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index de23e929e2..edf9657f53 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -48,6 +48,7 @@ #include "qqmlcontext_p.h" #include "qqmlbinding_p.h" #include "qqmlpropertyvalueinterceptor_p.h" +#include #include @@ -60,6 +61,8 @@ #include #include +#include // for CHAR_BIT + QT_BEGIN_NAMESPACE class ResolvedList @@ -67,13 +70,22 @@ class ResolvedList Q_DISABLE_COPY_MOVE(ResolvedList) public: - ResolvedList(QQmlListProperty *prop) : - m_metaObject(static_cast(QObjectPrivate::get(prop->object)->metaObject)), - m_id(quintptr(prop->data)) + ResolvedList(QQmlListProperty *prop) { + // see QQmlVMEMetaObject::metaCall for how this was constructed + auto encodedIndex = quintptr(prop->data); + constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT; + quintptr inheritanceDepth = encodedIndex >> (usableBits / 2); + m_id = encodedIndex & ((quintptr(1) << (usableBits / 2)) - 1); + + // walk up to the correct meta object if necessary + auto mo = prop->object->metaObject(); + while (inheritanceDepth--) + mo = mo->superClass(); + m_metaObject = static_cast(const_cast(mo)); Q_ASSERT(m_metaObject); + Q_ASSERT( ::strstr(m_metaObject->property(m_metaObject->propOffset() + m_id).typeName(), "QQmlListProperty") ); Q_ASSERT(m_metaObject->object == prop->object); - Q_ASSERT(m_id <= quintptr(std::numeric_limits::max() - m_metaObject->methodOffset())); // readPropertyAsList() with checks transformed into Q_ASSERT // and without allocation. @@ -747,10 +759,35 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * break; case QV4::CompiledData::BuiltinType::InvalidBuiltin: if (property.isList) { + // when reading from the list, we need to find the correct MetaObject, + // namely this. However, obejct->metaObject might point to any MetaObject + // down the inheritance hierarchy, so we need to store how far we have + // to go down + // To do this, we encode the hierarchy depth together with the id of the + // property in a single quintptr, with the first half storing the depth + // and the second half storing the property id + auto mo = object->metaObject(); + quintptr inheritanceDepth = 0u; + while (mo && mo != this) { + mo = mo->superClass(); + ++inheritanceDepth; + } + constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT; + if (Q_UNLIKELY(inheritanceDepth >= (quintptr(1) << quintptr(usableBits / 2u) ) )) { + qmlWarning(object) << "Too many objects in inheritance hierarchy for list property"; + return -1; + } + if (Q_UNLIKELY(quintptr(id) >= (quintptr(1) << quintptr(usableBits / 2) ) )) { + qmlWarning(object) << "Too many properties in object for list property"; + return -1; + } + quintptr encodedIndex = (inheritanceDepth << (usableBits/2)) + id; + + readPropertyAsList(id); // Initializes if necessary *static_cast *>(a[0]) = QQmlListProperty( - object, reinterpret_cast(quintptr(id)), + object, reinterpret_cast(quintptr(encodedIndex)), list_append, list_count, list_at, list_clear, list_replace, list_removeLast); } else { -- cgit v1.2.3 From 08c78ecb91df3cb67934a89d84091775aa1e2bb8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 17 Feb 2020 14:00:21 +0100 Subject: Doc: Fix imports documentation We promote QML_ELEMENT and QML_NAMED_ELEMENT() ways to declare types, rather than qmlRegisterType(). Change-Id: I78d64a0ab4412499815da8c0f71bea6dc5dd0b93 Reviewed-by: Shawn Rutledge --- src/qml/doc/src/qmllanguageref/syntax/imports.qdoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc index 32106d5bb8..fdba452271 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc @@ -127,15 +127,15 @@ Rectangle { In this case, the engine will emit an error and refuse to load the file. -\section4 Non-module Namespace Imports +\section4 C++ Module Imports -Types can also be registered into namespaces directly via the various -registration functions in C++ (such as qmlRegisterType()). The types which -have been registered into a namespace in this way may be imported by importing -the namespace, as if the namespace was a module identifier. +Usually, C++ types are declared using the QML_ELEMENT and QML_NAMED_ELEMENT() +macros and registered via the build system using QML_IMPORT_NAME and +QML_IMPORT_MAJOR_VERSION. The import name and version given this way form a +module that can be imported to access the types. This is most common in client applications which define their own QML object -types in C++ and register them with the QML type system manually. +types in C++. \section4 Importing into a Qualified Local Namespace -- cgit v1.2.3 From 8f86214856753a2cb58507336ef6ea98b580094c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 17 Feb 2020 13:06:05 +0100 Subject: Doc: Fix the qmltypes format documentation The case of plain element name without URI is highly atypical and should not be advertised to end users. Also, stress that minor versions and revisions should match and that you should use the QML_* macros to register types. Task-number: QTBUG-81615 Change-Id: I1fd89c708ef8c33cbe44bacb3b37f25661eb3d1e Reviewed-by: Shawn Rutledge --- src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc | 43 +++++++++++++--------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index f7d71030b5..99c7fa5621 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -422,7 +422,7 @@ import QtQuick.tooling 1.1 // Component objects. Module { // A Component object directly corresponds to a type exported - // in a plugin with a call to qmlRegisterType. + // using the QML_ELEMENT or QML_NAMED_ELEMENT macros. Component { // The name is a unique identifier used to refer to this type. @@ -440,25 +440,34 @@ Module { attachedType: "QQuickAnimationAttached" // The list of exports determines how a type can be imported. - // Each string has the format "URI/Name version" and matches the - // arguments to qmlRegisterType. Usually types are only exported - // once, if at all. - // If the "URI/" part of the string is missing that means the - // type should be put into the package defined by the URI the - // module was imported with. - // For example if this module was imported with 'import Foo 4.8' - // the Animation object would be found in the package Foo and - // QtQuick. + // Each string has the format "URI/Name version". The URI is + // the import name given via the build system, for example as + // QML_IMPORT_NAME in qmake. The name is either the C++ class + // name or, in case of QML_NAMED_ELEMENT(), an explicitly given + // name. The version is constructed from the major version + // given via the build system, as QML_IMPORT_MAJOR_VERSION in + // qmake, and any revisions given in the class or its base + // classes by Q_REVISION(), the REVISION argument to Q_PROPERTY, + // or QML_ADDED_IN_MINOR_VERSION(). Usually types are only + // exported once, if at all. The following tells us that there + // are two variants of Animation, and that 'import QtQuick 2.0' + // will expose a different revision than imports of later + // versions. exports: [ - "Animation 4.7", - "QtQuick/Animation 1.0" + "QtQuick/Animation 2.0", + "QtQuick/Animation 2.1" ] // The meta object revisions for the exports specified in 'exports'. - // Describes with revisioned properties will be visible in an export. - // The list must have exactly the same length as the 'exports' list. - // For example the 'animations' propery described below will only be - // available through the QtQuick/Animation 1.0 export. + // Each meta object revision may add additional properties or methods, + // relative to the previous one. Those will only be visible when the + // module is imported with at least the corresponding version as + // specified in the 'exports' list. + // The exportMetaObjectRevisions list must have exactly the same + // length as the 'exports' list. For example, the 'animations' property + // described below will only be available through the QtQuick/Animation + // 2.1 export. Usually the revisions will match the versions in the + // 'exports' list. exportMetaObjectRevisions: [0, 1] Property { @@ -486,7 +495,7 @@ Module { // declarations also support the isReadonly, isPointer and isList // attributes which mean the same as for Property Method { name: "restart" } - Signal { name: "started"; revision: 2 } + Signal { name: "started"; revision: 1 } Signal { name: "runningChanged" Parameter { type: "bool" } -- cgit v1.2.3 From 410f835a40bda737c8933fe630251752fba2ba4f Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 19 Feb 2020 00:15:27 +0100 Subject: Doc: Fix documentation warnings for Qt QML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-82313 Change-Id: I7c2f30411ab8011254d7c232c87cb12a39761bda Reviewed-by: Topi Reiniö --- src/qml/doc/snippets/qml/qml-documents/Images.qml | 2 +- src/qml/doc/src/cppintegration/definetypes.qdoc | 2 +- src/qml/doc/src/qmlfunctions.qdoc | 19 ++++++++++--------- .../doc/src/qmllanguageref/documents/definetypes.qdoc | 9 +++++---- .../src/qmllanguageref/syntax/objectattributes.qdoc | 2 +- src/qml/qml/qqmlincubator.cpp | 4 ++-- src/qml/qml/qqmltypeloader.cpp | 2 +- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 12 ++++++------ 8 files changed, 27 insertions(+), 25 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/snippets/qml/qml-documents/Images.qml b/src/qml/doc/snippets/qml/qml-documents/Images.qml index 80a4d95fbb..fc9fa60282 100644 --- a/src/qml/doc/snippets/qml/qml-documents/Images.qml +++ b/src/qml/doc/snippets/qml/qml-documents/Images.qml @@ -81,4 +81,4 @@ Item { } property LabeledImage selectedImage: before } -// Images.qml +//! [document] diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc index f66dc44383..cbbbd9ba58 100644 --- a/src/qml/doc/src/cppintegration/definetypes.qdoc +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -307,7 +307,7 @@ merged with the original target class when used from within QML. For example: The \c leftMargin property is a new property added to an existing C++ type, \l QLineEdit, without modifying its source code. -The \l {QML_EXTENDED(extended)} macro is for registering extended types. The +The QML_EXTENDED(extended) macro is for registering extended types. The argument is the name of another class to be used as extension. An extension class is a regular QObject, with a constructor that takes a QObject diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 63c28d7aa7..04d907f168 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -27,7 +27,7 @@ /*! \macro QML_ELEMENT - \related QQmlEngine + \relates QQmlEngine Declares the enclosing type or namespace to be available in QML, using its class or namespace name as the QML element name. @@ -45,10 +45,10 @@ \endcode You can use the build system to register the type in the type namespace - "com.mycompany.qmlcomponents" with major version \c 1 by specifying the + \e {com.mycompany.qmlcomponents} with major version \c 1 by specifying the following in your project file: - \code + \badcode CONFIG += qmltypes QML_IMPORT_NAME = com.mycompany.qmlcomponents QML_IMPORT_MAJOR_VERSION = 1 @@ -74,7 +74,7 @@ /*! \macro QML_NAMED_ELEMENT(name) - \related QQmlEngine + \relates QQmlEngine Declares the enclosing type or namespace to be available in QML, using \a name as the element name. Otherwise behaves the same as QML_ELEMENT. @@ -209,7 +209,7 @@ {attached property} to other types. This takes effect if the type is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro. - \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAtachedPropertiesObject(), + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(), {Providing Attached Properties} */ @@ -234,7 +234,7 @@ \l QML_ATTACHED(), or \l QML_EXTENDED() macros in the enclosing C++ type do not apply to the enclosing type but instead to \a FOREIGN_TYPE. The enclosing type still needs to be registered with the - \l {The Meta-Object System}{meta object system} using a \l G_GADGET or + \l {The Meta-Object System}{meta object system} using a \l Q_GADGET or \l Q_OBJECT macro. This is useful for registering types that cannot be amended to add the macros, @@ -278,13 +278,14 @@ This will cause any QML which attempts to use the "Game" type to produce an error message: - \code + + \badcode fun.qml: Get back to work, slacker! Game { ^ \endcode - Using this technique, you only need a \l G_GADGET struct to customize the error + Using this technique, you only need a \l Q_GADGET struct to customize the error message, not a full-blown \l QObject. Without \l QML_UNCREATABLE(), \l QML_UNAVAILABLE still results in a more specific error message than the usual "is not a type" for completely unknown types. @@ -905,7 +906,7 @@ */ /*! - \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject* cppObject) + \fn template auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, T *cppObject) \relates QQmlEngine \since 5.14 diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc index 2eaedf8f9b..a4119ff793 100644 --- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc @@ -125,10 +125,11 @@ component : BaseType { Inside the file which declares the inline component, the type can be referenced simply by its name. -\snippet src/qml/doc/snippets/qml/qml-documents/Images.qml document +\snippet qml/qml-documents/Images.qml document In other files, it has to be prefixed with the name of its containing component. -\snippet src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml document + +\snippet qml/qml-documents/LabeledImageBox.qml document \note Inline components don't share their scope with the component they are declared in. In the following example, when \c A.MyInlineComponent in file @@ -137,8 +138,8 @@ an id in B.qml. It is therefore advisable not to reference objects in an inline component which are not part of it. -\snippet src/qml/doc/snippets/qml/qml-documents/A.qml document -\snippet src/qml/doc/snippets/qml/qml-documents/B.qml document +\snippet qml/qml-documents/A.qml document +\snippet qml/qml-documents/B.qml document \note Inline components cannot be nested. diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index 832d9a9e26..ecfef2e04f 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc @@ -684,7 +684,7 @@ Required properties play a special role in model-view-delegate code: If the delegate of a view has required properties whose names match with the role names of the view's model, then those properties will be initialized with the model's corresponding values. -For more information, visit the \l{Models and Views in QtQuick} page. +For more information, visit the \l{Models and Views in Qt Quick} page. \sa {QQmlComponent::createWithInitialProperties}, {QQmlApplicationEngine::setInitialProperties} and {QQuickView::setInitialProperties} for ways to initialize required properties from C++. diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index 4911cd2879..0ad013e90b 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -722,8 +722,8 @@ bool QQmlIncubatorPrivate::hadRequiredProperties() const } /*! -Stores a mapping from property names to initial values with which the incubated -component will be initialized +Stores a mapping from property names to initial values, contained in +\a initialProperties, with which the incubated component will be initialized. \sa QQmlComponent::setInitialProperties \since 5.15 diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 983592fccf..f910fe1140 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -393,7 +393,7 @@ QQmlEngine *QQmlTypeLoader::engine() const return m_engine; } -/*! +/*! \internal Call the initializeEngine() method on \a iface. Used by QQmlImportDatabase to ensure it gets called in the correct thread. */ diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 70134bad35..02628a9810 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -809,7 +809,7 @@ parameter may be any of the possible format values as described for \l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}. If \a format is not specified, \a date is formatted using -\l {QLocale::FormatType::ShortFormat}{Locale.ShortFormat} using the +\l {QLocale::FormatType}{Locale.ShortFormat} using the default locale. \sa Locale @@ -838,7 +838,7 @@ possible format values as described for \l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}. If \a format is not specified, \a time is formatted using -\l {QLocale::FormatType::ShortFormat}{Locale.ShortFormat} using the default locale. +\l {QLocale::FormatType}{Locale.ShortFormat} using the default locale. \sa Locale */ @@ -863,13 +863,13 @@ ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value * \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format, variant localeFormatOption) Returns a string representation of \a dateTime, optionally formatted using -\a format. +\a format and \a localeFormatOption. The \a dateTime parameter may be a JavaScript \c Date object, a \l{date}{date} property, a QDate, QTime, or QDateTime value. If \a format is not provided, \a dateTime is formatted using -\l {QLocale::FormatType::ShortFormat}{Locale.ShortFormat} using the +\l {QLocale::FormatType}{Locale.ShortFormat} using the default locale. Otherwise, \a format should be either: \list @@ -880,9 +880,9 @@ default locale. Otherwise, \a format should be either: \endlist If \a format specifies a locale object, \dateTime is formatted -with \li{QLocale::toString}. In this case, localeFormatType can hold a value +with \l{QLocale::toString}. In this case, \a localeFormatOption can hold a value of type \l {QLocale::FormatType} to further tune the formatting. If none is -provided, \l {QLocale::FormatType::ShortFormat}{Locale.ShortFormat} is used. +provided, \l {QLocale::FormatType}{Locale.ShortFormat} is used. If \a format specifies a format string, it should use the following expressions to specify the date: -- cgit v1.2.3 From 6b67a538336112671c3512509c7a0c9031732e37 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 20 Feb 2020 09:55:41 +0100 Subject: Inline components: do not leak context Change-Id: Ic738f3ea8f91cf2ffc7fb86ad9f72c0d630b6de8 Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlobjectcreator.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 28dd3d4ab4..aff982012d 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1264,7 +1264,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo ddata->columnNumber = obj->location.column; ddata->setImplicitDestructible(); - if (static_cast(index) == /*root object*/0 || ddata->rootObjectInCreation) { + // inline components are root objects, but their index is != 0, so we need + // an additional check + const bool isInlineComponent = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot; + if (static_cast(index) == /*root object*/0 || ddata->rootObjectInCreation || isInlineComponent) { if (ddata->context) { Q_ASSERT(ddata->context != context); Q_ASSERT(ddata->outerContext); -- cgit v1.2.3 From ea0956ccad5faab85f828279d500caedb07efac3 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 20 Feb 2020 10:18:10 +0100 Subject: Inline component: Avoid even more leaks Amends d4f3445bb050bbc34f0e86832fca9b7047041c1e Change-Id: I1071577529c2db6937affb3fd3087fec75917e8a Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlimport.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 2a6a77a2fc..e442f07527 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -901,6 +901,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int placeholderId = type_return->generatePlaceHolderICId(); icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId)); auto icType = QQmlType(icTypePriv); + icTypePriv->release(); type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType); *type_return = icType; } @@ -937,6 +938,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int placeholderId = type_return->generatePlaceHolderICId(); icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId)); auto icType = QQmlType(icTypePriv); + icTypePriv->release(); type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType); *type_return = icType; } -- cgit v1.2.3 From 78fd438f158839ffebcd52cc7974eac28489dbdd Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 20 Feb 2020 10:36:37 +0100 Subject: QV4Engine: Avoid memory leak in toVariant conversion Change-Id: I2c713fd759ac40aaaac0c0943edb993d3e27686b Reviewed-by: Ulf Hermann --- src/qml/jsruntime/qv4engine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a900e710c2..aea81b1e07 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1520,7 +1520,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return retn; #endif if (typeHint != -1) { - retn = QVariant(typeHint, QMetaType::create(typeHint)); + // the QVariant constructor will create a copy, so we have manually + // destroy the value returned by QMetaType::create + auto temp = QMetaType::create(typeHint); + retn = QVariant(typeHint, temp); + QMetaType::destroy(typeHint, temp); auto retnAsIterable = retn.value(); if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) { auto const length = a->getLength(); -- cgit v1.2.3 From 5884c214dce3d5c1f5d21f63e60d6a9e0dfdacfa Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 20 Feb 2020 15:21:08 +0100 Subject: Avoid cast from ASCII to QString The previous attempt to fix this was lost in a merge resolution. Change-Id: I0638c434543d231352c44687b06bf429b7be7a04 Reviewed-by: Fabian Kosmale --- src/qml/jsruntime/qv4engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index aea81b1e07..f1b20ce53b 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1537,8 +1537,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int if (!couldConvert) { qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3") .arg(QString::number(i), - QMetaType::typeName(originalType), - QMetaType::typeName(retnAsIterable._metaType_id)); + QString::fromUtf8(QMetaType::typeName(originalType)), + QString::fromUtf8(QMetaType::typeName(retnAsIterable._metaType_id))); // create default constructed value asVariant = QVariant(retnAsIterable._metaType_id, nullptr); } -- cgit v1.2.3 From 5054bb49a88a8ab76f586f79b6ef62a9142e6c83 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 17 Feb 2020 17:39:23 +0100 Subject: Fix QML basic type documentation Removed the documentation of some limitations that no longer apply. Fixed up grammar in the process. Fixes: QTBUG-82249 Change-Id: I807cbef10393f11bf864cf44ddd7556aa0eabb92 Reviewed-by: Ulf Hermann --- .../src/qmllanguageref/typesystem/basictypes.qdoc | 33 +++++----------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc index 5144fe219e..53984a440d 100644 --- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc @@ -582,34 +582,15 @@ property is only invoked when the property is reassigned to a different object v QML objects (and certainly not JavaScript object either) and the key-value pairs in \c attributes are \e not QML properties. Rather, the \c items property holds an array of values, and \c attributes holds a set of key-value - pairs. Since they are stored as a set of values, instead of as an object, - their contents \e cannot be modified individually: - - \qml - Item { - property variant items: [1, 2, 3, "four", "five"] - property variant attributes: { 'color': 'red', 'width': 100 } - - Component.onCompleted: { - items[0] = 10 - console.log(items[0]) // This will still be '1'! - attributes.color = 'blue' - console.log(attributes.color) // This will still be 'red'! - } - } - \endqml - - Since it is not possible to individually add or remove items from a list or - object stored in a \c variant, the only way to modify its contents is to - reassign a new value. However, this is not efficient, as it causes the value - to be serialized and deserialized. + pairs. Additionally, since \c items and \c attributes are not QML objects, changing - their individual values do not trigger property change notifications. If - the above example had \c onNumberChanged or \c onAnimalChanged signal - handlers, they would not have been called. If, however, the \c items or - \c attributes properties themselves were reassigned to different values, then - such handlers would be called. + the values they contain does not trigger property change notifications. If + the above example had \c onItemsChanged or \c onAttributesChanged signal + handlers, they would not be called when assigning individual entries in + either property. If, however, the \c items or \c attributes properties + themselves were reassigned to different values, then such handlers would be + called. JavaScript programmers should also note that when a JavaScript object is copied to an array or map property, the \e contents of the object (that is, -- cgit v1.2.3