aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-02-17 01:01:00 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-02-17 10:21:59 +0100
commit3e758800b4daf8fbc870a2ff5d54fce9d4402ce8 (patch)
treeba237b9da1c7dfd08bf13e71c5dbd6b3c2e77633 /src
parent925a0e499a5dbdb180fd9969a79abf96006ce4fd (diff)
parent55546991e24ca6799709cbe0171b9ab87216c35f (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: src/imports/qtqml/plugin.cpp src/qml/qml/qqml.h src/qml/qml/qqmlmetatype.cpp src/qml/qml/qqmlmetatype_p.h src/qml/qml/qqmltypeloader.cpp src/qml/types/qqmlbind.cpp src/quick/items/qquickitemsmodule.cpp tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp Change-Id: I52548938a582cb6510271ed4bc3a9aa0c3c11df6
Diffstat (limited to 'src')
-rw-r--r--src/imports/folderlistmodel/plugin.cpp9
-rw-r--r--src/imports/labsanimation/plugin.cpp8
-rw-r--r--src/imports/labsmodels/plugin.cpp8
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent.cpp24
-rw-r--r--src/imports/labsmodels/qqmldelegatecomponent_p.h2
-rw-r--r--src/imports/labsmodels/qqmltablemodel.cpp17
-rw-r--r--src/imports/labsmodels/qqmltablemodel_p.h2
-rw-r--r--src/imports/layouts/plugin.cpp4
-rw-r--r--src/imports/layouts/qquicklayout.cpp21
-rw-r--r--src/imports/layouts/qquicklayout_p.h4
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp10
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h4
-rw-r--r--src/imports/localstorage/plugin.cpp4
-rw-r--r--src/imports/models/plugin.cpp17
-rw-r--r--src/imports/particles/plugin.cpp7
-rw-r--r--src/imports/qtqml/plugin.cpp10
-rw-r--r--src/imports/qtquick2/plugin.cpp7
-rw-r--r--src/imports/settings/plugin.cpp8
-rw-r--r--src/imports/shapes/plugin.cpp2
-rw-r--r--src/imports/sharedimage/plugin.cpp8
-rw-r--r--src/imports/statemachine/childrenprivate.h138
-rw-r--r--src/imports/statemachine/finalstate.cpp4
-rw-r--r--src/imports/statemachine/finalstate.h2
-rw-r--r--src/imports/statemachine/plugin.cpp8
-rw-r--r--src/imports/statemachine/state.cpp4
-rw-r--r--src/imports/statemachine/state.h2
-rw-r--r--src/imports/statemachine/statemachine.cpp4
-rw-r--r--src/imports/statemachine/statemachine.h2
-rw-r--r--src/imports/testlib/TestCase.qml17
-rw-r--r--src/imports/testlib/main.cpp8
-rw-r--r--src/imports/wavefrontmesh/plugin.cpp4
-rw-r--r--src/imports/window/plugin.cpp8
-rw-r--r--src/imports/workerscript/plugin.cpp17
-rw-r--r--src/particles/qquickimageparticle.cpp18
-rw-r--r--src/particles/qquickparticlegroup.cpp13
-rw-r--r--src/particles/qtquickparticlesglobal_p.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp68
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h87
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json2
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp5
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces.cpp1
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h21
-rw-r--r--src/qml/doc/snippets/code/backend/backend.h2
-rw-r--r--src/qml/doc/snippets/code/backend/backend.pro17
-rw-r--r--src/qml/doc/snippets/code/backend/main.cpp4
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp144
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h3
-rw-r--r--src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro22
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/A.qml61
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/B.qml58
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/Images.qml84
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml64
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc136
-rw-r--r--src/qml/doc/src/cppintegration/topic.qdoc18
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc4
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc113
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc52
-rw-r--r--src/qml/jsruntime/qv4engine.cpp27
-rw-r--r--src/qml/jsruntime/qv4value.cpp4
-rw-r--r--src/qml/parser/qqmljs.g20
-rw-r--r--src/qml/parser/qqmljsast.cpp257
-rw-r--r--src/qml/parser/qqmljsast_p.h311
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h4
-rw-r--r--src/qml/parser/qqmljsastvisitor.cpp6
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h805
-rw-r--r--src/qml/qml/qqml.cpp37
-rw-r--r--src/qml/qml/qqml.h71
-rw-r--r--src/qml/qml/qqmlbinding.cpp9
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp31
-rw-r--r--src/qml/qml/qqmlengine.cpp6
-rw-r--r--src/qml/qml/qqmlengine_p.h16
-rw-r--r--src/qml/qml/qqmlmetatype.cpp22
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp6
-rw-r--r--src/qml/qml/qqmlprivate.h21
-rw-r--r--src/qml/qml/qqmlproperty.cpp47
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp2
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp6
-rw-r--r--src/qml/qml/qqmltypedata.cpp5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp82
-rw-r--r--src/qml/qml/qqmltypenotavailable.cpp2
-rw-r--r--src/qml/qml/qqmltypenotavailable_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp92
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h49
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp29
-rw-r--r--src/qml/qtqmlglobal_p.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp3
-rw-r--r--src/qmldebug/qmldebug.pro4
-rw-r--r--src/qmldebug/qqmldebugtranslationclient.cpp76
-rw-r--r--src/qmldebug/qqmldebugtranslationclient_p.h81
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp3
-rw-r--r--src/qmlmodels/qqmladaptormodel_p.h5
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp2
-rw-r--r--src/qmlmodels/qqmldelegatemodel_p.h2
-rw-r--r--src/qmlmodels/qqmllistaccessor.cpp6
-rw-r--r--src/qmlmodels/qqmllistaccessor_p.h2
-rw-r--r--src/qmlmodels/qqmlobjectmodel.cpp34
-rw-r--r--src/qmlmodels/qqmlobjectmodel_p.h2
-rw-r--r--src/qmlmodels/qqmltableinstancemodel_p.h4
-rw-r--r--src/qmlmodels/qquickpackage.cpp19
-rw-r--r--src/qmlmodels/qtqmlmodelsglobal_p.h2
-rw-r--r--src/qmlworkerscript/qquickworkerscript_p.h2
-rw-r--r--src/qmlworkerscript/qtqmlworkerscriptglobal_p.h2
-rw-r--r--src/quick/accessible/qaccessiblequickview.cpp8
-rw-r--r--src/quick/designer/qquickdesignersupportproperties.cpp8
-rw-r--r--src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml81
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc20
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc1
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp5
-rw-r--r--src/quick/handlers/qquickhoverhandler.cpp19
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h1
-rw-r--r--src/quick/items/qquickevents.cpp162
-rw-r--r--src/quick/items/qquickevents_p_p.h71
-rw-r--r--src/quick/items/qquickflickable.cpp19
-rw-r--r--src/quick/items/qquickflickable_p_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp7
-rw-r--r--src/quick/items/qquickitemsmodule_p.h12
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquicklistview.cpp168
-rw-r--r--src/quick/items/qquickloader.cpp93
-rw-r--r--src/quick/items/qquickloader_p_p.h7
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp28
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h4
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp4
-rw-r--r--src/quick/items/qquickspriteengine_p.h12
-rw-r--r--src/quick/items/qquickspritesequence.cpp4
-rw-r--r--src/quick/items/qquicktableview.cpp20
-rw-r--r--src/quick/items/qquicktableview_p_p.h2
-rw-r--r--src/quick/items/qquicktext.cpp7
-rw-r--r--src/quick/items/qquickwindow.cpp60
-rw-r--r--src/quick/items/qquickwindow.h3
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/qtquickglobal_p.h2
-rw-r--r--src/quick/quick.pro5
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp16
-rw-r--r--src/quick/util/qquickpixmapcache.cpp12
-rw-r--r--src/quick/util/qquickstate.cpp10
-rw-r--r--src/quick/util/qquickstate_p_p.h17
-rw-r--r--src/quick/util/qquickstategroup.cpp36
-rw-r--r--src/quick/util/qquicktimeline_p_p.h3
-rw-r--r--src/quickshapes/qquickshapesglobal_p.h1
144 files changed, 3487 insertions, 1082 deletions
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 28837655ef..7a38769b77 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquickfolderlistmodel.h"
+extern void qml_register_types_Qt_labs_folderlistmodel();
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -51,7 +53,12 @@ class QmlFolderListModelPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QmlFolderListModelPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QmlFolderListModelPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_folderlistmodel;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
diff --git a/src/imports/labsanimation/plugin.cpp b/src/imports/labsanimation/plugin.cpp
index bd732a6aba..9c985f0dcf 100644
--- a/src/imports/labsanimation/plugin.cpp
+++ b/src/imports/labsanimation/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquickboundaryrule_p.h"
+extern void qml_register_types_Qt_labs_animation();
+
QT_BEGIN_NAMESPACE
/*!
@@ -66,7 +68,11 @@ class QtLabsAnimationPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtLabsAnimationPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_animation;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/labsmodels/plugin.cpp b/src/imports/labsmodels/plugin.cpp
index feb4f3ba0a..ab5e0023a6 100644
--- a/src/imports/labsmodels/plugin.cpp
+++ b/src/imports/labsmodels/plugin.cpp
@@ -50,6 +50,8 @@
#include "qqmldelegatecomponent_p.h"
#endif
+extern void qml_register_types_Qt_labs_qmlmodels();
+
QT_BEGIN_NAMESPACE
/*!
@@ -74,7 +76,11 @@ class QtQmlLabsModelsPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQmlLabsModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_qmlmodels;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/labsmodels/qqmldelegatecomponent.cpp b/src/imports/labsmodels/qqmldelegatecomponent.cpp
index aaf3fea5da..b8eb8049b3 100644
--- a/src/imports/labsmodels/qqmldelegatecomponent.cpp
+++ b/src/imports/labsmodels/qqmldelegatecomponent.cpp
@@ -250,7 +250,9 @@ QQmlListProperty<QQmlDelegateChoice> QQmlDelegateChooser::choices()
QQmlDelegateChooser::choices_append,
QQmlDelegateChooser::choices_count,
QQmlDelegateChooser::choices_at,
- QQmlDelegateChooser::choices_clear);
+ QQmlDelegateChooser::choices_clear,
+ QQmlDelegateChooser::choices_replace,
+ QQmlDelegateChooser::choices_removeLast);
}
void QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *prop, QQmlDelegateChoice *choice)
@@ -282,6 +284,26 @@ void QQmlDelegateChooser::choices_clear(QQmlListProperty<QQmlDelegateChoice> *pr
q->delegateChanged();
}
+void QQmlDelegateChooser::choices_replace(QQmlListProperty<QQmlDelegateChoice> *prop, int index,
+ QQmlDelegateChoice *choice)
+{
+ QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
+ disconnect(q->m_choices[index], &QQmlDelegateChoice::changed,
+ q, &QQmlAbstractDelegateComponent::delegateChanged);
+ q->m_choices[index] = choice;
+ connect(choice, &QQmlDelegateChoice::changed, q,
+ &QQmlAbstractDelegateComponent::delegateChanged);
+ q->delegateChanged();
+}
+
+void QQmlDelegateChooser::choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *prop)
+{
+ QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
+ disconnect(q->m_choices.takeLast(), &QQmlDelegateChoice::changed,
+ q, &QQmlAbstractDelegateComponent::delegateChanged);
+ q->delegateChanged();
+}
+
QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int row, int column) const
{
QVariant v;
diff --git a/src/imports/labsmodels/qqmldelegatecomponent_p.h b/src/imports/labsmodels/qqmldelegatecomponent_p.h
index 4c39dc0d0a..8473831b1d 100644
--- a/src/imports/labsmodels/qqmldelegatecomponent_p.h
+++ b/src/imports/labsmodels/qqmldelegatecomponent_p.h
@@ -116,6 +116,8 @@ public:
static int choices_count(QQmlListProperty<QQmlDelegateChoice> *);
static QQmlDelegateChoice *choices_at(QQmlListProperty<QQmlDelegateChoice> *, int);
static void choices_clear(QQmlListProperty<QQmlDelegateChoice> *);
+ static void choices_replace(QQmlListProperty<QQmlDelegateChoice> *, int, QQmlDelegateChoice *);
+ static void choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *);
QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = -1) const override;
diff --git a/src/imports/labsmodels/qqmltablemodel.cpp b/src/imports/labsmodels/qqmltablemodel.cpp
index b6468d760f..6ba2cecf19 100644
--- a/src/imports/labsmodels/qqmltablemodel.cpp
+++ b/src/imports/labsmodels/qqmltablemodel.cpp
@@ -644,7 +644,9 @@ QQmlListProperty<QQmlTableModelColumn> QQmlTableModel::columns()
&QQmlTableModel::columns_append,
&QQmlTableModel::columns_count,
&QQmlTableModel::columns_at,
- &QQmlTableModel::columns_clear);
+ &QQmlTableModel::columns_clear,
+ &QQmlTableModel::columns_replace,
+ &QQmlTableModel::columns_removeLast);
}
void QQmlTableModel::columns_append(QQmlListProperty<QQmlTableModelColumn> *property,
@@ -674,6 +676,19 @@ void QQmlTableModel::columns_clear(QQmlListProperty<QQmlTableModelColumn> *prope
return model->mColumns.clear();
}
+void QQmlTableModel::columns_replace(QQmlListProperty<QQmlTableModelColumn> *property, int index, QQmlTableModelColumn *value)
+{
+ QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
+ if (QQmlTableModelColumn *column = qobject_cast<QQmlTableModelColumn*>(value))
+ return model->mColumns.replace(index, column);
+}
+
+void QQmlTableModel::columns_removeLast(QQmlListProperty<QQmlTableModelColumn> *property)
+{
+ QQmlTableModel *model = static_cast<QQmlTableModel*>(property->object);
+ model->mColumns.removeLast();
+}
+
/*!
\qmlmethod QModelIndex TableModel::index(int row, int column)
diff --git a/src/imports/labsmodels/qqmltablemodel_p.h b/src/imports/labsmodels/qqmltablemodel_p.h
index d6e982d19a..75e2768849 100644
--- a/src/imports/labsmodels/qqmltablemodel_p.h
+++ b/src/imports/labsmodels/qqmltablemodel_p.h
@@ -96,6 +96,8 @@ public:
static int columns_count(QQmlListProperty<QQmlTableModelColumn> *property);
static QQmlTableModelColumn *columns_at(QQmlListProperty<QQmlTableModelColumn> *property, int index);
static void columns_clear(QQmlListProperty<QQmlTableModelColumn> *property);
+ static void columns_replace(QQmlListProperty<QQmlTableModelColumn> *property, int index, QQmlTableModelColumn *value);
+ static void columns_removeLast(QQmlListProperty<QQmlTableModelColumn> *property);
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp
index c302b79164..af270c1732 100644
--- a/src/imports/layouts/plugin.cpp
+++ b/src/imports/layouts/plugin.cpp
@@ -42,6 +42,8 @@
#include "qquicklinearlayout_p.h"
#include "qquickstacklayout_p.h"
+extern void qml_register_types_QtQuick_Layouts();
+
QT_BEGIN_NAMESPACE
//![class decl]
@@ -52,6 +54,8 @@ class QtQuickLayoutsPlugin : public QQmlEngineExtensionPlugin
public:
QtQuickLayoutsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_Layouts;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 1ca4056ba9..33c27bd928 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -700,8 +700,10 @@ QQuickItem *QQuickLayoutAttached::item() const
QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent)
- : QQuickItem(dd, parent),
- m_dirty(false)
+ : QQuickItem(dd, parent)
+ , m_dirty(false)
+ , m_inUpdatePolish(false)
+ , m_polishInsideUpdatePolish(0)
{
}
@@ -728,7 +730,9 @@ QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object)
void QQuickLayout::updatePolish()
{
+ m_inUpdatePolish = true;
rearrange(QSizeF(width(), height()));
+ m_inUpdatePolish = false;
}
void QQuickLayout::componentComplete()
@@ -749,7 +753,18 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/)
if (!qobject_cast<QQuickLayout *>(parentItem())) {
quickLayoutDebug() << "QQuickLayout::invalidate(), polish()";
- polish();
+
+ if (m_inUpdatePolish)
+ ++m_polishInsideUpdatePolish;
+ else
+ m_polishInsideUpdatePolish = 0;
+
+ if (m_polishInsideUpdatePolish <= 2)
+ // allow at most two consecutive loops in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ polish();
+ else
+ qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations.";
}
}
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index cb46c41e6c..3322d03636 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -123,7 +123,9 @@ protected slots:
void invalidateSenderItem();
private:
- bool m_dirty;
+ unsigned m_dirty : 1;
+ unsigned m_inUpdatePolish : 1;
+ unsigned m_polishInsideUpdatePolish : 2;
Q_DECLARE_PRIVATE(QQuickLayout)
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 344ea7237c..e47eba4164 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -469,6 +469,16 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size)
if (!isReady())
return;
+ const auto refCounter = qScopeGuard([&d] {
+ --(d->m_recurRearrangeCounter);
+ });
+ if (d->m_recurRearrangeCounter++ == 2) {
+ // allow a recursive depth of two in order to respond to height-for-width
+ // (e.g QQuickText changes implicitHeight when its width gets changed)
+ qWarning() << "Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.";
+ return;
+ }
+
d->m_rearranging = true;
quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size;
Qt::LayoutDirection visualDir = effectiveLayoutDirection();
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index 634e51a048..f36f99741d 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -106,7 +106,8 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate
Q_DECLARE_PUBLIC(QQuickGridLayoutBase)
public:
- QQuickGridLayoutBasePrivate() : m_rearranging(false)
+ QQuickGridLayoutBasePrivate() : m_recurRearrangeCounter(0)
+ , m_rearranging(false)
, m_updateAfterRearrange(false)
, m_layoutDirection(Qt::LeftToRight)
{}
@@ -119,6 +120,7 @@ public:
QQuickGridLayoutEngine engine;
Qt::Orientation orientation;
+ unsigned m_recurRearrangeCounter : 2;
unsigned m_rearranging : 1;
unsigned m_updateAfterRearrange : 1;
QVector<QQuickItem *> m_invalidateAfterRearrange;
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index ae9f37784d..e488b3d43c 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -42,6 +42,8 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
+extern void qml_register_types_QtQuick_LocalStorage();
+
QT_BEGIN_NAMESPACE
class QQmlLocalStoragePlugin : public QQmlEngineExtensionPlugin
@@ -52,6 +54,8 @@ class QQmlLocalStoragePlugin : public QQmlEngineExtensionPlugin
public:
QQmlLocalStoragePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_LocalStorage;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp
index 4aa9f27766..c15866cf05 100644
--- a/src/imports/models/plugin.cpp
+++ b/src/imports/models/plugin.cpp
@@ -37,17 +37,11 @@
**
****************************************************************************/
-#include <QtQmlModels/private/qqmlobjectmodel_p.h>
-
+#include <QtQmlModels/private/qtqmlmodelsglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qmlModelsPlugin, "qt.qmlModelsPlugin")
-
/*!
\qmlmodule QtQml.Models 2.\QtMinorVersion
\title Qt QML Models QML Types
@@ -92,13 +86,8 @@ class QtQmlModelsPlugin : public QQmlEngineExtensionPlugin
public:
QtQmlModelsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- if (qmlModelsPlugin().isDebugEnabled()) {
- // Superficial debug message that causes the dependency between QtQmlWorkerScript
- // and the workerscript plugin to be retained.
- // As qCDebug() can be a noop, retrieve the className in a separate step.
- const QString className = QQmlObjectModel::staticMetaObject.className();
- qCDebug(qmlModelsPlugin) << "Loading QmlModels plugin:" << className;
- }
+ volatile auto registration = &qml_register_types_QtQml_Models;
+ Q_UNUSED(registration);
}
};
//![class decl]
diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp
index 4f319db9f1..6629a660af 100644
--- a/src/imports/particles/plugin.cpp
+++ b/src/imports/particles/plugin.cpp
@@ -50,7 +50,12 @@ class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QtQuick2ParticlesPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QtQuick2ParticlesPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick_Particles;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_UNUSED(uri);
diff --git a/src/imports/qtqml/plugin.cpp b/src/imports/qtqml/plugin.cpp
index ec08992355..a32d86eeb1 100644
--- a/src/imports/qtqml/plugin.cpp
+++ b/src/imports/qtqml/plugin.cpp
@@ -37,10 +37,8 @@
**
****************************************************************************/
+#include <QtQml/private/qtqmlglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/private/qqmlengine_p.h>
-#include <QtQml/private/qqmlcomponentattached_p.h>
-#include <QtQml/private/qqmlbind_p.h>
QT_BEGIN_NAMESPACE
@@ -66,7 +64,11 @@ class QtQmlPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QtQmlPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQml;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index 98056aa551..4e14aff15e 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -50,7 +50,12 @@ class QtQuick2Plugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QtQuick2Plugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
+ QtQuick2Plugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick;
+ Q_UNUSED(registration);
+ }
+
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick"));
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index 24ff43ea6f..e8e640412b 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -42,6 +42,8 @@
#include "qqmlsettings_p.h"
+extern void qml_register_types_Qt_labs_settings();
+
QT_BEGIN_NAMESPACE
class QmlSettingsPlugin : public QQmlEngineExtensionPlugin
@@ -50,7 +52,11 @@ class QmlSettingsPlugin : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QmlSettingsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QmlSettingsPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_settings;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp
index 3855a93fc7..48eecbd8f1 100644
--- a/src/imports/shapes/plugin.cpp
+++ b/src/imports/shapes/plugin.cpp
@@ -52,6 +52,8 @@ public:
QmlShapesPlugin(QObject *parent = nullptr)
: QQmlExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_QtQuick_Shapes;
+ Q_UNUSED(registration);
}
void registerTypes(const char *uri) override
diff --git a/src/imports/sharedimage/plugin.cpp b/src/imports/sharedimage/plugin.cpp
index 237fa64c61..d7c2ef8d17 100644
--- a/src/imports/sharedimage/plugin.cpp
+++ b/src/imports/sharedimage/plugin.cpp
@@ -99,6 +99,8 @@
The shared image module does not provide any directly usable QML types.
*/
+extern void qml_register_types_Qt_labs_sharedimage();
+
QT_BEGIN_NAMESPACE
class QtQuickSharedImagePlugin : public QQmlEngineExtensionPlugin
@@ -106,7 +108,11 @@ class QtQuickSharedImagePlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) {}
+ QtQuickSharedImagePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_Qt_labs_sharedimage;
+ Q_UNUSED(registration);
+ }
void initializeEngine(QQmlEngine *engine, const char *uri) override
{
diff --git a/src/imports/statemachine/childrenprivate.h b/src/imports/statemachine/childrenprivate.h
index 57cda1c796..2dcecd6531 100644
--- a/src/imports/statemachine/childrenprivate.h
+++ b/src/imports/statemachine/childrenprivate.h
@@ -46,54 +46,142 @@
#include <QQmlInfo>
#include <QQmlListProperty>
-template <class T>
-class ChildrenPrivate
+enum class ChildrenMode {
+ None = 0x0,
+ State = 0x1,
+ Transition = 0x2,
+ StateOrTransition = State | Transition
+};
+
+template<typename T>
+static T *parentObject(QQmlListProperty<QObject> *prop) { return static_cast<T *>(prop->object); }
+
+template<class T, ChildrenMode Mode>
+struct ParentHandler
{
-public:
- ChildrenPrivate()
- {}
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem);
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item);
+};
- static void append(QQmlListProperty<QObject> *prop, QObject *item)
+template<class T>
+struct ParentHandler<T, ChildrenMode::None>
+{
+ static bool unparentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
+ static bool parentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::State>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
+ {
+ if (QAbstractState *state = qobject_cast<QAbstractState *>(item)) {
+ state->setParent(parentObject<T>(prop));
+ return true;
+ }
+ return false;
+ }
+
+ static bool unparentItem(QQmlListProperty<QObject> *, QObject *oldItem)
+ {
+ if (QAbstractState *state = qobject_cast<QAbstractState *>(oldItem)) {
+ state->setParent(nullptr);
+ return true;
+ }
+ return false;
+ }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::Transition>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
{
- QAbstractState *state = qobject_cast<QAbstractState*>(item);
- if (state) {
- item->setParent(prop->object);
- } else {
- QAbstractTransition *trans = qobject_cast<QAbstractTransition*>(item);
- if (trans)
- static_cast<T *>(prop->object)->addTransition(trans);
+ if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(item)) {
+ parentObject<T>(prop)->addTransition(trans);
+ return true;
}
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
- emit static_cast<T *>(prop->object)->childrenChanged();
+ return false;
}
- static void appendNoTransition(QQmlListProperty<QObject> *prop, QObject *item)
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
{
- QAbstractState *state = qobject_cast<QAbstractState*>(item);
- if (state) {
- item->setParent(prop->object);
+ if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(oldItem)) {
+ parentObject<T>(prop)->removeTransition(trans);
+ return true;
}
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
- emit static_cast<T *>(prop->object)->childrenChanged();
+ return false;
+ }
+};
+
+template<class T>
+struct ParentHandler<T, ChildrenMode::StateOrTransition>
+{
+ static bool parentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
+ {
+ return ParentHandler<T, ChildrenMode::State>::parentItem(prop, oldItem)
+ || ParentHandler<T, ChildrenMode::Transition>::parentItem(prop, oldItem);
+ }
+
+ static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
+ {
+ return ParentHandler<T, ChildrenMode::State>::unparentItem(prop, oldItem)
+ || ParentHandler<T, ChildrenMode::Transition>::unparentItem(prop, oldItem);
+ }
+};
+
+template <class T, ChildrenMode Mode>
+class ChildrenPrivate
+{
+public:
+ static void append(QQmlListProperty<QObject> *prop, QObject *item)
+ {
+ Handler::parentItem(prop, item);
+ static_cast<Self *>(prop->data)->children.append(item);
+ emit parentObject<T>(prop)->childrenChanged();
}
static int count(QQmlListProperty<QObject> *prop)
{
- return static_cast<ChildrenPrivate<T>*>(prop->data)->children.count();
+ return static_cast<Self *>(prop->data)->children.count();
}
static QObject *at(QQmlListProperty<QObject> *prop, int index)
{
- return static_cast<ChildrenPrivate<T>*>(prop->data)->children.at(index);
+ return static_cast<Self *>(prop->data)->children.at(index);
}
static void clear(QQmlListProperty<QObject> *prop)
{
- static_cast<ChildrenPrivate<T>*>(prop->data)->children.clear();
- emit static_cast<T *>(prop->object)->childrenChanged();
+ auto &children = static_cast<Self *>(prop->data)->children;
+ for (QObject *oldItem : qAsConst(children))
+ Handler::unparentItem(prop, oldItem);
+
+ children.clear();
+ emit parentObject<T>(prop)->childrenChanged();
+ }
+
+ static void replace(QQmlListProperty<QObject> *prop, int index, QObject *item)
+ {
+ auto &children = static_cast<Self *>(prop->data)->children;
+
+ Handler::unparentItem(prop, children.at(index));
+ Handler::parentItem(prop, item);
+
+ children.replace(index, item);
+ emit parentObject<T>(prop)->childrenChanged();
+ }
+
+ static void removeLast(QQmlListProperty<QObject> *prop)
+ {
+ Handler::unparentItem(prop, static_cast<Self *>(prop->data)->children.takeLast());
+ emit parentObject<T>(prop)->childrenChanged();
}
private:
+ using Self = ChildrenPrivate<T, Mode>;
+ using Handler = ParentHandler<T, Mode>;
+
QList<QObject *> children;
};
diff --git a/src/imports/statemachine/finalstate.cpp b/src/imports/statemachine/finalstate.cpp
index 54dcc82bae..4d4c6b2cc7 100644
--- a/src/imports/statemachine/finalstate.cpp
+++ b/src/imports/statemachine/finalstate.cpp
@@ -50,7 +50,9 @@ FinalState::FinalState(QState *parent)
QQmlListProperty<QObject> FinalState::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.appendNoTransition, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/finalstate.h b/src/imports/statemachine/finalstate.h
index 9cdbb51584..117a358e53 100644
--- a/src/imports/statemachine/finalstate.h
+++ b/src/imports/statemachine/finalstate.h
@@ -66,7 +66,7 @@ Q_SIGNALS:
void childrenChanged();
private:
- ChildrenPrivate<FinalState> m_children;
+ ChildrenPrivate<FinalState, ChildrenMode::State> m_children;
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp
index 4c991994f3..c370504029 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -48,6 +48,8 @@
#include <QQmlExtensionPlugin>
#include <qqml.h>
+extern void qml_register_types_QtQml_StateMachine();
+
QT_BEGIN_NAMESPACE
class QtQmlStateMachinePlugin : public QQmlEngineExtensionPlugin
@@ -56,7 +58,11 @@ class QtQmlStateMachinePlugin : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQmlStateMachinePlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQml_StateMachine;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/state.cpp b/src/imports/statemachine/state.cpp
index af76087256..10530c2985 100644
--- a/src/imports/statemachine/state.cpp
+++ b/src/imports/statemachine/state.cpp
@@ -61,7 +61,9 @@ void State::componentComplete()
QQmlListProperty<QObject> State::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h
index 4b17ea0e5f..68184775ab 100644
--- a/src/imports/statemachine/state.h
+++ b/src/imports/statemachine/state.h
@@ -69,7 +69,7 @@ Q_SIGNALS:
void childrenChanged();
private:
- ChildrenPrivate<State> m_children;
+ ChildrenPrivate<State, ChildrenMode::StateOrTransition> m_children;
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/statemachine.cpp b/src/imports/statemachine/statemachine.cpp
index a983644018..bdad2e6bde 100644
--- a/src/imports/statemachine/statemachine.cpp
+++ b/src/imports/statemachine/statemachine.cpp
@@ -90,7 +90,9 @@ void StateMachine::componentComplete()
QQmlListProperty<QObject> StateMachine::children()
{
- return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
+ return QQmlListProperty<QObject>(this, &m_children,
+ m_children.append, m_children.count, m_children.at,
+ m_children.clear, m_children.replace, m_children.removeLast);
}
/*!
diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h
index 04894477b3..cc0360db54 100644
--- a/src/imports/statemachine/statemachine.h
+++ b/src/imports/statemachine/statemachine.h
@@ -82,7 +82,7 @@ Q_SIGNALS:
void qmlRunningChanged();
private:
- ChildrenPrivate<StateMachine> m_children;
+ ChildrenPrivate<StateMachine, ChildrenMode::StateOrTransition> m_children;
bool m_completed;
bool m_running;
};
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 20c5ce6418..380b7e38d7 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -198,7 +198,7 @@ import Qt.test.qtestroot 1.0
}
\endcode
- The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence()
+ The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence()
and mouseMove() methods can be used to simulate mouse events in a
similar fashion.
@@ -1331,7 +1331,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mousePress(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mousePress"))
@@ -1365,7 +1365,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseRelease(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseRelease"))
@@ -1398,7 +1398,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel()
*/
function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseDrag"))
@@ -1453,7 +1453,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseClick(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseClick"))
@@ -1475,6 +1475,7 @@ Item {
/*!
\qmlmethod TestCase::mouseDoubleClick(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)
+ \deprecated
Simulates double-clicking a mouse \a button with optional \a modifiers
on an \a item. The position of the click is defined by \a x and \a y.
@@ -1528,7 +1529,7 @@ Item {
This QML method was introduced in Qt 5.5.
- \sa mouseDoubleClick(), mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseDoubleClickSequence(item, x, y, button, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseDoubleClickSequence"))
@@ -1560,7 +1561,7 @@ Item {
If \a item is obscured by another item, or a child of \a item occupies
that position, then the event will be delivered to the other item instead.
- \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel()
+ \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel()
*/
function mouseMove(item, x, y, delay, buttons) {
if (!qtest_verifyItem(item, "mouseMove"))
@@ -1588,7 +1589,7 @@ Item {
The \a xDelta and \a yDelta contain the wheel rotation distance in eighths of a degree. see \l QWheelEvent::angleDelta() for more details.
- \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta()
+ \sa mousePress(), mouseClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta()
*/
function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) {
if (!qtest_verifyItem(item, "mouseWheel"))
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 1914c02dd0..83fc150e6c 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -50,6 +50,8 @@ QML_DECLARE_TYPE(QuickTestResult)
QML_DECLARE_TYPE(QuickTestEvent)
QML_DECLARE_TYPE(QuickTestUtil)
+extern void qml_register_types_QtTest();
+
QT_BEGIN_NAMESPACE
class QTestQmlModule : public QQmlEngineExtensionPlugin
@@ -58,7 +60,11 @@ class QTestQmlModule : public QQmlEngineExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QTestQmlModule(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtTest;
+ Q_UNUSED(registration);
+ }
};
QT_END_NAMESPACE
diff --git a/src/imports/wavefrontmesh/plugin.cpp b/src/imports/wavefrontmesh/plugin.cpp
index 9bb7a45b2f..eea0db19db 100644
--- a/src/imports/wavefrontmesh/plugin.cpp
+++ b/src/imports/wavefrontmesh/plugin.cpp
@@ -42,6 +42,8 @@
#include "qwavefrontmesh.h"
+extern void qml_register_types_Qt_labs_wavefrontmesh();
+
QT_BEGIN_NAMESPACE
class QmlWavefrontMeshPlugin : public QQmlEngineExtensionPlugin
@@ -52,6 +54,8 @@ public:
QmlWavefrontMeshPlugin(QObject *parent = nullptr)
: QQmlEngineExtensionPlugin(parent)
{
+ volatile auto registration = &qml_register_types_Qt_labs_wavefrontmesh;
+ Q_UNUSED(registration);
}
};
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index ec4f2c5d2a..5152fa02ec 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -41,6 +41,8 @@
#include "plugin.h"
+extern void qml_register_types_QtQuick_Window();
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,7 +66,11 @@ class QtQuick2WindowPlugin : public QQmlEngineExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
public:
- QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { }
+ QtQuick2WindowPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = &qml_register_types_QtQuick_Window;
+ Q_UNUSED(registration);
+ }
};
//![class decl]
diff --git a/src/imports/workerscript/plugin.cpp b/src/imports/workerscript/plugin.cpp
index 0961979c53..1323b17ef4 100644
--- a/src/imports/workerscript/plugin.cpp
+++ b/src/imports/workerscript/plugin.cpp
@@ -37,17 +37,11 @@
**
****************************************************************************/
-#include <QtQmlWorkerScript/private/qquickworkerscript_p.h>
-
+#include <QtQmlWorkerScript/private/qtqmlworkerscriptglobal_p.h>
#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(workerScriptPlugin, "qt.workerScriptPlugin")
-
/*!
\qmlmodule QtQml.WorkerScript 2.\QtMinorVersion
\title Qt QML WorkerScript QML Types
@@ -71,13 +65,8 @@ class QtQmlWorkerScriptPlugin : public QQmlEngineExtensionPlugin
public:
QtQmlWorkerScriptPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent)
{
- if (workerScriptPlugin().isDebugEnabled()) {
- // Superficial debug message that causes the dependency between QtQmlWorkerScript
- // and the workerscript plugin to be retained.
- // As qCDebug() can be a noop, retrieve the className in a separate step.
- const QString className = QQuickWorkerScript::staticMetaObject.className();
- qCDebug(workerScriptPlugin) << "Loading WorkerScript plugin:" << className;
- }
+ volatile auto registration = &qml_register_types_QtQml_WorkerScript;
+ Q_UNUSED(registration);
}
};
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index 4ce8186c7c..4d67691771 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -389,10 +389,10 @@ private:
QSGMaterialType DeformableMaterial::m_type;
-class SpriteMaterialShader : public QSGMaterialShader
+class ParticleSpriteMaterialShader : public QSGMaterialShader
{
public:
- SpriteMaterialShader()
+ ParticleSpriteMaterialShader()
{
QSGShaderSourceBuilder builder;
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
@@ -478,10 +478,10 @@ public:
QOpenGLFunctions* glFuncs;
};
-class SpriteMaterialRhiShader : public QSGMaterialRhiShader
+class ParticleSpriteMaterialRhiShader : public QSGMaterialRhiShader
{
public:
- SpriteMaterialRhiShader()
+ ParticleSpriteMaterialRhiShader()
{
setShaderFileName(VertexStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.vert.qsb"));
setShaderFileName(FragmentStage, QStringLiteral(":/particles/shaders_ng/imageparticle_sprite.frag.qsb"));
@@ -544,9 +544,9 @@ public:
SpriteMaterial() { setFlag(SupportsRhiShader, true); }
QSGMaterialShader *createShader() const override {
if (flags().testFlag(RhiShaderWanted))
- return new SpriteMaterialRhiShader;
+ return new ParticleSpriteMaterialRhiShader;
else
- return new SpriteMaterialShader;
+ return new ParticleSpriteMaterialShader;
}
QSGMaterialType *type() const override { return &m_type; }
@@ -1143,7 +1143,9 @@ QQuickImageParticle::~QQuickImageParticle()
QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
{
- return QQmlListProperty<QQuickSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
void QQuickImageParticle::sceneGraphInvalidated()
diff --git a/src/particles/qquickparticlegroup.cpp b/src/particles/qquickparticlegroup.cpp
index 052fda6eff..902c23331d 100644
--- a/src/particles/qquickparticlegroup.cpp
+++ b/src/particles/qquickparticlegroup.cpp
@@ -106,10 +106,15 @@ void delayedRedirect(QQmlListProperty<QObject> *prop, QObject *value)
QQmlListProperty<QObject> QQuickParticleGroup::particleChildren()
{
QQuickParticleSystem* system = qobject_cast<QQuickParticleSystem*>(parent());
- if (system)
- return QQmlListProperty<QObject>(this, nullptr, &QQuickParticleSystem::statePropertyRedirect, nullptr, nullptr, nullptr);
- else
- return QQmlListProperty<QObject>(this, nullptr, &delayedRedirect, nullptr, nullptr, nullptr);
+ if (system) {
+ return QQmlListProperty<QObject>(this, nullptr,
+ &QQuickParticleSystem::statePropertyRedirect, nullptr,
+ nullptr, nullptr, nullptr, nullptr);
+ } else {
+ return QQmlListProperty<QObject>(this, nullptr,
+ &delayedRedirect, nullptr, nullptr,
+ nullptr, nullptr, nullptr);
+ }
}
void QQuickParticleGroup::setSystem(QQuickParticleSystem* arg)
diff --git a/src/particles/qtquickparticlesglobal_p.h b/src/particles/qtquickparticlesglobal_p.h
index d7647b3d97..927bc29050 100644
--- a/src/particles/qtquickparticlesglobal_p.h
+++ b/src/particles/qtquickparticlesglobal_p.h
@@ -65,4 +65,6 @@
# define Q_QUICKPARTICLES_PRIVATE_EXPORT
#endif
+void Q_QUICKPARTICLES_PRIVATE_EXPORT qml_register_types_QtQuick_Particles();
+
#endif // QTQUICKPARTICLESGLOBAL_P_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 61fea96e2f..333ce4b26f 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -66,7 +66,6 @@ void JavaScriptJob::run()
QV4::ScopedContext ctx(scope, engine->currentStackFrame ? engine->currentContext()
: engine->scriptContext());
- QObject scopeObject;
QV4::CppStackFrame *frame = engine->currentStackFrame;
@@ -76,9 +75,10 @@ void JavaScriptJob::run()
ctx = static_cast<QV4::ExecutionContext *>(&frame->jsFrame->context);
if (context >= 0) {
- QQmlContext *extraContext = qmlContext(QQmlDebugService::objectForId(context));
+ QObject *forId = QQmlDebugService::objectForId(context);
+ QQmlContext *extraContext = qmlContext(forId);
if (extraContext)
- ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), &scopeObject);
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), forId);
} else if (frameNr < 0) { // Use QML context if available
QQmlEngine *qmlEngine = engine->qmlEngine();
if (qmlEngine) {
@@ -99,7 +99,7 @@ void JavaScriptJob::run()
}
}
if (!engine->qmlContext())
- ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), &scopeObject);
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), nullptr);
}
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro b/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
index 08686a43e3..e1cbc393f7 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
+++ b/src/plugins/qmltooling/qmldbg_preview/qmldbg_preview.pro
@@ -3,6 +3,7 @@ QT += core-private qml-private packetprotocol-private network quick-private gui-
TARGET = qmldbg_preview
SOURCES += \
+ $$PWD/qqmldebugtranslationservice.cpp \
$$PWD/qqmlpreviewblacklist.cpp \
$$PWD/qqmlpreviewfileengine.cpp \
$$PWD/qqmlpreviewfileloader.cpp \
@@ -12,6 +13,7 @@ SOURCES += \
$$PWD/qqmlpreviewservicefactory.cpp
HEADERS += \
+ $$PWD/qqmldebugtranslationservice.h \
$$PWD/qqmlpreviewblacklist.h \
$$PWD/qqmlpreviewfileengine.h \
$$PWD/qqmlpreviewfileloader.h \
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
new file mode 100644
index 0000000000..1561777202
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugtranslationservice.h"
+
+QT_BEGIN_NAMESPACE
+
+QQmlDebugTranslationServiceImpl::QQmlDebugTranslationServiceImpl(QObject *parent) :
+ QQmlDebugTranslationService(1, parent)
+{
+}
+
+void QQmlDebugTranslationServiceImpl::messageReceived(const QByteArray &message)
+{
+ Q_UNUSED(message)
+}
+
+QString QQmlDebugTranslationServiceImpl::foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText)
+{
+ Q_UNUSED(textObject)
+ Q_UNUSED(layoutText)
+ return elideText;
+}
+
+void QQmlDebugTranslationServiceImpl::foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData)
+{
+ Q_UNUSED(binding)
+ Q_UNUSED(scopeObject)
+ Q_UNUSED(contextData)
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
new file mode 100644
index 0000000000..a337a937a5
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDEBUGMESSAGESERVICE_H
+#define QDEBUGMESSAGESERVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qqmldebugserviceinterfaces_p.h>
+
+#include <QtCore/qlogging.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qelapsedtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugTranslationServicePrivate;
+
+class QQmlDebugTranslationServiceImpl : public QQmlDebugTranslationService
+{
+ Q_OBJECT
+public:
+ //needs to be in sync with QQmlDebugTranslationClient in qqmldebugtranslationclient_p.h
+ enum Command {
+ ChangeLanguage,
+ ChangeWarningColor,
+ ChangeElidedTextWarningString,
+ SetDebugTranslationServiceLogFile,
+ EnableElidedTextWarning,
+ DisableElidedTextWarning,
+ TestAllLanguages
+ };
+ QQmlDebugTranslationServiceImpl(QObject *parent = 0);
+
+ QString foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText) override;
+ void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) override;
+ void messageReceived(const QByteArray &message) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDEBUGMESSAGESERVICE_H
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
index d7e1ef1f10..5e148f8101 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.json
@@ -1,3 +1,3 @@
{
- "Keys" : [ "QmlPreview" ]
+ "Keys" : [ "QmlPreview", "DebugTranslation" ]
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
index f0aa3226c8..6ff9805bbe 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp
@@ -39,12 +39,18 @@
#include "qqmlpreviewservicefactory.h"
#include "qqmlpreviewservice.h"
+#include "qqmldebugtranslationservice.h"
QT_BEGIN_NAMESPACE
QQmlDebugService *QQmlPreviewServiceFactory::create(const QString &key)
{
- return key == QQmlPreviewServiceImpl::s_key ? new QQmlPreviewServiceImpl(this) : nullptr;
+ if (key == QQmlPreviewServiceImpl::s_key)
+ return new QQmlPreviewServiceImpl(this);
+ if (key == QQmlDebugTranslationServiceImpl::s_key)
+ return new QQmlDebugTranslationServiceImpl(this);
+
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index cc663cd6b3..33b6606b44 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -422,6 +422,11 @@ void QQmlDebugServerImpl::parseArguments()
<< tr("Sends qDebug() and similar messages over the QML debug\n"
"\t\t connection. QtCreator uses this for showing debug\n"
"\t\t messages in the debugger console.") << '\n'
+ << '\n' << QQmlDebugTranslationService::s_key << "\t- "
+ //: Please preserve the line breaks and formatting
+ << tr("helps to see if a translated text\n"
+ "\t\t will result in an elided text\n"
+ "\t\t in QML elements.") << '\n'
<< tr("Other services offered by qmltooling plugins that implement "
"QQmlDebugServiceFactory and which can be found in the standard plugin "
"paths will also be available and can be specified. If no \"services\" "
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
index 76205c7760..3df1a21bda 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp
+++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp
@@ -48,6 +48,7 @@ const QString QQmlProfilerService::s_key = QStringLiteral("CanvasFrameRate");
const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages");
const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl");
const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger");
+const QString QQmlDebugTranslationService::s_key = QStringLiteral("DebugTranslation");
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 01693aee24..644d9d6ba9 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QQuickWindow;
+class QQmlTranslationBinding;
#if !QT_CONFIG(qml_debug)
@@ -103,6 +104,10 @@ public:
class QDebugMessageService {};
class QQmlEngineControlService {};
class QQmlNativeDebugService {};
+class QQmlDebugTranslationService {
+ virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};}
+ virtual void foundTranslationBinding(QQmlTranslationBinding *, QObject *, QQmlContextData *) {}
+};
#else
@@ -162,6 +167,22 @@ protected:
QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; }
};
+class Q_QML_PRIVATE_EXPORT QQmlDebugTranslationService : public QQmlDebugService
+{
+ Q_OBJECT
+public:
+ static const QString s_key;
+
+ virtual QString foundElidedText(QObject *qQuickTextObject, const QString &layoutText, const QString &elideText) = 0;
+ virtual void foundTranslationBinding(QQmlTranslationBinding *binding, QObject *scopeObject, QQmlContextData *contextData) = 0;
+protected:
+ friend class QQmlDebugConnector;
+
+ QQmlDebugTranslationService(float version, QObject *parent = nullptr) :
+ QQmlDebugService(s_key, version, parent) {}
+
+};
+
class Q_QML_PRIVATE_EXPORT QQmlInspectorService : public QQmlDebugService
{
Q_OBJECT
diff --git a/src/qml/doc/snippets/code/backend/backend.h b/src/qml/doc/snippets/code/backend/backend.h
index fa7ce9eb86..6c64236bc7 100644
--- a/src/qml/doc/snippets/code/backend/backend.h
+++ b/src/qml/doc/snippets/code/backend/backend.h
@@ -53,11 +53,13 @@
#include <QObject>
#include <QString>
+#include <qqml.h>
class BackEnd : public QObject
{
Q_OBJECT
Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
+ QML_ELEMENT
public:
explicit BackEnd(QObject *parent = nullptr);
diff --git a/src/qml/doc/snippets/code/backend/backend.pro b/src/qml/doc/snippets/code/backend/backend.pro
new file mode 100644
index 0000000000..8bd2422718
--- /dev/null
+++ b/src/qml/doc/snippets/code/backend/backend.pro
@@ -0,0 +1,17 @@
+QT += qml
+
+#![registration]
+CONFIG += qmltypes
+QML_IMPORT_NAME = io.qt.examples.backend
+QML_IMPORT_MAJOR_VERSION = 1
+#![registration]
+
+HEADERS += \
+ backend.h
+
+SOURCES += \
+ backend.cpp \
+ main.cpp
+
+RESOURCES += \
+ main.qml
diff --git a/src/qml/doc/snippets/code/backend/main.cpp b/src/qml/doc/snippets/code/backend/main.cpp
index 91a012dfda..52fcb38621 100644
--- a/src/qml/doc/snippets/code/backend/main.cpp
+++ b/src/qml/doc/snippets/code/backend/main.cpp
@@ -51,14 +51,10 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
-#include "backend.h"
-
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd");
-
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
index d74cc13d04..b41a9b4dff 100644
--- a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.cpp
@@ -51,84 +51,102 @@
#include "avatarExample.h"
#include <QQmlEngine>
#include <QQmlComponent>
+#include <QGuiApplication>
-void registerTypes()
+struct Expectations
{
-//![0]
- qmlRegisterType<AvatarExample>("Qt.example", 1, 0, "AvatarExample");
-//![0]
-}
+ QQmlEngine engine;
-void expectOne()
-{
+ void expectOne()
+ {
//![1]
-QQmlComponent component(&engine, "exampleOne.qml");
-QObject *object = component.create();
-// The scarce resource will have been released automatically
-// by this point, after the binding expression was evaluated.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleOne.qml");
+ QObject *object = component.create();
+ // The scarce resource will have been released automatically
+ // by this point, after the binding expression was evaluated.
+ bool expectedResult = (object->property("avatarWidth").toInt() == 100);
+ delete object;
//![1]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectTwo()
-{
+ void expectTwo()
+ {
//![2]
-QQmlComponent component(&engine, "exampleTwo.qml");
-QObject *object = component.create();
-// The scarce resource will not have been released automatically
-// after the binding expression was evaluated.
-// Since the scarce resource was not released explicitly prior
-// to the binding expression being evaluated, we get:
-bool expectedResult = (object->property("avatar").isValid() == true);
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleTwo.qml");
+ QObject *object = component.create();
+ // The scarce resource will not have been released automatically
+ // after the binding expression was evaluated.
+ // Since the scarce resource was not released explicitly prior
+ // to the binding expression being evaluated, we get:
+ bool expectedResult = (object->property("avatar").isValid() == true);
+ delete object;
//![2]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectThree()
-{
+ void expectThree()
+ {
//![3]
-QQmlComponent component(&engine, "exampleThree.qml");
-QObject *object = component.create();
-// The resource was preserved explicitly during evaluation of the
-// JavaScript expression. Thus, during property assignment, the
-// scarce resource was still valid, and so we get:
-bool expectedResult = (object->property("avatar").isValid() == true);
-// The scarce resource will not be released until all references to
-// the resource are released, and the JavaScript garbage collector runs.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleThree.qml");
+ QObject *object = component.create();
+ // The resource was preserved explicitly during evaluation of the
+ // JavaScript expression. Thus, during property assignment, the
+ // scarce resource was still valid, and so we get:
+ bool expectedResult = (object->property("avatar").isValid() == true);
+ // The scarce resource will not be released until all references to
+ // the resource are released, and the JavaScript garbage collector runs.
+ delete object;
//![3]
-}
+ Q_ASSERT(expectedResult);
+ }
-void expectFour()
-{
+ void expectFour()
+ {
//![4]
-QQmlComponent component(&engine, "exampleFour.qml");
-QObject *object = component.create();
-// The scarce resource was explicitly preserved by the client during
-// the importAvatar() function, and so the scarce resource
-// remains valid until the explicit call to releaseAvatar(). As such,
-// we get the expected results:
-bool expectedResultOne = (object->property("avatarOne").isValid() == true);
-bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
-// Because the scarce resource referenced by avatarTwo was released explicitly,
-// it will no longer be consuming any system resources (beyond what a normal
-// JS Object would; that small overhead will exist until the JS GC runs, as per
-// any other JavaScript object).
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleFour.qml");
+ QObject *object = component.create();
+ // The scarce resource was explicitly preserved by the client during
+ // the importAvatar() function, and so the scarce resource
+ // remains valid until the explicit call to releaseAvatar(). As such,
+ // we get the expected results:
+ bool expectedResultOne = (object->property("avatarOne").isValid() == true);
+ bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+ // Because the scarce resource referenced by avatarTwo was released explicitly,
+ // it will no longer be consuming any system resources (beyond what a normal
+ // JS Object would; that small overhead will exist until the JS GC runs, as per
+ // any other JavaScript object).
+ delete object;
//![4]
-}
+ Q_ASSERT(expectedResultOne);
+ Q_ASSERT(expectedResultTwo);
+ }
-void expectFive()
-{
+ void expectFive()
+ {
//![5]
-QQmlComponent component(&engine, "exampleFive.qml");
-QObject *object = component.create();
-// We have the expected results:
-bool expectedResultOne = (object->property("avatarOne").isValid() == false);
-bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
-// Because although only avatarTwo was explicitly released,
-// avatarOne and avatarTwo were referencing the same
-// scarce resource.
-delete object;
+ QQmlComponent component(&engine, "qrc:/exampleFive.qml");
+ QObject *object = component.create();
+ // We have the expected results:
+ bool expectedResultOne = (object->property("avatarOne").isValid() == false);
+ bool expectedResultTwo = (object->property("avatarTwo").isValid() == false);
+ // Because although only avatarTwo was explicitly released,
+ // avatarOne and avatarTwo were referencing the same
+ // scarce resource.
+ delete object;
//![5]
+ Q_ASSERT(expectedResultOne);
+ Q_ASSERT(expectedResultTwo);
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ Expectations expectations;
+ expectations.expectOne();
+ expectations.expectTwo();
+ expectations.expectThree();
+ expectations.expectFour();
+ expectations.expectFive();
}
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
index fb9e238512..1acc3a1c2f 100644
--- a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/avatarExample.h
@@ -53,6 +53,7 @@
#include <QObject>
#include <QPixmap>
+#include <qqml.h>
//![0]
// avatarExample.h
@@ -60,6 +61,8 @@ class AvatarExample : public QObject
{
Q_OBJECT
Q_PROPERTY(QPixmap avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)
+ QML_ELEMENT
+
public:
AvatarExample(QObject *parent = 0)
: QObject(parent), m_value(100, 100)
diff --git a/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro
new file mode 100644
index 0000000000..d88f8f574c
--- /dev/null
+++ b/src/qml/doc/snippets/qml/integrating-javascript/scarceresources/scarceresources.pro
@@ -0,0 +1,22 @@
+QT += qml gui
+
+#![0]
+CONFIG += qmltypes
+QML_IMPORT_NAME = Qt.example
+QML_IMPORT_MAJOR_VERSION = 1
+#![0]
+
+RESOURCES += \
+ exampleFive.qml \
+ exampleFour.js \
+ exampleFour.qml \
+ exampleOne.qml \
+ exampleThree.js \
+ exampleThree.qml \
+ exampleTwo.qml
+
+HEADERS += \
+ avatarExample.h
+
+SOURCES += \
+ avatarExample.cpp
diff --git a/src/qml/doc/snippets/qml/qml-documents/A.qml b/src/qml/doc/snippets/qml/qml-documents/A.qml
new file mode 100644
index 0000000000..83c59dc5d7
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/A.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//! [document]
+// A.qml
+import QtQuick 2.15
+
+Item {
+ id: root
+ property string message: "From A"
+ component MyInlineComponent : Item {
+ Component.onCompleted: console.log(root.message)
+ }
+}
+//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/B.qml b/src/qml/doc/snippets/qml/qml-documents/B.qml
new file mode 100644
index 0000000000..5e603d50e0
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/B.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [document]
+// B.qml
+import QtQuick 2.15
+
+Item {
+ A.MyInlineComponent {}
+}
+//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/Images.qml b/src/qml/doc/snippets/qml/qml-documents/Images.qml
new file mode 100644
index 0000000000..80a4d95fbb
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/Images.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//! [document]
+// Images.qml
+import QtQuick 2.15
+
+Item {
+ component LabeledImage: Column {
+ property alias source: image.source
+ property alias caption: text.text
+
+ Image {
+ id: image
+ width: 50
+ height: 50
+ }
+ Text {
+ id: text
+ font.bold: true
+ }
+ }
+
+ Row {
+ LabeledImage {
+ id: before
+ source: "before.png"
+ caption: "Before"
+ }
+ LabeledImage {
+ id: after
+ source: "after.png"
+ caption: "After"
+ }
+ }
+ property LabeledImage selectedImage: before
+}
+// Images.qml
diff --git a/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml b/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml
new file mode 100644
index 0000000000..5a259a0cc6
--- /dev/null
+++ b/src/qml/doc/snippets/qml/qml-documents/LabeledImageBox.qml
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [document]
+// LabeledImageBox.qml
+import QtQuick 2.15
+
+Rectangle {
+ property alias caption: image.caption
+ property alias source: image.source
+ border.width: 2
+ border.color: "black"
+ Images.LabeledImage {
+ id: image
+ }
+}
+//! [document]
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 2e8102bd65..f66dc44383 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -80,9 +80,17 @@ class instance can be manipulated from QML; as
Types to QML} explains, the properties, methods and signals of any
QObject-derived class are accessible from QML code.
-To register a QObject-derived class as an instantiable QML object type, call
-qmlRegisterType() to register the class as QML type into a particular type
-namespace. Clients can then import that namespace in order to use the type.
+To register a QObject-derived class as an instantiable QML object type, add
+\c QML_ELEMENT or \c QML_NAMED_ELEMENT(<name>) to the class declaration and
+\c {CONFIG += qmltypes}, a \c {QML_IMPORT_NAME}, and a
+\c QML_IMPORT_MAJOR_VERSION to your project file. This will register the class
+into the type namespace under the given major version, using either the class
+name or an explicitly given name as QML type name. The minor version(s) will
+be derived from any revisions attached to properties, methods, or signals. The
+default minor version is \c 0. You can explicitly restrict the type to be
+available only from specific minor versions by adding the
+\c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can
+import suitable versions of the namespace in order to use the type.
For example, suppose there is a \c Message class with \c author and
\c creationDate properties:
@@ -93,17 +101,20 @@ class Message : public QObject
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
+ QML_ELEMENT
public:
// ...
};
\endcode
-This type can be registered by calling qmlRegisterType() with an appropriate
-type namespace and version number. For example, to make the type available in
-the \c com.mycompany.messaging namespace with version 1.0:
+This type can be registered by adding an appropriate type namespace and version
+number to the project file. For example, to make the type available in the
+\c com.mycompany.messaging namespace with version 1.0:
\code
-qmlRegisterType<Message>("com.mycompany.messaging", 1, 0, "Message");
+CONFIG += qmltypes
+QML_IMPORT_NAME = com.mycompany.messaging
+QML_IMPORT_MAJOR_VERSION = 1
\endcode
The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}
@@ -135,23 +146,25 @@ not be instantiable
should not be instantiable from QML
\endlist
-The \l {Qt QML} module provides several methods for registering non-instantiable
+The \l {Qt QML} module provides several macros for registering non-instantiable
types:
\list
-\li qmlRegisterType() (with no parameters) registers a C++ type that is not
-instantiable and cannot be referred to from QML. This enables the engine to
-coerce any inherited types that are instantiable from QML.
-\li qmlRegisterInterface() registers an existing Qt interface type. The type is
+\li QML_ANONYMOUS registers a C++ type that is not instantiable and cannot be
+referred to from QML. This enables the engine to coerce any inherited types that
+are instantiable from QML.
+\li QML_INTERFACE registers an existing Qt interface type. The type is
not instantiable from QML, and you cannot declare QML properties with it. Using
C++ properties of this type from QML will do the expected interface casts,
though.
-\li qmlRegisterUncreatableType() registers a named C++ type that is not
-instantiable but should be identifiable as a type to the QML type system. This
-is useful if a type's enums or attached properties should be accessible from QML
-but the type itself should not be instantiable.
-\li qmlRegisterSingletonType() registers a singleton type that can be imported
-from QML, as discussed below.
+\li QML_UNCREATABLE(reason) combined with with QML_ELEMENT or QML_NAMED_ELEMENT
+registers a named C++ type that is not instantiable but should be identifiable
+as a type to the QML type system. This is useful if a type's enums or attached
+properties should be accessible from QML but the type itself should not be
+instantiable. The parameter should be an error message to be emitted if an
+attempt at creating an instance of the type is detected.
+\li QML_SINGLETON combined with QML_ELEMENT or QML_NAMED_ELEMENT registers a
+singleton type that can be imported from QML, as discussed below.
\endlist
Note that all C++ types registered with the QML type system must be
@@ -195,7 +208,7 @@ Rectangle {
A QJSValue may also be exposed as a singleton type, however clients should
be aware that properties of such a singleton type cannot be bound to.
-See \l{qmlRegisterSingletonType()} for more information on how implement and
+See \l{QML_SINGLETON} for more information on how implement and
register a new singleton type, and how to use an existing singleton type.
\note Enum values for registered types in QML should start with a capital.
@@ -245,30 +258,20 @@ class CppType : public BaseType
{
Q_OBJECT
Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1)
+ QML_ELEMENT
signals:
Q_REVISION(1) void rootChanged();
};
\endcode
-To register the new class revision to a particular version the following
-function is used:
+The revisions given this way are automatically interpreted as minor versions to
+the major version given in the project file. In this case, \c root is only
+available when \c MyTypes version 1.1 or higher is imported. Imports of
+\c MyTypes version 1.0 remain unaffected.
-\code
-template<typename T, int metaObjectRevision>
-int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
-\endcode
-
-To register \c CppType version 1 for \c {MyTypes 1.1}:
-
-\code
-qmlRegisterType<CppType,1>("MyTypes", 1, 1, "CppType")
-\endcode
-
-\c root is only available when \c MyTypes version 1.1 is imported.
-
-For the same reason, new types introduced in later versions should use
-the minor version argument of qmlRegisterType.
+For the same reason, new types introduced in later versions should be tagged
+with the QML_ADDED_IN_MINOR_VERSION macro.
This feature of the language allows for behavioural changes to be made
without breaking existing applications. Consequently QML module authors
@@ -276,29 +279,10 @@ should always remember to document what changed between minor versions, and
QML module users should check that their application still runs correctly
before deploying an updated import statement.
-You may also register the revision of a base class that your type depends
-upon using the qmlRegisterRevision() function:
-
-\code
-template<typename T, int metaObjectRevision>
-int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
-
-template<typename T, int metaObjectRevision>
-int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
-
-template<typename T, typename E, int metaObjectRevision>
-int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
-\endcode
-
-For example, if \c BaseType is changed and now has a revision 1, you can
-specify that your type uses the new revision:
-
-\code
-qmlRegisterRevision<BaseType,1>("MyTypes", 1, 1);
-\endcode
-
-This is useful when deriving from base classes provided by other authors,
-e.g. when extending classes from the Qt Quick module.
+Revisions of a base class that your type depends upon are automatically
+registered when registering the type itself. This is useful when deriving
+from base classes provided by other authors, e.g. when extending classes from
+the Qt Quick module.
\note The QML engine does not support revisions for properties or signals of
grouped and attached property objects.
@@ -323,21 +307,8 @@ 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 {QQmlEngine::}{qmlRegisterExtendedType()} function is for registering extended types.
-Note that it has two forms.
-
-\code
-template<typename T, typename ExtendedT>
-int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
-
-template<typename T, typename ExtendedT>
-int qmlRegisterExtendedType()
-\endcode
-
-This functions should be used instead of the regular \c qmlRegisterType()
-variations. The arguments are identical to the corresponding non-extension
-registration functions, except for the ExtendedT parameter which is the type of
-the extension object.
+The \l {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
pointer. However, the extension class creation is delayed until the first
@@ -425,8 +396,9 @@ the attributes to be made accessible to \e attachee objects. For the
attached property accesses. Consequently the attachment object may not be
deleted until the attachee \c object is destroyed.
-\li is declared as an attaching type, by calling the QML_DECLARE_TYPEINFO()
- macro with the QML_HAS_ATTACHED_PROPERTIES flag
+\li is declared as an attaching type, by adding the QML_ATTACHED(attached) macro
+ to the class declaration. The argument is the name of the
+ \e{attached object type}
\endlist
@@ -441,6 +413,7 @@ class Message : public QObject
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
+ QML_ELEMENT
public:
// ...
};
@@ -472,6 +445,7 @@ class MessageBoardAttachedType : public QObject
{
Q_OBJECT
Q_PROPERTY(bool expired READ expired WRITE setExpired NOTIFY expiredChanged)
+ QML_ANONYMOUS
public:
MessageBoardAttachedType(QObject *parent);
bool expired() const;
@@ -485,20 +459,21 @@ signals:
Then the \e {attaching type}, \c MessageBoard, must declare a \c
qmlAttachedProperties() method that returns an instance of the
\e {attached object type} as implemented by MessageBoardAttachedType.
-Additionally, \c Message board must be declared as an attached type
-through the QML_DECLARE_TYPEINFO() macro:
+Additionally, \c MessageBoard must be declared as an attaching type
+via the QML_ATTACHED() macro:
\code
class MessageBoard : public QObject
{
Q_OBJECT
+ QML_ATTACHED(MessageBoardAttachedType)
+ QML_ELEMENT
public:
static MessageBoardAttachedType *qmlAttachedProperties(QObject *object)
{
return new MessageBoardAttachedType(object);
}
};
-QML_DECLARE_TYPEINFO(MessageBoard, QML_HAS_ATTACHED_PROPERTIES)
\endcode
Now, a \c Message type can access the properties and signals of the attached
@@ -607,6 +582,7 @@ class RandomNumberGenerator : public QObject, public QQmlPropertyValueSource
Q_OBJECT
Q_INTERFACES(QQmlPropertyValueSource)
Q_PROPERTY(int maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged);
+ QML_ELEMENT
public:
RandomNumberGenerator(QObject *parent)
: QObject(parent), m_maxValue(100)
@@ -690,6 +666,7 @@ class MessageBoard : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<Message> messages READ messages)
Q_CLASSINFO("DefaultProperty", "messages")
+ QML_ELEMENT
public:
QQmlListProperty<Message> messages();
@@ -766,6 +743,7 @@ class MyQmlType : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
+ QML_ELEMENT
public:
virtual void componentComplete()
{
diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc
index fbb654378d..bf4565a996 100644
--- a/src/qml/doc/src/cppintegration/topic.qdoc
+++ b/src/qml/doc/src/cppintegration/topic.qdoc
@@ -49,8 +49,16 @@ file contents with:
\snippet code/backend/backend.h backend_header
The \c Q_PROPERTY macro declares a property that could be accessed from QML.
+The \c QML_ELEMENT macro makes the BackEnd class available in QML.
-\li Replace its C++ file contents with:
+\li Add the following lines to your project file:
+
+\snippet code/backend/backend.pro registration
+
+The BackEnd class is automatically registered as a type, which is accessible
+from QML by importing the URL, "\c{io.qt.examples.backend 1.0}".
+
+\li Replace the contents of \c{backend.cpp} with:
\snippet code/backend/backend.cpp backend_cpp
@@ -58,14 +66,6 @@ The \c setUserName function emits the \c userNameChanged signal every time
\c m_userName value changes. The signal can be handled from QML using the
\c onUserNameChanged handler.
-\li Include \c "backend.h" in \c main.cpp and register the class as a QML type
-under a import URL as shown below:
-
-\snippet code/backend/main.cpp main_cpp
-
-The BackEnd class is registered as a type, which is accessible from QML by
-importing the URL, "\c{io.qt.examples.backend 1.0}".
-
\li Replace the contents of \c main.qml with the following code:
\snippet code/backend/main.qml main_qml
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index b83127389a..b27bde3cf9 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -147,7 +147,7 @@ Rectangle {
TapHandler {
id: inputHandler
- onTapped: {
+ onTapped: {
// arbitrary JavaScript expression
console.log("Tapped!")
}
@@ -339,7 +339,7 @@ For the following examples, imagine that we have defined the following class:
and that we have registered it with the QML type-system as follows:
-\snippet qml/integrating-javascript/scarceresources/avatarExample.cpp 0
+\snippet qml/integrating-javascript/scarceresources/scarceresources.pro 0
The AvatarExample class has a property which is a pixmap. When the property
is accessed in JavaScript scope, a copy of the resource will be created and
diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
index 2de4eb0c18..2eaedf8f9b 100644
--- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc
@@ -29,25 +29,37 @@
\title Defining Object Types through QML Documents
\brief Description of how a QML document is a reusable type definition
-One of the core features of QML is that it enables QML object types to be easily defined in a lightweight manner through QML documents to suit the needs of individual QML applications. The standard \l {Qt Quick} module provides various types like \l Rectangle, \l Text and \l Image for building a QML application; beyond these, you can easily define your own QML types to be reused within your application. This ability to create your own types forms the building blocks of any QML application.
+One of the core features of QML is that it enables QML object types to be
+easily defined in a lightweight manner through QML documents to suit the needs
+of individual QML applications. The standard \l {Qt Quick} module provides
+various types like \l Rectangle, \l Text and \l Image for building a QML
+application; beyond these, you can easily define your own QML types to be
+reused within your application. This ability to create your own types forms the
+building blocks of any QML application.
\section1 Defining an Object Type with a QML File
\section2 Naming Custom QML Object Types
-To create an object type, a QML document should be placed into a text file named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type. The type name has the following requirements:
+To create an object type, a QML document should be placed into a text file
+named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type.
+The type name has the following requirements:
\list
\li It must be comprised of alphanumeric characters or underscores.
\li It must begin with an uppercase letter.
\endlist
-This document is then automatically recognized by the engine as a definition of a QML type. Additionally, a type defined in this manner is automatically made available to other QML files within the same directory as the engine searches within the immediate directory when resolving QML type names.
+This document is then automatically recognized by the engine as a definition of
+a QML type. Additionally, a type defined in this manner is automatically made
+available to other QML files within the same directory as the engine searches
+within the immediate directory when resolving QML type names.
\section2 Custom QML Type Definition
-For example, below is a document that declares a \l Rectangle with a child \l MouseArea. The document has been saved to file named \c SquareButton.qml:
+For example, below is a document that declares a \l Rectangle with a child \l
+MouseArea. The document has been saved to file named \c SquareButton.qml:
\qml
// SquareButton.qml
@@ -65,7 +77,10 @@ Rectangle {
}
\endqml
-Since the file is named \c SquareButton.qml, \b {this can now be used as a type named \c SquareButton by any other QML file within the same directory}. For example, if there was a \c myapplication.qml file in the same directory, it could refer to the \c SquareButton type:
+Since the file is named \c SquareButton.qml, \b {this can now be used as a type
+named \c SquareButton by any other QML file within the same directory}. For
+example, if there was a \c myapplication.qml file in the same directory, it
+could refer to the \c SquareButton type:
\qml
// myapplication.qml
@@ -76,23 +91,79 @@ SquareButton {}
\image documents-definetypes-simple.png
-This creates a 100 x 100 red \l Rectangle with an inner \l MouseArea, as defined in \c SquareButton.qml. When this \c myapplication.qml document is loaded by the engine, it loads the SquareButton.qml document as a component and instantiates it to create a \c SquareButton object.
+This creates a 100 x 100 red \l Rectangle with an inner \l MouseArea, as
+defined in \c SquareButton.qml. When this \c myapplication.qml document is
+loaded by the engine, it loads the SquareButton.qml document as a component and
+instantiates it to create a \c SquareButton object.
+
+The \c SquareButton type encapsulates the tree of QML objects declared in \c
+SquareButton.qml. When the QML engine instantiates a \c SquareButton object
+from this type, it is instantiating an object from the \l Rectangle tree
+declared in \c SquareButton.qml.
+
+\note the letter case of the file name is significant on some (notably UNIX)
+filesystems. It is recommended the file name case matches the case of the
+desired QML type name exactly - for example, \c Box.qml and not \c BoX.qml -
+regardless of the platform to which the QML type will be deployed.
+
+\section2 Inline Components
+
+Sometimes, it can be inconvenient to create a new file for a type, for
+instance when reusing a small delegate in multiple views. If you don't actually
+need to expose the type, but only need to create an instance,
+\l{QtQml::Component}{Component} is an option.
+But if you want to declare properties with the component types, or if you
+want to use it in multiple files, \c Component is not an option. In that case,
+you can use \e {inline components}. Inline components declare a new component
+inside of a file. The syntax for that is
+\code
+component <component name> : BaseType {
+ // declare properties and bindings here
+}
+\endcode
+
+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
+
+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
+
+\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
+B.qml gets created, a ReferenceError will occur, as \c root does not exist as
+an id in B.qml.
+It is therefore advisable not to reference objects in an inline component
+which are not part of it.
-The \c SquareButton type encapsulates the tree of QML objects declared in \c SquareButton.qml. When the QML engine instantiates a \c SquareButton object from this type, it is instantiating an object from the \l Rectangle tree declared in \c SquareButton.qml.
+\snippet src/qml/doc/snippets/qml/qml-documents/A.qml document
+\snippet src/qml/doc/snippets/qml/qml-documents/B.qml document
-\note the letter case of the file name is significant on some (notably UNIX) filesystems. It is recommended the file name case matches the case of the desired QML type name exactly - for example, \c Box.qml and not \c BoX.qml - regardless of the platform to which the QML type will be deployed.
+\note Inline components cannot be nested.
\section2 Importing Types Defined Outside the Current Directory
If \c SquareButton.qml was not in the same directory as \c myapplication.qml,
-the \c SquareButton type would need to be specifically made available through an \e import statement in \c myapplication.qml. It could be imported from a relative path on the file system, or as an installed module; see \l {QML Modules}{module} for more details.
+the \c SquareButton type would need to be specifically made available through
+an \e import statement in \c myapplication.qml. It could be imported from a
+relative path on the file system, or as an installed module; see \l {QML
+Modules}{module} for more details.
\section1 Accessible Attributes of Custom Types
-The \b {root object} definition in a .qml file \b {defines the attributes that are available for a QML type}. All properties, signals and methods that belong to this root object - whether they are custom declared, or come from the QML type of the root object - are externally accessible and can be read and modified for objects of this type.
+The \b {root object} definition in a .qml file \b {defines the attributes that
+are available for a QML type}. All properties, signals and methods that belong
+to this root object - whether they are custom declared, or come from the QML
+type of the root object - are externally accessible and can be read and
+modified for objects of this type.
-For example, the root object type in the \c SquareButton.qml file above is \l Rectangle. This means any properties defined by the \l Rectangle type can be modified for a \c SquareButton object. The code below defines three \c SquareButton objects with customized values for some of the properties of the root \l Rectangle object of the \c SquareButton type:
+For example, the root object type in the \c SquareButton.qml file above is \l
+Rectangle. This means any properties defined by the \l Rectangle type can be
+modified for a \c SquareButton object. The code below defines three \c
+SquareButton objects with customized values for some of the properties of the
+root \l Rectangle object of the \c SquareButton type:
\qml
// application.qml
@@ -107,7 +178,12 @@ Column {
\image documents-definetypes-attributes.png
-The attributes that are accessible to objects of the custom QML type include any \l{Defining Property Attributes}{custom properties}, \l{Defining Method Attributes}{methods} and \l{Defining Signal Attributes}{signals} that have additionally been defined for an object. For example, suppose the \l Rectangle in \c SquareButton.qml had been defined as follows, with additional properties, methods and signals:
+The attributes that are accessible to objects of the custom QML type include
+any \l{Defining Property Attributes}{custom properties}, \l{Defining Method
+Attributes}{methods} and \l{Defining Signal Attributes}{signals} that have
+additionally been defined for an object. For example, suppose the \l Rectangle
+in \c SquareButton.qml had been defined as follows, with additional properties,
+methods and signals:
\qml
// SquareButton.qml
@@ -136,7 +212,9 @@ Rectangle {
}
\endqml
-Any \c SquareButton object could make use of the \c pressed property, \c buttonClicked signal and \c randomizeColor() method that have been added to the root \l Rectangle:
+Any \c SquareButton object could make use of the \c pressed property, \c
+buttonClicked signal and \c randomizeColor() method that have been added to the
+root \l Rectangle:
\qml
// application.qml
@@ -154,7 +232,14 @@ SquareButton {
}
\endqml
-Note that any of the \c id values defined in \c SquareButton.qml are not accessible to \c SquareButton objects, as id values are only accessible from within the component scope in which a component is declared. The \c SquareButton object definition above cannot refer to \c mouseArea in order to refer to the \l MouseArea child, and if it had an \c id of \c root rather than \c squareButton, this would not conflict with the \c id of the same value for the root object defined in \c SquareButton.qml as the two would be declared within separate scopes.
+Note that any of the \c id values defined in \c SquareButton.qml are not
+accessible to \c SquareButton objects, as id values are only accessible from
+within the component scope in which a component is declared. The \c
+SquareButton object definition above cannot refer to \c mouseArea in order to
+refer to the \l MouseArea child, and if it had an \c id of \c root rather than
+\c squareButton, this would not conflict with the \c id of the same value for
+the root object defined in \c SquareButton.qml as the two would be declared
+within separate scopes.
*/
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 401e099ebf..832d9a9e26 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -112,7 +112,7 @@ Alternatively, a custom property of an object type may be defined in
an object declaration in a QML document with the following syntax:
\code
- [default] property <propertyType> <propertyName>
+ [default] [required] [readonly] property <propertyType> <propertyName>
\endcode
In this way an object declaration may \l {Defining Object Types from QML}
@@ -121,10 +121,13 @@ state more easily.
Property names must begin with a lower case letter and can only contain
letters, numbers and underscores. \l {JavaScript Reserved Words}
-{JavaScript reserved words} are not valid property names. The \c default
-keyword is optional, and modifies the semantics of the property being declared.
-See the upcoming section on \l {Default Properties}{default properties} for
-more information about the \c default property modifier.
+{JavaScript reserved words} are not valid property names. The \c default,
+\c required, and \c readonly keywords are optional, and modify the semantics
+of the property being declared.
+See the upcoming sections on \l {Default Properties}{default properties},
+\l {Required Properties}{required properties} and,
+\l {Read-Only Properties}{read-only properties} for more information
+about their respective meaning.
Declaring a custom property implicitly creates a value-change
\l{Signal attributes}{signal} for that property, as well as an associated
@@ -647,6 +650,45 @@ the \l{TabWidget Example}, which uses a default property to
automatically reassign children of the TabWidget as children of an inner
ListView. See also \l {Extending QML}.
+\section3 Required Properties
+
+An object declaration may define a property as required, using the \c required
+keyword. The syntax is
+\code
+ required property <propertyType> <propertyName>
+\endcode
+
+As the name suggests, required properties must be set when an instance of the object
+is created. Violation of this rule will result in QML applications not starting if it can be
+detected statically. In case of dynamically instantiated QML components (for instance via
+\l {QtQml::Qt::createComponent()}{Qt.createComponent()}), violating this rule results in a
+warning and a null return value.
+
+It's possible to make an existing property required with
+\code
+ required <propertyName>
+\endcode
+The following example shows how to create a custom Rectangle component, in which the color
+property always needs to be specified.
+\qml
+// ColorRectangle.qml
+Rectangle {
+ required color
+}
+\endqml
+
+\note You can't assign an initial value to a required property from QML, as that would go
+directly against the intended usage of required properties.
+
+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.
+
+\sa {QQmlComponent::createWithInitialProperties}, {QQmlApplicationEngine::setInitialProperties}
+and {QQuickView::setInitialProperties} for ways to initialize required properties from C++.
+
\section3 Read-Only Properties
An object declaration may define a read-only property using the \c readonly
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 86e178d568..a900e710c2 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1512,12 +1512,37 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
}
+ QVariant retn;
#if QT_CONFIG(qml_sequence_object)
bool succeeded = false;
- QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
+ retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
if (succeeded)
return retn;
#endif
+ if (typeHint != -1) {
+ retn = QVariant(typeHint, QMetaType::create(typeHint));
+ auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
+ auto const length = a->getLength();
+ QV4::ScopedValue arrayValue(scope);
+ for (qint64 i = 0; i < length; ++i) {
+ arrayValue = a->get(i);
+ QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects);
+ auto originalType = asVariant.userType();
+ bool couldConvert = asVariant.convert(retnAsIterable._metaType_id);
+ 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));
+ // create default constructed value
+ asVariant = QVariant(retnAsIterable._metaType_id, nullptr);
+ }
+ retnAsIterable.append(asVariant.constData());
+ }
+ return retn;
+ }
+ }
}
if (value.isUndefined())
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index d29b060b9e..3449603a8a 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -250,6 +250,8 @@ bool Value::sameValue(Value other) const {
if (isDouble() && other.isInteger())
return other.int_32() ? (doubleValue() == double(other.int_32()))
: (doubleValue() == 0 && !std::signbit(doubleValue()));
+ if (isManaged())
+ return other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
return false;
}
@@ -269,6 +271,8 @@ bool Value::sameValueZero(Value other) const {
return true;
}
}
+ if (isManaged())
+ return other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
return false;
}
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index ce715b0b9c..a246dfba7a 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -326,6 +326,8 @@ public:
AST::UiQualifiedId *UiQualifiedId;
AST::UiEnumMemberList *UiEnumMemberList;
AST::UiVersionSpecifier *UiVersionSpecifier;
+ AST::UiAnnotation *UiAnnotation;
+ AST::UiAnnotationList *UiAnnotationList;
};
public:
@@ -967,24 +969,30 @@ UiAnnotationObjectDefinition: UiSimpleQualifiedId UiObjectInitializer;
return false;
}
- AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
+ AST::UiAnnotation *node = new (pool) AST::UiAnnotation(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
sym(1).Node = node;
} break;
./
UiAnnotation: T_AT UiAnnotationObjectDefinition;
+/.
+case $rule_number: {
+ sym(1).Node = sym(2).Node;
+} break;
+./
+
UiAnnotationList: UiAnnotation;
/.
case $rule_number: {
- sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotation);
} break;
./
UiAnnotationList: UiAnnotationList UiAnnotation;
/.
case $rule_number: {
- AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(sym(1).UiArrayMemberList, sym(3).UiObjectMember);
+ AST::UiAnnotationList *node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotationList, sym(2).UiAnnotation);
sym(1).Node = node;
} break;
./
@@ -992,7 +1000,9 @@ UiAnnotationList: UiAnnotationList UiAnnotation;
UiAnnotatedObject: UiAnnotationList UiObjectDefinition;
/.
case $rule_number: {
- sym(1).Node = sym(2).Node;
+ AST::UiObjectDefinition *node = sym(2).UiObjectDefinition;
+ node->annotations = sym(1).UiAnnotationList->finish();
+ sym(1).Node = node;
} break;
./
@@ -1060,6 +1070,8 @@ UiObjectDefinition: UiQualifiedId UiObjectInitializer;
UiAnnotatedObjectMember: UiAnnotationList UiObjectMember;
/.
case $rule_number: {
+ AST::UiObjectMember *node = sym(2).UiObjectMember;
+ node->annotations = sym(1).UiAnnotationList->finish();
sym(1).Node = sym(2).Node;
} break;
./
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 416916c547..2a34c5a66c 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -167,7 +167,7 @@ UiObjectMember *UiObjectMember::uiObjectMemberCast()
return this;
}
-void NestedExpression::accept0(Visitor *visitor)
+void NestedExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -185,7 +185,7 @@ ClassExpression *NestedExpression::asClassDefinition()
return expression->asClassDefinition();
}
-void ThisExpression::accept0(Visitor *visitor)
+void ThisExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -193,7 +193,7 @@ void ThisExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IdentifierExpression::accept0(Visitor *visitor)
+void IdentifierExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -201,7 +201,7 @@ void IdentifierExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NullExpression::accept0(Visitor *visitor)
+void NullExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -209,7 +209,7 @@ void NullExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TrueLiteral::accept0(Visitor *visitor)
+void TrueLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -217,7 +217,7 @@ void TrueLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FalseLiteral::accept0(Visitor *visitor)
+void FalseLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -225,7 +225,7 @@ void FalseLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void SuperLiteral::accept0(Visitor *visitor)
+void SuperLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -234,7 +234,7 @@ void SuperLiteral::accept0(Visitor *visitor)
}
-void StringLiteral::accept0(Visitor *visitor)
+void StringLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -242,7 +242,7 @@ void StringLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TemplateLiteral::accept0(Visitor *visitor)
+void TemplateLiteral::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (TemplateLiteral *it = this; it && accepted; it = it->next) {
@@ -251,7 +251,7 @@ void TemplateLiteral::accept0(Visitor *visitor)
}
}
-void NumericLiteral::accept0(Visitor *visitor)
+void NumericLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -259,7 +259,7 @@ void NumericLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void RegExpLiteral::accept0(Visitor *visitor)
+void RegExpLiteral::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -267,7 +267,7 @@ void RegExpLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ArrayPattern::accept0(Visitor *visitor)
+void ArrayPattern::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this))
accept(elements, visitor);
@@ -287,7 +287,7 @@ bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const {
return true;
}
-void ObjectPattern::accept0(Visitor *visitor)
+void ObjectPattern::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(properties, visitor);
@@ -462,7 +462,7 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
}
-void Elision::accept0(Visitor *visitor)
+void Elision::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
// ###
@@ -471,7 +471,7 @@ void Elision::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IdentifierPropertyName::accept0(Visitor *visitor)
+void IdentifierPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -479,7 +479,7 @@ void IdentifierPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void StringLiteralPropertyName::accept0(Visitor *visitor)
+void StringLiteralPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -487,7 +487,7 @@ void StringLiteralPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NumericLiteralPropertyName::accept0(Visitor *visitor)
+void NumericLiteralPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -517,7 +517,7 @@ QString NumericLiteralPropertyName::asString()const
return locale.toString(id, 'g', 16);
}
-void ArrayMemberExpression::accept0(Visitor *visitor)
+void ArrayMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -527,7 +527,7 @@ void ArrayMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FieldMemberExpression::accept0(Visitor *visitor)
+void FieldMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -536,7 +536,7 @@ void FieldMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NewMemberExpression::accept0(Visitor *visitor)
+void NewMemberExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -546,7 +546,7 @@ void NewMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NewExpression::accept0(Visitor *visitor)
+void NewExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -555,7 +555,7 @@ void NewExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CallExpression::accept0(Visitor *visitor)
+void CallExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -565,7 +565,7 @@ void CallExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ArgumentList::accept0(Visitor *visitor)
+void ArgumentList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ArgumentList *it = this; it; it = it->next) {
@@ -576,7 +576,7 @@ void ArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PostIncrementExpression::accept0(Visitor *visitor)
+void PostIncrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -585,7 +585,7 @@ void PostIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PostDecrementExpression::accept0(Visitor *visitor)
+void PostDecrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -594,7 +594,7 @@ void PostDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DeleteExpression::accept0(Visitor *visitor)
+void DeleteExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -603,7 +603,7 @@ void DeleteExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VoidExpression::accept0(Visitor *visitor)
+void VoidExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -612,7 +612,7 @@ void VoidExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeOfExpression::accept0(Visitor *visitor)
+void TypeOfExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -621,7 +621,7 @@ void TypeOfExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PreIncrementExpression::accept0(Visitor *visitor)
+void PreIncrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -630,7 +630,7 @@ void PreIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PreDecrementExpression::accept0(Visitor *visitor)
+void PreDecrementExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -639,7 +639,7 @@ void PreDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UnaryPlusExpression::accept0(Visitor *visitor)
+void UnaryPlusExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -648,7 +648,7 @@ void UnaryPlusExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UnaryMinusExpression::accept0(Visitor *visitor)
+void UnaryMinusExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -657,7 +657,7 @@ void UnaryMinusExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TildeExpression::accept0(Visitor *visitor)
+void TildeExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -666,7 +666,7 @@ void TildeExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NotExpression::accept0(Visitor *visitor)
+void NotExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -675,7 +675,7 @@ void NotExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void BinaryExpression::accept0(Visitor *visitor)
+void BinaryExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(left, visitor);
@@ -685,7 +685,7 @@ void BinaryExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ConditionalExpression::accept0(Visitor *visitor)
+void ConditionalExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -696,7 +696,7 @@ void ConditionalExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Expression::accept0(Visitor *visitor)
+void Expression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(left, visitor);
@@ -706,7 +706,7 @@ void Expression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Block::accept0(Visitor *visitor)
+void Block::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -715,7 +715,7 @@ void Block::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void StatementList::accept0(Visitor *visitor)
+void StatementList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (StatementList *it = this; it; it = it->next) {
@@ -726,7 +726,7 @@ void StatementList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VariableStatement::accept0(Visitor *visitor)
+void VariableStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(declarations, visitor);
@@ -735,7 +735,7 @@ void VariableStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void VariableDeclarationList::accept0(Visitor *visitor)
+void VariableDeclarationList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (VariableDeclarationList *it = this; it; it = it->next) {
@@ -746,7 +746,7 @@ void VariableDeclarationList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void EmptyStatement::accept0(Visitor *visitor)
+void EmptyStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -754,7 +754,7 @@ void EmptyStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExpressionStatement::accept0(Visitor *visitor)
+void ExpressionStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -763,7 +763,7 @@ void ExpressionStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void IfStatement::accept0(Visitor *visitor)
+void IfStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -774,7 +774,7 @@ void IfStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DoWhileStatement::accept0(Visitor *visitor)
+void DoWhileStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -784,7 +784,7 @@ void DoWhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void WhileStatement::accept0(Visitor *visitor)
+void WhileStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -794,7 +794,7 @@ void WhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ForStatement::accept0(Visitor *visitor)
+void ForStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(initialiser, visitor);
@@ -807,7 +807,7 @@ void ForStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ForEachStatement::accept0(Visitor *visitor)
+void ForEachStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(lhs, visitor);
@@ -818,7 +818,7 @@ void ForEachStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ContinueStatement::accept0(Visitor *visitor)
+void ContinueStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -826,7 +826,7 @@ void ContinueStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void BreakStatement::accept0(Visitor *visitor)
+void BreakStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -834,7 +834,7 @@ void BreakStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ReturnStatement::accept0(Visitor *visitor)
+void ReturnStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -843,7 +843,7 @@ void ReturnStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void YieldExpression::accept0(Visitor *visitor)
+void YieldExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -853,7 +853,7 @@ void YieldExpression::accept0(Visitor *visitor)
}
-void WithStatement::accept0(Visitor *visitor)
+void WithStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -863,7 +863,7 @@ void WithStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void SwitchStatement::accept0(Visitor *visitor)
+void SwitchStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -873,7 +873,7 @@ void SwitchStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseBlock::accept0(Visitor *visitor)
+void CaseBlock::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(clauses, visitor);
@@ -884,7 +884,7 @@ void CaseBlock::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseClauses::accept0(Visitor *visitor)
+void CaseClauses::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (CaseClauses *it = this; it; it = it->next) {
@@ -895,7 +895,7 @@ void CaseClauses::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void CaseClause::accept0(Visitor *visitor)
+void CaseClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -905,7 +905,7 @@ void CaseClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DefaultClause::accept0(Visitor *visitor)
+void DefaultClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -914,7 +914,7 @@ void DefaultClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void LabelledStatement::accept0(Visitor *visitor)
+void LabelledStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -923,7 +923,7 @@ void LabelledStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ThrowStatement::accept0(Visitor *visitor)
+void ThrowStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -932,7 +932,7 @@ void ThrowStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TryStatement::accept0(Visitor *visitor)
+void TryStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -943,7 +943,7 @@ void TryStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Catch::accept0(Visitor *visitor)
+void Catch::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(patternElement, visitor);
@@ -953,7 +953,7 @@ void Catch::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void Finally::accept0(Visitor *visitor)
+void Finally::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
@@ -962,7 +962,7 @@ void Finally::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FunctionDeclaration::accept0(Visitor *visitor)
+void FunctionDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
@@ -973,7 +973,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FunctionExpression::accept0(Visitor *visitor)
+void FunctionExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
@@ -1018,7 +1018,7 @@ BoundNames FormalParameterList::boundNames() const
return names;
}
-void FormalParameterList::accept0(Visitor *visitor)
+void FormalParameterList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (FormalParameterList *it = this; it && accepted; it = it->next) {
@@ -1043,7 +1043,7 @@ FormalParameterList *FormalParameterList::finish(QQmlJS::MemoryPool *pool)
return front;
}
-void Program::accept0(Visitor *visitor)
+void Program::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statements, visitor);
@@ -1052,7 +1052,7 @@ void Program::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportSpecifier::accept0(Visitor *visitor)
+void ImportSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
@@ -1060,7 +1060,7 @@ void ImportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportsList::accept0(Visitor *visitor)
+void ImportsList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ImportsList *it = this; it; it = it->next) {
@@ -1071,7 +1071,7 @@ void ImportsList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NamedImports::accept0(Visitor *visitor)
+void NamedImports::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importsList, visitor);
@@ -1080,7 +1080,7 @@ void NamedImports::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FromClause::accept0(Visitor *visitor)
+void FromClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1088,7 +1088,7 @@ void FromClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void NameSpaceImport::accept0(Visitor *visitor)
+void NameSpaceImport::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1096,7 +1096,7 @@ void NameSpaceImport::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportClause::accept0(Visitor *visitor)
+void ImportClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(nameSpaceImport, visitor);
@@ -1106,7 +1106,7 @@ void ImportClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ImportDeclaration::accept0(Visitor *visitor)
+void ImportDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importClause, visitor);
@@ -1116,7 +1116,7 @@ void ImportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportSpecifier::accept0(Visitor *visitor)
+void ExportSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
@@ -1125,7 +1125,7 @@ void ExportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportsList::accept0(Visitor *visitor)
+void ExportsList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (ExportsList *it = this; it; it = it->next) {
@@ -1136,7 +1136,7 @@ void ExportsList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportClause::accept0(Visitor *visitor)
+void ExportClause::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(exportsList, visitor);
@@ -1145,7 +1145,7 @@ void ExportClause::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ExportDeclaration::accept0(Visitor *visitor)
+void ExportDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(fromClause, visitor);
@@ -1156,7 +1156,7 @@ void ExportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ESModule::accept0(Visitor *visitor)
+void ESModule::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(body, visitor);
@@ -1165,7 +1165,7 @@ void ESModule::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void DebuggerStatement::accept0(Visitor *visitor)
+void DebuggerStatement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1173,7 +1173,7 @@ void DebuggerStatement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiProgram::accept0(Visitor *visitor)
+void UiProgram::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(headers, visitor);
@@ -1183,19 +1183,23 @@ void UiProgram::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiPublicMember::accept0(Visitor *visitor)
+void UiPublicMember::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
+ // accept(memberType, visitor); // accept manually in visit if interested
accept(statement, visitor);
accept(binding, visitor);
+ // accept(parameters, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiObjectDefinition::accept0(Visitor *visitor)
+void UiObjectDefinition::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor);
}
@@ -1203,7 +1207,7 @@ void UiObjectDefinition::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiObjectInitializer::accept0(Visitor *visitor)
+void UiObjectInitializer::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(members, visitor);
@@ -1212,16 +1216,18 @@ void UiObjectInitializer::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiParameterList::accept0(Visitor *visitor)
+void UiParameterList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(type, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiObjectBinding::accept0(Visitor *visitor)
+void UiObjectBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor);
@@ -1230,9 +1236,10 @@ void UiObjectBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiScriptBinding::accept0(Visitor *visitor)
+void UiScriptBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(statement, visitor);
}
@@ -1240,9 +1247,10 @@ void UiScriptBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiArrayBinding::accept0(Visitor *visitor)
+void UiArrayBinding::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor);
accept(members, visitor);
}
@@ -1250,7 +1258,7 @@ void UiArrayBinding::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiObjectMemberList::accept0(Visitor *visitor)
+void UiObjectMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (UiObjectMemberList *it = this; it; it = it->next)
@@ -1260,7 +1268,7 @@ void UiObjectMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiArrayMemberList::accept0(Visitor *visitor)
+void UiArrayMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (UiArrayMemberList *it = this; it; it = it->next)
@@ -1270,15 +1278,16 @@ void UiArrayMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiQualifiedId::accept0(Visitor *visitor)
+void UiQualifiedId::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(next, visitor) // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void Type::accept0(Visitor *visitor)
+void Type::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(typeId, visitor);
@@ -1288,7 +1297,7 @@ void Type::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeArgumentList::accept0(Visitor *visitor)
+void TypeArgumentList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (TypeArgumentList *it = this; it; it = it->next)
@@ -1298,7 +1307,7 @@ void TypeArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TypeAnnotation::accept0(Visitor *visitor)
+void TypeAnnotation::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(type, visitor);
@@ -1307,16 +1316,17 @@ void TypeAnnotation::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiImport::accept0(Visitor *visitor)
+void UiImport::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(importUri, visitor);
+ // accept(version, visitor); // accept manually in visit if interested
}
visitor->endVisit(this);
}
-void UiPragma::accept0(Visitor *visitor)
+void UiPragma::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1324,7 +1334,7 @@ void UiPragma::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void UiHeaderItemList::accept0(Visitor *visitor)
+void UiHeaderItemList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
@@ -1337,25 +1347,27 @@ void UiHeaderItemList::accept0(Visitor *visitor)
}
-void UiSourceElement::accept0(Visitor *visitor)
+void UiSourceElement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(sourceElement, visitor);
}
visitor->endVisit(this);
}
-void UiEnumDeclaration::accept0(Visitor *visitor)
+void UiEnumDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(members, visitor);
}
visitor->endVisit(this);
}
-void UiEnumMemberList::accept0(Visitor *visitor)
+void UiEnumMemberList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1363,7 +1375,7 @@ void UiEnumMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void TaggedTemplate::accept0(Visitor *visitor)
+void TaggedTemplate::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(base, visitor);
@@ -1373,7 +1385,7 @@ void TaggedTemplate::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PatternElement::accept0(Visitor *visitor)
+void PatternElement::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(bindingTarget, visitor);
@@ -1396,7 +1408,7 @@ void PatternElement::boundNames(BoundNames *names)
}
}
-void PatternElementList::accept0(Visitor *visitor)
+void PatternElementList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (PatternElementList *it = this; it && accepted; it = it->next) {
@@ -1417,7 +1429,7 @@ void PatternElementList::boundNames(BoundNames *names)
}
}
-void PatternProperty::accept0(Visitor *visitor)
+void PatternProperty::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
@@ -1434,7 +1446,7 @@ void PatternProperty::boundNames(BoundNames *names)
PatternElement::boundNames(names);
}
-void PatternPropertyList::accept0(Visitor *visitor)
+void PatternPropertyList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (PatternPropertyList *it = this; it && accepted; it = it->next) {
@@ -1451,7 +1463,7 @@ void PatternPropertyList::boundNames(BoundNames *names)
it->property->boundNames(names);
}
-void ComputedPropertyName::accept0(Visitor *visitor)
+void ComputedPropertyName::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
@@ -1460,7 +1472,7 @@ void ComputedPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ClassExpression::accept0(Visitor *visitor)
+void ClassExpression::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(heritage, visitor);
@@ -1475,7 +1487,7 @@ ClassExpression *ClassExpression::asClassDefinition()
return this;
}
-void ClassDeclaration::accept0(Visitor *visitor)
+void ClassDeclaration::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(heritage, visitor);
@@ -1485,7 +1497,7 @@ void ClassDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void ClassElementList::accept0(Visitor *visitor)
+void ClassElementList::accept0(BaseVisitor *visitor)
{
bool accepted = true;
for (ClassElementList *it = this; it && accepted; it = it->next) {
@@ -1514,7 +1526,7 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
return this;
}
-void UiVersionSpecifier::accept0(Visitor *visitor)
+void UiVersionSpecifier::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1545,16 +1557,17 @@ void Type::toString(QString *out) const
};
}
-void UiInlineComponent::accept0(Visitor *visitor)
+void UiInlineComponent::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
+ // accept(annotations, visitor); // accept manually in visit if interested
accept(component, visitor);
}
visitor->endVisit(this);
}
-void UiRequired::accept0(Visitor *visitor)
+void UiRequired::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
@@ -1562,6 +1575,26 @@ void UiRequired::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void UiAnnotationList::accept0(BaseVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (UiAnnotationList *it = this; it; it = it->next)
+ accept(it->annotation, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void UiAnnotation::accept0(BaseVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(qualifiedTypeNameId, visitor);
+ accept(initializer, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
} } // namespace QQmlJS::AST
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 446704be91..b92a635228 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -260,7 +260,9 @@ public:
Kind_UiEnumDeclaration,
Kind_UiEnumMemberList,
Kind_UiVersionSpecifier,
- Kind_UiRequired
+ Kind_UiRequired,
+ Kind_UiAnnotation,
+ Kind_UiAnnotationList
};
inline Node() {}
@@ -282,9 +284,9 @@ public:
bool ignoreRecursionDepth() const;
- inline void accept(Visitor *visitor)
+ inline void accept(BaseVisitor *visitor)
{
- Visitor::RecursionDepthCheck recursionCheck(visitor);
+ BaseVisitor::RecursionDepthCheck recursionCheck(visitor);
// Stack overflow is uncommon, ignoreRecursionDepth() only returns true if
// QV4_CRASH_ON_STACKOVERFLOW is set, and ignoreRecursionDepth() needs to be out of line.
@@ -298,19 +300,19 @@ public:
}
}
- inline static void accept(Node *node, Visitor *visitor)
+ inline static void accept(Node *node, BaseVisitor *visitor)
{
if (node)
node->accept(visitor);
}
// ### Remove when we can. This is part of the qmldevtools library, though.
- inline static void acceptChild(Node *node, Visitor *visitor)
+ inline static void acceptChild(Node *node, BaseVisitor *visitor)
{
return accept(node, visitor);
}
- virtual void accept0(Visitor *visitor) = 0;
+ virtual void accept0(BaseVisitor *visitor) = 0;
virtual SourceLocation firstSourceLocation() const = 0;
virtual SourceLocation lastSourceLocation() const = 0;
@@ -351,7 +353,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -375,7 +377,7 @@ public:
, typeArguments(typeArguments)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
@@ -410,7 +412,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeId->firstSourceLocation(); }
@@ -439,7 +441,7 @@ public:
: type(type)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return colonToken; }
@@ -484,7 +486,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lparenToken; }
@@ -509,7 +511,7 @@ public:
ThisExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return thisToken; }
@@ -529,7 +531,7 @@ public:
IdentifierExpression(const QStringRef &n):
name (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -549,7 +551,7 @@ public:
NullExpression() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return nullToken; }
@@ -568,7 +570,7 @@ public:
TrueLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return trueToken; }
@@ -587,7 +589,7 @@ public:
FalseLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return falseToken; }
@@ -606,7 +608,7 @@ public:
SuperLiteral() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return superToken; }
@@ -627,7 +629,7 @@ public:
NumericLiteral(double v):
value(v) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -650,7 +652,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override { return majorToken; }
@@ -673,7 +675,7 @@ public:
StringLiteral(const QStringRef &v):
value (v) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -704,7 +706,7 @@ public:
return (last->expression ? last->expression->lastSourceLocation() : last->literalToken);
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QStringRef value;
QStringRef rawValue;
@@ -721,7 +723,7 @@ public:
RegExpLiteral(const QStringRef &p, int f):
pattern (p), flags (f) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return literalToken; }
@@ -756,7 +758,7 @@ public:
: elements(elts)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbracketToken; }
@@ -787,7 +789,7 @@ public:
: properties(plist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -818,7 +820,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return commaToken; }
@@ -924,7 +926,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage);
SourceLocation firstSourceLocation() const override
@@ -977,7 +979,7 @@ public:
return front;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -1012,7 +1014,7 @@ public:
: PatternElement(pattern, i), name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return name->firstSourceLocation(); }
@@ -1048,7 +1050,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
void boundNames(BoundNames *names);
@@ -1077,7 +1079,7 @@ public:
IdentifierPropertyName(const QStringRef &n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return id.toString(); }
@@ -1093,7 +1095,7 @@ public:
StringLiteralPropertyName(const QStringRef &n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return id.toString(); }
@@ -1109,7 +1111,7 @@ public:
NumericLiteralPropertyName(double n):
id (n) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override;
@@ -1126,7 +1128,7 @@ public:
: expression(expression)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
QString asString() const override { return QString(); }
@@ -1150,7 +1152,7 @@ public:
base (b), expression (e)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1174,7 +1176,7 @@ public:
base (b), name (n)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1198,7 +1200,7 @@ public:
: base (b), templateLiteral(t)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1220,7 +1222,7 @@ public:
base (b), arguments (a)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return newToken; }
@@ -1244,7 +1246,7 @@ public:
NewExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return newToken; }
@@ -1266,7 +1268,7 @@ public:
base (b), arguments (a)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1298,7 +1300,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1332,7 +1334,7 @@ public:
PostIncrementExpression(ExpressionNode *b):
base (b) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1353,7 +1355,7 @@ public:
PostDecrementExpression(ExpressionNode *b):
base (b) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return base->firstSourceLocation(); }
@@ -1374,7 +1376,7 @@ public:
DeleteExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return deleteToken; }
@@ -1395,7 +1397,7 @@ public:
VoidExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return voidToken; }
@@ -1416,7 +1418,7 @@ public:
TypeOfExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return typeofToken; }
@@ -1437,7 +1439,7 @@ public:
PreIncrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return incrementToken; }
@@ -1458,7 +1460,7 @@ public:
PreDecrementExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return decrementToken; }
@@ -1479,7 +1481,7 @@ public:
UnaryPlusExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return plusToken; }
@@ -1500,7 +1502,7 @@ public:
UnaryMinusExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return minusToken; }
@@ -1521,7 +1523,7 @@ public:
TildeExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return tildeToken; }
@@ -1542,7 +1544,7 @@ public:
NotExpression(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return notToken; }
@@ -1566,7 +1568,7 @@ public:
BinaryExpression *binaryExpressionCast() override;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return left->firstSourceLocation(); }
@@ -1590,7 +1592,7 @@ public:
expression (e), ok (t), ko (f)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1614,7 +1616,7 @@ public:
Expression(ExpressionNode *l, ExpressionNode *r):
left (l), right (r) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return left->firstSourceLocation(); }
@@ -1636,7 +1638,7 @@ public:
Block(StatementList *slist):
statements (slist) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -1666,7 +1668,7 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return statement->firstSourceLocation(); }
@@ -1705,7 +1707,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declaration->firstSourceLocation(); }
@@ -1743,7 +1745,7 @@ public:
declarations (vlist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return declarationKindToken; }
@@ -1763,7 +1765,7 @@ public:
EmptyStatement() { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return semicolonToken; }
@@ -1783,7 +1785,7 @@ public:
ExpressionStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return expression->firstSourceLocation(); }
@@ -1805,7 +1807,7 @@ public:
expression (e), ok (t), ko (f)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return ifToken; }
@@ -1837,7 +1839,7 @@ public:
statement (stmt), expression (e)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return doToken; }
@@ -1864,7 +1866,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return whileToken; }
@@ -1894,7 +1896,7 @@ public:
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return forToken; }
@@ -1932,7 +1934,7 @@ public:
: lhs(v), expression(e), statement(stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return forToken; }
@@ -1963,7 +1965,7 @@ public:
ContinueStatement(const QStringRef &l = QStringRef()):
label (l) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return continueToken; }
@@ -1986,7 +1988,7 @@ public:
BreakStatement(const QStringRef &l):
label (l) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return breakToken; }
@@ -2009,7 +2011,7 @@ public:
ReturnStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return returnToken; }
@@ -2031,7 +2033,7 @@ public:
YieldExpression(ExpressionNode *e = nullptr):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return yieldToken; }
@@ -2054,7 +2056,7 @@ public:
expression (e), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return withToken; }
@@ -2079,7 +2081,7 @@ public:
clauses (c), defaultClause (d), moreClauses (r)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -2104,7 +2106,7 @@ public:
expression (e), block (b)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return switchToken; }
@@ -2129,7 +2131,7 @@ public:
expression (e), statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return caseToken; }
@@ -2161,7 +2163,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return clause->firstSourceLocation(); }
@@ -2192,7 +2194,7 @@ public:
statements (slist)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return defaultToken; }
@@ -2215,7 +2217,7 @@ public:
label (l), statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2238,7 +2240,7 @@ public:
ThrowStatement(ExpressionNode *e):
expression (e) { kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return throwToken; }
@@ -2261,7 +2263,7 @@ public:
: patternElement(p), statement(stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return catchToken; }
@@ -2287,7 +2289,7 @@ public:
statement (stmt)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return finallyToken; }
@@ -2317,7 +2319,7 @@ public:
statement (stmt), catchExpression (c), finallyExpression (nullptr)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return tryToken; }
@@ -2349,7 +2351,7 @@ public:
typeAnnotation(typeAnnotation)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return functionToken; }
@@ -2383,7 +2385,7 @@ public:
FunctionExpression(n, f, b, typeAnnotation)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
};
class QML_PARSER_EXPORT FormalParameterList: public Node
@@ -2454,7 +2456,7 @@ public:
BoundNames boundNames() const;
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return element->firstSourceLocation(); }
@@ -2480,7 +2482,7 @@ public:
: name(n), heritage(heritage), elements(elements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return classToken; }
@@ -2509,7 +2511,7 @@ public:
: ClassExpression(n, heritage, elements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
};
@@ -2531,7 +2533,7 @@ public:
return n;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return property->firstSourceLocation(); }
@@ -2559,7 +2561,7 @@ public:
: statements(statements)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return statements ? statements->firstSourceLocation() : SourceLocation(); }
@@ -2588,7 +2590,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifier.isNull() ? importedBindingToken : identifierToken; }
@@ -2633,7 +2635,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importSpecifierToken; }
@@ -2665,7 +2667,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2689,7 +2691,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual SourceLocation firstSourceLocation() const override
{ return starToken; }
@@ -2739,7 +2741,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
virtual SourceLocation firstSourceLocation() const override
{ return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->firstSourceLocation() : namedImports->firstSourceLocation()) : importedDefaultBindingToken; }
@@ -2764,7 +2766,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return fromToken; }
@@ -2795,7 +2797,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -2828,7 +2830,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return identifierToken; }
@@ -2873,7 +2875,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportSpecifier->firstSourceLocation(); }
@@ -2901,7 +2903,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return leftBraceToken; }
@@ -2945,7 +2947,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return exportToken; }
@@ -2972,7 +2974,7 @@ public:
kind = K;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return body ? body->firstSourceLocation() : SourceLocation(); }
@@ -2992,7 +2994,7 @@ public:
DebuggerStatement()
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return debuggerToken; }
@@ -3018,7 +3020,7 @@ public:
: importUri(uri)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return importToken; }
@@ -3045,6 +3047,9 @@ public:
SourceLocation lastSourceLocation() const override = 0;
UiObjectMember *uiObjectMemberCast() override;
+
+// attributes
+ UiAnnotationList *annotations = nullptr;
};
class QML_PARSER_EXPORT UiObjectMemberList: public Node
@@ -3064,7 +3069,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
@@ -3093,7 +3098,7 @@ public:
: name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return pragmaToken; }
@@ -3116,7 +3121,7 @@ public:
:name(name)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return requiredToken; }
@@ -3165,7 +3170,7 @@ public:
return head;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return headerItem->firstSourceLocation(); }
@@ -3187,7 +3192,7 @@ public:
: headers(headers), members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{
@@ -3229,7 +3234,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return member->firstSourceLocation(); }
@@ -3259,7 +3264,7 @@ public:
: members(members)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return lbraceToken; }
@@ -3290,7 +3295,7 @@ public:
previous->next = this;
}
- void accept0(Visitor *) override;
+ void accept0(BaseVisitor *) override;
SourceLocation firstSourceLocation() const override
{ return colonToken.isValid() ? identifierToken : propertyTypeToken; }
@@ -3334,7 +3339,7 @@ public:
: type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{
@@ -3391,7 +3396,7 @@ public:
: qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
{ kind = K; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return qualifiedTypeNameId->identifierToken; }
@@ -3413,17 +3418,18 @@ public:
: name(inlineComponentName), component(inlineComponent)
{ kind = K; }
- QStringRef name;
- UiObjectDefinition* component;
- SourceLocation componentToken;
-
SourceLocation lastSourceLocation() const override
{return component->lastSourceLocation();}
SourceLocation firstSourceLocation() const override
{return componentToken;}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
+
+ // attributes
+ QStringRef name;
+ UiObjectDefinition* component;
+ SourceLocation componentToken;
};
class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember
@@ -3455,7 +3461,7 @@ public:
return SourceLocation();
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3487,7 +3493,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return initializer->rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
@@ -3515,7 +3521,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return statement->lastSourceLocation(); }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3540,7 +3546,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbracketToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
UiQualifiedId *qualifiedId;
@@ -3584,7 +3590,7 @@ public:
return last->valueToken.isValid() ? last->valueToken : last->memberToken;
}
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
UiEnumMemberList *finish()
{
@@ -3618,7 +3624,7 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbraceToken; }
- void accept0(Visitor *visitor) override;
+ void accept0(BaseVisitor *visitor) override;
// attributes
SourceLocation enumToken;
@@ -3627,8 +3633,67 @@ public:
UiEnumMemberList *members;
};
-} } // namespace AST
+class QML_PARSER_EXPORT UiAnnotation: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiAnnotation)
+ UiAnnotation(UiQualifiedId *qualifiedTypeNameId,
+ UiObjectInitializer *initializer)
+ : qualifiedTypeNameId(qualifiedTypeNameId), initializer(initializer)
+ { kind = K; }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return qualifiedTypeNameId->identifierToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return initializer->rbraceToken; }
+
+// attributes
+ UiQualifiedId *qualifiedTypeNameId;
+ UiObjectInitializer *initializer;
+};
+
+class QML_PARSER_EXPORT UiAnnotationList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiAnnotationList)
+
+ UiAnnotationList(UiAnnotation *annotation)
+ : next(this), annotation(annotation)
+ { kind = K; }
+
+ UiAnnotationList(UiAnnotationList *previous, UiAnnotation *annotation)
+ : annotation(annotation)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return annotation->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return lastListElement(this)->annotation->lastSourceLocation(); }
+
+ UiAnnotationList *finish()
+ {
+ UiAnnotationList *head = next;
+ next = nullptr;
+ return head;
+ }
+
+// attributes
+ UiAnnotationList *next;
+ UiAnnotation *annotation;
+};
+
+} } // namespace AST
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index fe260e2bb5..8df0be7590 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
+class BaseVisitor;
class Visitor;
class Node;
class ExpressionNode;
@@ -151,7 +152,6 @@ class NamedImport;
class ImportClause;
class FromClause;
class ImportDeclaration;
-class ModuleItem;
class ESModule;
class DebuggerStatement;
class NestedExpression;
@@ -184,6 +184,8 @@ class UiEnumDeclaration;
class UiEnumMemberList;
class UiVersionSpecifier;
class UiRequired;
+class UiAnnotation;
+class UiAnnotationList;
} // namespace AST
} // namespace QQmlJS
diff --git a/src/qml/parser/qqmljsastvisitor.cpp b/src/qml/parser/qqmljsastvisitor.cpp
index 5ecac36423..7388eccebb 100644
--- a/src/qml/parser/qqmljsastvisitor.cpp
+++ b/src/qml/parser/qqmljsastvisitor.cpp
@@ -43,11 +43,13 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
-Visitor::Visitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth)
+Visitor::Visitor(quint16 parentRecursionDepth) : BaseVisitor(parentRecursionDepth)
{
}
-Visitor::~Visitor()
+BaseVisitor::BaseVisitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth) {}
+
+BaseVisitor::~BaseVisitor()
{
}
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index fcc48da1d3..8fbdb97ee2 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
namespace QQmlJS { namespace AST {
-class QML_PARSER_EXPORT Visitor
+class QML_PARSER_EXPORT BaseVisitor
{
public:
class RecursionDepthCheck
@@ -68,7 +68,7 @@ public:
RecursionDepthCheck(RecursionDepthCheck &&) = delete;
RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete;
- RecursionDepthCheck(Visitor *visitor) : m_visitor(visitor)
+ RecursionDepthCheck(BaseVisitor *visitor) : m_visitor(visitor)
{
++(m_visitor->m_recursionDepth);
}
@@ -84,338 +84,338 @@ public:
private:
static const quint16 s_recursionLimit = 4096;
- Visitor *m_visitor;
+ BaseVisitor *m_visitor;
};
- Visitor(quint16 parentRecursionDepth = 0);
- virtual ~Visitor();
+ BaseVisitor(quint16 parentRecursionDepth = 0);
+ virtual ~BaseVisitor();
- virtual bool preVisit(Node *) { return true; }
- virtual void postVisit(Node *) {}
+ virtual bool preVisit(Node *) = 0;
+ virtual void postVisit(Node *) = 0;
// Ui
- virtual bool visit(UiProgram *) { return true; }
- virtual bool visit(UiHeaderItemList *) { return true; }
- virtual bool visit(UiPragma *) { return true; }
- virtual bool visit(UiImport *) { return true; }
- virtual bool visit(UiPublicMember *) { return true; }
- virtual bool visit(UiSourceElement *) { return true; }
- virtual bool visit(UiObjectDefinition *) { return true; }
- virtual bool visit(UiObjectInitializer *) { return true; }
- virtual bool visit(UiObjectBinding *) { return true; }
- virtual bool visit(UiScriptBinding *) { return true; }
- virtual bool visit(UiArrayBinding *) { return true; }
- virtual bool visit(UiParameterList *) { return true; }
- virtual bool visit(UiObjectMemberList *) { return true; }
- virtual bool visit(UiArrayMemberList *) { return true; }
- virtual bool visit(UiQualifiedId *) { return true; }
- virtual bool visit(UiEnumDeclaration *) { return true; }
- virtual bool visit(UiEnumMemberList *) { return true; }
- virtual bool visit(UiVersionSpecifier *) { return true; }
- virtual bool visit(UiInlineComponent *) { return true; }
-
- virtual void endVisit(UiProgram *) {}
- virtual void endVisit(UiImport *) {}
- virtual void endVisit(UiHeaderItemList *) {}
- virtual void endVisit(UiPragma *) {}
- virtual void endVisit(UiPublicMember *) {}
- virtual void endVisit(UiSourceElement *) {}
- virtual void endVisit(UiObjectDefinition *) {}
- virtual void endVisit(UiObjectInitializer *) {}
- virtual void endVisit(UiObjectBinding *) {}
- virtual void endVisit(UiScriptBinding *) {}
- virtual void endVisit(UiArrayBinding *) {}
- virtual void endVisit(UiParameterList *) {}
- virtual void endVisit(UiObjectMemberList *) {}
- virtual void endVisit(UiArrayMemberList *) {}
- virtual void endVisit(UiQualifiedId *) {}
- virtual void endVisit(UiEnumDeclaration *) {}
- virtual void endVisit(UiEnumMemberList *) { }
- virtual void endVisit(UiVersionSpecifier *) {}
- virtual void endVisit(UiInlineComponent *) {}
+ virtual bool visit(UiProgram *) = 0;
+ virtual bool visit(UiHeaderItemList *) = 0;
+ virtual bool visit(UiPragma *) = 0;
+ virtual bool visit(UiImport *) = 0;
+ virtual bool visit(UiPublicMember *) = 0;
+ virtual bool visit(UiSourceElement *) = 0;
+ virtual bool visit(UiObjectDefinition *) = 0;
+ virtual bool visit(UiObjectInitializer *) = 0;
+ virtual bool visit(UiObjectBinding *) = 0;
+ virtual bool visit(UiScriptBinding *) = 0;
+ virtual bool visit(UiArrayBinding *) = 0;
+ virtual bool visit(UiParameterList *) = 0;
+ virtual bool visit(UiObjectMemberList *) = 0;
+ virtual bool visit(UiArrayMemberList *) = 0;
+ virtual bool visit(UiQualifiedId *) = 0;
+ virtual bool visit(UiEnumDeclaration *) = 0;
+ virtual bool visit(UiEnumMemberList *) = 0;
+ virtual bool visit(UiVersionSpecifier *) = 0;
+ virtual bool visit(UiInlineComponent *) = 0;
+ virtual bool visit(UiAnnotation *) = 0;
+ virtual bool visit(UiAnnotationList *) = 0;
+ virtual bool visit(UiRequired *) = 0;
+
+ virtual void endVisit(UiProgram *) = 0;
+ virtual void endVisit(UiImport *) = 0;
+ virtual void endVisit(UiHeaderItemList *) = 0;
+ virtual void endVisit(UiPragma *) = 0;
+ virtual void endVisit(UiPublicMember *) = 0;
+ virtual void endVisit(UiSourceElement *) = 0;
+ virtual void endVisit(UiObjectDefinition *) = 0;
+ virtual void endVisit(UiObjectInitializer *) = 0;
+ virtual void endVisit(UiObjectBinding *) = 0;
+ virtual void endVisit(UiScriptBinding *) = 0;
+ virtual void endVisit(UiArrayBinding *) = 0;
+ virtual void endVisit(UiParameterList *) = 0;
+ virtual void endVisit(UiObjectMemberList *) = 0;
+ virtual void endVisit(UiArrayMemberList *) = 0;
+ virtual void endVisit(UiQualifiedId *) = 0;
+ virtual void endVisit(UiEnumDeclaration *) = 0;
+ virtual void endVisit(UiEnumMemberList *) = 0;
+ virtual void endVisit(UiVersionSpecifier *) = 0;
+ virtual void endVisit(UiInlineComponent *) = 0;
+ virtual void endVisit(UiAnnotation *) = 0;
+ virtual void endVisit(UiAnnotationList *) = 0;
+ virtual void endVisit(UiRequired *) = 0;
// QQmlJS
- virtual bool visit(ThisExpression *) { return true; }
- virtual void endVisit(ThisExpression *) {}
-
- virtual bool visit(IdentifierExpression *) { return true; }
- virtual void endVisit(IdentifierExpression *) {}
+ virtual bool visit(ThisExpression *) = 0;
+ virtual void endVisit(ThisExpression *) = 0;
- virtual bool visit(NullExpression *) { return true; }
- virtual void endVisit(NullExpression *) {}
+ virtual bool visit(IdentifierExpression *) = 0;
+ virtual void endVisit(IdentifierExpression *) = 0;
- virtual bool visit(TrueLiteral *) { return true; }
- virtual void endVisit(TrueLiteral *) {}
+ virtual bool visit(NullExpression *) = 0;
+ virtual void endVisit(NullExpression *) = 0;
- virtual bool visit(FalseLiteral *) { return true; }
- virtual void endVisit(FalseLiteral *) {}
+ virtual bool visit(TrueLiteral *) = 0;
+ virtual void endVisit(TrueLiteral *) = 0;
- virtual bool visit(SuperLiteral *) { return true; }
- virtual void endVisit(SuperLiteral *) {}
+ virtual bool visit(FalseLiteral *) = 0;
+ virtual void endVisit(FalseLiteral *) = 0;
- virtual bool visit(StringLiteral *) { return true; }
- virtual void endVisit(StringLiteral *) {}
+ virtual bool visit(SuperLiteral *) = 0;
+ virtual void endVisit(SuperLiteral *) = 0;
- virtual bool visit(TemplateLiteral *) { return true; }
- virtual void endVisit(TemplateLiteral *) {}
+ virtual bool visit(StringLiteral *) = 0;
+ virtual void endVisit(StringLiteral *) = 0;
- virtual bool visit(NumericLiteral *) { return true; }
- virtual void endVisit(NumericLiteral *) {}
+ virtual bool visit(TemplateLiteral *) = 0;
+ virtual void endVisit(TemplateLiteral *) = 0;
- virtual bool visit(RegExpLiteral *) { return true; }
- virtual void endVisit(RegExpLiteral *) {}
+ virtual bool visit(NumericLiteral *) = 0;
+ virtual void endVisit(NumericLiteral *) = 0;
- virtual bool visit(ArrayPattern *) { return true; }
- virtual void endVisit(ArrayPattern *) {}
+ virtual bool visit(RegExpLiteral *) = 0;
+ virtual void endVisit(RegExpLiteral *) = 0;
- virtual bool visit(ObjectPattern *) { return true; }
- virtual void endVisit(ObjectPattern *) {}
+ virtual bool visit(ArrayPattern *) = 0;
+ virtual void endVisit(ArrayPattern *) = 0;
- virtual bool visit(PatternElementList *) { return true; }
- virtual void endVisit(PatternElementList *) {}
+ virtual bool visit(ObjectPattern *) = 0;
+ virtual void endVisit(ObjectPattern *) = 0;
- virtual bool visit(PatternPropertyList *) { return true; }
- virtual void endVisit(PatternPropertyList *) {}
+ virtual bool visit(PatternElementList *) = 0;
+ virtual void endVisit(PatternElementList *) = 0;
- virtual bool visit(PatternElement *) { return true; }
- virtual void endVisit(PatternElement *) {}
+ virtual bool visit(PatternPropertyList *) = 0;
+ virtual void endVisit(PatternPropertyList *) = 0;
- virtual bool visit(PatternProperty *) { return true; }
- virtual void endVisit(PatternProperty *) {}
+ virtual bool visit(PatternElement *) = 0;
+ virtual void endVisit(PatternElement *) = 0;
- virtual bool visit(Elision *) { return true; }
- virtual void endVisit(Elision *) {}
+ virtual bool visit(PatternProperty *) = 0;
+ virtual void endVisit(PatternProperty *) = 0;
- virtual bool visit(NestedExpression *) { return true; }
- virtual void endVisit(NestedExpression *) {}
+ virtual bool visit(Elision *) = 0;
+ virtual void endVisit(Elision *) = 0;
- virtual bool visit(IdentifierPropertyName *) { return true; }
- virtual void endVisit(IdentifierPropertyName *) {}
+ virtual bool visit(NestedExpression *) = 0;
+ virtual void endVisit(NestedExpression *) = 0;
- virtual bool visit(StringLiteralPropertyName *) { return true; }
- virtual void endVisit(StringLiteralPropertyName *) {}
+ virtual bool visit(IdentifierPropertyName *) = 0;
+ virtual void endVisit(IdentifierPropertyName *) = 0;
- virtual bool visit(NumericLiteralPropertyName *) { return true; }
- virtual void endVisit(NumericLiteralPropertyName *) {}
+ virtual bool visit(StringLiteralPropertyName *) = 0;
+ virtual void endVisit(StringLiteralPropertyName *) = 0;
- virtual bool visit(ComputedPropertyName *) { return true; }
- virtual void endVisit(ComputedPropertyName *) {}
+ virtual bool visit(NumericLiteralPropertyName *) = 0;
+ virtual void endVisit(NumericLiteralPropertyName *) = 0;
- virtual bool visit(ArrayMemberExpression *) { return true; }
- virtual void endVisit(ArrayMemberExpression *) {}
+ virtual bool visit(ComputedPropertyName *) = 0;
+ virtual void endVisit(ComputedPropertyName *) = 0;
- virtual bool visit(FieldMemberExpression *) { return true; }
- virtual void endVisit(FieldMemberExpression *) {}
+ virtual bool visit(ArrayMemberExpression *) = 0;
+ virtual void endVisit(ArrayMemberExpression *) = 0;
- virtual bool visit(TaggedTemplate *) { return true; }
- virtual void endVisit(TaggedTemplate *) {}
+ virtual bool visit(FieldMemberExpression *) = 0;
+ virtual void endVisit(FieldMemberExpression *) = 0;
- virtual bool visit(NewMemberExpression *) { return true; }
- virtual void endVisit(NewMemberExpression *) {}
+ virtual bool visit(TaggedTemplate *) = 0;
+ virtual void endVisit(TaggedTemplate *) = 0;
- virtual bool visit(NewExpression *) { return true; }
- virtual void endVisit(NewExpression *) {}
+ virtual bool visit(NewMemberExpression *) = 0;
+ virtual void endVisit(NewMemberExpression *) = 0;
- virtual bool visit(CallExpression *) { return true; }
- virtual void endVisit(CallExpression *) {}
+ virtual bool visit(NewExpression *) = 0;
+ virtual void endVisit(NewExpression *) = 0;
- virtual bool visit(ArgumentList *) { return true; }
- virtual void endVisit(ArgumentList *) {}
+ virtual bool visit(CallExpression *) = 0;
+ virtual void endVisit(CallExpression *) = 0;
- virtual bool visit(PostIncrementExpression *) { return true; }
- virtual void endVisit(PostIncrementExpression *) {}
+ virtual bool visit(ArgumentList *) = 0;
+ virtual void endVisit(ArgumentList *) = 0;
- virtual bool visit(PostDecrementExpression *) { return true; }
- virtual void endVisit(PostDecrementExpression *) {}
+ virtual bool visit(PostIncrementExpression *) = 0;
+ virtual void endVisit(PostIncrementExpression *) = 0;
- virtual bool visit(DeleteExpression *) { return true; }
- virtual void endVisit(DeleteExpression *) {}
+ virtual bool visit(PostDecrementExpression *) = 0;
+ virtual void endVisit(PostDecrementExpression *) = 0;
- virtual bool visit(VoidExpression *) { return true; }
- virtual void endVisit(VoidExpression *) {}
+ virtual bool visit(DeleteExpression *) = 0;
+ virtual void endVisit(DeleteExpression *) = 0;
- virtual bool visit(TypeOfExpression *) { return true; }
- virtual void endVisit(TypeOfExpression *) {}
+ virtual bool visit(VoidExpression *) = 0;
+ virtual void endVisit(VoidExpression *) = 0;
- virtual bool visit(PreIncrementExpression *) { return true; }
- virtual void endVisit(PreIncrementExpression *) {}
+ virtual bool visit(TypeOfExpression *) = 0;
+ virtual void endVisit(TypeOfExpression *) = 0;
- virtual bool visit(PreDecrementExpression *) { return true; }
- virtual void endVisit(PreDecrementExpression *) {}
+ virtual bool visit(PreIncrementExpression *) = 0;
+ virtual void endVisit(PreIncrementExpression *) = 0;
- virtual bool visit(UnaryPlusExpression *) { return true; }
- virtual void endVisit(UnaryPlusExpression *) {}
+ virtual bool visit(PreDecrementExpression *) = 0;
+ virtual void endVisit(PreDecrementExpression *) = 0;
- virtual bool visit(UnaryMinusExpression *) { return true; }
- virtual void endVisit(UnaryMinusExpression *) {}
+ virtual bool visit(UnaryPlusExpression *) = 0;
+ virtual void endVisit(UnaryPlusExpression *) = 0;
- virtual bool visit(TildeExpression *) { return true; }
- virtual void endVisit(TildeExpression *) {}
+ virtual bool visit(UnaryMinusExpression *) = 0;
+ virtual void endVisit(UnaryMinusExpression *) = 0;
- virtual bool visit(NotExpression *) { return true; }
- virtual void endVisit(NotExpression *) {}
+ virtual bool visit(TildeExpression *) = 0;
+ virtual void endVisit(TildeExpression *) = 0;
- virtual bool visit(BinaryExpression *) { return true; }
- virtual void endVisit(BinaryExpression *) {}
+ virtual bool visit(NotExpression *) = 0;
+ virtual void endVisit(NotExpression *) = 0;
- virtual bool visit(ConditionalExpression *) { return true; }
- virtual void endVisit(ConditionalExpression *) {}
+ virtual bool visit(BinaryExpression *) = 0;
+ virtual void endVisit(BinaryExpression *) = 0;
- virtual bool visit(Expression *) { return true; }
- virtual void endVisit(Expression *) {}
+ virtual bool visit(ConditionalExpression *) = 0;
+ virtual void endVisit(ConditionalExpression *) = 0;
- virtual bool visit(Block *) { return true; }
- virtual void endVisit(Block *) {}
+ virtual bool visit(Expression *) = 0;
+ virtual void endVisit(Expression *) = 0;
- virtual bool visit(StatementList *) { return true; }
- virtual void endVisit(StatementList *) {}
+ virtual bool visit(Block *) = 0;
+ virtual void endVisit(Block *) = 0;
- virtual bool visit(VariableStatement *) { return true; }
- virtual void endVisit(VariableStatement *) {}
+ virtual bool visit(StatementList *) = 0;
+ virtual void endVisit(StatementList *) = 0;
- virtual bool visit(VariableDeclarationList *) { return true; }
- virtual void endVisit(VariableDeclarationList *) {}
+ virtual bool visit(VariableStatement *) = 0;
+ virtual void endVisit(VariableStatement *) = 0;
- virtual bool visit(EmptyStatement *) { return true; }
- virtual void endVisit(EmptyStatement *) {}
+ virtual bool visit(VariableDeclarationList *) = 0;
+ virtual void endVisit(VariableDeclarationList *) = 0;
- virtual bool visit(ExpressionStatement *) { return true; }
- virtual void endVisit(ExpressionStatement *) {}
+ virtual bool visit(EmptyStatement *) = 0;
+ virtual void endVisit(EmptyStatement *) = 0;
- virtual bool visit(IfStatement *) { return true; }
- virtual void endVisit(IfStatement *) {}
+ virtual bool visit(ExpressionStatement *) = 0;
+ virtual void endVisit(ExpressionStatement *) = 0;
- virtual bool visit(DoWhileStatement *) { return true; }
- virtual void endVisit(DoWhileStatement *) {}
+ virtual bool visit(IfStatement *) = 0;
+ virtual void endVisit(IfStatement *) = 0;
- virtual bool visit(WhileStatement *) { return true; }
- virtual void endVisit(WhileStatement *) {}
+ virtual bool visit(DoWhileStatement *) = 0;
+ virtual void endVisit(DoWhileStatement *) = 0;
- virtual bool visit(ForStatement *) { return true; }
- virtual void endVisit(ForStatement *) {}
+ virtual bool visit(WhileStatement *) = 0;
+ virtual void endVisit(WhileStatement *) = 0;
- virtual bool visit(ForEachStatement *) { return true; }
- virtual void endVisit(ForEachStatement *) {}
+ virtual bool visit(ForStatement *) = 0;
+ virtual void endVisit(ForStatement *) = 0;
- virtual bool visit(ContinueStatement *) { return true; }
- virtual void endVisit(ContinueStatement *) {}
+ virtual bool visit(ForEachStatement *) = 0;
+ virtual void endVisit(ForEachStatement *) = 0;
- virtual bool visit(BreakStatement *) { return true; }
- virtual void endVisit(BreakStatement *) {}
+ virtual bool visit(ContinueStatement *) = 0;
+ virtual void endVisit(ContinueStatement *) = 0;
- virtual bool visit(ReturnStatement *) { return true; }
- virtual void endVisit(ReturnStatement *) {}
+ virtual bool visit(BreakStatement *) = 0;
+ virtual void endVisit(BreakStatement *) = 0;
- virtual bool visit(YieldExpression *) { return true; }
- virtual void endVisit(YieldExpression *) {}
+ virtual bool visit(ReturnStatement *) = 0;
+ virtual void endVisit(ReturnStatement *) = 0;
- virtual bool visit(WithStatement *) { return true; }
- virtual void endVisit(WithStatement *) {}
+ virtual bool visit(YieldExpression *) = 0;
+ virtual void endVisit(YieldExpression *) = 0;
- virtual bool visit(SwitchStatement *) { return true; }
- virtual void endVisit(SwitchStatement *) {}
+ virtual bool visit(WithStatement *) = 0;
+ virtual void endVisit(WithStatement *) = 0;
- virtual bool visit(CaseBlock *) { return true; }
- virtual void endVisit(CaseBlock *) {}
+ virtual bool visit(SwitchStatement *) = 0;
+ virtual void endVisit(SwitchStatement *) = 0;
- virtual bool visit(CaseClauses *) { return true; }
- virtual void endVisit(CaseClauses *) {}
+ virtual bool visit(CaseBlock *) = 0;
+ virtual void endVisit(CaseBlock *) = 0;
- virtual bool visit(CaseClause *) { return true; }
- virtual void endVisit(CaseClause *) {}
+ virtual bool visit(CaseClauses *) = 0;
+ virtual void endVisit(CaseClauses *) = 0;
- virtual bool visit(DefaultClause *) { return true; }
- virtual void endVisit(DefaultClause *) {}
+ virtual bool visit(CaseClause *) = 0;
+ virtual void endVisit(CaseClause *) = 0;
- virtual bool visit(LabelledStatement *) { return true; }
- virtual void endVisit(LabelledStatement *) {}
+ virtual bool visit(DefaultClause *) = 0;
+ virtual void endVisit(DefaultClause *) = 0;
- virtual bool visit(ThrowStatement *) { return true; }
- virtual void endVisit(ThrowStatement *) {}
+ virtual bool visit(LabelledStatement *) = 0;
+ virtual void endVisit(LabelledStatement *) = 0;
- virtual bool visit(TryStatement *) { return true; }
- virtual void endVisit(TryStatement *) {}
+ virtual bool visit(ThrowStatement *) = 0;
+ virtual void endVisit(ThrowStatement *) = 0;
- virtual bool visit(Catch *) { return true; }
- virtual void endVisit(Catch *) {}
+ virtual bool visit(TryStatement *) = 0;
+ virtual void endVisit(TryStatement *) = 0;
- virtual bool visit(Finally *) { return true; }
- virtual void endVisit(Finally *) {}
+ virtual bool visit(Catch *) = 0;
+ virtual void endVisit(Catch *) = 0;
- virtual bool visit(FunctionDeclaration *) { return true; }
- virtual void endVisit(FunctionDeclaration *) {}
+ virtual bool visit(Finally *) = 0;
+ virtual void endVisit(Finally *) = 0;
- virtual bool visit(FunctionExpression *) { return true; }
- virtual void endVisit(FunctionExpression *) {}
+ virtual bool visit(FunctionDeclaration *) = 0;
+ virtual void endVisit(FunctionDeclaration *) = 0;
- virtual bool visit(FormalParameterList *) { return true; }
- virtual void endVisit(FormalParameterList *) {}
+ virtual bool visit(FunctionExpression *) = 0;
+ virtual void endVisit(FunctionExpression *) = 0;
- virtual bool visit(ClassExpression *) { return true; }
- virtual void endVisit(ClassExpression *) {}
+ virtual bool visit(FormalParameterList *) = 0;
+ virtual void endVisit(FormalParameterList *) = 0;
- virtual bool visit(ClassDeclaration *) { return true; }
- virtual void endVisit(ClassDeclaration *) {}
+ virtual bool visit(ClassExpression *) = 0;
+ virtual void endVisit(ClassExpression *) = 0;
- virtual bool visit(ClassElementList *) { return true; }
- virtual void endVisit(ClassElementList *) {}
+ virtual bool visit(ClassDeclaration *) = 0;
+ virtual void endVisit(ClassDeclaration *) = 0;
- virtual bool visit(Program *) { return true; }
- virtual void endVisit(Program *) {}
+ virtual bool visit(ClassElementList *) = 0;
+ virtual void endVisit(ClassElementList *) = 0;
- virtual bool visit(NameSpaceImport *) { return true; }
- virtual void endVisit(NameSpaceImport *) {}
+ virtual bool visit(Program *) = 0;
+ virtual void endVisit(Program *) = 0;
- virtual bool visit(ImportSpecifier *) { return true; }
- virtual void endVisit(ImportSpecifier *) {}
+ virtual bool visit(NameSpaceImport *) = 0;
+ virtual void endVisit(NameSpaceImport *) = 0;
- virtual bool visit(ImportsList *) { return true; }
- virtual void endVisit(ImportsList *) {}
+ virtual bool visit(ImportSpecifier *) = 0;
+ virtual void endVisit(ImportSpecifier *) = 0;
- virtual bool visit(NamedImports *) { return true; }
- virtual void endVisit(NamedImports *) {}
+ virtual bool visit(ImportsList *) = 0;
+ virtual void endVisit(ImportsList *) = 0;
- virtual bool visit(FromClause *) { return true; }
- virtual void endVisit(FromClause *) {}
+ virtual bool visit(NamedImports *) = 0;
+ virtual void endVisit(NamedImports *) = 0;
- virtual bool visit(ImportClause *) { return true; }
- virtual void endVisit(ImportClause *) {}
+ virtual bool visit(FromClause *) = 0;
+ virtual void endVisit(FromClause *) = 0;
- virtual bool visit(ImportDeclaration *) { return true; }
- virtual void endVisit(ImportDeclaration *) {}
+ virtual bool visit(ImportClause *) = 0;
+ virtual void endVisit(ImportClause *) = 0;
- virtual bool visit(ExportSpecifier *) { return true; }
- virtual void endVisit(ExportSpecifier *) {}
+ virtual bool visit(ImportDeclaration *) = 0;
+ virtual void endVisit(ImportDeclaration *) = 0;
- virtual bool visit(ExportsList *) { return true; }
- virtual void endVisit(ExportsList *) {}
+ virtual bool visit(ExportSpecifier *) = 0;
+ virtual void endVisit(ExportSpecifier *) = 0;
- virtual bool visit(ExportClause *) { return true; }
- virtual void endVisit(ExportClause *) {}
+ virtual bool visit(ExportsList *) = 0;
+ virtual void endVisit(ExportsList *) = 0;
- virtual bool visit(ExportDeclaration *) { return true; }
- virtual void endVisit(ExportDeclaration *) {}
+ virtual bool visit(ExportClause *) = 0;
+ virtual void endVisit(ExportClause *) = 0;
- virtual bool visit(ModuleItem *) { return true; }
- virtual void endVisit(ModuleItem *) {}
+ virtual bool visit(ExportDeclaration *) = 0;
+ virtual void endVisit(ExportDeclaration *) = 0;
- virtual bool visit(ESModule *) { return true; }
- virtual void endVisit(ESModule *) {}
+ virtual bool visit(ESModule *) = 0;
+ virtual void endVisit(ESModule *) = 0;
- virtual bool visit(DebuggerStatement *) { return true; }
- virtual void endVisit(DebuggerStatement *) {}
+ virtual bool visit(DebuggerStatement *) = 0;
+ virtual void endVisit(DebuggerStatement *) = 0;
- virtual bool visit(Type *) { return true; }
- virtual void endVisit(Type *) {}
+ virtual bool visit(Type *) = 0;
+ virtual void endVisit(Type *) = 0;
- virtual bool visit(TypeArgumentList *) { return true; }
- virtual void endVisit(TypeArgumentList *) {}
+ virtual bool visit(TypeArgumentList *) = 0;
+ virtual void endVisit(TypeArgumentList *) = 0;
- virtual bool visit(TypeAnnotation *) { return true; }
- virtual void endVisit(TypeAnnotation *) {}
-
- virtual bool visit(UiRequired *) { return true; }
- virtual void endVisit(UiRequired *) {}
+ virtual bool visit(TypeAnnotation *) = 0;
+ virtual void endVisit(TypeAnnotation *) = 0;
virtual void throwRecursionDepthError() = 0;
@@ -426,6 +426,339 @@ protected:
friend class RecursionDepthCheck;
};
+class QML_PARSER_EXPORT Visitor: public BaseVisitor
+{
+public:
+ Visitor(quint16 parentRecursionDepth = 0);
+
+ bool preVisit(Node *) override { return true; }
+ void postVisit(Node *) override {}
+
+ // Ui
+ bool visit(UiProgram *) override { return true; }
+ bool visit(UiHeaderItemList *) override { return true; }
+ bool visit(UiPragma *) override { return true; }
+ bool visit(UiImport *) override { return true; }
+ bool visit(UiPublicMember *) override { return true; }
+ bool visit(UiSourceElement *) override { return true; }
+ bool visit(UiObjectDefinition *) override { return true; }
+ bool visit(UiObjectInitializer *) override { return true; }
+ bool visit(UiObjectBinding *) override { return true; }
+ bool visit(UiScriptBinding *) override { return true; }
+ bool visit(UiArrayBinding *) override { return true; }
+ bool visit(UiParameterList *) override { return true; }
+ bool visit(UiObjectMemberList *) override { return true; }
+ bool visit(UiArrayMemberList *) override { return true; }
+ bool visit(UiQualifiedId *) override { return true; }
+ bool visit(UiEnumDeclaration *) override { return true; }
+ bool visit(UiEnumMemberList *) override { return true; }
+ bool visit(UiVersionSpecifier *) override { return true; }
+ bool visit(UiInlineComponent *) override { return true; }
+ bool visit(UiAnnotation *) override { return true; }
+ bool visit(UiAnnotationList *) override { return true; }
+ bool visit(UiRequired *) override { return true; }
+
+ void endVisit(UiProgram *) override {}
+ void endVisit(UiImport *) override {}
+ void endVisit(UiHeaderItemList *) override {}
+ void endVisit(UiPragma *) override {}
+ void endVisit(UiPublicMember *) override {}
+ void endVisit(UiSourceElement *) override {}
+ void endVisit(UiObjectDefinition *) override {}
+ void endVisit(UiObjectInitializer *) override {}
+ void endVisit(UiObjectBinding *) override {}
+ void endVisit(UiScriptBinding *) override {}
+ void endVisit(UiArrayBinding *) override {}
+ void endVisit(UiParameterList *) override {}
+ void endVisit(UiObjectMemberList *) override {}
+ void endVisit(UiArrayMemberList *) override {}
+ void endVisit(UiQualifiedId *) override {}
+ void endVisit(UiEnumDeclaration *) override {}
+ void endVisit(UiEnumMemberList *) override {}
+ void endVisit(UiVersionSpecifier *) override {}
+ void endVisit(UiInlineComponent *) override {}
+ void endVisit(UiAnnotation *) override {}
+ void endVisit(UiAnnotationList *) override {}
+ void endVisit(UiRequired *) override {}
+
+ // QQmlJS
+ bool visit(ThisExpression *) override { return true; }
+ void endVisit(ThisExpression *) override {}
+
+ bool visit(IdentifierExpression *) override { return true; }
+ void endVisit(IdentifierExpression *) override {}
+
+ bool visit(NullExpression *) override { return true; }
+ void endVisit(NullExpression *) override {}
+
+ bool visit(TrueLiteral *) override { return true; }
+ void endVisit(TrueLiteral *) override {}
+
+ bool visit(FalseLiteral *) override { return true; }
+ void endVisit(FalseLiteral *) override {}
+
+ bool visit(SuperLiteral *) override { return true; }
+ void endVisit(SuperLiteral *) override {}
+
+ bool visit(StringLiteral *) override { return true; }
+ void endVisit(StringLiteral *) override {}
+
+ bool visit(TemplateLiteral *) override { return true; }
+ void endVisit(TemplateLiteral *) override {}
+
+ bool visit(NumericLiteral *) override { return true; }
+ void endVisit(NumericLiteral *) override {}
+
+ bool visit(RegExpLiteral *) override { return true; }
+ void endVisit(RegExpLiteral *) override {}
+
+ bool visit(ArrayPattern *) override { return true; }
+ void endVisit(ArrayPattern *) override {}
+
+ bool visit(ObjectPattern *) override { return true; }
+ void endVisit(ObjectPattern *) override {}
+
+ bool visit(PatternElementList *) override { return true; }
+ void endVisit(PatternElementList *) override {}
+
+ bool visit(PatternPropertyList *) override { return true; }
+ void endVisit(PatternPropertyList *) override {}
+
+ bool visit(PatternElement *) override { return true; }
+ void endVisit(PatternElement *) override {}
+
+ bool visit(PatternProperty *) override { return true; }
+ void endVisit(PatternProperty *) override {}
+
+ bool visit(Elision *) override { return true; }
+ void endVisit(Elision *) override {}
+
+ bool visit(NestedExpression *) override { return true; }
+ void endVisit(NestedExpression *) override {}
+
+ bool visit(IdentifierPropertyName *) override { return true; }
+ void endVisit(IdentifierPropertyName *) override {}
+
+ bool visit(StringLiteralPropertyName *) override { return true; }
+ void endVisit(StringLiteralPropertyName *) override {}
+
+ bool visit(NumericLiteralPropertyName *) override { return true; }
+ void endVisit(NumericLiteralPropertyName *) override {}
+
+ bool visit(ComputedPropertyName *) override { return true; }
+ void endVisit(ComputedPropertyName *) override {}
+
+ bool visit(ArrayMemberExpression *) override { return true; }
+ void endVisit(ArrayMemberExpression *) override {}
+
+ bool visit(FieldMemberExpression *) override { return true; }
+ void endVisit(FieldMemberExpression *) override {}
+
+ bool visit(TaggedTemplate *) override { return true; }
+ void endVisit(TaggedTemplate *) override {}
+
+ bool visit(NewMemberExpression *) override { return true; }
+ void endVisit(NewMemberExpression *) override {}
+
+ bool visit(NewExpression *) override { return true; }
+ void endVisit(NewExpression *) override {}
+
+ bool visit(CallExpression *) override { return true; }
+ void endVisit(CallExpression *) override {}
+
+ bool visit(ArgumentList *) override { return true; }
+ void endVisit(ArgumentList *) override {}
+
+ bool visit(PostIncrementExpression *) override { return true; }
+ void endVisit(PostIncrementExpression *) override {}
+
+ bool visit(PostDecrementExpression *) override { return true; }
+ void endVisit(PostDecrementExpression *) override {}
+
+ bool visit(DeleteExpression *) override { return true; }
+ void endVisit(DeleteExpression *) override {}
+
+ bool visit(VoidExpression *) override { return true; }
+ void endVisit(VoidExpression *) override {}
+
+ bool visit(TypeOfExpression *) override { return true; }
+ void endVisit(TypeOfExpression *) override {}
+
+ bool visit(PreIncrementExpression *) override { return true; }
+ void endVisit(PreIncrementExpression *) override {}
+
+ bool visit(PreDecrementExpression *) override { return true; }
+ void endVisit(PreDecrementExpression *) override {}
+
+ bool visit(UnaryPlusExpression *) override { return true; }
+ void endVisit(UnaryPlusExpression *) override {}
+
+ bool visit(UnaryMinusExpression *) override { return true; }
+ void endVisit(UnaryMinusExpression *) override {}
+
+ bool visit(TildeExpression *) override { return true; }
+ void endVisit(TildeExpression *) override {}
+
+ bool visit(NotExpression *) override { return true; }
+ void endVisit(NotExpression *) override {}
+
+ bool visit(BinaryExpression *) override { return true; }
+ void endVisit(BinaryExpression *) override {}
+
+ bool visit(ConditionalExpression *) override { return true; }
+ void endVisit(ConditionalExpression *) override {}
+
+ bool visit(Expression *) override { return true; }
+ void endVisit(Expression *) override {}
+
+ bool visit(Block *) override { return true; }
+ void endVisit(Block *) override {}
+
+ bool visit(StatementList *) override { return true; }
+ void endVisit(StatementList *) override {}
+
+ bool visit(VariableStatement *) override { return true; }
+ void endVisit(VariableStatement *) override {}
+
+ bool visit(VariableDeclarationList *) override { return true; }
+ void endVisit(VariableDeclarationList *) override {}
+
+ bool visit(EmptyStatement *) override { return true; }
+ void endVisit(EmptyStatement *) override {}
+
+ bool visit(ExpressionStatement *) override { return true; }
+ void endVisit(ExpressionStatement *) override {}
+
+ bool visit(IfStatement *) override { return true; }
+ void endVisit(IfStatement *) override {}
+
+ bool visit(DoWhileStatement *) override { return true; }
+ void endVisit(DoWhileStatement *) override {}
+
+ bool visit(WhileStatement *) override { return true; }
+ void endVisit(WhileStatement *) override {}
+
+ bool visit(ForStatement *) override { return true; }
+ void endVisit(ForStatement *) override {}
+
+ bool visit(ForEachStatement *) override { return true; }
+ void endVisit(ForEachStatement *) override {}
+
+ bool visit(ContinueStatement *) override { return true; }
+ void endVisit(ContinueStatement *) override {}
+
+ bool visit(BreakStatement *) override { return true; }
+ void endVisit(BreakStatement *) override {}
+
+ bool visit(ReturnStatement *) override { return true; }
+ void endVisit(ReturnStatement *) override {}
+
+ bool visit(YieldExpression *) override { return true; }
+ void endVisit(YieldExpression *) override {}
+
+ bool visit(WithStatement *) override { return true; }
+ void endVisit(WithStatement *) override {}
+
+ bool visit(SwitchStatement *) override { return true; }
+ void endVisit(SwitchStatement *) override {}
+
+ bool visit(CaseBlock *) override { return true; }
+ void endVisit(CaseBlock *) override {}
+
+ bool visit(CaseClauses *) override { return true; }
+ void endVisit(CaseClauses *) override {}
+
+ bool visit(CaseClause *) override { return true; }
+ void endVisit(CaseClause *) override {}
+
+ bool visit(DefaultClause *) override { return true; }
+ void endVisit(DefaultClause *) override {}
+
+ bool visit(LabelledStatement *) override { return true; }
+ void endVisit(LabelledStatement *) override {}
+
+ bool visit(ThrowStatement *) override { return true; }
+ void endVisit(ThrowStatement *) override {}
+
+ bool visit(TryStatement *) override { return true; }
+ void endVisit(TryStatement *) override {}
+
+ bool visit(Catch *) override { return true; }
+ void endVisit(Catch *) override {}
+
+ bool visit(Finally *) override { return true; }
+ void endVisit(Finally *) override {}
+
+ bool visit(FunctionDeclaration *) override { return true; }
+ void endVisit(FunctionDeclaration *) override {}
+
+ bool visit(FunctionExpression *) override { return true; }
+ void endVisit(FunctionExpression *) override {}
+
+ bool visit(FormalParameterList *) override { return true; }
+ void endVisit(FormalParameterList *) override {}
+
+ bool visit(ClassExpression *) override { return true; }
+ void endVisit(ClassExpression *) override {}
+
+ bool visit(ClassDeclaration *) override { return true; }
+ void endVisit(ClassDeclaration *) override {}
+
+ bool visit(ClassElementList *) override { return true; }
+ void endVisit(ClassElementList *) override {}
+
+ bool visit(Program *) override { return true; }
+ void endVisit(Program *) override {}
+
+ bool visit(NameSpaceImport *) override { return true; }
+ void endVisit(NameSpaceImport *) override {}
+
+ bool visit(ImportSpecifier *) override { return true; }
+ void endVisit(ImportSpecifier *) override {}
+
+ bool visit(ImportsList *) override { return true; }
+ void endVisit(ImportsList *) override {}
+
+ bool visit(NamedImports *) override { return true; }
+ void endVisit(NamedImports *) override {}
+
+ bool visit(FromClause *) override { return true; }
+ void endVisit(FromClause *) override {}
+
+ bool visit(ImportClause *) override { return true; }
+ void endVisit(ImportClause *) override {}
+
+ bool visit(ImportDeclaration *) override { return true; }
+ void endVisit(ImportDeclaration *) override {}
+
+ bool visit(ExportSpecifier *) override { return true; }
+ void endVisit(ExportSpecifier *) override {}
+
+ bool visit(ExportsList *) override { return true; }
+ void endVisit(ExportsList *) override {}
+
+ bool visit(ExportClause *) override { return true; }
+ void endVisit(ExportClause *) override {}
+
+ bool visit(ExportDeclaration *) override { return true; }
+ void endVisit(ExportDeclaration *) override {}
+
+ bool visit(ESModule *) override { return true; }
+ void endVisit(ESModule *) override {}
+
+ bool visit(DebuggerStatement *) override { return true; }
+ void endVisit(DebuggerStatement *) override {}
+
+ bool visit(Type *) override { return true; }
+ void endVisit(Type *) override {}
+
+ bool visit(TypeArgumentList *) override { return true; }
+ void endVisit(TypeArgumentList *) override {}
+
+ bool visit(TypeAnnotation *) override { return true; }
+ void endVisit(TypeAnnotation *) override {}
+};
+
} } // namespace AST
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index c71e6b68b8..ea6f15e9c2 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -46,6 +46,7 @@
#include <private/qqmlmetatypedata_p.h>
#include <private/qqmltype_p_p.h>
#include <private/qqmltypemodule_p_p.h>
+#include <private/qqmltypenotavailable_p.h>
#include <QtCore/qmutex.h>
@@ -358,4 +359,40 @@ void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
}
}
+namespace QQmlPrivate {
+ template<>
+ void qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject)
+ {
+ using T = QQmlTypeNotAvailable;
+
+ QML_GETTYPENAMES
+
+ RegisterTypeAndRevisions type = {
+ 0,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ 0,
+ nullptr,
+
+ uri,
+ QTypeRevision::fromMajorVersion(versionMajor),
+
+ &QQmlTypeNotAvailable::staticMetaObject,
+ classInfoMetaObject,
+
+ attachedPropertiesFunc<T>(),
+ attachedPropertiesMetaObject<T>(),
+
+ StaticCastSelector<T, QQmlParserStatus>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
+ StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
+
+ nullptr, nullptr, qmlCreateCustomParser<T>
+ };
+
+ qmlregister(TypeAndRevisionsRegistration, &type);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 096bef7e4b..b9445e48a8 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -120,6 +120,16 @@
template<typename T, typename... Args> \
friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+#define QML_INTERFACE \
+ Q_CLASSINFO("QML.Element", "anonymous") \
+ enum class QmlIsInterface {yes = true}; \
+ template<typename, typename> friend struct QML_PRIVATE_NAMESPACE::QmlInterface; \
+ template<typename T, typename... Args> \
+ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor);
+
+#define QML_UNAVAILABLE \
+ QML_FOREIGN(QQmlTypeNotAvailable)
+
enum { /* TYPEINFO flags */
QML_HAS_ATTACHED_PROPERTIES = 0x01
};
@@ -183,7 +193,8 @@ QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegi
}
#endif
-int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
+int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor,
+ const char *qmlName, const QString& message);
template<typename T>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
@@ -422,9 +433,8 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
-
template<typename T, typename E>
-int qmlRegisterExtendedType()
+int qmlRegisterExtendedType(const char *uri, int versionMajor)
{
QML_GETTYPENAMES
@@ -437,7 +447,7 @@ int qmlRegisterExtendedType()
nullptr,
QString(),
- nullptr, QTypeRevision::zero(), nullptr, &T::staticMetaObject,
+ uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -455,6 +465,15 @@ int qmlRegisterExtendedType()
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+#if QT_DEPRECATED_SINCE(5, 15)
+template<typename T, typename E>
+QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterExtendedType(uri, versionMajor) instead")
+int qmlRegisterExtendedType()
+{
+ return qmlRegisterExtendedType<T, E>("", 0);
+}
+#endif
+
template<typename T, typename E>
int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName)
@@ -494,7 +513,9 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+#if QT_DEPRECATED_SINCE(5, 15)
template<typename T>
+QT_DEPRECATED_VERSION_X_5_15("Use qmlRegisterInterface(uri, versionMajor) instead")
int qmlRegisterInterface(const char *typeName)
{
QByteArray name(typeName);
@@ -503,12 +524,33 @@ int qmlRegisterInterface(const char *typeName)
QByteArray listName("QQmlListProperty<" + name + '>');
QQmlPrivate::RegisterInterface qmlInterface = {
- 0,
+ 1,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- qobject_interface_iid<T *>()
+ qobject_interface_iid<T *>(),
+ "",
+ QTypeRevision::zero()
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
+}
+#endif
+
+template<typename T>
+int qmlRegisterInterface(const char *uri, int versionMajor)
+{
+ QML_GETTYPENAMES
+
+ QQmlPrivate::RegisterInterface qmlInterface = {
+ 1,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T>>(listName.constData()),
+ qobject_interface_iid<T *>(),
+
+ uri,
+ QTypeRevision::fromVersion(versionMajor, 0)
};
return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface);
@@ -766,11 +808,11 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i
return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type);
}
-template<class T, class Resolved, class Extended, bool Singleton>
+template<class T, class Resolved, class Extended, bool Singleton, bool Interface>
struct QmlTypeAndRevisionsRegistration;
template<class T, class Resolved, class Extended>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor)
{
QQmlPrivate::qmlRegisterTypeAndRevisions<Resolved, Extended>(
@@ -779,7 +821,7 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, Extended, false> {
};
template<class T, class Resolved>
-struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true> {
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true, false> {
static void registerTypeAndRevisions(const char *uri, int versionMajor)
{
QQmlPrivate::qmlRegisterSingletonAndRevisions<Resolved>(
@@ -787,6 +829,14 @@ struct QmlTypeAndRevisionsRegistration<T, Resolved, void, true> {
}
};
+template<class T, class Resolved>
+struct QmlTypeAndRevisionsRegistration<T, Resolved, void, false, true> {
+ static void registerTypeAndRevisions(const char *uri, int versionMajor)
+ {
+ qmlRegisterInterface<Resolved>(uri, versionMajor);
+ }
+};
+
template<typename T = void, typename... Args>
void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor);
@@ -796,7 +846,8 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor)
QmlTypeAndRevisionsRegistration<
T, typename QQmlPrivate::QmlResolved<T>::Type,
typename QQmlPrivate::QmlExtended<T>::Type,
- QQmlPrivate::QmlSingleton<T>::Value>
+ QQmlPrivate::QmlSingleton<T>::Value,
+ QQmlPrivate::QmlInterface<T>::Value>
::registerTypeAndRevisions(uri, versionMajor);
qmlRegisterTypesAndRevisions<Args...>(uri, versionMajor);
}
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index e14b00af22..b9566d5862 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -43,6 +43,10 @@
#include "qqmlcontext.h"
#include "qqmlinfo.h"
#include "qqmldata_p.h"
+
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <private/qqmlprofiler_p.h>
#include <private/qqmlexpression_p.h>
#include <private/qqmlscriptstring_p.h>
@@ -392,6 +396,11 @@ QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer<QV4::Exe
b->QQmlJavaScriptExpression::setContext(ctxt);
b->setScopeObject(obj);
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ service->foundTranslationBinding(b, obj, ctxt);
+ }
+
return b;
}
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 87f7fffe41..02c2b87a6e 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -125,8 +125,13 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
// * <TypeName>.<EnumValue>
// * <TypeName>.<ScopedEnumName>.<EnumValue>
- int dot = script.indexOf('.');
- if (dot == -1 || dot == script.length()-1)
+ auto nextDot = [&](int dot) {
+ const int nextDot = script.indexOf('.', dot + 1);
+ return (nextDot == script.length() - 1) ? -1 : nextDot;
+ };
+
+ int dot = nextDot(-1);
+ if (dot == -1)
return -1;
QString scope = QString::fromUtf8(script.left(dot));
@@ -137,18 +142,32 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
QQmlType type;
if (imports.isT1()) {
- imports.asT1()->resolveType(scope, &type, nullptr, nullptr, nullptr);
+ QQmlImportNamespace *ns = nullptr;
+ if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns))
+ return -1;
+ if (!type.isValid() && ns != nullptr) {
+ dot = nextDot(dot);
+ if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)),
+ &type, nullptr, nullptr)) {
+ return -1;
+ }
+ }
} else {
QQmlTypeNameCache::Result result = imports.asT2()->query(scope);
- if (result.isValid())
+ if (result.isValid()) {
type = result.type;
+ } else if (result.importNamespace) {
+ dot = nextDot(dot);
+ if (dot != -1)
+ type = imports.asT2()->query(QString::fromUtf8(script.left(dot))).type;
+ }
}
if (!type.isValid())
return -1;
- int dot2 = script.indexOf('.', dot+1);
- const bool dot2Valid = dot2 != -1 && dot2 != script.length()-1;
+ const int dot2 = nextDot(dot);
+ const bool dot2Valid = (dot2 != -1);
QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray());
if (!scopedEnumName.isEmpty())
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7f30c4d713..c8b41d3684 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -654,11 +654,7 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
for (auto iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter) {
iter.value()->isRegisteredWithEngine = false;
-
- // since unregisterInternalCompositeType() will not be called in this
- // case, we have to clean up the type registration manually
- QMetaType::unregisterType(iter.value()->metaTypeId);
- QMetaType::unregisterType(iter.value()->listMetaTypeId);
+ QQmlMetaType::unregisterInternalCompositeType({iter.value()->metaTypeId, iter.value()->listMetaTypeId});
}
#if QT_CONFIG(qml_debug)
delete profiler;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 2c702367a4..8e292c4bbc 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -269,8 +269,24 @@ public:
mutable QMutex networkAccessManagerMutex;
+ QQmlGadgetPtrWrapper *valueTypeInstance(int typeIndex)
+ {
+ auto it = cachedValueTypeInstances.find(typeIndex);
+ if (it != cachedValueTypeInstances.end())
+ return *it;
+
+ if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(typeIndex)) {
+ QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType, q_func());
+ cachedValueTypeInstances.insert(typeIndex, instance);
+ return instance;
+ }
+
+ return nullptr;
+ }
+
private:
QHash<QQmlType, QJSValue> singletonInstances;
+ QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
// These members must be protected by a QQmlEnginePrivate::Locker as they are required by
// the threaded loader. Only access them through their respective accessor methods.
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index c5c767df43..0baf142913 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -92,7 +92,12 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data,
d->typeId = type.typeId;
d->listId = type.listId;
d->isSetup = true;
- d->version = QTypeRevision::zero();
+ if (type.structVersion > 0) {
+ d->module = QString::fromUtf8(type.uri);
+ d->version = type.version;
+ } else {
+ d->version = QTypeRevision::zero();
+ }
data->registerType(d);
return d;
}
@@ -293,6 +298,17 @@ bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri)
return data->registerModuleTypes(uri);
}
+/*!
+ \internal
+ Method is only used to in tst_qqmlenginecleanup.cpp to test whether all
+ types have been removed from qmlLists after shutdown of QQmlEngine
+ */
+int QQmlMetaType::qmlRegisteredListTypeCount()
+{
+ QQmlMetaTypeDataPtr data;
+ return data->qmlLists.count();
+}
+
void QQmlMetaType::clearTypeRegistrations()
{
//Only cleans global static, assumed no running engine
@@ -329,7 +345,7 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun
QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type)
{
- if (type.structVersion > 0)
+ if (type.structVersion > 1)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QQmlMetaTypeDataPtr data;
@@ -338,8 +354,6 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
data->idToType.insert(priv->typeId, priv);
data->idToType.insert(priv->listId, priv);
- if (!priv->elementName.isEmpty())
- data->nameToType.insert(priv->elementName, priv);
if (data->interfaces.size() <= type.typeId)
data->interfaces.resize(type.typeId + 16);
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index c68bf0c551..0fc179fd34 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -202,6 +202,8 @@ public:
static void qmlRemoveModuleRegistration(const QString &uri);
static bool qmlRegisterModuleTypes(const QString &uri);
+
+ static int qmlRegisteredListTypeCount();
};
Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 6cc2bf49c8..28dd3d4ab4 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -173,7 +173,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context = new QQmlContextData;
context->isInternal = true;
context->imports = compilationUnit->typeNameCache;
- context->initFromTypeCompilationUnit(compilationUnit, flags & CreationFlags::NormalObject ? subComponentIndex : -1);
+ context->initFromTypeCompilationUnit(compilationUnit, subComponentIndex);
context->setParent(parentContext);
if (!sharedState->rootContext) {
@@ -856,12 +856,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
QObject *groupObject = nullptr;
- QQmlValueType *valueType = nullptr;
+ QQmlGadgetPtrWrapper *valueType = nullptr;
const QQmlPropertyData *valueTypeProperty = nullptr;
QObject *bindingTarget = _bindingTarget;
if (QQmlValueTypeFactory::isValueType(bindingProperty->propType())) {
- valueType = QQmlValueTypeFactory::valueType(bindingProperty->propType());
+ valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType());
if (!valueType) {
recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
return false;
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 527c5ee603..2e4bc60f79 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -125,6 +125,7 @@ class QJSValue;
class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
+class QQmlTypeNotAvailable;
template<class T>
QQmlCustomParser *qmlCreateCustomParser()
@@ -406,6 +407,9 @@ namespace QQmlPrivate
int listId;
const char *iid;
+
+ const char *uri;
+ QTypeRevision version;
};
struct RegisterAutoParent {
@@ -578,6 +582,18 @@ namespace QQmlPrivate
static constexpr bool Value = bool(T::QmlIsSingleton::yes);
};
+ template<class T, class = QmlVoidT<>>
+ struct QmlInterface
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlInterface<T, QmlVoidT<typename T::QmlIsInterface>>
+ {
+ static constexpr bool Value = bool(T::QmlIsInterface::yes);
+ };
+
template<typename T>
void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
const QMetaObject *classInfoMetaObject)
@@ -636,6 +652,11 @@ namespace QQmlPrivate
qmlregister(TypeAndRevisionsRegistration, &type);
}
+
+ template<>
+ void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject);
+
} // namespace QQmlPrivate
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 93020661e2..8521de6ab3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -353,10 +353,15 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (terminal.count() >= 3 &&
terminal.at(0) == QLatin1Char('o') &&
terminal.at(1) == QLatin1Char('n') &&
- terminal.at(2).isUpper()) {
+ (terminal.at(2).isUpper() || terminal.at(2) == '_')) {
QString signalName = terminal.mid(2).toString();
- signalName[0] = signalName.at(0).toLower();
+ int firstNon_;
+ int length = signalName.length();
+ for (firstNon_ = 0; firstNon_ < length; ++firstNon_)
+ if (signalName.at(firstNon_) != '_')
+ break;
+ signalName[firstNon_] = signalName.at(firstNon_).toLower();
// XXX - this code treats methods as signals
@@ -1044,13 +1049,19 @@ QVariant QQmlProperty::read(const QObject *object, const QString &name, QQmlEngi
QVariant QQmlPropertyPrivate::readValueProperty()
{
- if (isValueType()) {
-
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType());
- Q_ASSERT(valueType);
- valueType->read(object, core.coreIndex());
- return valueType->metaObject()->property(valueTypeData.coreIndex()).read(valueType);
+ auto doRead = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ return wrapper->property(valueTypeData.coreIndex()).read(wrapper);
+ };
+ if (isValueType()) {
+ if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType()))
+ return doRead(wrapper);
+ if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ return doRead(&wrapper);
+ }
+ return QVariant();
} else if (core.isQList()) {
QQmlListProperty<QObject> prop;
@@ -1183,10 +1194,22 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
bool rv = false;
if (valueTypeData.isValid()) {
- QQmlValueType *writeBack = QQmlValueTypeFactory::valueType(core.propType());
- writeBack->read(object, core.coreIndex());
- rv = write(writeBack, valueTypeData, value, context, flags);
- writeBack->write(object, core.coreIndex(), flags);
+ auto doWrite = [&](QQmlGadgetPtrWrapper *wrapper) {
+ wrapper->read(object, core.coreIndex());
+ rv = write(wrapper, valueTypeData, value, context, flags);
+ wrapper->write(object, core.coreIndex(), flags);
+ };
+
+ QQmlGadgetPtrWrapper *wrapper = context
+ ? QQmlGadgetPtrWrapper::instance(context->engine, core.propType())
+ : nullptr;
+ if (wrapper) {
+ doWrite(wrapper);
+ } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) {
+ QQmlGadgetPtrWrapper wrapper(valueType, nullptr);
+ doWrite(&wrapper);
+ }
+
} else {
rv = write(object, core, value, context, flags);
}
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 001b19a8e5..3fb2eb399f 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -104,7 +104,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
validateObject(it->objectIndex, /* instantiatingBinding*/ nullptr);
}
- if (obj->flags & QV4::CompiledData::Object::IsComponent) {
+ if (obj->flags & QV4::CompiledData::Object::IsComponent && !(obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)) {
Q_ASSERT(obj->nBindings == 1);
const QV4::CompiledData::Binding *componentBinding = obj->bindingTable();
Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index d7a549e380..3518b21a70 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -881,6 +881,10 @@ bool QQmlComponentAndAliasResolver::resolve()
const int objCountWithoutSynthesizedComponents = qmlObjects->count();
for (int i = 0; i < objCountWithoutSynthesizedComponents; ++i) {
QmlIR::Object *obj = qmlObjects->at(i);
+ if (obj->isInlineComponent) {
+ componentRoots.append(i);
+ continue;
+ }
QQmlPropertyCache *cache = propertyCaches.at(i);
if (obj->inheritedTypeNameIndex == 0 && !cache)
continue;
@@ -936,7 +940,7 @@ bool QQmlComponentAndAliasResolver::resolve()
_objectsWithAliases.clear();
- if (!collectIdsAndAliases(rootBinding->value.objectIndex))
+ if (!collectIdsAndAliases(component->isInlineComponent ? componentRoots.at(i) : rootBinding->value.objectIndex))
return false;
component->namedObjectsInComponent.allocate(pool, _idToObjectIndex);
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index ec9061d04e..30d50b911e 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -829,8 +829,9 @@ void QQmlTypeData::resolveTypes()
if (ref.type.isCompositeSingleton()) {
ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
- if (ref.typeData->status() == QQmlDataBlob::ResolvingDependencies || m_waitingOnMe.contains(ref.typeData.data())) {
- // TODO: give an error message? If so, we should record and show the path of the cycle.
+ if (ref.typeData->isWaiting() || m_waitingOnMe.contains(ref.typeData.data())) {
+ qWarning() << "Cyclic dependency detected between" << ref.typeData->urlString()
+ << "and" << urlString();
continue;
}
addDependency(ref.typeData.data());
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index afad15331c..d8cfd80b9b 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -602,51 +602,59 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
scriptImported(blob, import->location, script.nameSpace, import->qualifier);
}
}
+ } else if (
+ // Major version of module already registered:
+ // We believe that the registration is complete.
+ QQmlMetaType::typeModule(import->uri, import->version)
+
+ // Otherwise, try to register further module types.
+ || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri))
+
+ // Otherwise, there is no way to register any further types.
+ // Try with any module of that name.
+ || QQmlMetaType::isAnyModule(import->uri)) {
+
+ if (!m_importCache.addLibraryImport(
+ importDatabase, import->uri, import->qualifier, import->version,
+ QString(), QString(), false, errors)) {
+ return false;
+ }
} else {
- // Is this a module?
- if (QQmlMetaType::isAnyModule(import->uri)
- || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
- && QQmlMetaType::qmlRegisterModuleTypes(import->uri))) {
+ // We haven't yet resolved this import
+ m_unresolvedImports << import;
+
+ QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
+
+ // Query any network import paths for this library.
+ // Interceptor might redirect local paths.
+ QStringList remotePathList = importDatabase->importPathList(
+ interceptor ? QQmlImportDatabase::LocalOrRemote
+ : QQmlImportDatabase::Remote);
+ if (!remotePathList.isEmpty()) {
+ // Add this library and request the possible locations for it
if (!m_importCache.addLibraryImport(
importDatabase, import->uri, import->qualifier, import->version,
- QString(), QString(), false, errors))
+ QString(), QString(), true, errors))
return false;
- } else {
- // We haven't yet resolved this import
- m_unresolvedImports << import;
-
- QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
-
- // Query any network import paths for this library.
- // Interceptor might redirect local paths.
- QStringList remotePathList = importDatabase->importPathList(
- interceptor ? QQmlImportDatabase::LocalOrRemote
- : QQmlImportDatabase::Remote);
- if (!remotePathList.isEmpty()) {
- // Add this library and request the possible locations for it
- if (!m_importCache.addLibraryImport(
- importDatabase, import->uri, import->qualifier, import->version,
- QString(), QString(), true, errors))
- return false;
- // Probe for all possible locations
- int priority = 0;
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
- import->uri, remotePathList, import->version);
- for (const QString &qmldirPath : qmlDirPaths) {
- if (interceptor) {
- QUrl url = interceptor->intercept(
- QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
- QQmlAbstractUrlInterceptor::QmldirFile);
- if (!QQmlFile::isLocalFile(url)
- && !fetchQmldir(url, import, ++priority, errors)) {
- return false;
- }
- } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ // Probe for all possible locations
+ int priority = 0;
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
+ import->uri, remotePathList, import->version);
+ for (const QString &qmldirPath : qmlDirPaths) {
+ if (interceptor) {
+ QUrl url = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ if (!QQmlFile::isLocalFile(url)
+ && !fetchQmldir(url, import, ++priority, errors)) {
return false;
}
-
+ } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ return false;
}
+
}
}
}
diff --git a/src/qml/qml/qqmltypenotavailable.cpp b/src/qml/qml/qqmltypenotavailable.cpp
index ffa4472e4b..0e95d6062c 100644
--- a/src/qml/qml/qqmltypenotavailable.cpp
+++ b/src/qml/qml/qqmltypenotavailable.cpp
@@ -46,8 +46,6 @@ int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMi
return qmlRegisterUncreatableType<QQmlTypeNotAvailable>(uri,versionMajor,versionMinor,qmlName,message);
}
-QQmlTypeNotAvailable::QQmlTypeNotAvailable() { }
-
QT_END_NAMESPACE
#include "moc_qqmltypenotavailable_p.cpp"
diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h
index 8db5876b10..9bb19ed86c 100644
--- a/src/qml/qml/qqmltypenotavailable_p.h
+++ b/src/qml/qml/qqmltypenotavailable_p.h
@@ -55,14 +55,10 @@
QT_BEGIN_NAMESPACE
-
class QQmlTypeNotAvailable : public QObject {
Q_OBJECT
QML_NAMED_ELEMENT(TypeNotAvailable)
QML_UNCREATABLE("Type not available.")
-
-public:
- QQmlTypeNotAvailable();
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 4beb6a4d07..254f1015e2 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -42,11 +42,11 @@
#include <QtCore/qmutex.h>
#include <private/qqmlglobal_p.h>
#include <QtCore/qdebug.h>
+#include <private/qqmlengine_p.h>
#include <private/qmetaobjectbuilder_p.h>
#if QT_CONFIG(qml_itemmodel)
#include <private/qqmlmodelindexvaluetype_p.h>
#endif
-#include <private/qmetatype_p.h>
Q_DECLARE_METATYPE(QQmlProperty)
@@ -221,61 +221,82 @@ void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor,
#endif
}
-QQmlValueType::QQmlValueType() :
- _metaObject(nullptr),
- gadgetPtr(nullptr),
- metaType(QMetaType::UnknownType)
+QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
+ : metaType(typeId)
{
+ QMetaObjectBuilder builder(gadgetMetaObject);
+ dynamicMetaObject = builder.toMetaObject();
+ *static_cast<QMetaObject*>(this) = *dynamicMetaObject;
}
-QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
- : gadgetPtr(QMetaType::create(typeId))
- , metaType(typeId)
+QQmlValueType::~QQmlValueType()
{
- QObjectPrivate *op = QObjectPrivate::get(this);
- Q_ASSERT(!op->metaObject);
- op->metaObject = this;
+ ::free(dynamicMetaObject);
+}
- QMetaObjectBuilder builder(gadgetMetaObject);
- _metaObject = builder.toMetaObject();
+QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, int index)
+{
+ return engine ? QQmlEnginePrivate::get(engine)->valueTypeInstance(index) : nullptr;
+}
- *static_cast<QMetaObject*>(this) = *_metaObject;
+QQmlGadgetPtrWrapper::QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent)
+ : QObject(parent), m_gadgetPtr(valueType->create())
+{
+ QObjectPrivate *d = QObjectPrivate::get(this);
+ Q_ASSERT(!d->metaObject);
+ d->metaObject = valueType;
}
-QQmlValueType::~QQmlValueType()
+QQmlGadgetPtrWrapper::~QQmlGadgetPtrWrapper()
{
- QObjectPrivate *op = QObjectPrivate::get(this);
- Q_ASSERT(op->metaObject == nullptr || op->metaObject == this);
- op->metaObject = nullptr;
- ::free(const_cast<QMetaObject *>(_metaObject));
- metaType.destroy(gadgetPtr);
+ QObjectPrivate *d = QObjectPrivate::get(this);
+ static_cast<const QQmlValueType *>(d->metaObject)->destroy(m_gadgetPtr);
+ d->metaObject = nullptr;
}
-void QQmlValueType::read(QObject *obj, int idx)
+void QQmlGadgetPtrWrapper::read(QObject *obj, int idx)
{
- void *a[] = { gadgetPtr, nullptr };
+ Q_ASSERT(m_gadgetPtr);
+ void *a[] = { m_gadgetPtr, nullptr };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
+void QQmlGadgetPtrWrapper::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags)
{
- Q_ASSERT(gadgetPtr);
+ Q_ASSERT(m_gadgetPtr);
int status = -1;
- void *a[] = { gadgetPtr, nullptr, &status, &flags };
+ void *a[] = { m_gadgetPtr, nullptr, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
-QVariant QQmlValueType::value()
+QVariant QQmlGadgetPtrWrapper::value()
+{
+ Q_ASSERT(m_gadgetPtr);
+ return QVariant(metaTypeId(), m_gadgetPtr);
+}
+
+void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
+{
+ Q_ASSERT(m_gadgetPtr);
+ Q_ASSERT(metaTypeId() == value.userType());
+ const QQmlValueType *type = valueType();
+ type->destruct(m_gadgetPtr);
+ type->construct(m_gadgetPtr, value.constData());
+}
+
+int QQmlGadgetPtrWrapper::metaCall(QMetaObject::Call type, int id, void **argv)
{
- Q_ASSERT(gadgetPtr);
- return QVariant(metaType.id(), gadgetPtr);
+ Q_ASSERT(m_gadgetPtr);
+ const QMetaObject *metaObject = valueType();
+ QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &id);
+ metaObject->d.static_metacall(static_cast<QObject *>(m_gadgetPtr), type, id, argv);
+ return id;
}
-void QQmlValueType::setValue(const QVariant &value)
+const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const
{
- Q_ASSERT(metaType.id() == value.userType());
- metaType.destruct(gadgetPtr);
- metaType.construct(gadgetPtr, value.constData());
+ const QObjectPrivate *d = QObjectPrivate::get(this);
+ return static_cast<const QQmlValueType *>(d->metaObject);
}
QAbstractDynamicMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
@@ -287,12 +308,9 @@ void QQmlValueType::objectDestroyed(QObject *)
{
}
-int QQmlValueType::metaCall(QObject *, QMetaObject::Call type, int _id, void **argv)
+int QQmlValueType::metaCall(QObject *object, QMetaObject::Call type, int _id, void **argv)
{
- const QMetaObject *mo = _metaObject;
- QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &mo, &_id);
- mo->d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), type, _id, argv);
- return _id;
+ return static_cast<QQmlGadgetPtrWrapper *>(object)->metaCall(type, _id, argv);
}
QString QQmlPointFValueType::toString() const
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 901b7a6fd7..6768991581 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -54,7 +54,9 @@
#include "qqml.h"
#include "qqmlproperty.h"
#include "qqmlproperty_p.h"
+
#include <private/qqmlnullablevalue_p.h>
+#include <private/qmetatype_p.h>
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
@@ -65,16 +67,20 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject, public QAbstractDynamicMetaObject
+class Q_QML_PRIVATE_EXPORT QQmlValueType : public QAbstractDynamicMetaObject
{
public:
- QQmlValueType();
+ QQmlValueType() : metaType(QMetaType::UnknownType) {}
QQmlValueType(int userType, const QMetaObject *metaObject);
- ~QQmlValueType() override;
- void read(QObject *, int);
- void write(QObject *, int, QQmlPropertyData::WriteFlags flags);
- QVariant value();
- void setValue(const QVariant &);
+ ~QQmlValueType();
+
+ void *create() const { return metaType.create(); }
+ void destroy(void *gadgetPtr) const { metaType.destroy(gadgetPtr); }
+
+ void construct(void *gadgetPtr, const void *copy) const { metaType.construct(gadgetPtr, copy); }
+ void destruct(void *gadgetPtr) const { metaType.destruct(gadgetPtr); }
+
+ int metaTypeId() const { return metaType.id(); }
// ---- dynamic meta object data interface
QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override;
@@ -82,12 +88,33 @@ public:
int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv) override;
// ----
-private:
- const QMetaObject *_metaObject;
- void *gadgetPtr;
-
public:
QMetaType metaType;
+ QMetaObject *dynamicMetaObject = nullptr;
+};
+
+class Q_QML_PRIVATE_EXPORT QQmlGadgetPtrWrapper : public QObject
+{
+ Q_OBJECT
+public:
+ static QQmlGadgetPtrWrapper *instance(QQmlEngine *engine, int index);
+
+ QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent);
+ ~QQmlGadgetPtrWrapper();
+
+ void read(QObject *obj, int idx);
+ void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags);
+ QVariant value();
+ void setValue(const QVariant &value);
+
+ int metaTypeId() const { return valueType()->metaTypeId(); }
+ int metaCall(QMetaObject::Call type, int id, void **argv);
+ QMetaProperty property(int index) { return valueType()->property(index); }
+
+private:
+ const QQmlValueType *valueType() const;
+
+ void *m_gadgetPtr = nullptr;
};
class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index ecb86e2f10..de23e929e2 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -136,6 +136,20 @@ static void list_clear(QQmlListProperty<QObject> *prop)
resolved.activateSignal();
}
+static void list_replace(QQmlListProperty<QObject> *prop, int index, QObject *o)
+{
+ const ResolvedList resolved(prop);
+ resolved.list()->replace(index, o);
+ resolved.activateSignal();
+}
+
+static void list_removeLast(QQmlListProperty<QObject> *prop)
+{
+ const ResolvedList resolved(prop);
+ resolved.list()->removeLast();
+ resolved.activateSignal();
+}
+
QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
: QQmlGuard<QObject>(nullptr), m_target(nullptr), m_index(-1)
{
@@ -289,11 +303,13 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
continue;
const int valueIndex = vi->m_propertyIndex.valueTypeIndex();
- int type = QQmlData::get(object)->propertyCache->property(id)->propType();
+ const QQmlData *data = QQmlData::get(object);
+ const int type = data->propertyCache->property(id)->propType();
if (type != QMetaType::UnknownType) {
if (valueIndex != -1) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
+ QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
+ data->context->engine, type);
Q_ASSERT(valueType);
//
@@ -327,7 +343,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
// (7) Issue the interceptor call with the new component value.
//
- QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
+ QMetaProperty valueProp = valueType->property(valueIndex);
QVariant newValue(type, a[0]);
valueType->read(object, id);
@@ -735,7 +751,8 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
*static_cast<QQmlListProperty<QObject> *>(a[0])
= QQmlListProperty<QObject>(
object, reinterpret_cast<void *>(quintptr(id)),
- list_append, list_count, list_at, list_clear);
+ list_append, list_count, list_at,
+ list_clear, list_replace, list_removeLast);
} else {
*reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
}
@@ -879,9 +896,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
return -1;
const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
// Value type property or deep alias
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(pd->propType());
+ QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
+ ctxt->engine, pd->propType());
if (valueType) {
-
valueType->read(target, coreIndex);
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h
index 9ca0cf2abe..a729729b67 100644
--- a/src/qml/qtqmlglobal_p.h
+++ b/src/qml/qtqmlglobal_p.h
@@ -60,6 +60,8 @@
#define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT
+void Q_QML_PRIVATE_EXPORT qml_register_types_QtQml();
+
#if !defined(QT_QMLDEVTOOLS_LIB) && !defined(QT_BUILD_QMLDEVTOOLS_LIB)
# define Q_QML_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
#else
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 1e801641e5..4c44bba43e 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -238,7 +238,8 @@ void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableC
const QV4::CompiledData::Binding *binding = props.at(ii);
const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);
- if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) {
+ const bool thirdCharacterIsValid = (propName.length() >= 2) && (propName.at(2).isUpper() || propName.at(2) == '_');
+ if (!propName.startsWith(QLatin1String("on")) || !thirdCharacterIsValid) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return;
}
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
index 94d300b765..ac3f3bf3bf 100644
--- a/src/qmldebug/qmldebug.pro
+++ b/src/qmldebug/qmldebug.pro
@@ -1,5 +1,5 @@
TARGET = QtQmlDebug
-QT = core-private network packetprotocol-private
+QT = core-private qml-private network packetprotocol-private
CONFIG += static internal_module
load(qt_module)
@@ -8,6 +8,7 @@ SOURCES += \
qqmldebugclient.cpp \
qqmldebugconnection.cpp \
qqmldebugmessageclient.cpp \
+ qqmldebugtranslationclient.cpp \
qqmlenginecontrolclient.cpp \
qqmlenginedebugclient.cpp \
qqmlinspectorclient.cpp \
@@ -24,6 +25,7 @@ HEADERS += \
qqmldebugclient_p_p.h \
qqmldebugconnection_p.h \
qqmldebugmessageclient_p.h \
+ qqmldebugtranslationclient_p.h \
qqmlenginedebugclient_p.h \
qqmlenginedebugclient_p_p.h \
qqmlenginecontrolclient_p.h \
diff --git a/src/qmldebug/qqmldebugtranslationclient.cpp b/src/qmldebug/qqmldebugtranslationclient.cpp
new file mode 100644
index 0000000000..1fd0748fa0
--- /dev/null
+++ b/src/qmldebug/qqmldebugtranslationclient.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugtranslationclient_p.h"
+#include "qqmldebugconnection_p.h"
+
+#include <QUrl>
+#include <QDataStream>
+
+#include <QDebug>
+#include <QtPacketProtocol/private/qpacket_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlDebugTranslationClient
+ \internal
+
+ \brief Client for the debug translation service
+
+ The QQmlDebugTranslationClient can test if translated texts will fit.
+ */
+
+QQmlDebugTranslationClient::QQmlDebugTranslationClient(QQmlDebugConnection *client)
+ : QQmlDebugClient(QLatin1String("DebugTranslation"), client)
+{
+}
+
+void QQmlDebugTranslationClient::messageReceived(const QByteArray &data)
+{
+ Q_UNUSED(data);
+}
+
+void QQmlDebugTranslationClient::triggerLanguage(const QUrl &url, const QString &locale)
+{
+ Q_UNUSED(url)
+ Q_UNUSED(locale)
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmldebugtranslationclient_p.h b/src/qmldebug/qqmldebugtranslationclient_p.h
new file mode 100644
index 0000000000..3163759d9e
--- /dev/null
+++ b/src/qmldebug/qqmldebugtranslationclient_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQMLDEBUGTRANSLATIONCLIENT_P_H
+#define QQMLDEBUGTRANSLATIONCLIENT_P_H
+
+#include "qqmldebugclient_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDebugTranslationClient : public QQmlDebugClient
+{
+ Q_OBJECT
+
+public:
+ //needs to be in sync with QQmlDebugTranslationServiceImpl in qqmldebugtranslationservice.h
+ enum Command {
+ ChangeLanguage,
+ ChangeWarningColor,
+ ChangeElidedTextWarningString,
+ SetDebugTranslationServiceLogFile,
+ EnableElidedTextWarning,
+ DisableElidedTextWarning,
+ TestAllLanguages
+ };
+
+ explicit QQmlDebugTranslationClient(QQmlDebugConnection *client);
+
+ virtual void messageReceived(const QByteArray &) override;
+ void triggerLanguage(const QUrl &url, const QString &locale);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGTRANSLATIONCLIENT_P_H
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 54bbccd617..33b57a0332 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -977,6 +977,9 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEn
} else if (list.type() == QQmlListAccessor::ListProperty) {
setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent);
accessors = new VDMObjectDelegateDataType;
+ } else if (list.type() == QQmlListAccessor::ObjectList) {
+ setObject(nullptr, parent);
+ accessors = new VDMObjectDelegateDataType;
} else if (list.type() != QQmlListAccessor::Invalid
&& list.type() != QQmlListAccessor::Instance) { // Null QObject
setObject(nullptr, parent);
diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h
index d243edda92..2c90ffc1d1 100644
--- a/src/qmlmodels/qqmladaptormodel_p.h
+++ b/src/qmlmodels/qqmladaptormodel_p.h
@@ -146,7 +146,10 @@ public:
return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index));
}
inline bool hasProxyObject() const {
- return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; }
+ return list.type() == QQmlListAccessor::Instance
+ || list.type() == QQmlListAccessor::ListProperty
+ || list.type() == QQmlListAccessor::ObjectList;
+ }
inline bool notify(
const QList<QQmlDelegateModelItem *> &items,
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index ee407538f1..c32caafaa6 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -731,7 +731,7 @@ QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
QQmlDelegateModelPrivate::group_append,
QQmlDelegateModelPrivate::group_count,
QQmlDelegateModelPrivate::group_at,
- nullptr);
+ nullptr, nullptr, nullptr);
}
/*!
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index adb5f7008b..8aab4badca 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -144,8 +144,6 @@ Q_SIGNALS:
void defaultGroupsChanged();
void rootIndexChanged();
void delegateChanged();
- void itemPooled(int index, QObject *object);
- void itemReused(int index, QObject *object);
private Q_SLOTS:
void _q_itemsChanged(int index, int count, const QVector<int> &roles);
diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp
index c450c616e7..69427df184 100644
--- a/src/qmlmodels/qqmllistaccessor.cpp
+++ b/src/qmlmodels/qqmllistaccessor.cpp
@@ -80,6 +80,8 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
m_type = StringList;
} else if (d.userType() == QMetaType::QVariantList) {
m_type = VariantList;
+ } else if (d.userType() == qMetaTypeId<QList<QObject *>>()) {
+ m_type = ObjectList;
} else if (d.canConvert(QMetaType::Int)) {
// Here we have to check for an upper limit, because down the line code might (well, will)
// allocate memory depending on the number of elements. The upper limit cannot be INT_MAX:
@@ -120,6 +122,8 @@ int QQmlListAccessor::count() const
return qvariant_cast<QStringList>(d).count();
case VariantList:
return qvariant_cast<QVariantList>(d).count();
+ case ObjectList:
+ return qvariant_cast<QList<QObject *>>(d).count();
case ListProperty:
return ((const QQmlListReference *)d.constData())->count();
case Instance:
@@ -140,6 +144,8 @@ QVariant QQmlListAccessor::at(int idx) const
return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx));
case VariantList:
return qvariant_cast<QVariantList>(d).at(idx);
+ case ObjectList:
+ return QVariant::fromValue(qvariant_cast<QList<QObject *>>(d).at(idx));
case ListProperty:
return QVariant::fromValue(((const QQmlListReference *)d.constData())->at(idx));
case Instance:
diff --git a/src/qmlmodels/qqmllistaccessor_p.h b/src/qmlmodels/qqmllistaccessor_p.h
index bcd079adef..a57e4173e3 100644
--- a/src/qmlmodels/qqmllistaccessor_p.h
+++ b/src/qmlmodels/qqmllistaccessor_p.h
@@ -70,7 +70,7 @@ public:
int count() const;
QVariant at(int) const;
- enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer };
+ enum Type { Invalid, StringList, VariantList, ObjectList, ListProperty, Instance, Integer };
Type type() const { return m_type; }
private:
diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp
index 85e64cc2f9..dac868a0a2 100644
--- a/src/qmlmodels/qqmlobjectmodel.cpp
+++ b/src/qmlmodels/qqmlobjectmodel.cpp
@@ -91,6 +91,15 @@ public:
static_cast<QQmlObjectModelPrivate *>(prop->data)->clear();
}
+ static void children_replace(QQmlListProperty<QObject> *prop, int index, QObject *item) {
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->replace(index, item);
+ }
+
+ static void children_removeLast(QQmlListProperty<QObject> *prop) {
+ auto data = static_cast<QQmlObjectModelPrivate *>(prop->data);
+ data->remove(data->children.count() - 1, 1);
+ }
+
void insert(int index, QObject *item) {
Q_Q(QQmlObjectModel);
children.insert(index, Item(item));
@@ -105,6 +114,18 @@ public:
emit q->childrenChanged();
}
+ void replace(int index, QObject *item) {
+ Q_Q(QQmlObjectModel);
+ auto *attached = QQmlObjectModelAttached::properties(children.at(index).item);
+ attached->setIndex(-1);
+ children.replace(index, Item(item));
+ QQmlObjectModelAttached::properties(children.at(index).item)->setIndex(index);
+ QQmlChangeSet changeSet;
+ changeSet.change(index, 1);
+ emit q->modelUpdated(changeSet, false);
+ emit q->childrenChanged();
+ }
+
void move(int from, int to, int n) {
Q_Q(QQmlObjectModel);
if (from > to) {
@@ -229,12 +250,13 @@ QQmlObjectModel::QQmlObjectModel(QObject *parent)
QQmlListProperty<QObject> QQmlObjectModel::children()
{
Q_D(QQmlObjectModel);
- return QQmlListProperty<QObject>(this,
- d,
- d->children_append,
- d->children_count,
- d->children_at,
- d->children_clear);
+ return QQmlListProperty<QObject>(this, d,
+ QQmlObjectModelPrivate::children_append,
+ QQmlObjectModelPrivate::children_count,
+ QQmlObjectModelPrivate::children_at,
+ QQmlObjectModelPrivate::children_clear,
+ QQmlObjectModelPrivate::children_replace,
+ QQmlObjectModelPrivate::children_removeLast);
}
/*!
diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h
index 6c68e55012..7fb4f64676 100644
--- a/src/qmlmodels/qqmlobjectmodel_p.h
+++ b/src/qmlmodels/qqmlobjectmodel_p.h
@@ -104,6 +104,8 @@ Q_SIGNALS:
void createdItem(int index, QObject *object);
void initItem(int index, QObject *object);
void destroyingItem(QObject *object);
+ void itemPooled(int index, QObject *object);
+ void itemReused(int index, QObject *object);
protected:
QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h
index 7e28984789..80ba7ddaaf 100644
--- a/src/qmlmodels/qqmltableinstancemodel_p.h
+++ b/src/qmlmodels/qqmltableinstancemodel_p.h
@@ -122,10 +122,6 @@ public:
void setWatchedRoles(const QList<QByteArray> &) override { Q_UNREACHABLE(); }
int indexOf(QObject *, QObject *) const override { Q_UNREACHABLE(); return 0; }
-Q_SIGNALS:
- void itemPooled(int index, QObject *object);
- void itemReused(int index, QObject *object);
-
private:
QQmlComponent *resolveDelegate(int index);
diff --git a/src/qmlmodels/qquickpackage.cpp b/src/qmlmodels/qquickpackage.cpp
index 567381e5ab..42e7d0e09f 100644
--- a/src/qmlmodels/qquickpackage.cpp
+++ b/src/qmlmodels/qquickpackage.cpp
@@ -115,6 +115,14 @@ public:
QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
return list->count();
}
+ static void data_replace(QQmlListProperty<QObject> *prop, int index, QObject *o) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->replace(index, DataGuard(o, list));
+ }
+ static void data_removeLast(QQmlListProperty<QObject> *prop) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->removeLast();
+ }
};
QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
@@ -152,10 +160,13 @@ QQuickPackage::~QQuickPackage()
QQmlListProperty<QObject> QQuickPackage::data()
{
Q_D(QQuickPackage);
- return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append,
- QQuickPackagePrivate::data_count,
- QQuickPackagePrivate::data_at,
- QQuickPackagePrivate::data_clear);
+ return QQmlListProperty<QObject>(this, &d->dataList,
+ QQuickPackagePrivate::data_append,
+ QQuickPackagePrivate::data_count,
+ QQuickPackagePrivate::data_at,
+ QQuickPackagePrivate::data_clear,
+ QQuickPackagePrivate::data_replace,
+ QQuickPackagePrivate::data_removeLast);
}
bool QQuickPackage::hasPart(const QString &name)
diff --git a/src/qmlmodels/qtqmlmodelsglobal_p.h b/src/qmlmodels/qtqmlmodelsglobal_p.h
index 145112c9c1..1a1157138d 100644
--- a/src/qmlmodels/qtqmlmodelsglobal_p.h
+++ b/src/qmlmodels/qtqmlmodelsglobal_p.h
@@ -58,4 +58,6 @@
#define Q_QMLMODELS_PRIVATE_EXPORT Q_QMLMODELS_EXPORT
#define Q_QMLMODELS_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
+void Q_QMLMODELS_PRIVATE_EXPORT qml_register_types_QtQml_Models();
+
#endif // QTQMLMODELSGLOBAL_P_H
diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h
index 03581089e0..22a205cfe4 100644
--- a/src/qmlworkerscript/qquickworkerscript_p.h
+++ b/src/qmlworkerscript/qquickworkerscript_p.h
@@ -84,7 +84,7 @@ private:
};
class QQmlV4Function;
-class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus
+class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
diff --git a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
index 34236cd79e..c75d5f3129 100644
--- a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
+++ b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
@@ -57,4 +57,6 @@
#define Q_QMLWORKERSCRIPT_PRIVATE_EXPORT Q_QMLWORKERSCRIPT_EXPORT
#define Q_QMLWORKERSCRIPT_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
+void Q_QMLWORKERSCRIPT_PRIVATE_EXPORT qml_register_types_QtQml_WorkerScript();
+
#endif // QTQMLWORKERSCRIPTGLOBAL_P_H
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index 41a02fc09c..b23b0316f5 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -84,8 +84,12 @@ QAccessibleInterface *QAccessibleQuickWindow::child(int index) const
QAccessibleInterface *QAccessibleQuickWindow::focusChild() const
{
QObject *focusObject = window()->focusObject();
- if (focusObject)
- return QAccessible::queryAccessibleInterface(focusObject);
+ if (focusObject) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(focusObject);
+ if (!iface || iface == this || !iface->focusChild())
+ return iface;
+ return iface->focusChild();
+ }
return nullptr;
}
diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
index c746f55daa..335795acf1 100644
--- a/src/quick/designer/qquickdesignersupportproperties.cpp
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -155,8 +155,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
+ '.', inspectedObjects));
}
- } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ } else if (QQmlGadgetPtrWrapper *valueType
+ = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) {
valueType->setValue(metaProperty.read(object));
propertyNameList.append(propertyNameListForWritableProperties(valueType,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
@@ -223,8 +223,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
+ QQuickDesignerSupport::PropertyName(metaProperty.name())
+ '.', inspectedObjects));
}
- } else if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
+ } else if (QQmlGadgetPtrWrapper *valueType
+ = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) {
valueType->setValue(metaProperty.read(object));
propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
propertyNameList.append(allPropertyNames(valueType,
diff --git a/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
new file mode 100644
index 0000000000..e9a668ed8f
--- /dev/null
+++ b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [document]
+import QtQuick 2.0
+
+Item {
+ width: 200
+ height: 250
+
+ ListModel {
+ id: myModel
+ ListElement { type: "Dog"; age: 8; noise: "meow" }
+ ListElement { type: "Cat"; age: 5; noise: "woof" }
+ }
+
+ component MyDelegate : Text {
+ required property string type
+ required property int age
+ text: type + ", " + age
+ // WRONG: Component.onCompleted: () => console.log(noise)
+ // The above line would cause a ReferenceError
+ // as there is no required property noise,
+ // and the presence of the required properties prevents
+ // noise from being injected into the scope
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: myModel
+ delegate: MyDelegate {}
+ }
+}
+//! [document]
diff --git a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
index 04dbf1cf20..555f730c9e 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
@@ -164,6 +164,16 @@ To visualize data, bind the view's \c model property to a model and the
\snippet qml/qml-data-models/listmodel-listview.qml document
+ To get finer control over which roles are accessible, and to make delegates
+ more self-contained and usable outside of views,
+ \li{Required Properties}{required properties} can be used. If a delegate
+ contains required properties, the named roles are not provided. Instead,
+ the QML engine will check if the name of a required property matches that of
+ a model role. If so, that property will be bound to the corresponding value
+ from the model.
+
+ \snippet qml/qml-data-models/listmodel-listview-required.qml document
+
If there is a naming clash between the model's properties and the delegate's
properties, the roles can be accessed with the qualified \e model name
instead. For example, if a \l Text type had \e type or \e age properties,
@@ -186,6 +196,10 @@ To visualize data, bind the view's \c model property to a model and the
modelData role is also provided for models that have only one role. In this
case the \e modelData role contains the same data as the named role.
+ \note \e model, \e index, and \e modelData roles are not accessible
+ if the delegate contains required properties, unless it has also required
+ properties with matching names.
+
QML provides several types of data models among the built-in set of QML
types. In addition, models can be created with Qt C++ and then made
available to \l{QQmlEngine} for use by
@@ -417,6 +431,12 @@ ListView {
\note The \c edit role is equal to \l Qt::EditRole. See \l{QAbstractItemModel::}{roleNames}()
for the built-in role names. However, real life models would usually register custom roles.
+\node If a model role is bound to a \li{Required Property}{required property}, assigning to
+that property will not modify the model. It will instead break the binding to the model (just
+like assigning to any other property breaks existing bindings). If you want to use
+required properties and change the model data, make model also a required property and assign to
+\e model.propertyName.
+
For more information, visit the \l{qtquick-modelviewsdata-cppmodels.html#changing-model-data}{Using C++ Models with Qt Quick Views}
article.
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 418475f100..528444cad3 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -179,6 +179,7 @@ available when you import \c QtQuick.
\li \l bool \c font.kerning
\li \l bool \c font.preferShaping
\li \l enumeration \c font.hintingPreference
+ \li \l string \c font.styleName
\endlist
Example:
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index f3d92cf200..e6148ca072 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -120,7 +120,10 @@ void QQuickHandlerPoint::reset(const QQuickEventPoint *point)
m_pressure = tp->pressure();
m_ellipseDiameters = tp->ellipseDiameters();
} else if (event->asPointerTabletEvent()) {
- // TODO
+ m_uniqueId = event->device()->uniqueId();
+ m_rotation = static_cast<const QQuickEventTabletPoint *>(point)->rotation();
+ m_pressure = static_cast<const QQuickEventTabletPoint *>(point)->pressure();
+ m_ellipseDiameters = QSizeF();
} else {
m_uniqueId = event->device()->uniqueId();
m_rotation = 0;
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp
index 1216eda477..b12d85784a 100644
--- a/src/quick/handlers/qquickhoverhandler.cpp
+++ b/src/quick/handlers/qquickhoverhandler.cpp
@@ -93,11 +93,22 @@ bool QQuickHoverHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
QQuickEventPoint *point = event->point(0);
if (QQuickPointerDeviceHandler::wantsPointerEvent(event) && wantsEventPoint(point) && parentContains(point)) {
- // assume this is a mouse event, so there's only one point
+ // assume this is a mouse or tablet event, so there's only one point
setPointId(point->pointId());
return true;
}
- setHovered(false);
+
+ // Some hover events come from QQuickWindow::tabletEvent(). In between,
+ // some hover events come from QQWindowPrivate::flushFrameSynchronousEvents(),
+ // but those look like mouse events. If a particular HoverHandler instance
+ // is filtering for tablet events only (e.g. by setting
+ // acceptedDevices:PointerDevice.Stylus), those events should not cause
+ // the hovered property to transition to false prematurely.
+ // If a QQuickPointerTabletEvent caused the hovered property to become true,
+ // then only another QQuickPointerTabletEvent can make it become false.
+ if (!(m_hoveredTablet && event->asPointerMouseEvent()))
+ setHovered(false);
+
return false;
}
@@ -107,6 +118,8 @@ void QQuickHoverHandler::handleEventPoint(QQuickEventPoint *point)
if (point->state() == QQuickEventPoint::Released &&
point->pointerEvent()->device()->pointerType() == QQuickPointerDevice::Finger)
hovered = false;
+ else if (point->pointerEvent()->asPointerTabletEvent())
+ m_hoveredTablet = true;
setHovered(hovered);
setPassiveGrab(point);
}
@@ -124,6 +137,8 @@ void QQuickHoverHandler::setHovered(bool hovered)
if (m_hovered != hovered) {
qCDebug(lcHoverHandler) << objectName() << "hovered" << m_hovered << "->" << hovered;
m_hovered = hovered;
+ if (!hovered)
+ m_hoveredTablet = false;
emit hoveredChanged();
}
}
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index e4786bfa53..313b87217c 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -84,6 +84,7 @@ private:
private:
bool m_hovered = false;
+ bool m_hoveredTablet = false;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 469dc3cb4d..3c01bd2cb1 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -658,14 +658,73 @@ QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
return g_genericMouseDevice;
}
-QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
-{
- auto it = g_tabletDevices->find(id);
+QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
+{
+ // QTabletEvent::uniqueId() is the same for the pointy end and the eraser end of the stylus.
+ // We need to make those unique. QTabletEvent::PointerType only needs 2 bits' worth of storage.
+ // The key into g_tabletDevices just needs to be unique; we don't need to extract uniqueId
+ // back out of it, because QQuickPointerDevice stores that separately anyway.
+ // So the shift-and-add can be thought of as a sort of hash function, even though
+ // most of the time the result will be recognizable because the uniqueId MSBs are often 0.
+ qint64 key = event->uniqueId() + (qint64(event->pointerType()) << 60);
+ auto it = g_tabletDevices->find(key);
if (it != g_tabletDevices->end())
return it.value();
- // ### Figure out how to populate the tablet devices
- return nullptr;
+ DeviceType type = UnknownDevice;
+ int buttonCount = 0;
+ Capabilities caps = Position | Pressure | Hover;
+ // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a
+ // QTabletDevice populated with capabilities provided by QPA plugins
+
+ switch (event->device()) {
+ case QTabletEvent::Stylus:
+ type = QQuickPointerDevice::Stylus;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::RotationStylus:
+ type = QQuickPointerDevice::Stylus;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 1;
+ break;
+ case QTabletEvent::Airbrush:
+ type = QQuickPointerDevice::Airbrush;
+ buttonCount = 2;
+ break;
+ case QTabletEvent::Puck:
+ type = QQuickPointerDevice::Puck;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::FourDMouse:
+ type = QQuickPointerDevice::Mouse;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 3;
+ break;
+ default:
+ type = QQuickPointerDevice::UnknownDevice;
+ break;
+ }
+
+ PointerType ptype = GenericPointer;
+ switch (event->pointerType()) {
+ case QTabletEvent::Pen:
+ ptype = Pen;
+ break;
+ case QTabletEvent::Eraser:
+ ptype = Eraser;
+ break;
+ case QTabletEvent::Cursor:
+ ptype = Cursor;
+ break;
+ case QTabletEvent::UnknownPointer:
+ break;
+ }
+
+ QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
+ QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());
+
+ g_tabletDevices->insert(key, device);
+ return device;
}
/*!
@@ -1284,6 +1343,12 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
QQuickPointerEvent::~QQuickPointerEvent()
{}
+QQuickPointerMouseEvent::QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
{
auto ev = static_cast<QMouseEvent*>(event);
@@ -1398,6 +1463,12 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
}
#if QT_CONFIG(gestures)
+QQuickPointerNativeGestureEvent::QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
auto ev = static_cast<QNativeGestureEvent*>(event);
@@ -1560,6 +1631,12 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
\note Many platforms provide no such information. On such platforms,
\c inverted always returns false.
*/
+QQuickPointerScrollEvent::QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
@@ -1832,6 +1909,81 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
return &m_synthMouseEvent;
}
+#if QT_CONFIG(tabletevent)
+QQuickPointerTabletEvent::QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventTabletPoint(this);
+}
+
+QQuickPointerEvent *QQuickPointerTabletEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QTabletEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ Q_ASSERT(m_device == QQuickPointerDevice::tabletDevice(ev));
+ m_device->eventDeliveryTargets().clear();
+ m_button = ev->button();
+ m_pressedButtons = ev->buttons();
+ static_cast<QQuickEventTabletPoint *>(m_point)->reset(ev);
+ return this;
+}
+
+QQuickEventTabletPoint::QQuickEventTabletPoint(QQuickPointerTabletEvent *parent)
+ : QQuickEventPoint(parent)
+{
+}
+
+void QQuickEventTabletPoint::reset(const QTabletEvent *ev)
+{
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (ev->type()) {
+ case QEvent::TabletPress:
+ state = Qt::TouchPointPressed;
+ clearPassiveGrabbers();
+ break;
+ case QEvent::TabletRelease:
+ state = Qt::TouchPointReleased;
+ break;
+ case QEvent::TabletMove:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ break;
+ }
+ QQuickEventPoint::reset(state, ev->posF(), 1, ev->timestamp());
+ m_rotation = ev->rotation();
+ m_pressure = ev->pressure();
+ m_tangentialPressure = ev->tangentialPressure();
+ m_tilt = QVector2D(ev->xTilt(), ev->yTilt());
+}
+
+bool QQuickPointerTabletEvent::isPressEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletPress;
+}
+
+bool QQuickPointerTabletEvent::isUpdateEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletMove;
+}
+
+bool QQuickPointerTabletEvent::isReleaseEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletRelease;
+}
+
+QTabletEvent *QQuickPointerTabletEvent::asTabletEvent() const
+{
+ return static_cast<QTabletEvent *>(m_event);
+}
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::isPressEvent() const
{
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 94b61fd364..84450e060a 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -478,8 +478,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointEvent : public QQuickPointerEvent
{
Q_OBJECT
public:
- QQuickSinglePointEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickPointerEvent(parent, device), m_point(new QQuickEventPoint(this)) { }
+ QQuickSinglePointEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickPointerEvent(parent, device) { }
void localize(QQuickItem *target) override;
int pointCount() const override { return 1; }
@@ -493,7 +493,7 @@ public:
bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
protected:
- QQuickEventPoint *m_point;
+ QQuickEventPoint *m_point = nullptr;
Q_DISABLE_COPY(QQuickSinglePointEvent)
};
@@ -507,8 +507,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointE
QML_ADDED_IN_MINOR_VERSION(12)
public:
- QQuickPointerMouseEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -570,6 +569,60 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+#if QT_CONFIG(tabletevent)
+class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(qreal tangentialPressure READ tangentialPressure)
+ Q_PROPERTY(QVector2D tilt READ tilt)
+
+ QML_NAMED_ELEMENT(EventTabletPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(15)
+
+public:
+ QQuickEventTabletPoint(QQuickPointerTabletEvent *parent);
+
+ void reset(const QTabletEvent *e);
+
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ qreal tangentialPressure() const { return m_tangentialPressure; }
+ QVector2D tilt() const { return m_tilt; }
+
+private:
+ qreal m_rotation;
+ qreal m_pressure;
+ qreal m_tangentialPressure;
+ QVector2D m_tilt;
+
+ friend class QQuickPointerTouchEvent;
+
+ Q_DISABLE_COPY(QQuickEventTabletPoint)
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerTabletEvent : public QQuickSinglePointEvent
+{
+ Q_OBJECT
+public:
+ QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device);
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerTabletEvent *asPointerTabletEvent() override { return this; }
+ const QQuickPointerTabletEvent *asPointerTabletEvent() const override { return this; }
+ const QQuickEventTabletPoint *tabletPoint() const { return static_cast<QQuickEventTabletPoint *>(m_point); }
+
+ QTabletEvent *asTabletEvent() const;
+
+ Q_DISABLE_COPY(QQuickPointerTabletEvent)
+};
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSinglePointEvent
{
@@ -578,8 +631,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSing
Q_PROPERTY(qreal value READ value CONSTANT)
public:
- QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -608,8 +660,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
QML_ADDED_IN_MINOR_VERSION(14)
public:
- QQuickPointerScrollEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
void localize(QQuickItem *target) override;
@@ -714,7 +765,7 @@ public:
static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
- static QQuickPointerDevice *tabletDevice(qint64);
+ static QQuickPointerDevice *tabletDevice(const QTabletEvent *event);
QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 8ade5b7e37..27c57e147a 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -128,8 +128,13 @@ void QQuickFlickableVisibleArea::updateVisible()
// Vertical
const qreal viewheight = flickable->height();
const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
- qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
- qreal pageSize = viewheight / (maxyextent + viewheight);
+ const qreal maxYBounds = maxyextent + viewheight;
+ qreal pagePos = 0;
+ qreal pageSize = 0;
+ if (!qFuzzyIsNull(maxYBounds)) {
+ pagePos = (-p->vData.move.value() + flickable->minYExtent()) / maxYBounds;
+ pageSize = viewheight / maxYBounds;
+ }
if (pageSize != m_heightRatio) {
m_heightRatio = pageSize;
@@ -143,8 +148,14 @@ void QQuickFlickableVisibleArea::updateVisible()
// Horizontal
const qreal viewwidth = flickable->width();
const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
- pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
- pageSize = viewwidth / (maxxextent + viewwidth);
+ const qreal maxXBounds = maxxextent + viewwidth;
+ if (!qFuzzyIsNull(maxXBounds)) {
+ pagePos = (-p->hData.move.value() + flickable->minXExtent()) / maxXBounds;
+ pageSize = viewwidth / maxXBounds;
+ } else {
+ pagePos = 0;
+ pageSize = 0;
+ }
if (pageSize != m_widthRatio) {
m_widthRatio = pageSize;
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 1ff55dae90..3f5f11effd 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -73,7 +73,7 @@ class QQuickFlickableVisibleArea;
class QQuickTransition;
class QQuickFlickableReboundTransition;
-class Q_AUTOTEST_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickFlickable)
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index bd6b9d741e..125518e51b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -183,13 +183,6 @@ static void qt_quickitems_defineModule()
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
qRegisterMetaType<QQuickHandlerPoint>();
-
-#if !QT_CONFIG(quick_animatedimage)
- qmlRegisterTypeNotAvailable(
- "QtQuick", 2, 15, "AnimatedImage",
- QCoreApplication::translate("QQuickAnimatedImage",
- "Qt was built without support for QMovie"));
-#endif
}
static void initResources()
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index 6ceb0d56e6..28dff65dff 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
#include <QtGui/qevent.h>
#include <qqml.h>
@@ -71,6 +72,17 @@ struct QPointingDeviceUniqueIdForeign
QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.")
};
+#if !QT_CONFIG(quick_animatedimage)
+struct QQuickAnimatedImageNotAvailable
+{
+ Q_GADGET
+ QML_UNAVAILABLE
+ QML_NAMED_ELEMENT(AnimatedImage)
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_UNCREATABLE("Qt was built without support for QMovie.")
+};
+#endif
+
QT_END_NAMESPACE
#endif // QQUICKITEMSMODULE_P_H
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 7fb392233e..3e3a2c262b 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2419,7 +2419,7 @@ void QQuickItemView::destroyingItem(QObject *object)
Q_D(QQuickItemView);
QQuickItem* item = qmlobject_cast<QQuickItem*>(object);
if (item) {
- item->setParentItem(nullptr);
+ QQuickItemPrivate::get(item)->setCulled(true);
d->unrequestedItems.remove(item);
}
}
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index badd2efe29..b91e705ad0 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -141,6 +141,8 @@ public:
QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+ void fixupHeader();
+ void fixupHeaderCompleted();
QQuickListView::Orientation orient;
qreal visiblePos;
qreal averageSize;
@@ -169,6 +171,12 @@ public:
QString nextSection;
qreal overshootDist;
+
+ qreal desiredViewportPosition;
+ qreal fixupHeaderPosition;
+ bool headerNeedsSeparateFixup : 1;
+ bool desiredHeaderVisible : 1;
+
bool correctFlick : 1;
bool inFlickCorrection : 1;
@@ -182,7 +190,9 @@ public:
, highlightPosAnimator(nullptr), highlightWidthAnimator(nullptr), highlightHeightAnimator(nullptr)
, highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1)
, sectionCriteria(nullptr), currentSectionItem(nullptr), nextSectionItem(nullptr)
- , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
+ , overshootDist(0.0), desiredViewportPosition(0.0), fixupHeaderPosition(0.0)
+ , headerNeedsSeparateFixup(false), desiredHeaderVisible(false)
+ , correctFlick(false), inFlickCorrection(false)
{
highlightMoveDuration = -1; //override default value set in base class
}
@@ -1402,6 +1412,31 @@ void QQuickListViewPrivate::updateFooter()
emit q->footerItemChanged();
}
+void QQuickListViewPrivate::fixupHeaderCompleted()
+{
+ headerNeedsSeparateFixup = false;
+ QObjectPrivate::disconnect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+}
+
+void QQuickListViewPrivate::fixupHeader()
+{
+ FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
+ if (fixingUp && headerPositioning == QQuickListView::PullBackHeader && visibleItems.count()) {
+ int fixupDura = timeline.duration();
+ if (fixupDura < 0)
+ fixupDura = fixupDuration/2;
+ const int t = timeline.time();
+
+ const qreal progress = qreal(t)/fixupDura;
+ const qreal ultimateHeaderPosition = desiredHeaderVisible ? desiredViewportPosition : desiredViewportPosition - headerSize();
+ const qreal headerPosition = fixupHeaderPosition * (1 - progress) + ultimateHeaderPosition * progress;
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ const qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
+ listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
+ }
+}
+
void QQuickListViewPrivate::updateHeader()
{
Q_Q(QQuickListView);
@@ -1419,9 +1454,14 @@ void QQuickListViewPrivate::updateHeader()
if (headerPositioning == QQuickListView::OverlayHeader) {
listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
} else if (visibleItems.count()) {
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
if (headerPositioning == QQuickListView::PullBackHeader) {
- qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
- qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size());
+ qreal headerPosition = listItem->position();
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ // Make sure the header is not shown if we absolutely do not have any plans to show it
+ if (fixingUp && !headerNeedsSeparateFixup)
+ headerPosition = viewPos - headerSize();
+ qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
} else {
qreal startPos = originPosition();
@@ -1539,13 +1579,46 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
bias = -bias;
tempPosition -= bias;
}
- FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
+
+ qreal snapOffset = 0;
+ qreal overlayHeaderOffset = 0;
+ bool isHeaderWithinBounds = false;
+ if (header) {
+ qreal visiblePartOfHeader = header->position() + header->size() - tempPosition;
+ isHeaderWithinBounds = visiblePartOfHeader > 0;
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ break;
+ case QQuickListView::InlineHeader:
+ if (isHeaderWithinBounds && tempPosition < originPosition())
+ // For the inline header, we want to snap to the first item
+ // if we're more than halfway down the inline header.
+ // So if we look for an item halfway down of the header
+ snapOffset = header->size() / 2;
+ break;
+ case QQuickListView::PullBackHeader:
+ desiredHeaderVisible = visiblePartOfHeader > header->size()/2;
+ if (qFuzzyCompare(header->position(), tempPosition)) {
+ // header was pulled down; make sure it remains visible and snap items to bottom of header
+ snapOffset = header->size();
+ } else if (desiredHeaderVisible) {
+ // More than 50% of the header is shown. Show it fully.
+ // Scroll the view so the next item snaps to the header.
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ }
+ break;
+ }
+ }
+ FxViewItem *topItem = snapItemAt(tempPosition + snapOffset + highlightRangeStart);
if (strictHighlightRange && currentItem && (!topItem || (topItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
- FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
+ FxViewItem *bottomItem = snapItemAt(tempPosition + snapOffset + highlightRangeEnd);
if (strictHighlightRange && currentItem && (!bottomItem || (bottomItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
@@ -1553,27 +1626,92 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
}
qreal pos;
bool isInBounds = -position() > maxExtent && -position() <= minExtent;
- if (topItem && (isInBounds || strictHighlightRange)) {
- if (topItem->index == 0 && header && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
- pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart;
+
+ if (header && !topItem && isInBounds) {
+ // We are trying to pull back further than needed
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ pos = startPosition() - overlayHeaderOffset;
+ break;
+ case QQuickListView::InlineHeader:
+ pos = isContentFlowReversed() ? header->size() - size() : header->position();
+ break;
+ case QQuickListView::PullBackHeader:
+ pos = isContentFlowReversed() ? -size() : startPosition();
+ break;
+ }
+ } else if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && !hasStickyHeader() && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
+ pos = isContentFlowReversed() ? -header->position() + highlightRangeStart - size() : (header->position() - highlightRangeStart + header->size());
} else {
- if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size(), -maxExtent), -minExtent);
- else
- pos = qMax(qMin(static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart, -maxExtent), -minExtent);
+ if (header && headerPositioning == QQuickListView::PullBackHeader) {
+ // We pulled down the header. If it isn't pulled all way down, we need to snap
+ // the header.
+ if (qFuzzyCompare(tempPosition, header->position())) {
+ // It is pulled all way down. Scroll-snap the content, but not the header.
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + snapOffset;
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - snapOffset;
+ } else {
+ // Header is not pulled all way down, make it completely visible or hide it.
+ // Depends on how much of the header is visible.
+ if (desiredHeaderVisible) {
+ // More than half of the header is visible - show it.
+ // Scroll so that the topItem is aligned to a fully visible header
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + headerSize();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - headerSize();
+ } else {
+ // Less than half is visible - hide the header. Scroll so
+ // that the topItem is aligned to the top of the view
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart;
+ }
+ }
+
+ headerNeedsSeparateFixup = isHeaderWithinBounds || desiredHeaderVisible;
+ if (headerNeedsSeparateFixup) {
+ // We need to animate the header independently if it starts visible or should end as visible,
+ // since the header should not necessarily follow the content.
+ // Store the desired viewport position.
+ // Also store the header position so we know where to animate the header from (fixupHeaderPosition).
+ // We deduce the desired header position from the desiredViewportPosition variable.
+ pos = qBound(-minExtent, pos, -maxExtent);
+ desiredViewportPosition = isContentFlowReversed() ? -pos - size() : pos;
+
+ FxListItemSG *headerItem = static_cast<FxListItemSG*>(header);
+ fixupHeaderPosition = headerItem->position();
+
+ // follow the same fixup timeline
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::completed, this, &QQuickListViewPrivate::fixupHeaderCompleted);
+ }
+ } else if (isContentFlowReversed()) {
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + overlayHeaderOffset;
+ } else {
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - overlayHeaderOffset;
+ }
}
} else if (bottomItem && isInBounds) {
if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size(), -maxExtent), -minExtent);
+ pos = -static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size() + overlayHeaderOffset;
else
- pos = qMax(qMin(static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd, -maxExtent), -minExtent);
+ pos = static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd - overlayHeaderOffset;
} else {
QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
}
+ pos = qBound(-minExtent, pos, -maxExtent);
qreal dist = qAbs(data.move + pos);
- if (dist > 0) {
+ if (dist >= 0) {
+ // Even if dist == 0 we still start the timeline, because we use the same timeline for
+ // moving the header. And we might need to move the header while the content does not
+ // need moving
timeline.reset(data.move);
if (fixupMode != Immediate) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8722a45373..1fb71272b1 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -56,7 +56,7 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges
QQuickLoaderPrivate::QQuickLoaderPrivate()
: item(nullptr), object(nullptr), itemContext(nullptr), incubator(nullptr), updatingSize(false),
- active(true), loadingFromSource(false), asynchronous(false)
+ active(true), loadingFromSource(false), asynchronous(false), status(computeStatus())
{
}
@@ -379,7 +379,7 @@ void QQuickLoader::setActive(bool newVal)
d->object = nullptr;
emit itemChanged();
}
- emit statusChanged();
+ d->updateStatus();
}
emit activeChanged();
}
@@ -432,7 +432,7 @@ void QQuickLoader::loadFromSource()
Q_D(QQuickLoader);
if (d->source.isEmpty()) {
emit sourceChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -503,7 +503,7 @@ void QQuickLoader::loadFromSourceComponent()
Q_D(QQuickLoader);
if (!d->component) {
emit sourceComponentChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -619,7 +619,7 @@ void QQuickLoaderPrivate::load()
q, SLOT(_q_sourceLoaded()));
QObject::connect(component, SIGNAL(progressChanged(qreal)),
q, SIGNAL(progressChanged()));
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (loadingFromSource)
emit q->sourceChanged();
@@ -707,7 +707,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (status == QQmlIncubator::Ready)
emit q->loaded();
@@ -724,7 +724,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
emit q->itemChanged(); //Like clearing source, emit itemChanged even if previous item was also null
disposeInitialPropertyValues(); // cleanup
@@ -742,7 +742,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
component->create(*incubator, itemContext);
if (incubator && incubator->status() == QQmlIncubator::Loading)
- emit q->statusChanged();
+ updateStatus();
}
/*!
@@ -789,37 +789,7 @@ QQuickLoader::Status QQuickLoader::status() const
{
Q_D(const QQuickLoader);
- if (!d->active)
- return Null;
-
- if (d->component) {
- switch (d->component->status()) {
- case QQmlComponent::Loading:
- return Loading;
- case QQmlComponent::Error:
- return Error;
- case QQmlComponent::Null:
- return Null;
- default:
- break;
- }
- }
-
- if (d->incubator) {
- switch (d->incubator->status()) {
- case QQmlIncubator::Loading:
- return Loading;
- case QQmlIncubator::Error:
- return Error;
- default:
- break;
- }
- }
-
- if (d->object)
- return Ready;
-
- return d->source.isEmpty() ? Null : Error;
+ return static_cast<Status>(d->status);
}
void QQuickLoader::componentComplete()
@@ -1020,6 +990,51 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
return valuemap->asReturnedValue();
}
+QQuickLoader::Status QQuickLoaderPrivate::computeStatus() const
+{
+ if (!active)
+ return QQuickLoader::Status::Null;
+
+ if (component) {
+ switch (component->status()) {
+ case QQmlComponent::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlComponent::Error:
+ return QQuickLoader::Status::Error;
+ case QQmlComponent::Null:
+ return QQuickLoader::Status::Null;
+ default:
+ break;
+ }
+ }
+
+ if (incubator) {
+ switch (incubator->status()) {
+ case QQmlIncubator::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlIncubator::Error:
+ return QQuickLoader::Status::Error;
+ default:
+ break;
+ }
+ }
+
+ if (object)
+ return QQuickLoader::Status::Ready;
+
+ return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
+}
+
+void QQuickLoaderPrivate::updateStatus()
+{
+ Q_Q(QQuickLoader);
+ auto newStatus = computeStatus();
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
#include <moc_qquickloader_p.cpp>
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 349b5c6c06..39d50280c5 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -96,6 +96,8 @@ public:
void disposeInitialPropertyValues();
static QUrl resolveSourceUrl(QQmlV4Function *args);
QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error);
+ QQuickLoader::Status computeStatus() const;
+ void updateStatus();
qreal getImplicitWidth() const override;
qreal getImplicitHeight() const override;
@@ -112,6 +114,11 @@ public:
bool active : 1;
bool loadingFromSource : 1;
bool asynchronous : 1;
+ // We need to use char instead of QQuickLoader::Status
+ // as otherwise the size of the class would increase
+ // on 32-bit systems, as sizeof(Status) == sizeof(int)
+ // and sizeof(int) > remaining padding on 32 bit
+ char status;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 9a371207ce..3a807d3c66 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -88,20 +88,18 @@ void QQuickTouchPoint::setPointId(int id)
These properties hold the current position of the touch point.
*/
-void QQuickTouchPoint::setX(qreal x)
+void QQuickTouchPoint::setPosition(QPointF p)
{
- if (_x == x)
+ bool xch = (_x != p.x());
+ bool ych = (_y != p.y());
+ if (!xch && !ych)
return;
- _x = x;
- emit xChanged();
-}
-
-void QQuickTouchPoint::setY(qreal y)
-{
- if (_y == y)
- return;
- _y = y;
- emit yChanged();
+ _x = p.x();
+ _y = p.y();
+ if (xch)
+ emit xChanged();
+ if (ych)
+ emit yChanged();
}
/*!
@@ -798,8 +796,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT
//TODO: if !qmlDefined, could bypass setters.
// also, should only emit signals after all values have been set
dtp->setUniqueId(p->uniqueId());
- dtp->setX(p->pos().x());
- dtp->setY(p->pos().y());
+ dtp->setPosition(p->pos());
dtp->setEllipseDiameters(p->ellipseDiameters());
dtp->setPressure(p->pressure());
dtp->setRotation(p->rotation());
@@ -817,8 +814,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QM
{
dtp->setPreviousX(dtp->x());
dtp->setPreviousY(dtp->y());
- dtp->setX(e->localPos().x());
- dtp->setY(e->localPos().y());
+ dtp->setPosition(e->localPos());
if (e->type() == QEvent::MouseButtonPress) {
dtp->setStartX(e->localPos().x());
dtp->setStartY(e->localPos().y());
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 363e62593b..e34a3faad6 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -97,10 +97,8 @@ public:
void setUniqueId(const QPointingDeviceUniqueId &id);
qreal x() const { return _x; }
- void setX(qreal x);
-
qreal y() const { return _y; }
- void setY(qreal y);
+ void setPosition(QPointF pos);
QSizeF ellipseDiameters() const { return _ellipseDiameters; }
void setEllipseDiameters(const QSizeF &d);
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index f9f3e5cfa3..b298ed74da 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -161,10 +161,6 @@ public:
\l sourceItem while still handling input. For this, you can use
the \l hideSource property.
- \note If \l sourceItem is a \l Rectangle with border, by default half the
- border width falls outside the texture. To get the whole border, you can
- extend the \l sourceRect.
-
\note The ShaderEffectSource relies on FBO multisampling support
to antialias edges. If the underlying hardware does not support this,
which is the case for most embedded graphics chips, edges rendered
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index d76055c831..5ad33389de 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -330,6 +330,18 @@ inline int spriteCount(QQmlListProperty<QQuickSprite> *p)
return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
}
+inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, int idx, QQuickSprite *s)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->replace(idx, s);
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline void spriteRemoveLast(QQmlListProperty<QQuickSprite> *p)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->removeLast();
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
QT_END_NAMESPACE
#endif // QQUICKSPRITEENGINE_P_H
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index eb4b5335e7..c29938a1bb 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -162,7 +162,9 @@ void QQuickSpriteSequence::setInterpolate(bool arg)
QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
{
Q_D(QQuickSpriteSequence);
- return QQmlListProperty<QQuickSprite>(this, &d->m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &d->m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
bool QQuickSpriteSequence::running() const
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 496aea73d1..56c5bedd4d 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -2352,14 +2352,11 @@ void QQuickTableViewPrivate::connectToModel()
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::connect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- // Connect atYEndChanged to a function that fetches data if more is available
- QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
// When the model exposes a QAIM, we connect to it directly. This means that if the current model is
@@ -2387,13 +2384,10 @@ void QQuickTableViewPrivate::disconnectFromModel()
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::disconnect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
disconnect(aim, &QAbstractItemModel::rowsMoved, this, &QQuickTableViewPrivate::rowsMovedCallback);
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 03fe019916..a3cc39419f 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -91,7 +91,7 @@ private:
Q_DECLARE_PRIVATE(QQuickTableSectionSizeProvider)
};
-class Q_QML_AUTOTEST_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
{
Q_DECLARE_PUBLIC(QQuickTableView)
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index f89e7d970f..816b48b190 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -40,6 +40,9 @@
#include "qquicktext_p.h"
#include "qquicktext_p_p.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
@@ -1146,6 +1149,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elideLayout->setFont(layout.font());
elideLayout->setTextOption(layout.textOption());
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ elideText = service->foundElidedText(q, layoutText, elideText);
+ }
elideLayout->setText(elideText);
elideLayout->beginLayout();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 491334f439..5832242961 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -93,6 +93,7 @@ Q_LOGGING_CATEGORY(DBG_TOUCH, "qt.quick.touch")
Q_LOGGING_CATEGORY(DBG_TOUCH_TARGET, "qt.quick.touch.target")
Q_LOGGING_CATEGORY(DBG_MOUSE, "qt.quick.mouse")
Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target")
+Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet")
Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target")
Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target")
Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace")
@@ -547,7 +548,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
else
context->endNextFrame(renderer);
- if (renderer->hasCustomRenderModeWithContinuousUpdate()) {
+ if (renderer && renderer->hasCustomRenderModeWithContinuousUpdate()) {
// For the overdraw visualizer. This update is not urgent so avoid a
// direct update() call, this is only here to keep the overdraw
// visualization box rotating even when the scene is static.
@@ -682,10 +683,13 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear);
+ return QQmlListProperty<QObject>(q_func(), nullptr,
+ QQuickWindowPrivate::data_append,
+ QQuickWindowPrivate::data_count,
+ QQuickWindowPrivate::data_at,
+ QQuickWindowPrivate::data_clear,
+ QQuickWindowPrivate::data_replace,
+ QQuickWindowPrivate::data_removeLast);
}
static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
@@ -2119,6 +2123,17 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
}
#endif // wheelevent
+#if QT_CONFIG(tabletevent)
+/*! \reimp */
+void QQuickWindow::tabletEvent(QTabletEvent *event)
+{
+ Q_D(QQuickWindow);
+ qCDebug(lcTablet) << event;
+ // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here
+ d->deliverPointerEvent(d->pointerEventInstance(event));
+}
+#endif // tabletevent
+
bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
{
qCDebug(DBG_TOUCH) << event;
@@ -2397,8 +2412,12 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
+ case QQuickPointerDevice::Stylus:
+ case QQuickPointerDevice::Airbrush:
+ case QQuickPointerDevice::Puck:
+ ev = new QQuickPointerTabletEvent(q, device);
+ break;
default:
- // TODO tablet event types
break;
}
pointerEventInstances << ev;
@@ -2429,7 +2448,15 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
break;
- // TODO tablet event types
+#if QT_CONFIG(tabletevent)
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ dev = QQuickPointerDevice::tabletDevice(static_cast<QTabletEvent *>(event));
+ break;
+#endif
#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
@@ -2464,6 +2491,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverTouchEvent(event->asPointerTouchEvent());
} else {
deliverSinglePointEventUntilAccepted(event);
+ // If any handler got interested in the tablet event, we don't want to receive a synth-mouse event from QtGui
+ // TODO Qt 6: QTabletEvent will be accepted by default, like other events
+ if (event->asPointerTabletEvent() &&
+ (!event->point(0)->passiveGrabbers().isEmpty() || event->point(0)->exclusiveGrabber()))
+ event->setAccepted(true);
}
event->reset(nullptr);
@@ -3257,6 +3289,20 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
itemProperty.clear(&itemProperty);
}
+void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, int i, QObject *o)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.replace(&itemProperty, i, o);
+}
+
+void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.removeLast(&itemProperty);
+}
+
bool QQuickWindowPrivate::isRenderable() const
{
Q_Q(const QQuickWindow);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index d22bba4512..097627374c 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -252,6 +252,9 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *) override;
#endif
+#if QT_CONFIG(tabletevent)
+ void tabletEvent(QTabletEvent *) override;
+#endif
private Q_SLOTS:
void maybeUpdate();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 6e6dc7a400..86bdaf6396 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -299,6 +299,8 @@ public:
static int data_count(QQmlListProperty<QObject> *);
static QObject *data_at(QQmlListProperty<QObject> *, int);
static void data_clear(QQmlListProperty<QObject> *);
+ static void data_replace(QQmlListProperty<QObject> *, int, QObject *);
+ static void data_removeLast(QQmlListProperty<QObject> *);
static void contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h
index f6376a6d17..80e59563c7 100644
--- a/src/quick/qtquickglobal_p.h
+++ b/src/quick/qtquickglobal_p.h
@@ -61,6 +61,8 @@
#define Q_QUICK_PRIVATE_EXPORT Q_QUICK_EXPORT
+void Q_QUICK_PRIVATE_EXPORT qml_register_types_QtQuick();
+
QT_BEGIN_NAMESPACE
void QQuick_initializeProviders();
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 6db2ae884e..9ddd67c33d 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -23,13 +23,10 @@ exists("qqml_enable_gcov") {
QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf
-ANDROID_LIB_DEPENDENCIES = \
- lib/libQt5QuickParticles.so
MODULE_PLUGIN_TYPES += \
scenegraph
ANDROID_BUNDLED_FILES += \
- qml \
- lib/libQt5QuickParticles.so
+ qml
include(util/util.pri)
include(scenegraph/scenegraph.pri)
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4777f46f0a..9b288029b4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -660,6 +660,11 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted");
}
+ // Two special cases: For grabs we do not care about blocking the gui
+ // (main) thread. When this is from an expose, we will keep locked until
+ // the frame is rendered (submitted), so in that case waking happens later
+ // in syncAndRender(). Otherwise, wake now and let the main thread go on
+ // while we render.
if (!inExpose && !inGrab) {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui");
waitCondition.wakeOne();
@@ -756,13 +761,11 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)));
// Before returning we need to ensure the same wake up logic that
// would have happened if beginFrame() had suceeded.
- if (exposeRequested) {
+ if (syncRequested && !grabRequested) {
+ // Lock like sync() would do. Note that exposeRequested always includes syncRequested.
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui");
- waitCondition.wakeOne();
- mutex.unlock();
- } else if (syncRequested && !grabRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui like sync would do");
mutex.lock();
+ // Go ahead with waking because we will return right after this.
waitCondition.wakeOne();
mutex.unlock();
}
@@ -885,7 +888,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
// has started rendering with a bad window, causing makeCurrent to
// fail or if the window has a bad size.
if (exposeRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose");
+ // With expose sync() did not wake gui, do it now.
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after expose");
waitCondition.wakeOne();
mutex.unlock();
}
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 2ae9debbc9..8846edcd44 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -427,11 +427,12 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
imgio.setScaledSize(scSize);
if (!requestRegion.isNull())
imgio.setScaledClipRect(requestRegion);
+ const QSize originalSize = imgio.size();
qCDebug(lcImg) << url << "frame" << frame << "of" << imgio.imageCount()
- << "requestRegion" << requestRegion << "QImageReader size" << imgio.size() << "-> scSize" << scSize;
+ << "requestRegion" << requestRegion << "QImageReader size" << originalSize << "-> scSize" << scSize;
if (impsize)
- *impsize = imgio.size();
+ *impsize = originalSize;
if (imgio.read(image)) {
maybeRemoveAlpha(image);
@@ -1025,8 +1026,11 @@ public:
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.region == *rhs.region && *lhs.size == *rhs.size && *lhs.url == *rhs.url &&
- lhs.options == rhs.options && lhs.frame == rhs.frame;
+ return *lhs.url == *rhs.url &&
+ *lhs.region == *rhs.region &&
+ *lhs.size == *rhs.size &&
+ lhs.frame == rhs.frame &&
+ lhs.options == rhs.options;
}
inline uint qHash(const QQuickPixmapKey &key)
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index c106528f45..71ab1f4d62 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -267,9 +267,13 @@ void QQuickState::setExtends(const QString &extends)
QQmlListProperty<QQuickStateOperation> QQuickState::changes()
{
Q_D(QQuickState);
- return QQmlListProperty<QQuickStateOperation>(this, &d->operations, QQuickStatePrivate::operations_append,
- QQuickStatePrivate::operations_count, QQuickStatePrivate::operations_at,
- QQuickStatePrivate::operations_clear);
+ return QQmlListProperty<QQuickStateOperation>(this, &d->operations,
+ QQuickStatePrivate::operations_append,
+ QQuickStatePrivate::operations_count,
+ QQuickStatePrivate::operations_at,
+ QQuickStatePrivate::operations_clear,
+ QQuickStatePrivate::operations_replace,
+ QQuickStatePrivate::operations_removeLast);
}
int QQuickState::operationCount() const
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index 2fa5321165..ae4ed291b5 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -244,6 +244,23 @@ public:
QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
return list->at(index);
}
+ static void operations_replace(QQmlListProperty<QQuickStateOperation> *prop, int index,
+ QQuickStateOperation *op) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ auto &guard = list->at(index);
+ if (guard.object() == op) {
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ } else {
+ list->at(index)->setState(nullptr);
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ list->replace(index, OperationGuard(op, list));
+ }
+ }
+ static void operations_removeLast(QQmlListProperty<QQuickStateOperation> *prop) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ list->last()->setState(nullptr);
+ list->removeLast();
+ }
QQuickTransitionManager transitionManager;
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 46e7d62fc1..2109aafc10 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -70,6 +70,8 @@ public:
static int count_state(QQmlListProperty<QQuickState> *list);
static QQuickState *at_state(QQmlListProperty<QQuickState> *list, int index);
static void clear_states(QQmlListProperty<QQuickState> *list);
+ static void replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state);
+ static void removeLast_states(QQmlListProperty<QQuickState> *list);
static void append_transition(QQmlListProperty<QQuickTransition> *list, QQuickTransition *state);
static int count_transitions(QQmlListProperty<QQuickTransition> *list);
@@ -163,10 +165,13 @@ QList<QQuickState *> QQuickStateGroup::states() const
QQmlListProperty<QQuickState> QQuickStateGroup::statesProperty()
{
Q_D(QQuickStateGroup);
- return QQmlListProperty<QQuickState>(this, &d->states, &QQuickStateGroupPrivate::append_state,
- &QQuickStateGroupPrivate::count_state,
- &QQuickStateGroupPrivate::at_state,
- &QQuickStateGroupPrivate::clear_states);
+ return QQmlListProperty<QQuickState>(this, &d->states,
+ &QQuickStateGroupPrivate::append_state,
+ &QQuickStateGroupPrivate::count_state,
+ &QQuickStateGroupPrivate::at_state,
+ &QQuickStateGroupPrivate::clear_states,
+ &QQuickStateGroupPrivate::replace_states,
+ &QQuickStateGroupPrivate::removeLast_states);
}
void QQuickStateGroupPrivate::append_state(QQmlListProperty<QQuickState> *list, QQuickState *state)
@@ -201,6 +206,29 @@ void QQuickStateGroupPrivate::clear_states(QQmlListProperty<QQuickState> *list)
_this->d_func()->states.clear();
}
+void QQuickStateGroupPrivate::replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state)
+{
+ auto *self = qobject_cast<QQuickStateGroup *>(list->object);
+ auto *d = self->d_func();
+ auto *oldState = d->states.at(index);
+ if (oldState != state) {
+ oldState->setStateGroup(nullptr);
+ state->setStateGroup(self);
+ d->states.replace(index, state);
+ if (d->currentState == oldState->name())
+ d->setCurrentStateInternal(state->name(), true);
+ }
+}
+
+void QQuickStateGroupPrivate::removeLast_states(QQmlListProperty<QQuickState> *list)
+{
+ auto *d = qobject_cast<QQuickStateGroup *>(list->object)->d_func();
+ if (d->currentState == d->states.last()->name())
+ d->setCurrentStateInternal(d->states.length() > 1 ? d->states.first()->name() : QString(), true);
+ d->states.last()->setStateGroup(nullptr);
+ d->states.removeLast();
+}
+
/*!
\qmlproperty list<Transition> QtQuick::StateGroup::transitions
This property holds a list of transitions defined by the state group.
diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h
index abb5369b7b..fc5bd15ed1 100644
--- a/src/quick/util/qquicktimeline_p_p.h
+++ b/src/quick/util/qquicktimeline_p_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/QObject>
+#include <private/qtquickglobal_p.h>
#include "private/qabstractanimationjob_p.h"
QT_BEGIN_NAMESPACE
@@ -61,7 +62,7 @@ class QQuickTimeLineValue;
class QQuickTimeLineCallback;
struct QQuickTimeLinePrivate;
class QQuickTimeLineObject;
-class Q_AUTOTEST_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
+class Q_QUICK_PRIVATE_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
{
Q_OBJECT
public:
diff --git a/src/quickshapes/qquickshapesglobal_p.h b/src/quickshapes/qquickshapesglobal_p.h
index 2f559b45a0..40f6cfbdcf 100644
--- a/src/quickshapes/qquickshapesglobal_p.h
+++ b/src/quickshapes/qquickshapesglobal_p.h
@@ -59,5 +59,6 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
+void Q_QUICKSHAPES_PRIVATE_EXPORT qml_register_types_QtQuick_Shapes();
#endif // QQUICKSHAPESGLOBAL_P_H