Merge tag 'v6.5.5-lts' into tqtc/lts-6.5-opensource
Qt 6.5.5-lts release Conflicts solved: dependencies.yaml src/quick/doc/snippets/qml/treeview/qml-customdelegate.qml Change-Id: Ifa297315fa0e6e70d9f26312f9183da4769d18fc
This commit is contained in:
commit
7ac842cba1
|
@ -1,4 +1,4 @@
|
|||
set(QT_REPO_MODULE_VERSION "6.5.4")
|
||||
set(QT_REPO_MODULE_VERSION "6.5.5")
|
||||
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
|
||||
|
||||
set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1")
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
dependencies:
|
||||
../tqtc-qtbase:
|
||||
ref: 8ff0b254e4c3db81254782262d827f7831d15f6b
|
||||
ref: fdf57f5df57e7d12cf871699d857a71acf272e0c
|
||||
required: true
|
||||
../tqtc-qtimageformats:
|
||||
ref: 8170735657e6df87c1275b6ad7ca1e60ed0b9314
|
||||
ref: 93317400471b1ef875471bfd719b00fe4fffc4fe
|
||||
required: false
|
||||
../tqtc-qtlanguageserver:
|
||||
ref: c24ae032c6991321046bb47ba3b680ddac1c242c
|
||||
ref: a4240e7eea774e7cc3019e3f1bf3168fd76612bc
|
||||
required: false
|
||||
../tqtc-qtshadertools:
|
||||
ref: 5bf9de4a39fe2385998307c3e5ae16df6c0a5bd7
|
||||
ref: 8191dce7e16f9bf42476c41a3b7aab9a62b26daa
|
||||
required: false
|
||||
../tqtc-qtsvg:
|
||||
ref: 7c01c49a83d851196d990da86c08d59b3c7951f8
|
||||
ref: c9ca482a2876fb7d37717e5146eb37f7e26f03da
|
||||
required: false
|
||||
|
|
|
@ -45,7 +45,5 @@ install(TARGETS painteditemexample
|
|||
include(../../shared/QtBundleQmlModuleForMacOS.cmake)
|
||||
|
||||
set(app_target "painteditemexample")
|
||||
set(qml_plugin_target "qmltextballoon")
|
||||
set(qml_module_uri "TextBalloon")
|
||||
add_qml_module_to_macos_app_bundle(
|
||||
"${app_target}" "${qml_plugin_target}" "${qml_module_uri}")
|
||||
set(qml_module "qmltextballoon")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "${qml_module}")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<RCC>
|
||||
<qresource prefix="/qt/qml/embeddedinwidgets">
|
||||
<qresource prefix="/embeddedinwidgets">
|
||||
<file>main.qml</file>
|
||||
<file>reflect.frag.qsb</file>
|
||||
</qresource>
|
||||
|
|
|
@ -9,6 +9,7 @@ TapHandler {
|
|||
signal triggered(string text)
|
||||
|
||||
id: menuTap
|
||||
acceptedButtons: Qt.RightButton
|
||||
gesturePolicy: TapHandler.DragWithinBounds
|
||||
onPressedChanged: if (pressed) {
|
||||
impl.x = point.position.x - impl.width / 2
|
||||
|
@ -22,7 +23,10 @@ TapHandler {
|
|||
parent: menuTap.parent
|
||||
width: 100
|
||||
height: 100
|
||||
scale: Math.min(1, Math.max(0, menuTap.timeHeld * 4))
|
||||
// with touchscreen or stylus, long-press slowly expands the menu to size
|
||||
// with mouse or touchpad right-click, it opens instantly
|
||||
scale: menuTap.point.device.pointerType === PointerDevice.Generic ?
|
||||
1 : Math.min(1, Math.max(0, menuTap.timeHeld * 4))
|
||||
opacity: scale * 2
|
||||
visible: menuTap.pressed
|
||||
property Shape highlightedShape: null
|
||||
|
|
|
@ -63,14 +63,22 @@ MainWindow::MainWindow()
|
|||
setCentralWidget(centralWidget);
|
||||
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(tr("Grab framebuffer"), this, &MainWindow::grabFramebuffer);
|
||||
fileMenu->addAction(tr("Render to pixmap"), this, &MainWindow::renderToPixmap);
|
||||
fileMenu->addAction(tr("Grab via grabToImage"), this, &MainWindow::grabToImage);
|
||||
auto grabAction = fileMenu->addAction(tr("Grab framebuffer"), this, &MainWindow::grabFramebuffer);
|
||||
auto renderAction = fileMenu->addAction(tr("Render to pixmap"), this, &MainWindow::renderToPixmap);
|
||||
auto grabToImageAction = fileMenu->addAction(tr("Grab via grabToImage"), this, &MainWindow::grabToImage);
|
||||
fileMenu->addAction(tr("Quit"), qApp, &QCoreApplication::quit);
|
||||
|
||||
QMenu *windowMenu = menuBar()->addMenu(tr("&Window"));
|
||||
windowMenu->addAction(tr("Add tab widget"), this,
|
||||
[this, centralWidget] { createQuickWidgetsInTabs(centralWidget); });
|
||||
|
||||
connect(m_quickWidget, &QObject::destroyed, this,
|
||||
[this, grabAction, renderAction, grabToImageAction] {
|
||||
m_quickWidget = nullptr;
|
||||
grabAction->setEnabled(false);
|
||||
renderAction->setEnabled(false);
|
||||
grabToImageAction->setEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::createQuickWidgetsInTabs(QMdiArea *mdiArea)
|
||||
|
@ -123,6 +131,7 @@ void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status)
|
|||
{
|
||||
if (status == QQuickWidget::Error) {
|
||||
QStringList errors;
|
||||
Q_ASSERT(m_quickWidget);
|
||||
const auto widgetErrors = m_quickWidget->errors();
|
||||
for (const QQmlError &error : widgetErrors)
|
||||
errors.append(error.toString());
|
||||
|
@ -147,12 +156,14 @@ template<class T> void saveToFile(QWidget *parent, T *saveable)
|
|||
|
||||
void MainWindow::grabFramebuffer()
|
||||
{
|
||||
Q_ASSERT(m_quickWidget);
|
||||
QImage image = m_quickWidget->grabFramebuffer();
|
||||
saveToFile(this, &image);
|
||||
}
|
||||
|
||||
void MainWindow::renderToPixmap()
|
||||
{
|
||||
Q_ASSERT(m_quickWidget);
|
||||
QPixmap pixmap(m_quickWidget->size());
|
||||
m_quickWidget->render(&pixmap);
|
||||
saveToFile(this, &pixmap);
|
||||
|
@ -165,6 +176,7 @@ void MainWindow::grabToImage()
|
|||
fd.setDefaultSuffix("png");
|
||||
fd.selectFile("test_grabToImage.png");
|
||||
if (fd.exec() == QDialog::Accepted) {
|
||||
Q_ASSERT(m_quickWidget);
|
||||
QMetaObject::invokeMethod(m_quickWidget->rootObject(), "performLayerBasedGrab",
|
||||
Q_ARG(QVariant, fd.selectedFiles().first()));
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
\ingroup qtquickexamples
|
||||
\brief Shows how to implement a custom geometry in the Qt Quick Scene Graph.
|
||||
|
||||
The custom geometry example shows how to create a QQuickItem which
|
||||
The custom geometry example shows how to create a \l QQuickItem that
|
||||
uses the scene graph API to build a custom geometry for the scene
|
||||
graph. It does this by creating a BezierCurve item which is made
|
||||
graph. It does this by creating a \c BezierCurve item, which is made
|
||||
part of the CustomGeometry module and makes use of this in a QML
|
||||
file.
|
||||
|
||||
|
@ -115,7 +115,7 @@
|
|||
\snippet scenegraph/customgeometry/beziercurve.cpp 6
|
||||
|
||||
The scene graph API provides a few commonly used material
|
||||
implementations. In this example we use the QSGFlatColorMaterial
|
||||
implementations. In this example we use the QSGFlatColorMaterial,
|
||||
which will fill the shape defined by the geometry with a solid
|
||||
color. Again we pass the ownership of the material to the node, so
|
||||
it can be cleaned up by the scene graph.
|
||||
|
@ -130,7 +130,7 @@
|
|||
|
||||
\snippet scenegraph/customgeometry/beziercurve.cpp 8
|
||||
|
||||
To fill the geometry, we first extract the vertex array from
|
||||
To fill the geometry we first extract the vertex array from
|
||||
it. Since we are using one of the default attribute sets, we can
|
||||
use the convenience function QSGGeometry::vertexDataAsPoint2D().
|
||||
Then we go through each segment and calculate its position and
|
||||
|
@ -138,7 +138,7 @@
|
|||
|
||||
\snippet scenegraph/customgeometry/beziercurve.cpp 9
|
||||
|
||||
In the end of the function, we return the node so the scene graph
|
||||
At the end of the function we return the node so the scene graph
|
||||
can render it.
|
||||
|
||||
\section1 Application Entry-Point
|
||||
|
@ -153,9 +153,26 @@
|
|||
To make use of the BezierCurve item, we need to register it in the QML
|
||||
engine, using the QML_ELEMENT macro. This gives it the name
|
||||
BezierCurve and makes it part of the \c {CustomGeometry 1.0}
|
||||
module as defined in the customgeometry.pro file:
|
||||
module as defined in the project's build files:
|
||||
|
||||
\if defined(onlinedocs)
|
||||
\tab {build-qt-app}{tab-cmake}{CMake}{checked}
|
||||
\tab {build-qt-app}{tab-qmake}{qmake}{}
|
||||
\tabcontent {tab-cmake}
|
||||
\else
|
||||
\section1 Using CMake
|
||||
\endif
|
||||
\quotefile scenegraph/customgeometry/CMakeLists.txt
|
||||
\if defined(onlinedocs)
|
||||
\endtabcontent
|
||||
\tabcontent {tab-qmake}
|
||||
\else
|
||||
\section1 Using qmake
|
||||
\endif
|
||||
\quotefile scenegraph/customgeometry/customgeometry.pro
|
||||
\if defined(onlinedocs)
|
||||
\endtabcontent
|
||||
\endif
|
||||
|
||||
As the bezier curve is drawn as line strips, we specify that
|
||||
the view should be multisampled to get antialiasing. This is not
|
||||
|
|
|
@ -103,6 +103,11 @@ Item {
|
|||
}
|
||||
|
||||
|
||||
Button {
|
||||
text: qsTr("Toggle custom item visibility")
|
||||
onClicked: custom.visible = !custom.visible
|
||||
}
|
||||
|
||||
CustomRender {
|
||||
id: custom
|
||||
width: Math.min(parent.width, parent.height)
|
||||
|
|
|
@ -42,10 +42,8 @@ include(QtBundleQmlModuleForMacOS.cmake)
|
|||
# Puts the shared qml module plugin and qmldir into the macOS app bundle directory.
|
||||
# Only call this function if your main project has the MACOSX_BUNDLE option set.
|
||||
function(bundle_shared app_target)
|
||||
set(qml_plugin_target "${PROJECT_NAME}_shared")
|
||||
set(qml_module_uri "shared")
|
||||
add_qml_module_to_macos_app_bundle(
|
||||
"${app_target}" "${qml_plugin_target}" "${qml_module_uri}")
|
||||
set(qml_module_target "${PROJECT_NAME}_shared")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "${qml_module_target}")
|
||||
endfunction()
|
||||
|
||||
set(INSTALL_SHAREDDIR "${INSTALL_EXAMPLESDIR}/quick/${PROJECT_NAME}/shared")
|
||||
|
|
|
@ -174,9 +174,14 @@ Rectangle {
|
|||
id: back
|
||||
source: "images/back.png"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: 2
|
||||
anchors.verticalCenterOffset: 1
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 16
|
||||
anchors.leftMargin: 6
|
||||
width: 38
|
||||
height: 31
|
||||
fillMode: Image.Pad
|
||||
horizontalAlignment: Image.AlignHCenter
|
||||
verticalAlignment: Image.AlignVCenter
|
||||
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
|
@ -188,10 +193,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.centerIn: back
|
||||
width: 38
|
||||
height: 31
|
||||
anchors.verticalCenterOffset: -1
|
||||
anchors.fill: parent
|
||||
opacity: tapHandler.pressed ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation{ duration: 100 }}
|
||||
gradient: Gradient {
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
function(add_qml_module_to_macos_app_bundle app_target qml_plugin_target qml_module_uri)
|
||||
function(add_qml_module_to_macos_app_bundle app_target qml_module)
|
||||
if(QT6_IS_SHARED_LIBS_BUILD AND APPLE)
|
||||
# The application's main.cpp adds an explicit QML import path to look for qml module plugins
|
||||
# under a PlugIns subdirectory of a macOS app bundle.
|
||||
# Copy the qmldir and shared library qml plugin.
|
||||
|
||||
qt6_query_qml_module(${qml_module}
|
||||
QMLDIR qmldir_file
|
||||
PLUGIN_TARGET qml_plugin_target
|
||||
URI qml_module_uri
|
||||
)
|
||||
|
||||
# Ensure the executable depends on the plugin so the plugin is copied
|
||||
# only after it was built.
|
||||
add_dependencies(${app_target} ${qml_plugin_target})
|
||||
|
@ -17,9 +23,6 @@ function(add_qml_module_to_macos_app_bundle app_target qml_plugin_target qml_mod
|
|||
|
||||
set(dest_module_dir_in_app_bundle "${app_dir}/../PlugIns/${escaped_uri}")
|
||||
|
||||
set(qml_plugin_dir "$<TARGET_FILE_DIR:${qml_plugin_target}>")
|
||||
set(qmldir_file "${qml_plugin_dir}/qmldir")
|
||||
|
||||
add_custom_command(TARGET ${app_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${dest_module_dir_in_app_bundle}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
|
|
|
@ -9,7 +9,7 @@ Rectangle {
|
|||
|
||||
property Item exampleItem
|
||||
width: ListView.view.width
|
||||
height: button.implicitHeight + 22
|
||||
height: col.implicitHeight + 22
|
||||
|
||||
signal clicked()
|
||||
|
||||
|
@ -22,10 +22,18 @@ Rectangle {
|
|||
GradientStop {
|
||||
position: 1
|
||||
Behavior on color {ColorAnimation { duration: 100 }}
|
||||
color: tapHandler.pressed ? "#e0e0e0" : button.containsMouse ? "#f5f5f5" : "#eee"
|
||||
color: tapHandler.pressed ? "#e0e0e0" : hoverHandler.hovered ? "#f5f5f5" : "#eee"
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
onTapped: container.clicked()
|
||||
}
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
opacity: 0.7
|
||||
|
@ -36,55 +44,30 @@ Rectangle {
|
|||
anchors.rightMargin: 16
|
||||
}
|
||||
|
||||
Item {
|
||||
id: button
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right:image.left
|
||||
implicitHeight: col.height
|
||||
height: implicitHeight
|
||||
width: buttonLabel.width + 20
|
||||
property alias containsMouse: hoverHandler.hovered
|
||||
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
onTapped: container.clicked()
|
||||
}
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
id: col
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
Text {
|
||||
id: buttonLabel
|
||||
spacing: 2
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
anchors.right:image.left
|
||||
anchors.margins: 10
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Text {
|
||||
width: parent.width
|
||||
text: container.name
|
||||
color: "black"
|
||||
font.pixelSize: 22
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
styleColor: "white"
|
||||
style: Text.Raised
|
||||
|
||||
}
|
||||
Text {
|
||||
id: buttonLabel2
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
width: parent.width
|
||||
text: container.description
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
color: "#666"
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
|
|
|
@ -46,7 +46,5 @@ install(TARGETS attachedstylepropertiesexample
|
|||
include(../../quick/shared/QtBundleQmlModuleForMacOS.cmake)
|
||||
|
||||
set(app_target "attachedstylepropertiesexample")
|
||||
set(qml_plugin_target "MyStyleplugin")
|
||||
set(qml_module_uri "MyStyle")
|
||||
add_qml_module_to_macos_app_bundle(
|
||||
"${app_target}" "${qml_plugin_target}" "${qml_module_uri}")
|
||||
set(qml_module_target "MyStyle")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "${qml_module_target}")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# Copyright (C) 2023 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
@ -28,7 +28,7 @@ qt_add_qml_module(contactlistexample
|
|||
"ContactForm.ui.qml"
|
||||
"ContactView.ui.qml"
|
||||
"SectionDelegate.ui.qml"
|
||||
"contactlist.qml"
|
||||
"ContactList.qml"
|
||||
"designer/Backend/ContactModel.qml"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
@ -7,14 +7,18 @@ import QtQuick.Controls
|
|||
|
||||
ItemDelegate {
|
||||
id: delegate
|
||||
|
||||
checkable: true
|
||||
|
||||
required property string fullName
|
||||
required property string address
|
||||
required property string city
|
||||
required property string number
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 10
|
||||
|
||||
Label {
|
||||
text: fullName
|
||||
text: delegate.fullName
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
|
@ -34,7 +38,7 @@ ItemDelegate {
|
|||
}
|
||||
|
||||
Label {
|
||||
text: address
|
||||
text: delegate.address
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
|
@ -46,7 +50,7 @@ ItemDelegate {
|
|||
}
|
||||
|
||||
Label {
|
||||
text: city
|
||||
text: delegate.city
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
|
@ -58,7 +62,7 @@ ItemDelegate {
|
|||
}
|
||||
|
||||
Label {
|
||||
text: number
|
||||
text: delegate.number
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
|
@ -74,6 +78,7 @@ ItemDelegate {
|
|||
PropertyChanges {
|
||||
// TODO: When Qt Design Studio supports generalized grouped properties, change to:
|
||||
// grid.visible: true
|
||||
// qmllint disable Quick.property-changes-parsed
|
||||
target: grid
|
||||
visible: true
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
@ -41,5 +41,9 @@ Dialog {
|
|||
id: form
|
||||
}
|
||||
|
||||
onAccepted: finished(form.fullName.text, form.address.text, form.city.text, form.number.text)
|
||||
onAccepted: {
|
||||
if (form.fullName.text && form.address.text && form.city.text && form.number.text) {
|
||||
finished(form.fullName.text, form.address.text, form.city.text, form.number.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
@ -17,10 +17,10 @@ ApplicationWindow {
|
|||
ContactDialog {
|
||||
id: contactDialog
|
||||
onFinished: function(fullName, address, city, number) {
|
||||
if (currentContact === -1)
|
||||
if (window.currentContact === -1)
|
||||
contactView.model.append(fullName, address, city, number)
|
||||
else
|
||||
contactView.model.set(currentContact, fullName, address, city, number)
|
||||
contactView.model.set(window.currentContact, fullName, address, city, number)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,23 +35,23 @@ ApplicationWindow {
|
|||
font.bold: true
|
||||
width: parent.width
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
text: currentContact >= 0 ? contactView.model.get(currentContact).fullName : ""
|
||||
text: window.currentContact >= 0 ? contactView.model.get(window.currentContact).fullName : ""
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Edit...")
|
||||
onTriggered: contactDialog.editContact(contactView.model.get(currentContact))
|
||||
onTriggered: contactDialog.editContact(contactView.model.get(window.currentContact))
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Remove")
|
||||
onTriggered: contactView.model.remove(currentContact)
|
||||
onTriggered: contactView.model.remove(window.currentContact)
|
||||
}
|
||||
}
|
||||
|
||||
ContactView {
|
||||
id: contactView
|
||||
anchors.fill: parent
|
||||
onPressAndHold: {
|
||||
currentContact = index
|
||||
onPressAndHold: function(index) {
|
||||
window.currentContact = index
|
||||
contactMenu.open()
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ ApplicationWindow {
|
|||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: {
|
||||
currentContact = -1
|
||||
window.currentContact = -1
|
||||
contactDialog.createContact()
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Backend
|
||||
import contactlist
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
|
@ -25,6 +27,9 @@ ListView {
|
|||
delegate: ContactDelegate {
|
||||
id: delegate
|
||||
width: listView.width
|
||||
|
||||
required property int index
|
||||
|
||||
onPressAndHold: listView.pressAndHold(index)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
@ -7,9 +7,11 @@ import QtQuick.Controls
|
|||
ToolBar {
|
||||
id: background
|
||||
|
||||
required property string section
|
||||
|
||||
Label {
|
||||
id: label
|
||||
text: section
|
||||
text: background.section
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
|
|
@ -2,6 +2,12 @@ TEMPLATE = app
|
|||
TARGET = contactlist
|
||||
QT += quick
|
||||
|
||||
CONFIG += qmltypes
|
||||
|
||||
QML_IMPORT_PATH = $$pwd/.
|
||||
QML_IMPORT_NAME = contactlist
|
||||
QML_IMPORT_MAJOR_VERSION = 1
|
||||
|
||||
HEADERS += \
|
||||
contactmodel.h
|
||||
|
||||
|
@ -9,15 +15,20 @@ SOURCES += \
|
|||
main.cpp \
|
||||
contactmodel.cpp
|
||||
|
||||
RESOURCES += \
|
||||
qml_resources.files = \
|
||||
qmldir \
|
||||
ContactDelegate.ui.qml \
|
||||
ContactDialog.qml \
|
||||
ContactForm.ui.qml \
|
||||
contactlist.qml \
|
||||
ContactList.qml \
|
||||
ContactView.ui.qml \
|
||||
designer/Backend/ContactModel.qml \
|
||||
SectionDelegate.ui.qml
|
||||
|
||||
qml_resources.prefix = /qt/qml/contactlist
|
||||
|
||||
RESOURCES += qml_resources
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH = $$PWD/designer
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "contactmodel.h"
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef CONTACTMODEL_H
|
||||
#define CONTACTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class ContactModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
public:
|
||||
enum ContactRole {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
#include "contactmodel.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
qmlRegisterType<ContactModel>("Backend", 1, 0, "ContactModel");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.load(QUrl(QStringLiteral("qrc:/contactlist.qml")));
|
||||
engine.loadFromModule("contactlist", "ContactList");
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
module contactlist
|
||||
|
||||
ContactDelegate 1.0 ContactDelegate.ui.qml
|
||||
ContactDialog 1.0 ContactDialog.qml
|
||||
ContactForm 1.0 ContactForm.ui.qml
|
||||
ContactList 1.0 ContactList.qml
|
||||
ContactView 1.0 ContactView.ui.qml
|
||||
SectionDelegate 1.0 SectionDelegate.ui.qml
|
|
@ -54,6 +54,6 @@ install(TARGETS wearableexample
|
|||
include(../../quick/shared/QtBundleQmlModuleForMacOS.cmake)
|
||||
|
||||
set(app_target "wearableexample")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearable" "Wearable")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearablesettings" "WearableSettings")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearablestyle" "WearableStyle")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearable")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearablesettings")
|
||||
add_qml_module_to_macos_app_bundle("${app_target}" "wearablestyle")
|
||||
|
|
|
@ -8,17 +8,17 @@
|
|||
"License": "BSD 2-clause \"Simplified\" License",
|
||||
"LicenseId": "BSD-2-Clause",
|
||||
"LicenseFile": "LICENSE",
|
||||
"Copyright": "Copyright (C) 2003-2018 Apple Inc. All rights reserved.
|
||||
Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
|
||||
Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. (http://www.torchmobile.com/)
|
||||
Copyright (C) 2009, 2010 University of Szeged
|
||||
Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
|
||||
Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
|
||||
Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
|
||||
Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
|
||||
Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
|
||||
Copyright (C) 2011 Google Inc. All rights reserved.
|
||||
Copyright (C) 2013 Samsung Electronics. All rights reserved.
|
||||
Copyright (C) 2015 Cisco Systems, Inc. All rights reserved.
|
||||
Copyright (c) 2002-2009 Vivek Thampi"
|
||||
"Copyright": ["Copyright (C) 2003-2018 Apple Inc. All rights reserved.",
|
||||
"Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)",
|
||||
"Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. (http://www.torchmobile.com/)",
|
||||
"Copyright (C) 2009, 2010 University of Szeged",
|
||||
"Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.",
|
||||
"Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.",
|
||||
"Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged",
|
||||
"Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.",
|
||||
"Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.",
|
||||
"Copyright (C) 2011 Google Inc. All rights reserved.",
|
||||
"Copyright (C) 2013 Samsung Electronics. All rights reserved.",
|
||||
"Copyright (C) 2015 Cisco Systems, Inc. All rights reserved.",
|
||||
"Copyright (c) 2002-2009 Vivek Thampi"]
|
||||
}
|
||||
|
|
|
@ -114,10 +114,7 @@ void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable,
|
|||
if (result == MAP_FAILED)
|
||||
CRASH();
|
||||
|
||||
while (madvise(result, bytes, MADV_DONTNEED)) {
|
||||
if (errno != EAGAIN)
|
||||
CRASH();
|
||||
}
|
||||
while (madvise(result, bytes, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
@ -250,8 +247,10 @@ void OSAllocator::decommit(void* address, size_t bytes)
|
|||
mmap(address, bytes, PROT_NONE, MAP_FIXED | MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#elif OS(LINUX)
|
||||
while (madvise(address, bytes, MADV_DONTNEED)) {
|
||||
if (errno != EAGAIN)
|
||||
CRASH();
|
||||
if (errno != EAGAIN) {
|
||||
memset(address, 0, bytes); // We rely on madvise to zero-out the memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mprotect(address, bytes, PROT_NONE))
|
||||
CRASH();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#version 440
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#version 440
|
||||
|
||||
|
|
|
@ -1662,6 +1662,10 @@ void QQuickMultiEffectPrivate::updateBlurItemsAmount(int blurLevel)
|
|||
if (!m_shaderEffect)
|
||||
return;
|
||||
|
||||
const auto engine = qmlEngine(q);
|
||||
if (!engine)
|
||||
return;
|
||||
|
||||
// Lowest blur level uses 3 items, highest 5 items.
|
||||
int itemsAmount = blurLevel == 0 ? 0 : blurLevel + 2;
|
||||
|
||||
|
@ -1669,7 +1673,6 @@ void QQuickMultiEffectPrivate::updateBlurItemsAmount(int blurLevel)
|
|||
// Add more blur items.
|
||||
// Note that by design blur items are only added and never reduced
|
||||
// during the lifetime of the effect component.
|
||||
const auto engine = qmlEngine(q);
|
||||
QUrl blurVs = QUrl(QStringLiteral("qrc:/data/shaders/bluritems.vert.qsb"));
|
||||
QUrl blurFs = QUrl(QStringLiteral("qrc:/data/shaders/bluritems.frag.qsb"));
|
||||
QQmlComponent blurComponent(engine, QUrl(QStringLiteral("qrc:/data/BlurItem.qml")));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#version 440
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "quicklintplugin.h"
|
||||
|
||||
|
@ -761,11 +761,13 @@ void PropertyChangesValidatorPass::run(const QQmlSA::Element &element)
|
|||
return;
|
||||
|
||||
QString targetId = u"<id>"_s;
|
||||
const QString targetBinding = sourceCode(target->sourceLocation());
|
||||
const auto targetLocation = target->sourceLocation();
|
||||
const QString targetBinding = sourceCode(targetLocation);
|
||||
const QQmlSA::Element targetElement = resolveIdToElement(targetBinding, element);
|
||||
if (!targetElement.isNull())
|
||||
targetId = targetBinding;
|
||||
|
||||
bool hadCustomParsedBindings = false;
|
||||
for (auto it = bindings.begin(), end = bindings.end(); it != end; ++it) {
|
||||
const QString name = it->propertyName();
|
||||
if (element->hasProperty(name))
|
||||
|
@ -783,12 +785,19 @@ void PropertyChangesValidatorPass::run(const QQmlSA::Element &element)
|
|||
if (binding.length() > 16)
|
||||
binding = binding.left(13) + "..."_L1;
|
||||
|
||||
hadCustomParsedBindings = true;
|
||||
emitWarning(
|
||||
"Property \"%1\" is custom-parsed in PropertyChanges. "
|
||||
"You should phrase this binding as \"%2.%1: %3\""_L1
|
||||
.arg(name, targetId, binding),
|
||||
quickPropertyChangesParsed, bindingLocation);
|
||||
}
|
||||
|
||||
if (hadCustomParsedBindings && !targetElement.isNull()) {
|
||||
emitWarning("You should remove any bindings on the \"target\" property and avoid "
|
||||
"custom-parsed bindings in PropertyChanges.",
|
||||
quickPropertyChangesParsed, targetLocation);
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QUICKLINTPLUGIN_H
|
||||
#define QUICKLINTPLUGIN_H
|
||||
|
|
|
@ -226,6 +226,16 @@ function(_qt_internal_deploy_qml_imports_for_target)
|
|||
endforeach()
|
||||
endif()
|
||||
|
||||
# Install runtime dependencies on Windows.
|
||||
if(__QT_DEPLOY_SYSTEM_NAME STREQUAL "Windows")
|
||||
foreach(file IN LISTS __QT_DEPLOY_TARGET_${entry_LINKTARGET}_RUNTIME_DLLS)
|
||||
if(__QT_DEPLOY_VERBOSE)
|
||||
message(STATUS "runtime dependency for QML plugin '${entry_PLUGIN}':")
|
||||
endif()
|
||||
file(INSTALL ${file} DESTINATION "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_BIN_DIR}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(__QT_DEPLOY_TOOL STREQUAL "GRD" AND __QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH)
|
||||
# The RPATHs of the installed plugins do not match Qt's original lib directory.
|
||||
# We must set the RPATH to point to QT_DEPLOY_LIBDIR.
|
||||
|
|
|
@ -809,36 +809,68 @@ function(_qt_internal_target_enable_qmllint target)
|
|||
_qt_internal_extend_qml_import_paths(import_args)
|
||||
|
||||
_qt_internal_get_tool_wrapper_script_path(tool_wrapper)
|
||||
set(cmd
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
|
||||
|
||||
set(qmllint_args
|
||||
--bare
|
||||
${import_args}
|
||||
${qrc_args}
|
||||
${qmllint_files}
|
||||
)
|
||||
|
||||
get_target_property(target_binary_dir ${target} BINARY_DIR)
|
||||
set(qmllint_dir ${target_binary_dir}/.rcc/qmllint)
|
||||
set(qmllint_rsp_path ${qmllint_dir}/${target}.rsp)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${qmllint_rsp_path}"
|
||||
CONTENT "$<JOIN:${qmllint_args},\n>\n"
|
||||
)
|
||||
|
||||
set(cmd
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
|
||||
@${qmllint_rsp_path}
|
||||
)
|
||||
|
||||
set(cmd_dummy ${CMAKE_COMMAND} -E echo "Nothing to do for target ${lint_target}.")
|
||||
|
||||
# We need this target to depend on all qml type registrations. This is the
|
||||
# only way we can be sure that all *.qmltypes files for any QML modules we
|
||||
# depend on will have been generated.
|
||||
add_custom_target(${lint_target}
|
||||
COMMAND "$<${have_qmllint_files}:${cmd}>"
|
||||
COMMAND "$<IF:${have_qmllint_files},${cmd},${cmd_dummy}>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::qmllint
|
||||
${qmllint_files}
|
||||
${qmllint_rsp_path}
|
||||
$<TARGET_NAME_IF_EXISTS:all_qmltyperegistrations>
|
||||
WORKING_DIRECTORY "$<TARGET_PROPERTY:${target},SOURCE_DIR>"
|
||||
)
|
||||
_qt_internal_assign_to_qmllint_targets_folder(${lint_target})
|
||||
|
||||
set(lint_args "--json" "${CMAKE_BINARY_DIR}/${lint_target}.json")
|
||||
list(APPEND qmllint_args "--json" "${CMAKE_BINARY_DIR}/${lint_target}.json")
|
||||
|
||||
set(qmllint_rsp_path ${qmllint_dir}/${target}_json.rsp)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${qmllint_rsp_path}"
|
||||
CONTENT "$<JOIN:${qmllint_args},\n>\n"
|
||||
)
|
||||
|
||||
set(cmd
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
|
||||
@${qmllint_rsp_path}
|
||||
)
|
||||
|
||||
add_custom_target(${lint_target_json}
|
||||
COMMAND "$<${have_qmllint_files}:${cmd};${lint_args}>"
|
||||
COMMAND "$<${have_qmllint_files}:${cmd}>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::qmllint
|
||||
${qmllint_files}
|
||||
${qmllint_rsp_path}
|
||||
$<TARGET_NAME_IF_EXISTS:all_qmltyperegistrations>
|
||||
WORKING_DIRECTORY "$<TARGET_PROPERTY:${target},SOURCE_DIR>"
|
||||
)
|
||||
|
@ -849,18 +881,34 @@ function(_qt_internal_target_enable_qmllint target)
|
|||
get_target_property(module_uri ${target} QT_QML_MODULE_URI)
|
||||
|
||||
_qt_internal_get_tool_wrapper_script_path(tool_wrapper)
|
||||
add_custom_target(${lint_target_module}
|
||||
COMMAND
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
|
||||
|
||||
set(qmllint_args
|
||||
${import_args}
|
||||
${qrc_args}
|
||||
--module
|
||||
${module_uri}
|
||||
)
|
||||
|
||||
set(qmllint_rsp_path ${qmllint_dir}/${target}_module.rsp)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${qmllint_rsp_path}"
|
||||
CONTENT "$<JOIN:${qmllint_args},\n>\n"
|
||||
)
|
||||
|
||||
set(cmd
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmllint>
|
||||
@${qmllint_rsp_path}
|
||||
)
|
||||
|
||||
add_custom_target(${lint_target_module}
|
||||
COMMAND ${cmd}
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::qmllint
|
||||
${qmllint_files}
|
||||
${qmllint_rsp_path}
|
||||
$<TARGET_NAME_IF_EXISTS:all_qmltyperegistrations>
|
||||
WORKING_DIRECTORY "$<TARGET_PROPERTY:${target},SOURCE_DIR>"
|
||||
)
|
||||
|
@ -935,28 +983,54 @@ function(_qt_internal_add_all_qmllint_target target_var default_target_name lint
|
|||
if("${target_name}" STREQUAL "")
|
||||
set(target_name ${default_target_name})
|
||||
endif()
|
||||
if(NOT TARGET ${target_name})
|
||||
add_custom_target(${target_name})
|
||||
_qt_internal_assign_to_qmllint_targets_folder(${target_name})
|
||||
endif()
|
||||
if(CMAKE_GENERATOR MATCHES "^Visual Studio ")
|
||||
# For the Visual Studio generators we cannot use add_dependencies, because this would enable
|
||||
# ${lint_target} in the default build of the solution. See QTBUG-115166 and upstream CMake
|
||||
# issue #16668 for details. As a work-around, we run the ${lint_target} through 'cmake
|
||||
# --build' as PRE_BUILD step of the all_qmllint target.
|
||||
add_custom_command(
|
||||
TARGET ${target_name} PRE_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" -t ${lint_target}
|
||||
# issue #16668 for details. Instead, we record ${lint_target} and create an all_qmllint
|
||||
# target at the end of the top-level directory scope.
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.19.0")
|
||||
if(NOT QT_NO_QMLLINT_CREATION_WARNING)
|
||||
message(WARNING "Cannot create target ${target_name} with this CMake version. "
|
||||
"Please upgrade to CMake 3.19.0 or newer. "
|
||||
"Set QT_NO_QMLLINT_CREATION_WARNING to ON to disable this warning."
|
||||
)
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
set(property_name _qt_target_${target_name}_dependencies)
|
||||
get_property(recorded_targets GLOBAL PROPERTY ${property_name})
|
||||
if("${recorded_targets}" STREQUAL "")
|
||||
cmake_language(EVAL CODE
|
||||
"cmake_language(DEFER DIRECTORY \"${CMAKE_SOURCE_DIR}\" CALL _qt_internal_add_all_qmllint_target_deferred \"${target_name}\")"
|
||||
)
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY ${property_name} ${lint_target})
|
||||
|
||||
# Exclude ${lint_target} from the solution's default build to avoid it being enabled should
|
||||
# the user add a dependency to it.
|
||||
set_property(TARGET ${lint_target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD ON)
|
||||
else()
|
||||
if(NOT TARGET ${target_name})
|
||||
add_custom_target(${target_name})
|
||||
_qt_internal_assign_to_qmllint_targets_folder(${target_name})
|
||||
endif()
|
||||
add_dependencies(${target_name} ${lint_target})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Hack for the Visual Studio generator. Create the all_qmllint target named ${target} and work
|
||||
# around the lack of a working add_dependencies by calling 'cmake --build' for every dependency.
|
||||
function(_qt_internal_add_all_qmllint_target_deferred target)
|
||||
get_property(target_dependencies GLOBAL PROPERTY _qt_target_${target}_dependencies)
|
||||
set(target_commands "")
|
||||
foreach(dependency IN LISTS target_dependencies)
|
||||
list(APPEND target_commands
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" -t ${dependency}
|
||||
)
|
||||
endforeach()
|
||||
add_custom_target(${target} ${target_commands})
|
||||
_qt_internal_assign_to_qmllint_targets_folder(${target})
|
||||
endfunction()
|
||||
function(_qt_internal_target_enable_qmlcachegen target output_targets_var qmlcachegen)
|
||||
|
||||
set(output_targets)
|
||||
|
@ -1507,6 +1581,35 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
|||
endfunction()
|
||||
endif()
|
||||
|
||||
function(_qt_internal_set_qml_target_multi_config_output_directory target output_directory)
|
||||
# In multi-config builds we need to make sure that at least one configuration has the dynamic
|
||||
# plugin that is located next to qmldir file, otherwise QML engine won't be able to load the
|
||||
# plugin.
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
# We don't care about static plugins here since, they are linked at build time and
|
||||
# their location doesn't affect the runtime.
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if(target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
|
||||
if(NOT "${output_directory}")
|
||||
set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
list(GET CMAKE_CONFIGURATION_TYPES 0 default_config)
|
||||
string(JOIN "" output_directory_with_default_config
|
||||
"$<IF:$<CONFIG:${default_config}>,"
|
||||
"${output_directory},"
|
||||
"${output_directory}/$<CONFIG>"
|
||||
">"
|
||||
)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${output_directory_with_default_config}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${output_directory_with_default_config}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt6_add_qml_plugin target)
|
||||
set(args_option
|
||||
STATIC
|
||||
|
@ -1752,6 +1855,8 @@ function(qt6_add_qml_plugin target)
|
|||
)
|
||||
endif()
|
||||
|
||||
_qt_internal_set_qml_target_multi_config_output_directory(${target} "${arg_OUTPUT_DIRECTORY}")
|
||||
|
||||
if(NOT arg_NO_GENERATE_PLUGIN_SOURCE)
|
||||
set(generated_cpp_file_name_base "${target}_${arg_CLASS_NAME}")
|
||||
set(register_types_function_name "qml_register_types_${escaped_uri}")
|
||||
|
@ -1848,8 +1953,9 @@ function(qt6_target_qml_sources target)
|
|||
message(FATAL_ERROR "Unknown/unexpected arguments: ${arg_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
|
||||
if (NOT arg_QML_FILES AND NOT arg_RESOURCES)
|
||||
if(NOT arg_NO_LINT)
|
||||
get_target_property(no_lint ${target} QT_QML_MODULE_NO_LINT)
|
||||
if(NOT arg_QML_FILES AND NOT arg_RESOURCES)
|
||||
if(NOT arg_NO_LINT AND NOT no_lint)
|
||||
_qt_internal_target_enable_qmllint(${target})
|
||||
endif()
|
||||
|
||||
|
@ -1868,7 +1974,6 @@ function(qt6_target_qml_sources target)
|
|||
)
|
||||
endif()
|
||||
|
||||
get_target_property(no_lint ${target} QT_QML_MODULE_NO_LINT)
|
||||
get_target_property(no_cachegen ${target} QT_QML_MODULE_NO_CACHEGEN)
|
||||
get_target_property(no_qmldir ${target} QT_QML_MODULE_NO_GENERATE_QMLDIR)
|
||||
get_target_property(resource_prefix ${target} QT_QML_MODULE_RESOURCE_PREFIX)
|
||||
|
|
|
@ -670,6 +670,8 @@ struct Binding
|
|||
}
|
||||
bool evaluatesToString() const { return type() == Type_String || isTranslationBinding(); }
|
||||
|
||||
bool isNumberBinding() const { return type() == Type_Number; }
|
||||
|
||||
bool valueAsBoolean() const
|
||||
{
|
||||
if (type() == Type_Boolean)
|
||||
|
|
|
@ -455,7 +455,7 @@
|
|||
Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
|
||||
\l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
|
||||
\l QML_ADDED_IN_MINOR_VERSION(), \l QML_REMOVED_IN_MINOR_VERSION(),
|
||||
\l QML_ATTACHED(), \l QML_EXTENDED(), or \l QML_EXTENDED_NAMESPACE() macros
|
||||
\l QML_EXTENDED(), or \l QML_EXTENDED_NAMESPACE() macros
|
||||
in the enclosing C++ type do not apply to the enclosing type but instead to
|
||||
\a FOREIGN_TYPE. The enclosing type still needs to be registered with the
|
||||
\l {The Meta-Object System}{meta object system} using a \l Q_GADGET or
|
||||
|
@ -469,6 +469,9 @@
|
|||
the element will be named like the struct it is contained in, not the foreign type.
|
||||
See the \l {Extension Objects} for an example.
|
||||
|
||||
\note QML_ATTACHED() can currently not be redirected like this. It has to be
|
||||
specificed in the same type that implements qmlAttachedProperties().
|
||||
|
||||
\include {qualified-class-name.qdocinc} {class name must be qualified}
|
||||
|
||||
\sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN_NAMESPACE()
|
||||
|
|
|
@ -254,13 +254,23 @@ The same declaration can also be given for C++-defined types. See
|
|||
|
||||
\section2 ComponentBehavior
|
||||
|
||||
With this pragma you can restrict components defined in this file to only
|
||||
create objects within their original context. This holds for inline
|
||||
components as well as Component elements explicitly or implicitly created
|
||||
as properties. If a component is bound to its context, you can safely
|
||||
use IDs from the rest of the file within the component. Otherwise, the
|
||||
engine and the QML tooling cannot know in advance what type, if any, such
|
||||
IDs will resolve to at run time.
|
||||
You may have multiple components defined in the same QML file. The root
|
||||
scope of the QML file is a component, and you may additionally have
|
||||
elements of type \l QQmlComponent, explicitly or implicitly created
|
||||
as properties, or inline components. Those components are nested. Each
|
||||
of the inner components is within one specific outer component. Most of
|
||||
the time, IDs defined in an outer component are accessible within all
|
||||
its nested inner components. You can, however, create elements from a
|
||||
component in any a different context, with different IDs available.
|
||||
Doing so breaks the assumption that outer IDs are available. Therefore,
|
||||
the engine and the QML tooling cannot generally know in advance what
|
||||
type, if any, such IDs will resolve to at run time.
|
||||
|
||||
With the ComponentBehavior pragma you can restrict all inner components
|
||||
defined in a file to only create objects within their original context.
|
||||
If a component is bound to its context, you can safely use IDs from
|
||||
outer components in the same file within the component. QML tooling will
|
||||
then assume the outer IDs with their specific types to be available.
|
||||
|
||||
In order to bind the components to their context specify the \c{Bound}
|
||||
argument:
|
||||
|
@ -269,8 +279,33 @@ argument:
|
|||
pragma ComponentBehavior: Bound
|
||||
\endqml
|
||||
|
||||
The default is \c{Unbound}. You can also specify it explicitly. In a
|
||||
future version of Qt the default will change to \c{Bound}.
|
||||
This implies that, in case of name clashes, IDs defined outside a bound
|
||||
component override local properties of objects created from the
|
||||
component. Otherwise it wouldn't actually be safe to use the IDs since
|
||||
later versions of a module might add more properties to the component.
|
||||
If the component is not bound, local properties override IDs defined
|
||||
outside the component, but not IDs defined inside the component.
|
||||
|
||||
The example below prints the \e r property of the ListView object with
|
||||
the id \e color, not the \e r property of the rectangle's color.
|
||||
|
||||
\qml
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
|
||||
ListView {
|
||||
id: color
|
||||
property int r: 12
|
||||
model: 1
|
||||
delegate: Rectangle {
|
||||
Component.onCompleted: console.log(color.r)
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
The default value of \c ComponentBehavior is \c{Unbound}. You can also
|
||||
specify it explicitly. In a future version of Qt the default will change
|
||||
to \c{Bound}.
|
||||
|
||||
Delegate components bound to their context don't receive their own
|
||||
private contexts on instantiation. This means that model data can only
|
||||
|
|
|
@ -807,7 +807,7 @@ In order to be consistent with method declarations, you should prefer the
|
|||
type declarations using colons.
|
||||
|
||||
If the signal has no parameters, the "()" brackets are optional. If parameters
|
||||
are used, the parameter types must be declared, as for the \c string and \c var
|
||||
are used, the parameter types must be declared, as for the \c string and \c int
|
||||
arguments for the \c actionPerformed signal above. The allowed parameter types
|
||||
are the same as those listed under \l {Defining Property Attributes} on this page.
|
||||
|
||||
|
|
|
@ -372,8 +372,11 @@ bool QJSValue::isError() const
|
|||
}
|
||||
|
||||
/*!
|
||||
Returns true if this QJSValue is an object of the URL class;
|
||||
Returns true if this QJSValue is an object of the URL JavaScript class;
|
||||
otherwise returns false.
|
||||
|
||||
\note For a QJSValue that contains a QUrl, this function returns false.
|
||||
However, \c{toVariant().value<QUrl>()} works in both cases.
|
||||
*/
|
||||
bool QJSValue::isUrl() const
|
||||
{
|
||||
|
@ -635,8 +638,11 @@ QVariant QJSValue::toVariant(QJSValue::ObjectConversionBehavior behavior) const
|
|||
if (val.isString())
|
||||
return QVariant(val.toQString());
|
||||
if (val.as<QV4::Managed>()) {
|
||||
if (behavior == RetainJSObjects)
|
||||
return QV4::ExecutionEngine::toVariant(
|
||||
val, /*typeHint*/ QMetaType{}, behavior == RetainJSObjects);
|
||||
val, /*typeHint*/ QMetaType{}, /*createJSValueForObjectsAndSymbols=*/ true);
|
||||
else
|
||||
return QV4::ExecutionEngine::toVariantLossy(val);
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
|
|
|
@ -1478,11 +1478,13 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError()
|
|||
// Variant conversion code
|
||||
|
||||
typedef QSet<QV4::Heap::Object *> V4ObjectSet;
|
||||
enum class JSToQVariantConversionBehavior {Never, Safish, Aggressive };
|
||||
static QVariant toVariant(
|
||||
const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols,
|
||||
const QV4::Value &value, QMetaType typeHint, JSToQVariantConversionBehavior conversionBehavior,
|
||||
V4ObjectSet *visitedObjects);
|
||||
static QObject *qtObjectFromJS(const QV4::Value &value);
|
||||
static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr);
|
||||
static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr,
|
||||
JSToQVariantConversionBehavior behavior = JSToQVariantConversionBehavior::Safish);
|
||||
static bool convertToNativeQObject(const QV4::Value &value, QMetaType targetType, void **result);
|
||||
static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst);
|
||||
static QV4::ReturnedValue sequentialIterableToJS(QV4::ExecutionEngine *v4, const QSequentialIterable &lst);
|
||||
|
@ -1492,8 +1494,7 @@ static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant &
|
|||
return v4->metaTypeToJS(value.metaType(), value.constData());
|
||||
}
|
||||
|
||||
static QVariant toVariant(
|
||||
const QV4::Value &value, QMetaType metaType, bool createJSValueForObjectsAndSymbols,
|
||||
static QVariant toVariant(const QV4::Value &value, QMetaType metaType, JSToQVariantConversionBehavior conversionBehavior,
|
||||
V4ObjectSet *visitedObjects)
|
||||
{
|
||||
Q_ASSERT (!value.isEmpty());
|
||||
|
@ -1590,7 +1591,7 @@ static QVariant toVariant(
|
|||
}
|
||||
}
|
||||
|
||||
asVariant = toVariant(arrayValue, valueMetaType, false, visitedObjects);
|
||||
asVariant = toVariant(arrayValue, valueMetaType, JSToQVariantConversionBehavior::Never, visitedObjects);
|
||||
if (valueMetaType == QMetaType::fromType<QVariant>()) {
|
||||
retnAsIterable.metaContainer().addValue(retn.data(), &asVariant);
|
||||
} else {
|
||||
|
@ -1655,7 +1656,7 @@ static QVariant toVariant(
|
|||
if (const ArrayBuffer *d = value.as<ArrayBuffer>())
|
||||
return d->asByteArray();
|
||||
if (const Symbol *symbol = value.as<Symbol>()) {
|
||||
return createJSValueForObjectsAndSymbols
|
||||
return conversionBehavior == JSToQVariantConversionBehavior::Never
|
||||
? QVariant::fromValue(QJSValuePrivate::fromReturnedValue(symbol->asReturnedValue()))
|
||||
: symbol->descriptiveString();
|
||||
}
|
||||
|
@ -1676,20 +1677,27 @@ static QVariant toVariant(
|
|||
return result;
|
||||
}
|
||||
|
||||
if (createJSValueForObjectsAndSymbols)
|
||||
if (conversionBehavior == JSToQVariantConversionBehavior::Never)
|
||||
return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue()));
|
||||
|
||||
return objectToVariant(o, visitedObjects);
|
||||
return objectToVariant(o, visitedObjects, conversionBehavior);
|
||||
}
|
||||
|
||||
QVariant ExecutionEngine::toVariantLossy(const Value &value)
|
||||
{
|
||||
return ::toVariant(value, QMetaType(), JSToQVariantConversionBehavior::Aggressive, nullptr);
|
||||
}
|
||||
|
||||
QVariant ExecutionEngine::toVariant(
|
||||
const Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols)
|
||||
{
|
||||
return ::toVariant(value, typeHint, createJSValueForObjectsAndSymbols, nullptr);
|
||||
auto behavior = createJSValueForObjectsAndSymbols ? JSToQVariantConversionBehavior::Never
|
||||
: JSToQVariantConversionBehavior::Safish;
|
||||
return ::toVariant(value, typeHint, behavior, nullptr);
|
||||
}
|
||||
|
||||
static QVariantMap objectToVariantMap(const QV4::Object *o, V4ObjectSet *visitedObjects)
|
||||
static QVariantMap objectToVariantMap(const QV4::Object *o, V4ObjectSet *visitedObjects,
|
||||
JSToQVariantConversionBehavior conversionBehvior)
|
||||
{
|
||||
QVariantMap map;
|
||||
QV4::Scope scope(o->engine());
|
||||
|
@ -1704,12 +1712,13 @@ static QVariantMap objectToVariantMap(const QV4::Object *o, V4ObjectSet *visited
|
|||
QString key = name->toQStringNoThrow();
|
||||
map.insert(key, ::toVariant(
|
||||
val, /*type hint*/ QMetaType {},
|
||||
/*createJSValueForObjectsAndSymbols*/false, visitedObjects));
|
||||
conversionBehvior, visitedObjects));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects)
|
||||
static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects,
|
||||
JSToQVariantConversionBehavior conversionBehvior)
|
||||
{
|
||||
Q_ASSERT(o);
|
||||
|
||||
|
@ -1737,13 +1746,20 @@ static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObject
|
|||
int length = a->getLength();
|
||||
for (int ii = 0; ii < length; ++ii) {
|
||||
v = a->get(ii);
|
||||
list << ::toVariant(v, QMetaType {}, /*createJSValueForObjectsAndSymbols*/false,
|
||||
list << ::toVariant(v, QMetaType {}, conversionBehvior,
|
||||
visitedObjects);
|
||||
}
|
||||
|
||||
result = list;
|
||||
} else if (o->getPrototypeOf() == o->engine()->objectPrototype()->d()) {
|
||||
result = objectToVariantMap(o, visitedObjects);
|
||||
} else if (o->getPrototypeOf() == o->engine()->objectPrototype()->d()
|
||||
|| (conversionBehvior == JSToQVariantConversionBehavior::Aggressive &&
|
||||
!o->as<QV4::FunctionObject>())) {
|
||||
/* FunctionObject is excluded for historical reasons, even though
|
||||
objects with a custom prototype risk losing information
|
||||
But the Aggressive path is used only in QJSValue::toVariant
|
||||
which is documented to be lossy
|
||||
*/
|
||||
result = objectToVariantMap(o, visitedObjects, conversionBehvior);
|
||||
} else {
|
||||
// If it's not a plain object, we can only save it as QJSValue.
|
||||
result = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue()));
|
||||
|
@ -1974,7 +1990,7 @@ QVariantMap ExecutionEngine::variantMapFromJS(const Object *o)
|
|||
Q_ASSERT(o);
|
||||
V4ObjectSet visitedObjects;
|
||||
visitedObjects.insert(o->d());
|
||||
return objectToVariantMap(o, &visitedObjects);
|
||||
return objectToVariantMap(o, &visitedObjects, JSToQVariantConversionBehavior::Safish);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -644,6 +644,7 @@ public:
|
|||
// variant conversions
|
||||
static QVariant toVariant(
|
||||
const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols = true);
|
||||
static QVariant toVariantLossy(const QV4::Value &value);
|
||||
QV4::ReturnedValue fromVariant(const QVariant &);
|
||||
QV4::ReturnedValue fromVariant(
|
||||
const QVariant &variant, Heap::Object *parent, int property, uint flags);
|
||||
|
|
|
@ -195,6 +195,11 @@ public:
|
|||
return data->flags & CompiledData::Unit::ValueTypesCopied;
|
||||
}
|
||||
|
||||
bool componentsAreBound() const
|
||||
{
|
||||
return data->flags & CompiledData::Unit::ComponentsBound;
|
||||
}
|
||||
|
||||
int objectCount() const { return qmlData->nObjects; }
|
||||
const CompiledObject *objectAt(int index) const
|
||||
{
|
||||
|
|
|
@ -191,6 +191,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(PropertyFlags)
|
|||
|
||||
struct PropertyAttributes
|
||||
{
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_MSVC(4201) // nonstandard extension used: nameless struct/union
|
||||
union {
|
||||
uchar m_all;
|
||||
struct {
|
||||
|
@ -208,6 +210,7 @@ struct PropertyAttributes
|
|||
uchar configurable_set : 1;
|
||||
};
|
||||
};
|
||||
QT_WARNING_POP
|
||||
|
||||
enum Type {
|
||||
Data = 0,
|
||||
|
|
|
@ -155,10 +155,13 @@ ReturnedValue convertAndCall(
|
|||
values[0] = nullptr;
|
||||
}
|
||||
|
||||
if (const QV4::QObjectWrapper *cppThisObject = thisObject->as<QV4::QObjectWrapper>())
|
||||
if (const QV4::QObjectWrapper *cppThisObject = thisObject
|
||||
? thisObject->as<QV4::QObjectWrapper>()
|
||||
: nullptr) {
|
||||
call(cppThisObject->object(), values, types, argc);
|
||||
else
|
||||
} else {
|
||||
call(nullptr, values, types, argc);
|
||||
}
|
||||
|
||||
ReturnedValue result;
|
||||
if (values[0]) {
|
||||
|
@ -255,6 +258,156 @@ ReturnedValue coerceAndCall(
|
|||
return result->asReturnedValue();
|
||||
}
|
||||
|
||||
// Note: \a to is unininitialized here! This is in contrast to most other related functions.
|
||||
inline void coerce(
|
||||
ExecutionEngine *engine, QMetaType fromType, const void *from, QMetaType toType, void *to)
|
||||
{
|
||||
if ((fromType.flags() & QMetaType::PointerToQObject)
|
||||
&& (toType.flags() & QMetaType::PointerToQObject)) {
|
||||
QObject *fromObj = *static_cast<QObject * const*>(from);
|
||||
*static_cast<QObject **>(to)
|
||||
= (fromObj && fromObj->metaObject()->inherits(toType.metaObject()))
|
||||
? fromObj
|
||||
: nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (toType == QMetaType::fromType<QVariant>()) {
|
||||
new (to) QVariant(fromType, from);
|
||||
return;
|
||||
}
|
||||
|
||||
if (toType == QMetaType::fromType<QJSPrimitiveValue>()) {
|
||||
new (to) QJSPrimitiveValue(fromType, from);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fromType == QMetaType::fromType<QVariant>()) {
|
||||
const QVariant *fromVariant = static_cast<const QVariant *>(from);
|
||||
if (fromVariant->metaType() == toType)
|
||||
toType.construct(to, fromVariant->data());
|
||||
else
|
||||
coerce(engine, fromVariant->metaType(), fromVariant->data(), toType, to);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: This is expensive. We might establish a direct C++-to-C++ type coercion, like we have
|
||||
// will generate code that passes the right arguments.
|
||||
// for JS-to-JS. However, we shouldn't need this very often. Most of the time the compiler
|
||||
if (toType.flags() & QMetaType::NeedsConstruction)
|
||||
toType.construct(to);
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedValue value(scope, engine->fromData(fromType, from));
|
||||
if (!ExecutionEngine::metaTypeFromJS(value, toType, to))
|
||||
QMetaType::convert(fromType, from, toType, to);
|
||||
}
|
||||
|
||||
template<typename TypedFunction, typename Callable>
|
||||
void coerceAndCall(
|
||||
ExecutionEngine *engine, const TypedFunction *typedFunction,
|
||||
void **argv, const QMetaType *types, int argc, Callable call)
|
||||
{
|
||||
const qsizetype numFunctionArguments = typedFunction->parameterCount();
|
||||
|
||||
Q_ALLOCA_DECLARE(void *, transformedArguments);
|
||||
Q_ALLOCA_DECLARE(void, transformedResult);
|
||||
|
||||
const QMetaType returnType = typedFunction->returnMetaType();
|
||||
const QMetaType frameReturn = types[0];
|
||||
bool returnsQVariantWrapper = false;
|
||||
if (argv[0] && returnType != frameReturn) {
|
||||
Q_ALLOCA_ASSIGN(void *, transformedArguments, (numFunctionArguments + 1) * sizeof(void *));
|
||||
memcpy(transformedArguments, argv, (argc + 1) * sizeof(void *));
|
||||
|
||||
if (frameReturn == QMetaType::fromType<QVariant>()) {
|
||||
QVariant *returnValue = static_cast<QVariant *>(argv[0]);
|
||||
*returnValue = QVariant(returnType);
|
||||
transformedResult = transformedArguments[0] = returnValue->data();
|
||||
returnsQVariantWrapper = true;
|
||||
} else if (returnType.sizeOf() > 0) {
|
||||
Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf());
|
||||
transformedArguments[0] = transformedResult;
|
||||
if (returnType.flags() & QMetaType::NeedsConstruction)
|
||||
returnType.construct(transformedResult);
|
||||
} else {
|
||||
transformedResult = transformedArguments[0] = &argc; // Some non-null marker value
|
||||
}
|
||||
}
|
||||
|
||||
for (qsizetype i = 0; i < numFunctionArguments; ++i) {
|
||||
const bool isValid = argc > i;
|
||||
const QMetaType frameType = isValid ? types[i + 1] : QMetaType();
|
||||
|
||||
const QMetaType argumentType = typedFunction->parameterMetaType(i);
|
||||
if (isValid && argumentType == frameType)
|
||||
continue;
|
||||
|
||||
if (transformedArguments == nullptr) {
|
||||
Q_ALLOCA_ASSIGN(void *, transformedArguments, (numFunctionArguments + 1) * sizeof(void *));
|
||||
memcpy(transformedArguments, argv, (argc + 1) * sizeof(void *));
|
||||
}
|
||||
|
||||
if (argumentType.sizeOf() == 0) {
|
||||
transformedArguments[i + 1] = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
void *frameVal = isValid ? argv[i + 1] : nullptr;
|
||||
if (isValid && frameType == QMetaType::fromType<QVariant>()) {
|
||||
QVariant *variant = static_cast<QVariant *>(frameVal);
|
||||
|
||||
const QMetaType variantType = variant->metaType();
|
||||
if (variantType == argumentType) {
|
||||
// Slightly nasty, but we're allowed to do this.
|
||||
// We don't want to destruct() the QVariant's data() below.
|
||||
transformedArguments[i + 1] = argv[i + 1] = variant->data();
|
||||
} else {
|
||||
Q_ALLOCA_VAR(void, arg, argumentType.sizeOf());
|
||||
coerce(engine, variantType, variant->constData(), argumentType, arg);
|
||||
transformedArguments[i + 1] = arg;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Q_ALLOCA_VAR(void, arg, argumentType.sizeOf());
|
||||
|
||||
if (isValid)
|
||||
coerce(engine, frameType, frameVal, argumentType, arg);
|
||||
else
|
||||
argumentType.construct(arg);
|
||||
|
||||
transformedArguments[i + 1] = arg;
|
||||
}
|
||||
|
||||
if (!transformedArguments) {
|
||||
call(argv, numFunctionArguments);
|
||||
return;
|
||||
}
|
||||
|
||||
call(transformedArguments, numFunctionArguments);
|
||||
|
||||
if (transformedResult && !returnsQVariantWrapper) {
|
||||
if (frameReturn.sizeOf() > 0) {
|
||||
if (frameReturn.flags() & QMetaType::NeedsDestruction)
|
||||
frameReturn.destruct(argv[0]);
|
||||
coerce(engine, returnType, transformedResult, frameReturn, argv[0]);
|
||||
}
|
||||
if (returnType.flags() & QMetaType::NeedsDestruction)
|
||||
returnType.destruct(transformedResult);
|
||||
}
|
||||
|
||||
for (qsizetype i = 0; i < numFunctionArguments; ++i) {
|
||||
void *arg = transformedArguments[i + 1];
|
||||
if (arg == nullptr)
|
||||
continue;
|
||||
if (i >= argc || arg != argv[i + 1]) {
|
||||
const QMetaType argumentType = typedFunction->parameterMetaType(i);
|
||||
if (argumentType.flags() & QMetaType::NeedsDestruction)
|
||||
argumentType.destruct(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QV4
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -39,8 +39,11 @@ void Object::setInternalClass(Heap::InternalClass *ic)
|
|||
// Pick the members of the old IC that are still valid in the new IC.
|
||||
// Order them by index in memberData (or inline data).
|
||||
Scoped<MemberData> newMembers(scope, MemberData::allocate(scope.engine, ic->size));
|
||||
for (uint i = 0; i < ic->size; ++i)
|
||||
newMembers->set(scope.engine, i, get(ic->nameMap.at(i)));
|
||||
for (uint i = 0; i < ic->size; ++i) {
|
||||
// Note that some members might have been deleted. The key may be invalid.
|
||||
const PropertyKey key = ic->nameMap.at(i);
|
||||
newMembers->set(scope.engine, i, key.isValid() ? get(key) : Encode::undefined());
|
||||
}
|
||||
|
||||
p->internalClass.set(scope.engine, ic);
|
||||
const uint nInline = p->vtable()->nInlineProperties;
|
||||
|
|
|
@ -268,9 +268,33 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
|
|||
contextGetterFunction = QQmlContextWrapper::lookupScopeObjectProperty;
|
||||
}
|
||||
|
||||
QQmlRefPointer<QQmlContextData> outer = context;
|
||||
while (context) {
|
||||
if (auto property = searchContextProperties(v4, context, name, hasProperty, base, lookup, originalLookup, ep))
|
||||
if (outer == context) {
|
||||
if (auto property = searchContextProperties(
|
||||
v4, context, name, hasProperty, base, lookup, originalLookup, ep)) {
|
||||
return *property;
|
||||
}
|
||||
|
||||
outer = outer->parent();
|
||||
|
||||
if (const auto cu = context->typeCompilationUnit(); cu && cu->componentsAreBound()) {
|
||||
// If components are bound in this CU, we can search the whole context hierarchy
|
||||
// of the file. Bound components' contexts override their local properties.
|
||||
// You also can't instantiate bound components outside of their creation
|
||||
// context. Therefore this is safe.
|
||||
|
||||
for (;
|
||||
outer && outer->typeCompilationUnit() == cu;
|
||||
outer = outer->parent()) {
|
||||
if (auto property = searchContextProperties(
|
||||
v4, outer, name, hasProperty, base,
|
||||
nullptr, originalLookup, ep)) {
|
||||
return *property;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search scope object
|
||||
if (scopeObject) {
|
||||
|
|
|
@ -1100,7 +1100,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
|
|||
if (!v4)
|
||||
break;
|
||||
|
||||
QQmlMetaObject::ArgTypeStorage storage;
|
||||
QQmlMetaObject::ArgTypeStorage<9> storage;
|
||||
QQmlMetaObject::methodParameterTypes(This->signal, &storage, nullptr);
|
||||
|
||||
int argCount = storage.size();
|
||||
|
@ -1382,9 +1382,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
|
|||
if (!o->parent() && !ddata->indestructible) {
|
||||
if (ddata && ddata->ownContext) {
|
||||
Q_ASSERT(ddata->ownContext.data() == ddata->context);
|
||||
ddata->ownContext->emitDestruction();
|
||||
if (ddata->ownContext->contextObject() == o)
|
||||
ddata->ownContext->setContextObject(nullptr);
|
||||
ddata->ownContext->deepClearContextObject(o);
|
||||
ddata->ownContext.reset();
|
||||
ddata->context = nullptr;
|
||||
}
|
||||
|
@ -1803,7 +1801,7 @@ static ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQmlPro
|
|||
|
||||
if (data.hasArguments()) {
|
||||
|
||||
QQmlMetaObject::ArgTypeStorage storage;
|
||||
QQmlMetaObject::ArgTypeStorage<9> storage;
|
||||
|
||||
bool ok = false;
|
||||
if (data.isConstructor())
|
||||
|
@ -1884,7 +1882,7 @@ static const QQmlPropertyData *ResolveOverloaded(
|
|||
int sumMethodMatchScore = bestSumMatchScore;
|
||||
|
||||
if (!attempt->isV4Function()) {
|
||||
QQmlMetaObject::ArgTypeStorage storage;
|
||||
QQmlMetaObject::ArgTypeStorage<9> storage;
|
||||
int methodArgumentCount = 0;
|
||||
if (attempt->hasArguments()) {
|
||||
if (attempt->isConstructor()) {
|
||||
|
|
|
@ -35,6 +35,8 @@ struct Q_QML_PRIVATE_EXPORT CppStackFrameBase
|
|||
int originalArgumentsCount;
|
||||
int instructionPointer;
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_MSVC(4201) // nonstandard extension used: nameless struct/union
|
||||
union {
|
||||
struct {
|
||||
Value *savedStackTop;
|
||||
|
@ -57,6 +59,7 @@ struct Q_QML_PRIVATE_EXPORT CppStackFrameBase
|
|||
bool returnValueIsUndefined;
|
||||
};
|
||||
};
|
||||
QT_WARNING_POP
|
||||
|
||||
Kind kind;
|
||||
};
|
||||
|
|
|
@ -1255,7 +1255,8 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
|
|||
storeResult = resetObjectProperty(&l, qmlScopeObject);
|
||||
} else {
|
||||
QVariant var(propType);
|
||||
propType.convert(type, value, propType, var.data());
|
||||
QV4::ExecutionEngine *v4 = engine->handle();
|
||||
v4->metaTypeFromJS(v4->metaTypeToJS(type, value), propType, var.data());
|
||||
storeResult = storeObjectProperty(&l, qmlScopeObject, var.data());
|
||||
}
|
||||
|
||||
|
@ -1273,7 +1274,8 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType
|
|||
storeResult = resetFallbackProperty(&l, qmlScopeObject);
|
||||
} else {
|
||||
QVariant var(propType);
|
||||
propType.convert(type, value, propType, var.data());
|
||||
QV4::ExecutionEngine *v4 = engine->handle();
|
||||
v4->metaTypeFromJS(v4->metaTypeToJS(type, value), propType, var.data());
|
||||
storeResult = storeFallbackProperty(&l, qmlScopeObject, var.data());
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -179,7 +179,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
|
|||
QMetaObjectPrivate::signal(targetMeta, m_index).methodIndex());
|
||||
|
||||
int argCount = metaMethod.parameterCount();
|
||||
QQmlMetaObject::ArgTypeStorage storage;
|
||||
QQmlMetaObject::ArgTypeStorage<9> storage;
|
||||
storage.reserve(argCount + 1);
|
||||
storage.append(QMetaType()); // We're not interested in the return value
|
||||
for (int i = 0; i < argCount; ++i) {
|
||||
|
|
|
@ -1754,19 +1754,21 @@ enum ConsoleLogTypes {
|
|||
static QString jsStack(QV4::ExecutionEngine *engine) {
|
||||
QString stack;
|
||||
|
||||
QVector<QV4::StackFrame> stackTrace = engine->stackTrace(10);
|
||||
|
||||
for (int i = 0; i < stackTrace.size(); i++) {
|
||||
const QV4::StackFrame &frame = stackTrace.at(i);
|
||||
|
||||
int i = 0;
|
||||
for (CppStackFrame *f = engine->currentStackFrame; f && i < 10; f = f->parentFrame(), ++i) {
|
||||
QString stackFrame;
|
||||
if (frame.column >= 0) {
|
||||
stackFrame = QStringLiteral("%1 (%2:%3:%4)").arg(
|
||||
frame.function, frame.source,
|
||||
QString::number(qAbs(frame.line)), QString::number(frame.column));
|
||||
|
||||
if (f->isJSTypesFrame() && static_cast<JSTypesStackFrame *>(f)->isTailCalling()) {
|
||||
stackFrame = QStringLiteral("[elided tail calls]");
|
||||
} else {
|
||||
const int line = f->lineNumber();
|
||||
if (line != f->missingLineNumber()) {
|
||||
stackFrame = QStringLiteral("%1 (%2:%3)").arg(
|
||||
frame.function, frame.source, QString::number(qAbs(frame.line)));
|
||||
f->function(), f->source(), QString::number(qAbs(line)));
|
||||
} else {
|
||||
stackFrame = QStringLiteral("%1 (%2)").arg(
|
||||
f->function(), f->source());
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
|
|
|
@ -166,10 +166,7 @@ public:
|
|||
QObject *createWithProperties(QObject *parent, const QVariantMap &properties,
|
||||
QQmlContext *context, CreateBehavior behavior = CreateDefault);
|
||||
|
||||
bool isBound() const {
|
||||
return compilationUnit
|
||||
&& (compilationUnit->unitData()->flags & QV4::CompiledData::Unit::ComponentsBound);
|
||||
}
|
||||
bool isBound() const { return compilationUnit && (compilationUnit->componentsAreBound()); }
|
||||
};
|
||||
|
||||
QQmlComponentPrivate::ConstructionState::~ConstructionState()
|
||||
|
|
|
@ -128,6 +128,28 @@ public:
|
|||
QObject *contextObject() const { return m_contextObject; }
|
||||
void setContextObject(QObject *contextObject) { m_contextObject = contextObject; }
|
||||
|
||||
template<typename HandleSelf, typename HandleLinked>
|
||||
void deepClearContextObject(
|
||||
QObject *contextObject, HandleSelf &&handleSelf, HandleLinked &&handleLinked) {
|
||||
for (QQmlContextData *lc = m_linkedContext.data(); lc; lc = lc->m_linkedContext.data()) {
|
||||
handleLinked(lc);
|
||||
if (lc->m_contextObject == contextObject)
|
||||
lc->m_contextObject = nullptr;
|
||||
}
|
||||
|
||||
handleSelf(this);
|
||||
if (m_contextObject == contextObject)
|
||||
m_contextObject = nullptr;
|
||||
}
|
||||
|
||||
void deepClearContextObject(QObject *contextObject)
|
||||
{
|
||||
deepClearContextObject(
|
||||
contextObject,
|
||||
[](QQmlContextData *self) { self->emitDestruction(); },
|
||||
[](QQmlContextData *){});
|
||||
}
|
||||
|
||||
QQmlEngine *engine() const { return m_engine; }
|
||||
void setEngine(QQmlEngine *engine) { m_engine = engine; }
|
||||
|
||||
|
|
|
@ -215,23 +215,16 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
|
|||
{
|
||||
QObjectPrivate *p = QObjectPrivate::get(o);
|
||||
if (QQmlData *d = QQmlData::get(p)) {
|
||||
const auto invalidate = [](QQmlContextData *c) {c->invalidate();};
|
||||
if (d->ownContext) {
|
||||
for (QQmlRefPointer<QQmlContextData> lc = d->ownContext->linkedContext(); lc;
|
||||
lc = lc->linkedContext()) {
|
||||
lc->invalidate();
|
||||
if (lc->contextObject() == o)
|
||||
lc->setContextObject(nullptr);
|
||||
}
|
||||
d->ownContext->invalidate();
|
||||
if (d->ownContext->contextObject() == o)
|
||||
d->ownContext->setContextObject(nullptr);
|
||||
d->ownContext->deepClearContextObject(o, invalidate, invalidate);
|
||||
d->ownContext.reset();
|
||||
d->context = nullptr;
|
||||
Q_ASSERT(!d->outerContext || d->outerContext->contextObject() != o);
|
||||
} else if (d->outerContext && d->outerContext->contextObject() == o) {
|
||||
d->outerContext->deepClearContextObject(o, invalidate, invalidate);
|
||||
}
|
||||
|
||||
if (d->outerContext && d->outerContext->contextObject() == o)
|
||||
d->outerContext->setContextObject(nullptr);
|
||||
|
||||
if (d->hasVMEMetaObject || d->hasInterceptorMetaObject) {
|
||||
// This is somewhat dangerous because another thread might concurrently
|
||||
// try to resolve the dynamic metaobject. In practice this will then
|
||||
|
@ -407,9 +400,7 @@ void QQmlData::setQueuedForDeletion(QObject *object)
|
|||
if (QQmlData *ddata = QQmlData::get(object)) {
|
||||
if (ddata->ownContext) {
|
||||
Q_ASSERT(ddata->ownContext.data() == ddata->context);
|
||||
ddata->context->emitDestruction();
|
||||
if (ddata->ownContext->contextObject() == object)
|
||||
ddata->ownContext->setContextObject(nullptr);
|
||||
ddata->ownContext->deepClearContextObject(object);
|
||||
ddata->ownContext.reset();
|
||||
ddata->context = nullptr;
|
||||
}
|
||||
|
|
|
@ -166,8 +166,20 @@ void QQmlEngineExtensionPlugin::initializeEngine(QQmlEngine *engine, const char
|
|||
\since 6.2
|
||||
\relates QQmlEngineExtensionPlugin
|
||||
|
||||
Ensures the plugin whose metadata-declaring class is named \a PluginName
|
||||
is linked into static builds.
|
||||
Ensures the plugin whose metadata-declaring plugin extension class is named
|
||||
\a PluginName is linked into static builds. For the modules created using
|
||||
\l qt_add_qml_module, the default plugin extension class name is computed
|
||||
from the QML module URI by replacing dots with underscores, unless the
|
||||
\c CLASS_NAME argument is specified.
|
||||
|
||||
For example:
|
||||
\badcode
|
||||
qt_add_qml_module(myplugin
|
||||
# The plugin extension class name in this case is my_Company_QmlComponents.
|
||||
URI my.Company.QmlComponents
|
||||
...
|
||||
)
|
||||
\endcode
|
||||
|
||||
\sa Q_IMPORT_PLUGIN
|
||||
*/
|
||||
|
|
|
@ -78,42 +78,4 @@ QMetaType QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteAr
|
|||
return QMetaType();
|
||||
}
|
||||
|
||||
bool QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage,
|
||||
QByteArray *unknownTypeError) const
|
||||
{
|
||||
Q_ASSERT(_m && index >= 0);
|
||||
|
||||
QMetaMethod m = _m->method(index);
|
||||
return methodParameterTypes(m, argStorage, unknownTypeError);
|
||||
}
|
||||
|
||||
bool QQmlMetaObject::constructorParameterTypes(int index, ArgTypeStorage *dummy,
|
||||
QByteArray *unknownTypeError) const
|
||||
{
|
||||
QMetaMethod m = _m->constructor(index);
|
||||
return methodParameterTypes(m, dummy, unknownTypeError);
|
||||
}
|
||||
|
||||
bool QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *argStorage,
|
||||
QByteArray *unknownTypeError)
|
||||
{
|
||||
Q_ASSERT(argStorage);
|
||||
|
||||
int argc = m.parameterCount();
|
||||
argStorage->resize(argc);
|
||||
for (int ii = 0; ii < argc; ++ii) {
|
||||
QMetaType type = m.parameterMetaType(ii);
|
||||
// we treat enumerations as int
|
||||
if (type.flags().testFlag(QMetaType::IsEnumeration))
|
||||
type = QMetaType::fromType<int>();
|
||||
if (!type.isValid()) {
|
||||
if (unknownTypeError)
|
||||
*unknownTypeError = m.parameterTypeName(ii);
|
||||
return false;
|
||||
}
|
||||
argStorage->operator[](ii) = type;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -34,7 +34,8 @@ class QQmlPropertyData;
|
|||
class Q_QML_EXPORT QQmlMetaObject
|
||||
{
|
||||
public:
|
||||
typedef QVarLengthArray<QMetaType, 9> ArgTypeStorage;
|
||||
template<qsizetype Prealloc>
|
||||
using ArgTypeStorage = QVarLengthArray<QMetaType, Prealloc>;
|
||||
|
||||
inline QQmlMetaObject() = default;
|
||||
inline QQmlMetaObject(const QObject *);
|
||||
|
@ -52,30 +53,116 @@ public:
|
|||
inline const QMetaObject *metaObject() const;
|
||||
|
||||
QMetaType methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const;
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Returns false if one of the types is unknown. Otherwise, fills \a argstorage with the
|
||||
metatypes of the function.
|
||||
*/
|
||||
bool methodParameterTypes(int index, ArgTypeStorage *argStorage,
|
||||
QByteArray *unknownTypeError) const;
|
||||
template<typename ArgTypeStorage>
|
||||
bool methodParameterTypes(
|
||||
int index, ArgTypeStorage *argStorage, QByteArray *unknownTypeError) const
|
||||
{
|
||||
Q_ASSERT(_m && index >= 0);
|
||||
|
||||
QMetaMethod m = _m->method(index);
|
||||
return methodParameterTypes(m, argStorage, unknownTypeError);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Returns false if one of the types is unknown. Otherwise, fills \a argstorage with the
|
||||
metatypes of the function.
|
||||
*/
|
||||
bool constructorParameterTypes(int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const;
|
||||
template<typename ArgTypeStorage>
|
||||
bool constructorParameterTypes(
|
||||
int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const
|
||||
{
|
||||
QMetaMethod m = _m->constructor(index);
|
||||
return methodParameterTypes(m, dummy, unknownTypeError);
|
||||
}
|
||||
|
||||
|
||||
static bool canConvert(const QQmlMetaObject &from, const QQmlMetaObject &to);
|
||||
|
||||
// static_metacall (on Gadgets) doesn't call the base implementation and therefore
|
||||
// we need a helper to find the correct meta object and property/method index.
|
||||
static void resolveGadgetMethodOrPropertyIndex(QMetaObject::Call type, const QMetaObject **metaObject, int *index);
|
||||
static void resolveGadgetMethodOrPropertyIndex(
|
||||
QMetaObject::Call type, const QMetaObject **metaObject, int *index);
|
||||
|
||||
template<typename ArgTypeStorage>
|
||||
static bool methodParameterTypes(
|
||||
const QMetaMethod &method, ArgTypeStorage *argStorage, QByteArray *unknownTypeError)
|
||||
{
|
||||
Q_ASSERT(argStorage);
|
||||
|
||||
const int argc = method.parameterCount();
|
||||
argStorage->resize(argc);
|
||||
for (int ii = 0; ii < argc; ++ii) {
|
||||
if (!parameterType(method, ii, unknownTypeError, [argStorage](int ii, QMetaType &&type) {
|
||||
argStorage->operator[](ii) = std::forward<QMetaType>(type);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename ArgTypeStorage>
|
||||
static bool methodReturnAndParameterTypes(
|
||||
const QMetaMethod &method, ArgTypeStorage *argStorage, QByteArray *unknownTypeError)
|
||||
{
|
||||
Q_ASSERT(argStorage);
|
||||
|
||||
const int argc = method.parameterCount();
|
||||
argStorage->resize(argc + 1);
|
||||
|
||||
QMetaType type = method.returnMetaType();
|
||||
if (type.flags().testFlag(QMetaType::IsEnumeration))
|
||||
type = QMetaType::fromType<int>();
|
||||
|
||||
if (!type.isValid()) {
|
||||
if (unknownTypeError)
|
||||
*unknownTypeError = "return type";
|
||||
return false;
|
||||
}
|
||||
|
||||
argStorage->operator[](0) = type;
|
||||
|
||||
for (int ii = 0; ii < argc; ++ii) {
|
||||
if (!parameterType(
|
||||
method, ii, unknownTypeError, [argStorage](int ii, QMetaType &&type) {
|
||||
argStorage->operator[](ii + 1) = std::forward<QMetaType>(type);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage,
|
||||
QByteArray *unknownTypeError);
|
||||
protected:
|
||||
template<typename Store>
|
||||
static bool parameterType(
|
||||
const QMetaMethod &method, int ii, QByteArray *unknownTypeError, const Store &store)
|
||||
{
|
||||
QMetaType type = method.parameterMetaType(ii);
|
||||
|
||||
// we treat enumerations as int
|
||||
if (type.flags().testFlag(QMetaType::IsEnumeration))
|
||||
type = QMetaType::fromType<int>();
|
||||
|
||||
if (!type.isValid()) {
|
||||
if (unknownTypeError)
|
||||
*unknownTypeError = method.parameterTypeName(ii);
|
||||
return false;
|
||||
}
|
||||
|
||||
store(ii, std::move(type));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const QMetaObject *_m = nullptr;
|
||||
|
||||
};
|
||||
|
|
|
@ -154,7 +154,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
|
|||
} else {
|
||||
Q_ASSERT(subComponentIndex >= 0);
|
||||
if (flags & CreationFlags::InlineComponent) {
|
||||
if (compilationUnit->unitData()->flags & QV4::CompiledData::Unit::ComponentsBound
|
||||
if (compilationUnit->componentsAreBound()
|
||||
&& compilationUnit != parentContext->typeCompilationUnit()) {
|
||||
recordError({}, tr("Cannot instantiate bound inline component in different file"));
|
||||
phase = ObjectsCreated;
|
||||
|
@ -164,7 +164,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
|
|||
isComponentRoot = true;
|
||||
} else {
|
||||
Q_ASSERT(flags & CreationFlags::NormalObject);
|
||||
if (compilationUnit->unitData()->flags & QV4::CompiledData::Unit::ComponentsBound
|
||||
if (compilationUnit->componentsAreBound()
|
||||
&& sharedState->creationContext != parentContext) {
|
||||
recordError({}, tr("Cannot instantiate bound component "
|
||||
"outside its creation context"));
|
||||
|
@ -313,7 +313,10 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
|
|||
QMetaType propertyType = property->propType();
|
||||
|
||||
if (property->isEnum()) {
|
||||
if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum)) {
|
||||
if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum) ||
|
||||
// TODO: For historical reasons you can assign any number to an enum property alias
|
||||
// This can be fixed with an opt-out mechanism, for example a pragma.
|
||||
(property->isAlias() && binding->isNumberBinding())) {
|
||||
propertyType = QMetaType::fromType<int>();
|
||||
} else {
|
||||
// ### This should be resolved earlier at compile time and the binding value should be changed accordingly.
|
||||
|
|
|
@ -428,14 +428,15 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
|
|||
if (result != end)
|
||||
*result = result->toUpper();
|
||||
|
||||
if (findSignalInMetaObject(signalName.toUtf8())) {
|
||||
qWarning()
|
||||
<< terminalString
|
||||
<< "is not a properly capitalized signal handler name."
|
||||
<< handlerName
|
||||
<< "would be correct.";
|
||||
if (findSignalInMetaObject(signalName.toUtf8()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ddata && ddata->propertyCache) {
|
||||
const QQmlPropertyData *property = ddata->propertyCache->property(
|
||||
|
|
|
@ -864,10 +864,10 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
|
|||
resettable = property->isResettable();
|
||||
bindable = property->isBindable();
|
||||
|
||||
// Copy type flags
|
||||
propertyFlags->copyPropertyTypeFlags(property->flags());
|
||||
if (property->isVarProperty())
|
||||
propertyFlags->type = QQmlPropertyData::Flags::QVariantType;
|
||||
else
|
||||
propertyFlags->copyPropertyTypeFlags(property->flags());
|
||||
};
|
||||
|
||||
// for deep aliases, valueTypeIndex is always set
|
||||
|
|
|
@ -364,6 +364,11 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(
|
|||
if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum))
|
||||
return noError;
|
||||
|
||||
// TODO: For historical reasons you can assign any number to an enum property alias
|
||||
// This can be fixed with an opt-out mechanism, for example a pragma.
|
||||
if (property->isAlias() && binding->isNumberBinding())
|
||||
return noError;
|
||||
|
||||
QString value = compilationUnit->bindingValueAsString(binding);
|
||||
QMetaProperty p = propertyCache->firstCppMetaObject()->property(property->coreIndex());
|
||||
bool ok;
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
|
||||
#include "qqmlconnections_p.h"
|
||||
|
||||
#include <private/qqmlboundsignal_p.h>
|
||||
#include <private/qqmlcontext_p.h>
|
||||
#include <private/qqmlexpression_p.h>
|
||||
#include <private/qqmlproperty_p.h>
|
||||
#include <private/qqmlboundsignal_p.h>
|
||||
#include <qqmlcontext.h>
|
||||
#include <private/qqmlcontext_p.h>
|
||||
#include <private/qqmlvmemetaobject_p.h>
|
||||
#include <qqmlinfo.h>
|
||||
#include <private/qv4jscall_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
|
||||
#include <QtQml/qqmlcontext.h>
|
||||
#include <QtQml/qqmlinfo.h>
|
||||
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
#include <private/qobject_p.h>
|
||||
|
@ -21,10 +24,110 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
Q_LOGGING_CATEGORY(lcQmlConnections, "qt.qml.connections")
|
||||
|
||||
// This is the equivalent of QQmlBoundSignal for C++ methods as as slots.
|
||||
// If a type derived from QQmlConnnections is compiled using qmltc, the
|
||||
// JavaScript functions it contains are turned into C++ methods and we cannot
|
||||
// use QQmlBoundSignal to connect to those.
|
||||
struct QQmlConnectionSlotDispatcher : public QtPrivate::QSlotObjectBase
|
||||
{
|
||||
QV4::ExecutionEngine *v4 = nullptr;
|
||||
QObject *receiver = nullptr;
|
||||
|
||||
// Signals rarely have more than one argument.
|
||||
QQmlMetaObject::ArgTypeStorage<2> signalMetaTypes;
|
||||
QQmlMetaObject::ArgTypeStorage<2> slotMetaTypes;
|
||||
|
||||
QMetaObject::Connection connection;
|
||||
|
||||
int slotIndex = -1;
|
||||
bool enabled = true;
|
||||
|
||||
QQmlConnectionSlotDispatcher(
|
||||
QV4::ExecutionEngine *v4, QObject *sender, int signalIndex,
|
||||
QObject *receiver, int slotIndex, bool enabled)
|
||||
: QtPrivate::QSlotObjectBase(&impl)
|
||||
, v4(v4)
|
||||
, receiver(receiver)
|
||||
, slotIndex(slotIndex)
|
||||
, enabled(enabled)
|
||||
{
|
||||
QMetaMethod signal = sender->metaObject()->method(signalIndex);
|
||||
QQmlMetaObject::methodReturnAndParameterTypes(signal, &signalMetaTypes, nullptr);
|
||||
|
||||
QMetaMethod slot = receiver->metaObject()->method(slotIndex);
|
||||
QQmlMetaObject::methodReturnAndParameterTypes(slot, &slotMetaTypes, nullptr);
|
||||
}
|
||||
|
||||
template<typename ArgTypeStorage>
|
||||
struct TypedFunction
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(TypedFunction)
|
||||
public:
|
||||
TypedFunction(const ArgTypeStorage *storage) : storage(storage) {}
|
||||
|
||||
QMetaType returnMetaType() const { return storage->at(0); }
|
||||
qsizetype parameterCount() const { return storage->size() - 1; }
|
||||
QMetaType parameterMetaType(qsizetype i) const { return storage->at(i + 1); }
|
||||
|
||||
private:
|
||||
const ArgTypeStorage *storage;
|
||||
};
|
||||
|
||||
static void impl(int which, QSlotObjectBase *base, QObject *, void **metaArgs, bool *ret)
|
||||
{
|
||||
switch (which) {
|
||||
case Destroy: {
|
||||
delete static_cast<QQmlConnectionSlotDispatcher *>(base);
|
||||
break;
|
||||
}
|
||||
case Call: {
|
||||
QQmlConnectionSlotDispatcher *self = static_cast<QQmlConnectionSlotDispatcher *>(base);
|
||||
QV4::ExecutionEngine *v4 = self->v4;
|
||||
if (!v4)
|
||||
break;
|
||||
|
||||
if (!self->enabled)
|
||||
break;
|
||||
|
||||
TypedFunction typedFunction(&self->slotMetaTypes);
|
||||
QV4::coerceAndCall(
|
||||
v4, &typedFunction, metaArgs,
|
||||
self->signalMetaTypes.data(), self->signalMetaTypes.size() - 1,
|
||||
[&](void **argv, int) {
|
||||
self->receiver->metaObject()->metacall(
|
||||
self->receiver, QMetaObject::InvokeMetaMethod,
|
||||
self->slotIndex, argv);
|
||||
});
|
||||
|
||||
if (v4->hasException) {
|
||||
QQmlError error = v4->catchExceptionAsQmlError();
|
||||
if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
|
||||
QQmlEnginePrivate::get(qmlEngine)->warning(error);
|
||||
} else {
|
||||
QMessageLogger(
|
||||
qPrintable(error.url().toString()), error.line(), nullptr)
|
||||
.warning().noquote()
|
||||
<< error.toString();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Compare:
|
||||
// We're not implementing the Compare protocol here. It's insane.
|
||||
// QQmlConnectionSlotDispatcher compares false to anything. We use
|
||||
// the regular QObject::disconnect with QMetaObject::Connection.
|
||||
*ret = false;
|
||||
break;
|
||||
case NumOperations:
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class QQmlConnectionsPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
QList<QQmlBoundSignal*> boundsignals;
|
||||
QList<QBiPointer<QQmlBoundSignal, QQmlConnectionSlotDispatcher>> boundsignals;
|
||||
QQmlGuard<QObject> target;
|
||||
|
||||
bool enabled = true;
|
||||
|
@ -105,6 +208,22 @@ QQmlConnections::QQmlConnections(QObject *parent) :
|
|||
{
|
||||
}
|
||||
|
||||
QQmlConnections::~QQmlConnections()
|
||||
{
|
||||
Q_D(QQmlConnections);
|
||||
|
||||
// The slot dispatchers hold cyclic references to their connections. Clear them.
|
||||
for (const auto &bound : std::as_const(d->boundsignals)) {
|
||||
if (QQmlConnectionSlotDispatcher *dispatcher = bound.isT2() ? bound.asT2() : nullptr) {
|
||||
// No need to explicitly disconnect anymore since 'this' is the receiver.
|
||||
// But to be safe, explicitly break any cyclic references between the connection
|
||||
// and the slot object.
|
||||
dispatcher->connection = {};
|
||||
dispatcher->destroyIfLastRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty QtObject QtQml::Connections::target
|
||||
This property holds the object that sends the signal.
|
||||
|
@ -136,13 +255,19 @@ void QQmlConnections::setTarget(QObject *obj)
|
|||
if (d->targetSet && d->target == obj)
|
||||
return;
|
||||
d->targetSet = true; // even if setting to 0, it is *set*
|
||||
for (QQmlBoundSignal *s : std::as_const(d->boundsignals)) {
|
||||
for (const auto &bound : std::as_const(d->boundsignals)) {
|
||||
// It is possible that target is being changed due to one of our signal
|
||||
// handlers -> use deleteLater().
|
||||
if (s->isNotifying())
|
||||
(new QQmlBoundSignalDeleter(s))->deleteLater();
|
||||
if (QQmlBoundSignal *signal = bound.isT1() ? bound.asT1() : nullptr) {
|
||||
if (signal->isNotifying())
|
||||
(new QQmlBoundSignalDeleter(signal))->deleteLater();
|
||||
else
|
||||
delete s;
|
||||
delete signal;
|
||||
} else {
|
||||
QQmlConnectionSlotDispatcher *dispatcher = bound.asT2();
|
||||
QObject::disconnect(std::exchange(dispatcher->connection, {}));
|
||||
dispatcher->destroyIfLastRef();
|
||||
}
|
||||
}
|
||||
d->boundsignals.clear();
|
||||
d->target = obj;
|
||||
|
@ -172,8 +297,12 @@ void QQmlConnections::setEnabled(bool enabled)
|
|||
|
||||
d->enabled = enabled;
|
||||
|
||||
for (QQmlBoundSignal *s : std::as_const(d->boundsignals))
|
||||
s->setEnabled(d->enabled);
|
||||
for (const auto &bound : std::as_const(d->boundsignals)) {
|
||||
if (QQmlBoundSignal *signal = bound.isT1() ? bound.asT1() : nullptr)
|
||||
signal->setEnabled(d->enabled);
|
||||
else
|
||||
bound.asT2()->enabled = enabled;
|
||||
}
|
||||
|
||||
emit enabledChanged();
|
||||
}
|
||||
|
@ -274,33 +403,41 @@ void QQmlConnections::connectSignalsToMethods()
|
|||
++i) {
|
||||
|
||||
const QQmlPropertyData *handler = ddata->propertyCache->method(i);
|
||||
if (!handler || !handler->isVMEFunction())
|
||||
if (!handler)
|
||||
continue;
|
||||
|
||||
const QString propName = handler->name(this);
|
||||
|
||||
QQmlProperty prop(target, propName);
|
||||
if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) {
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedContext global(scope, engine->rootContext());
|
||||
|
||||
if (QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(this)) {
|
||||
int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex();
|
||||
auto *signal = new QQmlBoundSignal(target, signalIndex, this, qmlEngine(this));
|
||||
signal->setEnabled(d->enabled);
|
||||
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedContext global(scope, engine->rootContext());
|
||||
QV4::ScopedFunctionObject method(
|
||||
scope, vmeMetaObject->vmeMethod(handler->coreIndex()));
|
||||
|
||||
QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(this);
|
||||
Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this
|
||||
|
||||
QV4::ScopedFunctionObject method(scope, vmeMetaObject->vmeMethod(handler->coreIndex()));
|
||||
|
||||
QQmlBoundSignalExpression *expression =
|
||||
ctxtdata ? new QQmlBoundSignalExpression(
|
||||
QQmlBoundSignalExpression *expression = ctxtdata
|
||||
? new QQmlBoundSignalExpression(
|
||||
target, signalIndex, ctxtdata, this,
|
||||
method->as<QV4::FunctionObject>()->function())
|
||||
: nullptr;
|
||||
|
||||
signal->takeExpression(expression);
|
||||
d->boundsignals += signal;
|
||||
} else {
|
||||
QQmlConnectionSlotDispatcher *slot = new QQmlConnectionSlotDispatcher(
|
||||
scope.engine, target, prop.index(),
|
||||
this, handler->coreIndex(), d->enabled);
|
||||
slot->connection = QObjectPrivate::connect(
|
||||
target, prop.index(), slot, Qt::AutoConnection);
|
||||
slot->ref();
|
||||
d->boundsignals += slot;
|
||||
}
|
||||
} else if (!d->ignoreUnknownSignals
|
||||
&& propName.startsWith(QLatin1String("on")) && propName.size() > 2
|
||||
&& propName.at(2).isUpper()) {
|
||||
|
|
|
@ -40,7 +40,8 @@ class Q_QML_PRIVATE_EXPORT QQmlConnections : public QObject, public QQmlParserSt
|
|||
QML_CUSTOMPARSER
|
||||
|
||||
public:
|
||||
QQmlConnections(QObject *parent=nullptr);
|
||||
QQmlConnections(QObject *parent = nullptr);
|
||||
~QQmlConnections();
|
||||
|
||||
QObject *target() const;
|
||||
void setTarget(QObject *);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qcoloroutput_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QCOLOROUTPUT_H
|
||||
#define QCOLOROUTPUT_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QDEFERREDPOINTER_P_H
|
||||
#define QDEFERREDPOINTER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsannotation_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSANNOTATION_P_H
|
||||
#define QQMLJSANNOTATION_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsbasicblocks_p.h"
|
||||
|
||||
|
@ -155,16 +155,6 @@ static bool containsAny(const ContainerA &container, const ContainerB &elements)
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename ContainerA, typename ContainerB>
|
||||
static bool containsAll(const ContainerA &container, const ContainerB &elements)
|
||||
{
|
||||
for (const auto &element : elements) {
|
||||
if (!container.contains(element))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Key, class T, class Compare = std::less<Key>,
|
||||
class KeyContainer = QList<Key>, class MappedContainer = QList<T>>
|
||||
class NewFlatMap
|
||||
|
@ -191,7 +181,7 @@ private:
|
|||
|
||||
struct PendingBlock
|
||||
{
|
||||
QList<int> conversions;
|
||||
QQmlJSBasicBlocks::Conversions conversions;
|
||||
int start = -1;
|
||||
bool registerActive = false;
|
||||
};
|
||||
|
@ -278,7 +268,7 @@ void QQmlJSBasicBlocks::populateReaderLocations()
|
|||
auto nextBlock = m_basicBlocks.find(block.start);
|
||||
auto currentBlock = nextBlock++;
|
||||
bool registerActive = block.registerActive;
|
||||
QList<int> conversions = block.conversions;
|
||||
Conversions conversions = block.conversions;
|
||||
|
||||
const auto blockEnd = (nextBlock == m_basicBlocks.end())
|
||||
? m_annotations.end()
|
||||
|
@ -290,7 +280,7 @@ void QQmlJSBasicBlocks::populateReaderLocations()
|
|||
for (; blockInstr != blockEnd; ++blockInstr) {
|
||||
if (registerActive
|
||||
&& blockInstr->second.typeConversions.contains(writtenRegister)) {
|
||||
conversions.append(blockInstr.key());
|
||||
conversions.insert(blockInstr.key());
|
||||
}
|
||||
|
||||
for (auto readIt = blockInstr->second.readRegisters.constBegin(),
|
||||
|
@ -316,12 +306,26 @@ void QQmlJSBasicBlocks::populateReaderLocations()
|
|||
// If we find that an already processed block has the register activated by this jump,
|
||||
// we need to re-evaluate it. We also need to propagate any newly found conversions.
|
||||
const auto processed = processedBlocks.find(blockStart);
|
||||
if (processed == processedBlocks.end())
|
||||
if (processed == processedBlocks.end()) {
|
||||
blocks.append({conversions, blockStart, registerActive});
|
||||
else if (registerActive && !processed->registerActive)
|
||||
} else if (registerActive && !processed->registerActive) {
|
||||
blocks.append({conversions, blockStart, registerActive});
|
||||
else if (!containsAll(processed->conversions, conversions))
|
||||
blocks.append({processed->conversions + conversions, blockStart, registerActive});
|
||||
} else {
|
||||
|
||||
// TODO: Use unite() once it is fixed.
|
||||
// We don't use unite() here since it would be more expensive. unite()
|
||||
// effectively loops on only insert() and insert() does a number of checks
|
||||
// each time. We trade those checks for calculating the hash twice on each
|
||||
// iteration. Calculating the hash is very cheap for integers.
|
||||
Conversions merged = processed->conversions;
|
||||
for (const int conversion : std::as_const(conversions)) {
|
||||
if (!merged.contains(conversion))
|
||||
merged.insert(conversion);
|
||||
}
|
||||
|
||||
if (merged.size() > processed->conversions.size())
|
||||
blocks.append({std::move(merged), blockStart, registerActive});
|
||||
}
|
||||
};
|
||||
|
||||
if (!currentBlock->second.jumpIsUnconditional && nextBlock != m_basicBlocks.end())
|
||||
|
@ -407,7 +411,7 @@ void QQmlJSBasicBlocks::adjustTypes()
|
|||
valueType);
|
||||
}
|
||||
|
||||
for (const QList<int> &conversions : std::as_const(it->registerReadersAndConversions)) {
|
||||
for (const auto &conversions : std::as_const(it->registerReadersAndConversions)) {
|
||||
for (int conversion : conversions)
|
||||
liveConversions[conversion].append(it->trackedRegister);
|
||||
}
|
||||
|
@ -416,7 +420,7 @@ void QQmlJSBasicBlocks::adjustTypes()
|
|||
}
|
||||
|
||||
for (auto it = m_readerLocations.begin(), end = m_readerLocations.end(); it != end; ++it) {
|
||||
for (const QList<int> &conversions : std::as_const(it->registerReadersAndConversions)) {
|
||||
for (const auto &conversions : std::as_const(it->registerReadersAndConversions)) {
|
||||
for (int conversion : conversions)
|
||||
liveConversions[conversion].append(it->trackedRegister);
|
||||
}
|
||||
|
@ -426,6 +430,11 @@ void QQmlJSBasicBlocks::adjustTypes()
|
|||
if (it->trackedTypes.size() != 1)
|
||||
continue;
|
||||
|
||||
// Don't adjust renamed values. We only adjust the originals.
|
||||
const int writeLocation = it.key();
|
||||
if (writeLocation >= 0 && m_annotations[writeLocation].isRename)
|
||||
continue;
|
||||
|
||||
m_typeResolver->adjustTrackedType(it->trackedTypes[0], it->typeReaders.values());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSBASICBLOCKS_P_H
|
||||
#define QQMLJSBASICBLOCKS_P_H
|
||||
|
@ -23,6 +23,8 @@ QT_BEGIN_NAMESPACE
|
|||
class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSBasicBlocks : public QQmlJSCompilePass
|
||||
{
|
||||
public:
|
||||
using Conversions = QSet<int>;
|
||||
|
||||
struct BasicBlock {
|
||||
QList<int> jumpOrigins;
|
||||
QList<int> readRegisters;
|
||||
|
@ -46,7 +48,7 @@ private:
|
|||
{
|
||||
QList<QQmlJSScope::ConstPtr> trackedTypes;
|
||||
QHash<int, QQmlJSScope::ConstPtr> typeReaders;
|
||||
QHash<int, QList<int>> registerReadersAndConversions;
|
||||
QHash<int, Conversions> registerReadersAndConversions;
|
||||
int trackedRegister;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljscodegenerator_p.h"
|
||||
#include "qqmljsmetatypes_p.h"
|
||||
|
@ -191,8 +191,8 @@ QT_WARNING_POP
|
|||
|
||||
result.code += registerIt->variableName + u" = "_s;
|
||||
|
||||
const QString originalValue = u"*static_cast<"_s + castTargetName(original)
|
||||
+ u"*>(argumentsPtr["_s + QString::number(argumentIndex) + u"])"_s;
|
||||
const QString originalValue = u"(*static_cast<"_s + castTargetName(original)
|
||||
+ u"*>(argumentsPtr["_s + QString::number(argumentIndex) + u"]))"_s;
|
||||
|
||||
if (needsConversion)
|
||||
result.code += conversion(original, argument, originalValue);
|
||||
|
@ -2783,10 +2783,18 @@ void QQmlJSCodeGenerator::generateInPlaceOperation(const QString &cppOperator)
|
|||
void QQmlJSCodeGenerator::generateLookup(const QString &lookup, const QString &initialization,
|
||||
const QString &resultPreparation)
|
||||
{
|
||||
m_body += u"#ifndef QT_NO_DEBUG\n"_s;
|
||||
generateSetInstructionPointer();
|
||||
m_body += u"#endif\n"_s;
|
||||
|
||||
if (!resultPreparation.isEmpty())
|
||||
m_body += resultPreparation + u";\n"_s;
|
||||
m_body += u"while (!"_s + lookup + u") {\n"_s;
|
||||
|
||||
m_body += u"#ifdef QT_NO_DEBUG\n"_s;
|
||||
generateSetInstructionPointer();
|
||||
m_body += u"#endif\n"_s;
|
||||
|
||||
m_body += initialization + u";\n"_s;
|
||||
generateExceptionCheck();
|
||||
if (!resultPreparation.isEmpty())
|
||||
|
@ -3003,7 +3011,7 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
|
|||
if (m_typeResolver->equals(to, m_typeResolver->uintType()))
|
||||
return u"uint(QJSNumberCoercion::toInteger("_s + variable + u"))"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->boolType()))
|
||||
return u'(' + variable + u" && !std::isnan("_s + variable + u"))"_s;
|
||||
return u"[](double moved){ return moved && !std::isnan(moved); }("_s + variable + u')';
|
||||
}
|
||||
|
||||
if (isBoolOrNumber(from) && isBoolOrNumber(to))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSCODEGENERATOR_P_H
|
||||
#define QQMLJSCODEGENERATOR_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSCOMPILEPASS_P_H
|
||||
#define QQMLJSCOMPILEPASS_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljscompiler_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSCOMPILER_P_H
|
||||
#define QQMLJSCOMPILER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsfunctioninitializer_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSFUNCTIONINITIALIAZER_P_H
|
||||
#define QQMLJSFUNCTIONINITIALIAZER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsimporter_p.h"
|
||||
#include "qqmljstypedescriptionreader_p.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSIMPORTER_P_H
|
||||
#define QQMLJSIMPORTER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsimportvisitor_p.h"
|
||||
#include "qqmljsmetatypes_p.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSIMPORTEDMEMBERSVISITOR_P_H
|
||||
#define QQMLJSIMPORTEDMEMBERSVISITOR_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljslinter_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QMLJSLINTER_P_H
|
||||
#define QMLJSLINTER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljslintercodegen_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSLINTERCODEGEN_P_H
|
||||
#define QQMLJSLINTERCODEGEN_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsliteralbindingcheck_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSLITERALBINDINGCHECK_P_H
|
||||
#define QQMLJSLITERALBINDINGCHECK_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsloadergenerator_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSLOADERGENERATOR_P_H
|
||||
#define QQMLJSLOADERGENERATOR_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSLOGGER_P_H
|
||||
#define QQMLJSLOGGER_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsmetatypes_p.h"
|
||||
#include "qqmljstyperesolver_p.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSMETATYPES_P_H
|
||||
#define QQMLJSMETATYPES_P_H
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
Const,
|
||||
};
|
||||
|
||||
QQmlJSMetaParameter(const QString &name, const QString &typeName,
|
||||
QQmlJSMetaParameter(const QString &name = QString(), const QString &typeName = QString(),
|
||||
Constness typeQualifier = NonConst,
|
||||
QWeakPointer<const QQmlJSScope> type = {})
|
||||
: m_name(name), m_typeName(typeName), m_type(type), m_typeQualifier(typeQualifier)
|
||||
|
@ -135,9 +135,13 @@ public:
|
|||
void setType(QWeakPointer<const QQmlJSScope> type) { m_type = type; }
|
||||
Constness typeQualifier() const { return m_typeQualifier; }
|
||||
void setTypeQualifier(Constness typeQualifier) { m_typeQualifier = typeQualifier; }
|
||||
|
||||
bool isPointer() const { return m_isPointer; }
|
||||
void setIsPointer(bool isPointer) { m_isPointer = isPointer; }
|
||||
|
||||
bool isList() const { return m_isList; }
|
||||
void setIsList(bool isList) { m_isList = isList; }
|
||||
|
||||
friend bool operator==(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b)
|
||||
{
|
||||
return a.m_name == b.m_name && a.m_typeName == b.m_typeName
|
||||
|
@ -162,8 +166,11 @@ private:
|
|||
QWeakPointer<const QQmlJSScope> m_type;
|
||||
Constness m_typeQualifier = NonConst;
|
||||
bool m_isPointer = false;
|
||||
bool m_isList = false;
|
||||
};
|
||||
|
||||
using QQmlJSMetaReturnType = QQmlJSMetaParameter;
|
||||
|
||||
class QQmlJSMetaMethod
|
||||
{
|
||||
public:
|
||||
|
@ -191,20 +198,18 @@ public:
|
|||
QQmlJSMetaMethod() = default;
|
||||
explicit QQmlJSMetaMethod(QString name, QString returnType = QString())
|
||||
: m_name(std::move(name))
|
||||
, m_returnTypeName(std::move(returnType))
|
||||
, m_returnType(QString(), std::move(returnType))
|
||||
, m_methodType(Method)
|
||||
{}
|
||||
|
||||
QString methodName() const { return m_name; }
|
||||
void setMethodName(const QString &name) { m_name = name; }
|
||||
|
||||
QString returnTypeName() const { return m_returnTypeName; }
|
||||
QSharedPointer<const QQmlJSScope> returnType() const { return m_returnType.toStrongRef(); }
|
||||
void setReturnTypeName(const QString &type) { m_returnTypeName = type; }
|
||||
void setReturnType(const QSharedPointer<const QQmlJSScope> &type)
|
||||
{
|
||||
m_returnType = type;
|
||||
}
|
||||
QQmlJSMetaReturnType returnValue() const { return m_returnType; }
|
||||
void setReturnValue(const QQmlJSMetaReturnType returnValue) { m_returnType = returnValue; }
|
||||
QString returnTypeName() const { return m_returnType.typeName(); }
|
||||
QSharedPointer<const QQmlJSScope> returnType() const { return m_returnType.type(); }
|
||||
void setReturnTypeName(const QString &type) { m_returnType.setTypeName(type); }
|
||||
|
||||
QList<QQmlJSMetaParameter> parameters() const { return m_parameters; }
|
||||
|
||||
|
@ -257,7 +262,7 @@ public:
|
|||
|
||||
friend bool operator==(const QQmlJSMetaMethod &a, const QQmlJSMetaMethod &b)
|
||||
{
|
||||
return a.m_name == b.m_name && a.m_returnTypeName == b.m_returnTypeName
|
||||
return a.m_name == b.m_name && a.m_returnType == b.m_returnType
|
||||
&& a.m_returnType == b.m_returnType && a.m_parameters == b.m_parameters
|
||||
&& a.m_annotations == b.m_annotations && a.m_methodType == b.m_methodType
|
||||
&& a.m_methodAccess == b.m_methodAccess && a.m_revision == b.m_revision
|
||||
|
@ -274,8 +279,7 @@ public:
|
|||
QtPrivate::QHashCombine combine;
|
||||
|
||||
seed = combine(seed, method.m_name);
|
||||
seed = combine(seed, method.m_returnTypeName);
|
||||
seed = combine(seed, method.m_returnType.toStrongRef().data());
|
||||
seed = combine(seed, method.m_returnType);
|
||||
seed = combine(seed, method.m_annotations);
|
||||
seed = combine(seed, method.m_methodType);
|
||||
seed = combine(seed, method.m_methodAccess);
|
||||
|
@ -291,8 +295,8 @@ public:
|
|||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_returnTypeName;
|
||||
QWeakPointer<const QQmlJSScope> m_returnType;
|
||||
|
||||
QQmlJSMetaReturnType m_returnType;
|
||||
|
||||
QList<QQmlJSMetaParameter> m_parameters;
|
||||
QList<QQmlJSAnnotation> m_annotations;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsregistercontent_p.h"
|
||||
#include "qqmljstyperesolver_p.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#ifndef QQMLJSREGISTERCONTENT_P_H
|
||||
#define QQMLJSREGISTERCONTENT_P_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
|
||||
#include "qqmljsresourcefilemapper_p.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
|
||||
#ifndef QQMLJSRESOURCEFILEMAPPER_P_H
|
||||
#define QQMLJSRESOURCEFILEMAPPER_P_H
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue