Merge remote-tracking branch 'origin/5.8' into dev

Conflicts:
	src/qml/jsruntime/qv4object_p.h

Change-Id: Iff4d3aba7710a999b8befdc493cbe959e1ce02f9
This commit is contained in:
Liang Qi 2016-11-23 10:49:37 +01:00
commit 5d4cbf4094
75 changed files with 769 additions and 536 deletions

View File

@ -42,6 +42,72 @@ import QtQuick 2.0
ListModel { ListModel {
id: stocks id: stocks
// pre-fetch data for all entries
Component.onCompleted: {
for (var idx = 0; idx < count; ++idx) {
getCloseValue(idx)
}
}
function requestUrl(stockId) {
var endDate = new Date(""); // today
var startDate = new Date()
startDate.setDate(startDate.getDate() - 5);
var request = "http://ichart.finance.yahoo.com/table.csv?";
request += "s=" + stockId;
request += "&g=d";
request += "&a=" + startDate.getMonth();
request += "&b=" + startDate.getDate();
request += "&c=" + startDate.getFullYear();
request += "&d=" + endDate.getMonth();
request += "&e=" + endDate.getDate();
request += "&f=" + endDate.getFullYear();
request += "&g=d";
request += "&ignore=.csv";
return request;
}
function getCloseValue(index) {
var req = requestUrl(get(index).stockId);
if (!req)
return;
var xhr = new XMLHttpRequest;
xhr.open("GET", req, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
setProperty(index, "value", today.toFixed(2));
r = records[2].split(',');
var yesterday = parseFloat(r[4]);
var change = today - yesterday;
if (change >= 0.0)
setProperty(index, "change", "+" + change.toFixed(2));
else
setProperty(index, "change", change.toFixed(2));
var changePercentage = (change / yesterday) * 100.0;
if (changePercentage >= 0.0)
setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
else
setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
} else {
var unknown = "n/a";
set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
}
}
}
xhr.send()
}
// Uncomment to test invalid entries // Uncomment to test invalid entries
// ListElement {name: "The Qt Company"; stockId: "TQTC"; value: "999.0"; change: "0.0"; changePercentage: "0.0"} // ListElement {name: "The Qt Company"; stockId: "TQTC"; value: "999.0"; change: "0.0"; changePercentage: "0.0"}

View File

@ -64,65 +64,6 @@ Rectangle {
model: StockListModel{} model: StockListModel{}
currentIndex: -1 // Don't pre-select any item currentIndex: -1 // Don't pre-select any item
function requestUrl(stockId) {
var endDate = new Date(""); //today
var startDate = new Date()
startDate.setDate(startDate.getDate() - 5);
var request = "http://ichart.finance.yahoo.com/table.csv?";
request += "s=" + stockId;
request += "&g=d";
request += "&a=" + startDate.getMonth();
request += "&b=" + startDate.getDate();
request += "&c=" + startDate.getFullYear();
request += "&d=" + endDate.getMonth();
request += "&e=" + endDate.getDate();
request += "&f=" + endDate.getFullYear();
request += "&g=d";
request += "&ignore=.csv";
return request;
}
function getCloseValue(index) {
var req = requestUrl(model.get(index).stockId);
if (!req)
return;
var xhr = new XMLHttpRequest;
xhr.open("GET", req, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
model.setProperty(index, "value", today.toFixed(2));
r = records[2].split(',');
var yesterday = parseFloat(r[4]);
var change = today - yesterday;
if (change >= 0.0)
model.setProperty(index, "change", "+" + change.toFixed(2));
else
model.setProperty(index, "change", change.toFixed(2));
var changePercentage = (change / yesterday) * 100.0;
if (changePercentage >= 0.0)
model.setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
else
model.setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
} else {
var unknown = "n/a";
model.set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
}
}
}
xhr.send()
}
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (currentItem) { if (currentItem) {
root.currentStockId = model.get(currentIndex).stockId; root.currentStockId = model.get(currentIndex).stockId;
@ -175,7 +116,6 @@ Rectangle {
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
text: value text: value
Component.onCompleted: view.getCloseValue(index);
} }
Text { Text {

View File

@ -66,14 +66,14 @@ Rectangle {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: page.width / 32 anchors.leftMargin: page.width / 32
anchors.topMargin: page.height / 48 anchors.topMargin: page.height / 48
spacing: elementSpacing spacing: page.elementSpacing
//! [0] //! [0]
Rectangle { Rectangle {
id: green id: green
color: "#80c342" color: "#80c342"
width: 100 * ratio width: 100 * page.ratio
height: 100 * ratio height: 100 * page.ratio
Text { Text {
anchors.left: parent.right anchors.left: parent.right
@ -95,8 +95,8 @@ Rectangle {
Rectangle { Rectangle {
id: blue id: blue
color: "#14aaff" color: "#14aaff"
width: 100 * ratio width: 100 * page.ratio
height: 100 * ratio height: 100 * page.ratio
Text { Text {
anchors.left: parent.right anchors.left: parent.right
@ -117,8 +117,8 @@ Rectangle {
Rectangle { Rectangle {
id: purple id: purple
color: "#6400aa" color: "#6400aa"
width: 100 * ratio width: 100 * page.ratio
height: 100 * ratio height: 100 * page.ratio
Text { Text {
anchors.left: parent.right anchors.left: parent.right
@ -140,8 +140,8 @@ Rectangle {
Rectangle { Rectangle {
id: hidingRect id: hidingRect
color: "#006325" color: "#006325"
width: 100 * ratio width: 100 * page.ratio
height: 100 * ratio height: 100 * page.ratio
visible: false visible: false
Text { Text {

View File

@ -55,7 +55,7 @@ Item {
interval: 2000 interval: 2000
running: true running: true
repeat: true repeat: true
onTriggered: effectiveOpacity = (effectiveOpacity == 1.0 ? 0.0 : 1.0); onTriggered: page.effectiveOpacity = (page.effectiveOpacity == 1.0 ? 0.0 : 1.0);
} }
Column { Column {
@ -65,7 +65,7 @@ Item {
top: parent.top top: parent.top
topMargin: page.height / 48 topMargin: page.height / 48
} }
spacing: elementSpacing spacing: page.elementSpacing
populate: Transition { populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -77,32 +77,32 @@ Item {
NumberAnimation { properties: "y"; easing.type: Easing.OutBounce } NumberAnimation { properties: "y"; easing.type: Easing.OutBounce }
} }
Rectangle { color: "#80c342"; width: bigSize; height: smallSize } Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenV1 id: greenV1
visible: opacity != 0 visible: opacity != 0
width: bigSize; height: smallSize width: page.bigSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#14aaff"; width: bigSize; height: smallSize } Rectangle { color: "#14aaff"; width: page.bigSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenV2 id: greenV2
visible: opacity != 0 visible: opacity != 0
width: bigSize; height: smallSize width: page.bigSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#6400aa"; width: bigSize; height: smallSize } Rectangle { color: "#6400aa"; width: page.bigSize; height: page.smallSize }
Rectangle { color: "#80c342"; width: bigSize; height: smallSize } Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize }
} }
Row { Row {
@ -112,7 +112,7 @@ Item {
bottom: page.bottom bottom: page.bottom
bottomMargin: page.height / 48 bottomMargin: page.height / 48
} }
spacing: elementSpacing spacing: page.elementSpacing
populate: Transition { populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -124,40 +124,40 @@ Item {
NumberAnimation { properties: "x"; easing.type: Easing.OutBounce } NumberAnimation { properties: "x"; easing.type: Easing.OutBounce }
} }
Rectangle { color: "#80c342"; width: smallSize; height: bigSize } Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize }
Rectangle { Rectangle {
id: blueH1 id: blueH1
visible: opacity != 0 visible: opacity != 0
width: smallSize; height: bigSize width: page.smallSize; height: page.bigSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#14aaff"; width: smallSize; height: bigSize } Rectangle { color: "#14aaff"; width: page.smallSize; height: page.bigSize }
Rectangle { Rectangle {
id: greenH2 id: greenH2
visible: opacity != 0 visible: opacity != 0
width: smallSize; height: bigSize width: page.smallSize; height: page.bigSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#6400aa"; width: smallSize; height: bigSize } Rectangle { color: "#6400aa"; width: page.smallSize; height: page.bigSize }
Rectangle { color: "#80c342"; width: smallSize; height: bigSize } Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize }
} }
Grid { Grid {
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: page.height / 48 anchors.topMargin: page.height / 48
anchors.left: flow.left anchors.left: flowItem.left
columns: 3 columns: 3
spacing: elementSpacing spacing: page.elementSpacing
populate: Transition { populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce } NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -169,55 +169,55 @@ Item {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutBounce } NumberAnimation { properties: "x,y"; easing.type: Easing.OutBounce }
} }
Rectangle { color: "#80c342"; width: smallSize; height: smallSize } Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenG1 id: greenG1
visible: opacity != 0 visible: opacity != 0
width: smallSize; height: smallSize width: page.smallSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#14aaff"; width: smallSize; height: smallSize } Rectangle { color: "#14aaff"; width: page.smallSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenG2 id: greenG2
visible: opacity != 0 visible: opacity != 0
width: smallSize; height: smallSize width: page.smallSize; height:page. smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenG3 id: greenG3
visible: opacity != 0 visible: opacity != 0
width: smallSize; height: smallSize width: page.smallSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#80c342"; width: smallSize; height: smallSize } Rectangle { color: "#80c342"; width:page. smallSize; height: page.smallSize }
Rectangle { color: "#14aaff"; width: smallSize; height: smallSize } Rectangle { color: "#14aaff"; width: smallSize; height: page.smallSize }
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } Rectangle { color: "#6400aa"; width: page.page.smallSize; height: page.smallSize }
} }
Flow { Flow {
id: flow id: flowItem
anchors.right: page.right anchors.right: page.right
anchors.rightMargin: page.width / 32 anchors.rightMargin: page.width / 32
y: 2 * bigSize y: 2 * page.bigSize
width: 1.8 * bigSize width: 1.8 * page.bigSize
spacing: elementSpacing spacing: page.elementSpacing
//! [move] //! [move]
move: Transition { move: Transition {
@ -237,42 +237,42 @@ Item {
} }
//! [populate] //! [populate]
Rectangle { color: "#80c342"; width: smallSize; height: smallSize } Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenF1 id: greenF1
visible: opacity != 0 visible: opacity != 0
width: 0.6 * bigSize; height: smallSize width: 0.6 * page.bigSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#14aaff"; width: 0.3 * bigSize; height: smallSize } Rectangle { color: "#14aaff"; width: 0.3 * page.bigSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenF2 id: greenF2
visible: opacity != 0 visible: opacity != 0
width: 0.6 * bigSize; height: smallSize width: 0.6 * page.bigSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize } Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize }
Rectangle { Rectangle {
id: greenF3 id: greenF3
visible: opacity != 0 visible: opacity != 0
width: 0.4 * bigSize; height: smallSize width: 0.4 * page.bigSize; height: page.smallSize
color: "#006325" color: "#006325"
border.color: "transparent" border.color: "transparent"
Behavior on opacity { NumberAnimation {} } Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity opacity: page.effectiveOpacity
} }
Rectangle { color: "#80c342"; width: 0.8 * bigSize; height: smallSize } Rectangle { color: "#80c342"; width: 0.8 * page.bigSize; height: page.smallSize }
} }
} }

View File

@ -42,12 +42,10 @@
#include <QQuickItem> #include <QQuickItem>
#include <QQuickWindow> #include <QQuickWindow>
#include <QSGRendererInterface> #include <QSGRendererInterface>
#include <QFile>
#if QT_CONFIG(d3d12) #if QT_CONFIG(d3d12)
#include "vs_shader.hlslh"
#include "ps_shader.hlslh"
D3D12RenderNode::D3D12RenderNode(QQuickItem *item) D3D12RenderNode::D3D12RenderNode(QQuickItem *item)
: m_item(item) : m_item(item)
{ {
@ -78,7 +76,7 @@ void D3D12RenderNode::releaseResources()
void D3D12RenderNode::init() void D3D12RenderNode::init()
{ {
QSGRendererInterface *rif = m_item->window()->rendererInterface(); QSGRendererInterface *rif = m_item->window()->rendererInterface();
m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::Device)); m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::DeviceResource));
Q_ASSERT(m_device); Q_ASSERT(m_device);
D3D12_ROOT_PARAMETER rootParameter; D3D12_ROOT_PARAMETER rootParameter;
@ -111,12 +109,25 @@ void D3D12RenderNode::init()
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
}; };
QFile f(QStringLiteral(":/scenegraph/rendernode/shader_vert.cso"));
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open file with vertex shader bytecode");
return;
}
QByteArray vshader_cso = f.readAll();
f.close();
f.setFileName(QStringLiteral(":/scenegraph/rendernode/shader_frag.cso"));
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open file with fragment shader bytecode");
return;
}
QByteArray fshader_cso = f.readAll();
D3D12_SHADER_BYTECODE vshader; D3D12_SHADER_BYTECODE vshader;
vshader.pShaderBytecode = g_VS_Simple; vshader.pShaderBytecode = vshader_cso.constData();
vshader.BytecodeLength = sizeof(g_VS_Simple); vshader.BytecodeLength = vshader_cso.size();
D3D12_SHADER_BYTECODE pshader; D3D12_SHADER_BYTECODE pshader;
pshader.pShaderBytecode = g_PS_Simple; pshader.pShaderBytecode = fshader_cso.constData();
pshader.BytecodeLength = sizeof(g_PS_Simple); pshader.BytecodeLength = fshader_cso.size();
D3D12_RASTERIZER_DESC rastDesc = {}; D3D12_RASTERIZER_DESC rastDesc = {};
rastDesc.FillMode = D3D12_FILL_MODE_SOLID; rastDesc.FillMode = D3D12_FILL_MODE_SOLID;
@ -235,7 +246,8 @@ void D3D12RenderNode::render(const RenderState *state)
init(); init();
QSGRendererInterface *rif = m_item->window()->rendererInterface(); QSGRendererInterface *rif = m_item->window()->rendererInterface();
ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(rif->getResource(m_item->window(), QSGRendererInterface::CommandList)); ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(
rif->getResource(m_item->window(), QSGRendererInterface::CommandListResource));
Q_ASSERT(commandList); Q_ASSERT(commandList);
const int msize = 16 * sizeof(float); const int msize = 16 * sizeof(float);

View File

@ -15,24 +15,10 @@ target.path = $$[QT_INSTALL_EXAMPLES]/quick/scenegraph/rendernode
INSTALLS += target INSTALLS += target
OTHER_FILES += \ OTHER_FILES += \
main.qml \ main.qml
shader.hlsl
qtConfig(d3d12) { qtConfig(d3d12) {
HEADERS += d3d12renderer.h HEADERS += d3d12renderer.h
SOURCES += d3d12renderer.cpp SOURCES += d3d12renderer.cpp
LIBS += -ld3d12 LIBS += -ld3d12
VSPS = shader.hlsl
vshader.input = VSPS
vshader.header = vs_shader.hlslh
vshader.entry = VS_Simple
vshader.type = vs_5_0
pshader.input = VSPS
pshader.header = ps_shader.hlslh
pshader.entry = PS_Simple
pshader.type = ps_5_0
HLSL_SHADERS = vshader pshader
load(hlsl_bytecode_header)
} }

View File

@ -1,5 +1,7 @@
<RCC> <RCC>
<qresource prefix="/scenegraph/rendernode"> <qresource prefix="/scenegraph/rendernode">
<file>main.qml</file> <file>main.qml</file>
<file>shader_vert.cso</file>
<file>shader_frag.cso</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

Binary file not shown.

View File

@ -61,7 +61,7 @@ void SoftwareRenderNode::releaseResources()
void SoftwareRenderNode::render(const RenderState *renderState) void SoftwareRenderNode::render(const RenderState *renderState)
{ {
QSGRendererInterface *rif = m_item->window()->rendererInterface(); QSGRendererInterface *rif = m_item->window()->rendererInterface();
QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::Painter)); QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
Q_ASSERT(p); Q_ASSERT(p);
p->setTransform(matrix()->toTransform()); p->setTransform(matrix()->toTransform());

View File

@ -44,6 +44,7 @@
#include <QQuickView> //Not using QQmlApplicationEngine because many examples don't have a Window{} #include <QQuickView> //Not using QQmlApplicationEngine because many examples don't have a Window{}
#define DECLARATIVE_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \ #define DECLARATIVE_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \
{\ {\
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);\
QGuiApplication app(argc,argv);\ QGuiApplication app(argc,argv);\
app.setOrganizationName("QtProject");\ app.setOrganizationName("QtProject");\
app.setOrganizationDomain("qt-project.org");\ app.setOrganizationDomain("qt-project.org");\

View File

@ -221,7 +221,7 @@ Item {
\qmlproperty string TestCase::name \qmlproperty string TestCase::name
This property defines the name of the test case for result reporting. This property defines the name of the test case for result reporting.
The default is the empty string. The default value is an empty string.
\code \code
TestCase { TestCase {
@ -835,7 +835,7 @@ Item {
\c{QEXPECT_FAIL(tag, message, Abort)} in C++. \c{QEXPECT_FAIL(tag, message, Abort)} in C++.
If the test is not data-driven, then \a tag must be set to If the test is not data-driven, then \a tag must be set to
the empty string. an empty string.
\sa expectFailContinue() \sa expectFailContinue()
*/ */
@ -861,7 +861,7 @@ Item {
\c{QEXPECT_FAIL(tag, message, Continue)} in C++. \c{QEXPECT_FAIL(tag, message, Continue)} in C++.
If the test is not data-driven, then \a tag must be set to If the test is not data-driven, then \a tag must be set to
the empty string. an empty string.
\sa expectFail() \sa expectFail()
*/ */

View File

@ -55,8 +55,12 @@ Module {
name: "QQuickWindow" name: "QQuickWindow"
defaultProperty: "data" defaultProperty: "data"
prototype: "QWindow" prototype: "QWindow"
exports: ["QtQuick.Window/Window 2.0"] exports: [
exportMetaObjectRevisions: [0] "QtQuick.Window/Window 2.0",
"QtQuick.Window/Window 2.1",
"QtQuick.Window/Window 2.2"
]
exportMetaObjectRevisions: [0, 1, 2]
Enum { Enum {
name: "SceneGraphError" name: "SceneGraphError"
values: { values: {

View File

@ -1292,14 +1292,16 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
// OS X 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros, // OS X 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
// causing point sprites who read gl_PointCoord in the frag shader to come out as // causing point sprites who read gl_PointCoord in the frag shader to come out as
// green-red blobs. // green-red blobs.
if (perfLevel < Deformable && strstr((char *) glGetString(GL_VENDOR), "ATI")) { const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
perfLevel = Deformable; perfLevel = Deformable;
} }
#endif #endif
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
// Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path. // Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
if (perfLevel < Deformable && strstr((const char *) glGetString(GL_VENDOR), "nouveau")) const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
perfLevel = Deformable; perfLevel = Deformable;
#endif #endif

View File

@ -3236,11 +3236,11 @@ void QSGD3D12EnginePrivate::DeviceLossTester::killDevice()
void *QSGD3D12EnginePrivate::getResource(QSGRendererInterface::Resource resource) const void *QSGD3D12EnginePrivate::getResource(QSGRendererInterface::Resource resource) const
{ {
switch (resource) { switch (resource) {
case QSGRendererInterface::Device: case QSGRendererInterface::DeviceResource:
return device; return device;
case QSGRendererInterface::CommandQueue: case QSGRendererInterface::CommandQueueResource:
return commandQueue.Get(); return commandQueue.Get();
case QSGRendererInterface::CommandList: case QSGRendererInterface::CommandListResource:
return commandList; return commandList;
default: default:
break; break;

View File

@ -39,10 +39,6 @@
#include "qsgd3d12publicnodes_p.h" #include "qsgd3d12publicnodes_p.h"
// for rebuildGeometry
#include <private/qsgdefaultninepatchnode_p.h>
#include <private/qsgdefaultimagenode_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QSGD3D12RectangleNode::QSGD3D12RectangleNode() QSGD3D12RectangleNode::QSGD3D12RectangleNode()
@ -138,7 +134,7 @@ void QSGD3D12ImageNode::setRect(const QRectF &r)
return; return;
m_rect = r; m_rect = r;
QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyGeometry); markDirty(DirtyGeometry);
} }
@ -153,7 +149,7 @@ void QSGD3D12ImageNode::setSourceRect(const QRectF &r)
return; return;
m_sourceRect = r; m_sourceRect = r;
QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyGeometry); markDirty(DirtyGeometry);
} }
@ -170,7 +166,7 @@ void QSGD3D12ImageNode::setTexture(QSGTexture *texture)
delete m_material.texture(); delete m_material.texture();
m_material.setTexture(texture); m_material.setTexture(texture);
QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode); QSGImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode);
DirtyState dirty = DirtyMaterial; DirtyState dirty = DirtyMaterial;
const bool wasAtlas = m_isAtlasTexture; const bool wasAtlas = m_isAtlasTexture;
@ -192,7 +188,7 @@ void QSGD3D12ImageNode::setTextureCoordinatesTransform(TextureCoordinatesTransfo
return; return;
m_texCoordMode = mode; m_texCoordMode = mode;
QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyMaterial); markDirty(DirtyMaterial);
} }
@ -247,7 +243,7 @@ void QSGD3D12NinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal
void QSGD3D12NinePatchNode::update() void QSGD3D12NinePatchNode::update()
{ {
QSGDefaultNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio); QSGNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio);
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
} }

View File

@ -2692,6 +2692,7 @@ void convertConst(Const *c, Type targetType)
case UndefinedType: case UndefinedType:
c->value = qt_qnan(); c->value = qt_qnan();
c->type = targetType; c->type = targetType;
break;
default: default:
Q_UNIMPLEMENTED(); Q_UNIMPLEMENTED();
Q_ASSERT(!"Unimplemented!"); Q_ASSERT(!"Unimplemented!");

View File

@ -131,7 +131,8 @@ public:
Value *jsAlloca(int nValues) { Value *jsAlloca(int nValues) {
Value *ptr = jsStackTop; Value *ptr = jsStackTop;
jsStackTop = ptr + nValues; jsStackTop = ptr + nValues;
memset(ptr, 0, nValues*sizeof(Value)); for (int i = 0; i < nValues; ++i)
ptr[i] = Primitive::undefinedValue();
return ptr; return ptr;
} }

View File

@ -107,11 +107,18 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
(classname::func == QV4::Managed::func ? 0 : classname::func) (classname::func == QV4::Managed::func ? 0 : classname::func)
// Q_VTABLE_FUNCTION triggers a bogus tautological-compare warning in GCC6+ // Q_VTABLE_FUNCTION triggers a bogus tautological-compare warning in GCC6+
#if defined(Q_CC_GNU) && Q_CC_GNU >= 600 #if (defined(Q_CC_GNU) && Q_CC_GNU >= 600)
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ #define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
QT_WARNING_PUSH; \ QT_WARNING_PUSH; \
QT_WARNING_DISABLE_GCC("-Wtautological-compare") QT_WARNING_DISABLE_GCC("-Wtautological-compare")
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \
;QT_WARNING_POP
#elif defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
QT_WARNING_PUSH; \
QT_WARNING_DISABLE_CLANG("-Wtautological-compare")
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \ #define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \
;QT_WARNING_POP ;QT_WARNING_POP
#else #else

View File

@ -58,8 +58,6 @@
#include "qv4value_p.h" #include "qv4value_p.h"
#include "qv4internalclass_p.h" #include "qv4internalclass_p.h"
#include <type_traits>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -147,7 +145,7 @@ struct ObjectVTable
#define DEFINE_OBJECT_VTABLE_BASE(classname) \ #define DEFINE_OBJECT_VTABLE_BASE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \ const QV4::ObjectVTable classname::static_vtbl = \
{ \ { \
DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? Q_NULLPTR : &classname::SuperClass::static_vtbl.vTable), \ DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl.vTable), \
call, \ call, \
construct, \ construct, \
get, \ get, \

View File

@ -46,6 +46,7 @@
#include "qv4stringobject_p.h" #include "qv4stringobject_p.h"
#endif #endif
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/private/qnumeric_p.h>
using namespace QV4; using namespace QV4;

View File

@ -1100,6 +1100,13 @@ QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QStringRef &n
return qQmlPropertyCacheProperty<const QStringRef &>(engine, obj, name, context, local); return qQmlPropertyCacheProperty<const QStringRef &>(engine, obj, name, context, local);
} }
QQmlPropertyData *
QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QLatin1String &name,
QQmlContextData *context, QQmlPropertyData &local)
{
return qQmlPropertyCacheProperty<const QLatin1String &>(engine, obj, name, context, local);
}
// these two functions are copied from qmetaobject.cpp // these two functions are copied from qmetaobject.cpp
static inline const QMetaObjectPrivate *priv(const uint* data) static inline const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); } { return reinterpret_cast<const QMetaObjectPrivate*>(data); }

View File

@ -408,6 +408,8 @@ public:
static QQmlPropertyData *property(QJSEngine *, QObject *, const QStringRef &, static QQmlPropertyData *property(QJSEngine *, QObject *, const QStringRef &,
QQmlContextData *, QQmlPropertyData &); QQmlContextData *, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *, QObject *, const QLatin1String &,
QQmlContextData *, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *, QObject *, const QV4::String *, static QQmlPropertyData *property(QJSEngine *, QObject *, const QV4::String *,
QQmlContextData *, QQmlPropertyData &); QQmlContextData *, QQmlPropertyData &);

View File

@ -165,9 +165,9 @@ private:
void QQmlConnections::setTarget(QObject *obj) void QQmlConnections::setTarget(QObject *obj)
{ {
Q_D(QQmlConnections); Q_D(QQmlConnections);
d->targetSet = true; // even if setting to 0, it is *set* if (d->targetSet && d->target == obj)
if (d->target == obj)
return; return;
d->targetSet = true; // even if setting to 0, it is *set*
foreach (QQmlBoundSignal *s, d->boundsignals) { foreach (QQmlBoundSignal *s, d->boundsignals) {
// It is possible that target is being changed due to one of our signal // It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater(). // handlers -> use deleteLater().

View File

@ -183,6 +183,7 @@ namespace QtQuickTest
case MouseMove: case MouseMove:
// with move event the button is NoButton, but 'buttons' holds the currently pressed buttons // with move event the button is NoButton, but 'buttons' holds the currently pressed buttons
me = QMouseEvent(QEvent::MouseMove, pos, window->mapToGlobal(pos), Qt::NoButton, button, stateKey); me = QMouseEvent(QEvent::MouseMove, pos, window->mapToGlobal(pos), Qt::NoButton, button, stateKey);
me.setTimestamp(++lastMouseTimestamp);
break; break;
default: default:
QTEST_ASSERT(false); QTEST_ASSERT(false);

View File

@ -617,74 +617,75 @@ void QQuickAnchorsPrivate::updateVerticalAnchors()
if (fill || centerIn || !isItemComplete()) if (fill || centerIn || !isItemComplete())
return; return;
if (updatingVerticalAnchor < 2) { if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
++updatingVerticalAnchor;
if (usedAnchors & QQuickAnchors::TopAnchor) {
//Handle stretching
bool invalid = true;
qreal height = 0.0;
if (usedAnchors & QQuickAnchors::BottomAnchor) {
invalid = calcStretch(topAnchorItem, topAnchorLine,
bottomAnchorItem, bottomAnchorLine,
topMargin, -bottomMargin, QQuickAnchors::TopAnchor, height);
} else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
invalid = calcStretch(topAnchorItem, topAnchorLine,
vCenterAnchorItem, vCenterAnchorLine,
topMargin, vCenterOffset, QQuickAnchors::TopAnchor, height);
height *= 2;
}
if (!invalid)
setItemHeight(height);
//Handle top
if (topAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(topAnchorItem, topAnchorLine) + topMargin);
} else if (readParentItem(topAnchorItem) == readParentItem(item)) {
setItemY(position(topAnchorItem, topAnchorLine) + topMargin);
}
} else if (usedAnchors & QQuickAnchors::BottomAnchor) {
//Handle stretching (top + bottom case is handled above)
if (usedAnchors & QQuickAnchors::VCenterAnchor) {
qreal height = 0.0;
bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
bottomAnchorItem, bottomAnchorLine,
vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
height);
if (!invalid)
setItemHeight(height*2);
}
//Handle bottom
if (bottomAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
} else if (readParentItem(bottomAnchorItem) == readParentItem(item)) {
setItemY(position(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
}
} else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
//(stetching handled above)
//Handle vCenter
if (vCenterAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(vCenterAnchorItem, vCenterAnchorLine)
- vcenter(item) + vCenterOffset);
} else if (readParentItem(vCenterAnchorItem) == readParentItem(item)) {
setItemY(position(vCenterAnchorItem, vCenterAnchorLine) - vcenter(item) + vCenterOffset);
}
} else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
//Handle baseline
if (baselineAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(baselineAnchorItem, baselineAnchorLine)
- readBaselineOffset(item) + baselineOffset);
} else if (readParentItem(baselineAnchorItem) == readParentItem(item)) {
setItemY(position(baselineAnchorItem, baselineAnchorLine)
- readBaselineOffset(item) + baselineOffset);
}
}
--updatingVerticalAnchor;
} else {
// ### Make this certain :) // ### Make this certain :)
qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor."); qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
return;
} }
++updatingVerticalAnchor;
if (usedAnchors & QQuickAnchors::TopAnchor) {
//Handle stretching
bool invalid = true;
qreal height = 0.0;
if (usedAnchors & QQuickAnchors::BottomAnchor) {
invalid = calcStretch(topAnchorItem, topAnchorLine,
bottomAnchorItem, bottomAnchorLine,
topMargin, -bottomMargin, QQuickAnchors::TopAnchor, height);
} else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
invalid = calcStretch(topAnchorItem, topAnchorLine,
vCenterAnchorItem, vCenterAnchorLine,
topMargin, vCenterOffset, QQuickAnchors::TopAnchor, height);
height *= 2;
}
if (!invalid)
setItemHeight(height);
//Handle top
if (topAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(topAnchorItem, topAnchorLine) + topMargin);
} else if (readParentItem(topAnchorItem) == readParentItem(item)) {
setItemY(position(topAnchorItem, topAnchorLine) + topMargin);
}
} else if (usedAnchors & QQuickAnchors::BottomAnchor) {
//Handle stretching (top + bottom case is handled above)
if (usedAnchors & QQuickAnchors::VCenterAnchor) {
qreal height = 0.0;
bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
bottomAnchorItem, bottomAnchorLine,
vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
height);
if (!invalid)
setItemHeight(height*2);
}
//Handle bottom
if (bottomAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
} else if (readParentItem(bottomAnchorItem) == readParentItem(item)) {
setItemY(position(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
}
} else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
//(stetching handled above)
//Handle vCenter
if (vCenterAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(vCenterAnchorItem, vCenterAnchorLine)
- vcenter(item) + vCenterOffset);
} else if (readParentItem(vCenterAnchorItem) == readParentItem(item)) {
setItemY(position(vCenterAnchorItem, vCenterAnchorLine) - vcenter(item) + vCenterOffset);
}
} else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
//Handle baseline
if (baselineAnchorItem == readParentItem(item)) {
setItemY(adjustedPosition(baselineAnchorItem, baselineAnchorLine)
- readBaselineOffset(item) + baselineOffset);
} else if (readParentItem(baselineAnchorItem) == readParentItem(item)) {
setItemY(position(baselineAnchorItem, baselineAnchorLine)
- readBaselineOffset(item) + baselineOffset);
}
}
--updatingVerticalAnchor;
} }
static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine) static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)

View File

@ -113,12 +113,12 @@ public:
, inDestructor(false) , inDestructor(false)
, baselineAnchorLine(QQuickAnchors::InvalidAnchor) , baselineAnchorLine(QQuickAnchors::InvalidAnchor)
, centerAligned(true) , centerAligned(true)
, usedAnchors(QQuickAnchors::InvalidAnchor)
, componentComplete(true)
, updatingFill(0) , updatingFill(0)
, updatingCenterIn(0) , updatingCenterIn(0)
, updatingHorizontalAnchor(0) , updatingHorizontalAnchor(0)
, updatingVerticalAnchor(0) , updatingVerticalAnchor(0)
, componentComplete(true)
, usedAnchors(QQuickAnchors::InvalidAnchor)
{ {
} }
@ -198,13 +198,16 @@ public:
uint inDestructor : 1; uint inDestructor : 1;
QQuickAnchors::Anchor baselineAnchorLine : 7; QQuickAnchors::Anchor baselineAnchorLine : 7;
uint centerAligned : 1; uint centerAligned : 1;
uint updatingFill : 2;
uint updatingCenterIn : 2;
uint updatingHorizontalAnchor : 2;
uint updatingVerticalAnchor : 2;
uint componentComplete : 1;
uint usedAnchors : 7; // QQuickAnchors::Anchors uint usedAnchors : 7; // QQuickAnchors::Anchors
uint componentComplete : 1;
// Instead of using a mostly empty bit field, we can stretch the following fields up to be full
// bytes. The advantage is that incrementing/decrementing does not need any combining ands/ors.
qint8 updatingFill;
qint8 updatingCenterIn;
qint8 updatingHorizontalAnchor;
qint8 updatingVerticalAnchor;
static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) { static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) {
return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o)); return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o));

View File

@ -2308,29 +2308,31 @@ QQuickItem::~QQuickItem()
while (!d->childItems.isEmpty()) while (!d->childItems.isEmpty())
d->childItems.constFirst()->setParentItem(0); d->childItems.constFirst()->setParentItem(0);
const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!d->changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); for (const QQuickItemPrivate::ChangeListener &change : listeners) {
if (anchor) QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
anchor->clearItem(this); if (anchor)
} anchor->clearItem(this);
}
/* /*
update item anchors that depended on us unless they are our child (and will also be destroyed), update item anchors that depended on us unless they are our child (and will also be destroyed),
or our sibling, and our parent is also being destroyed. or our sibling, and our parent is also being destroyed.
*/ */
for (const QQuickItemPrivate::ChangeListener &change : listeners) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
anchor->update(); anchor->update();
} }
for (const QQuickItemPrivate::ChangeListener &change : listeners) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
if (change.types & QQuickItemPrivate::Destroyed) if (change.types & QQuickItemPrivate::Destroyed)
change.listener->itemDestroyed(this); change.listener->itemDestroyed(this);
} }
d->changeListeners.clear(); d->changeListeners.clear();
}
/* /*
Remove any references our transforms have to us, in case they try to Remove any references our transforms have to us, in case they try to
@ -2601,7 +2603,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
if (parentItem) { if (parentItem) {
QQuickItem *itemAncestor = parentItem; QQuickItem *itemAncestor = parentItem;
while (itemAncestor != 0) { while (itemAncestor != 0) {
if (itemAncestor == this) { if (Q_UNLIKELY(itemAncestor == this)) {
qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this; qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this;
return; return;
} }
@ -3549,10 +3551,12 @@ QQuickAnchors *QQuickItemPrivate::anchors() const
void QQuickItemPrivate::siblingOrderChanged() void QQuickItemPrivate::siblingOrderChanged()
{ {
Q_Q(QQuickItem); Q_Q(QQuickItem);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::SiblingOrder) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemSiblingOrderChanged(q); if (change.types & QQuickItemPrivate::SiblingOrder) {
change.listener->itemSiblingOrderChanged(q);
}
} }
} }
} }
@ -3654,20 +3658,18 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
QQuickAnchorsPrivate::get(d->_anchors)->updateMe(); QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
QQuickGeometryChange change; QQuickGeometryChange change;
QRectF diff(newGeometry.x() - oldGeometry.x(), change.setXChange(newGeometry.x() != oldGeometry.x());
newGeometry.y() - oldGeometry.y(), change.setYChange(newGeometry.y() != oldGeometry.y());
newGeometry.width() - oldGeometry.width(), change.setWidthChange(newGeometry.width() != oldGeometry.width());
newGeometry.height() - oldGeometry.height()); change.setHeightChange(newGeometry.height() != oldGeometry.height());
change.setXChange(diff.x() != 0);
change.setYChange(diff.y() != 0);
change.setWidthChange(diff.width() != 0);
change.setHeightChange(diff.height() != 0);
const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!d->changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &listener : listeners) { const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (listener.types & QQuickItemPrivate::Geometry) { for (const QQuickItemPrivate::ChangeListener &listener : listeners) {
if (change.matches(listener.gTypes)) if (listener.types & QQuickItemPrivate::Geometry) {
listener.listener->itemGeometryChanged(this, change, diff); if (change.matches(listener.gTypes))
listener.listener->itemGeometryChanged(this, change, oldGeometry);
}
} }
} }
@ -4224,12 +4226,14 @@ void QQuickItem::setBaselineOffset(qreal offset)
d->baselineOffset = offset; d->baselineOffset = offset;
const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!d->changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Geometry) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); if (change.types & QQuickItemPrivate::Geometry) {
if (anchor) QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
anchor->updateVerticalAnchors(); if (anchor)
anchor->updateVerticalAnchors();
}
} }
} }
@ -5977,20 +5981,24 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
switch (change) { switch (change) {
case QQuickItem::ItemChildAddedChange: { case QQuickItem::ItemChildAddedChange: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Children) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemChildAdded(q, data.item); if (change.types & QQuickItemPrivate::Children) {
change.listener->itemChildAdded(q, data.item);
}
} }
} }
break; break;
} }
case QQuickItem::ItemChildRemovedChange: { case QQuickItem::ItemChildRemovedChange: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Children) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemChildRemoved(q, data.item); if (change.types & QQuickItemPrivate::Children) {
change.listener->itemChildRemoved(q, data.item);
}
} }
} }
break; break;
@ -6000,30 +6008,36 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break; break;
case QQuickItem::ItemVisibleHasChanged: { case QQuickItem::ItemVisibleHasChanged: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Visibility) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemVisibilityChanged(q); if (change.types & QQuickItemPrivate::Visibility) {
change.listener->itemVisibilityChanged(q);
}
} }
} }
break; break;
} }
case QQuickItem::ItemParentHasChanged: { case QQuickItem::ItemParentHasChanged: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Parent) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemParentChanged(q, data.item); if (change.types & QQuickItemPrivate::Parent) {
change.listener->itemParentChanged(q, data.item);
}
} }
} }
break; break;
} }
case QQuickItem::ItemOpacityHasChanged: { case QQuickItem::ItemOpacityHasChanged: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Opacity) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemOpacityChanged(q); if (change.types & QQuickItemPrivate::Opacity) {
change.listener->itemOpacityChanged(q);
}
} }
} }
break; break;
@ -6033,10 +6047,12 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break; break;
case QQuickItem::ItemRotationHasChanged: { case QQuickItem::ItemRotationHasChanged: {
q->itemChange(change, data); q->itemChange(change, data);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::Rotation) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemRotationChanged(q); if (change.types & QQuickItemPrivate::Rotation) {
change.listener->itemRotationChanged(q);
}
} }
} }
break; break;
@ -6395,10 +6411,12 @@ void QQuickItem::resetWidth()
void QQuickItemPrivate::implicitWidthChanged() void QQuickItemPrivate::implicitWidthChanged()
{ {
Q_Q(QQuickItem); Q_Q(QQuickItem);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::ImplicitWidth) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemImplicitWidthChanged(q); if (change.types & QQuickItemPrivate::ImplicitWidth) {
change.listener->itemImplicitWidthChanged(q);
}
} }
} }
emit q->implicitWidthChanged(); emit q->implicitWidthChanged();
@ -6559,10 +6577,12 @@ void QQuickItem::resetHeight()
void QQuickItemPrivate::implicitHeightChanged() void QQuickItemPrivate::implicitHeightChanged()
{ {
Q_Q(QQuickItem); Q_Q(QQuickItem);
const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) if (!changeListeners.isEmpty()) {
for (const QQuickItemPrivate::ChangeListener &change : listeners) { const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
if (change.types & QQuickItemPrivate::ImplicitHeight) { for (const QQuickItemPrivate::ChangeListener &change : listeners) {
change.listener->itemImplicitHeightChanged(q); if (change.types & QQuickItemPrivate::ImplicitHeight) {
change.listener->itemImplicitHeightChanged(q);
}
} }
} }
emit q->implicitHeightChanged(); emit q->implicitHeightChanged();

View File

@ -115,12 +115,14 @@ private:
int kind; int kind;
}; };
#define QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING
class QQuickItemChangeListener class QQuickItemChangeListener
{ {
public: public:
virtual ~QQuickItemChangeListener() {} virtual ~QQuickItemChangeListener() {}
virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF & /* diff */) {} virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF & /* oldGeometry */) {}
virtual void itemSiblingOrderChanged(QQuickItem *) {} virtual void itemSiblingOrderChanged(QQuickItem *) {}
virtual void itemVisibilityChanged(QQuickItem *) {} virtual void itemVisibilityChanged(QQuickItem *) {}
virtual void itemOpacityChanged(QQuickItem *) {} virtual void itemOpacityChanged(QQuickItem *) {}

View File

@ -1207,10 +1207,10 @@ void QQuickItemViewPrivate::showVisibleItems() const
} }
void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change,
const QRectF &diff) const QRectF &oldGeometry)
{ {
Q_Q(QQuickItemView); Q_Q(QQuickItemView);
QQuickFlickablePrivate::itemGeometryChanged(item, change, diff); QQuickFlickablePrivate::itemGeometryChanged(item, change, oldGeometry);
if (!q->isComponentComplete()) if (!q->isComponentComplete())
return; return;

View File

@ -131,7 +131,7 @@ public:
void updateAverage(); void updateAverage();
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE; void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void fixupPosition() Q_DECL_OVERRIDE; void fixupPosition() Q_DECL_OVERRIDE;
void fixup(AxisData &data, qreal minExtent, qreal maxExtent) Q_DECL_OVERRIDE; void fixup(AxisData &data, qreal minExtent, qreal maxExtent) Q_DECL_OVERRIDE;
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
@ -1401,11 +1401,11 @@ bool QQuickListViewPrivate::hasStickyFooter() const
} }
void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change,
const QRectF &diff) const QRectF &oldGeometry)
{ {
Q_Q(QQuickListView); Q_Q(QQuickListView);
QQuickItemViewPrivate::itemGeometryChanged(item, change, diff); QQuickItemViewPrivate::itemGeometryChanged(item, change, oldGeometry);
if (!q->isComponentComplete()) if (!q->isComponentComplete())
return; return;
@ -1426,24 +1426,22 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry
// position all subsequent items // position all subsequent items
if (visibleItems.count() && item == visibleItems.constFirst()->item) { if (visibleItems.count() && item == visibleItems.constFirst()->item) {
FxListItemSG *listItem = static_cast<FxListItemSG*>(visibleItems.constFirst()); FxListItemSG *listItem = static_cast<FxListItemSG*>(visibleItems.constFirst());
const QRectF oldGeometry(item->x() - diff.x(),
item->y() - diff.y(),
item->width() - diff.width(),
item->height() - diff.height());
if (listItem->transitionScheduledOrRunning()) if (listItem->transitionScheduledOrRunning())
return; return;
if (orient == QQuickListView::Vertical) { if (orient == QQuickListView::Vertical) {
const qreal oldItemEndPosition = verticalLayoutDirection == QQuickItemView::BottomToTop ? -oldGeometry.y() : oldGeometry.y() + oldGeometry.height(); const qreal oldItemEndPosition = verticalLayoutDirection == QQuickItemView::BottomToTop ? -oldGeometry.y() : oldGeometry.y() + oldGeometry.height();
const qreal heightDiff = item->height() - oldGeometry.height();
if (verticalLayoutDirection == QQuickListView::TopToBottom && oldItemEndPosition < q->contentY()) if (verticalLayoutDirection == QQuickListView::TopToBottom && oldItemEndPosition < q->contentY())
listItem->setPosition(listItem->position() - diff.height(), true); listItem->setPosition(listItem->position() - heightDiff, true);
else if (verticalLayoutDirection == QQuickListView::BottomToTop && oldItemEndPosition > q->contentY()) else if (verticalLayoutDirection == QQuickListView::BottomToTop && oldItemEndPosition > q->contentY())
listItem->setPosition(listItem->position() + diff.height(), true); listItem->setPosition(listItem->position() + heightDiff, true);
} else { } else {
const qreal oldItemEndPosition = q->effectiveLayoutDirection() == Qt::RightToLeft ? -oldGeometry.x() : oldGeometry.x() + oldGeometry.width(); const qreal oldItemEndPosition = q->effectiveLayoutDirection() == Qt::RightToLeft ? -oldGeometry.x() : oldGeometry.x() + oldGeometry.width();
const qreal widthDiff = item->width() - oldGeometry.width();
if (q->effectiveLayoutDirection() == Qt::LeftToRight && oldItemEndPosition < q->contentX()) if (q->effectiveLayoutDirection() == Qt::LeftToRight && oldItemEndPosition < q->contentX())
listItem->setPosition(listItem->position() - diff.width(), true); listItem->setPosition(listItem->position() - widthDiff, true);
else if (q->effectiveLayoutDirection() == Qt::RightToLeft && oldItemEndPosition > q->contentX()) else if (q->effectiveLayoutDirection() == Qt::RightToLeft && oldItemEndPosition > q->contentX())
listItem->setPosition(listItem->position() + diff.width(), true); listItem->setPosition(listItem->position() + widthDiff, true);
} }
} }
forceLayoutPolish(); forceLayoutPolish();

View File

@ -65,12 +65,12 @@ QQuickLoaderPrivate::~QQuickLoaderPrivate()
disposeInitialPropertyValues(); disposeInitialPropertyValues();
} }
void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
, const QRectF &diff) const QRectF &oldGeometry)
{ {
if (resizeItem == item) if (resizeItem == item)
_q_updateSize(false); _q_updateSize(false);
QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff); QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
} }
void QQuickLoaderPrivate::itemImplicitWidthChanged(QQuickItem *) void QQuickLoaderPrivate::itemImplicitWidthChanged(QQuickItem *)

View File

@ -84,7 +84,7 @@ public:
QQuickLoaderPrivate(); QQuickLoaderPrivate();
~QQuickLoaderPrivate(); ~QQuickLoaderPrivate();
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE; void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void itemImplicitWidthChanged(QQuickItem *) Q_DECL_OVERRIDE; void itemImplicitWidthChanged(QQuickItem *) Q_DECL_OVERRIDE;
void itemImplicitHeightChanged(QQuickItem *) Q_DECL_OVERRIDE; void itemImplicitHeightChanged(QQuickItem *) Q_DECL_OVERRIDE;
void clear(); void clear();

View File

@ -892,7 +892,7 @@ void QQuickTextEdit::setWrapMode(WrapMode mode)
/*! /*!
\qmlproperty int QtQuick::TextEdit::lineCount \qmlproperty int QtQuick::TextEdit::lineCount
Returns the total number of lines in the textEdit item. Returns the total number of lines in the TextEdit item.
*/ */
int QQuickTextEdit::lineCount() const int QQuickTextEdit::lineCount() const
{ {
@ -2350,6 +2350,7 @@ void QQuickTextEdit::moveCursorDelegate()
QRectF cursorRect = cursorRectangle(); QRectF cursorRect = cursorRectangle();
d->cursorItem->setX(cursorRect.x()); d->cursorItem->setX(cursorRect.x());
d->cursorItem->setY(cursorRect.y()); d->cursorItem->setY(cursorRect.y());
d->cursorItem->setHeight(cursorRect.height());
} }
void QQuickTextEdit::updateSelection() void QQuickTextEdit::updateSelection()

View File

@ -160,18 +160,14 @@ void QQuickTextNode::addImage(const QRectF &rect, const QImage &image)
QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext(); QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
QSGInternalImageNode *node = sg->sceneGraphContext()->createInternalImageNode(); QSGInternalImageNode *node = sg->sceneGraphContext()->createInternalImageNode();
QSGTexture *texture = sg->createTexture(image); QSGTexture *texture = sg->createTexture(image);
if (m_ownerElement->smooth()) { if (m_ownerElement->smooth())
texture->setFiltering(QSGTexture::Linear); texture->setFiltering(QSGTexture::Linear);
texture->setMipmapFiltering(QSGTexture::Linear);
}
m_textures.append(texture); m_textures.append(texture);
node->setTargetRect(rect); node->setTargetRect(rect);
node->setInnerTargetRect(rect); node->setInnerTargetRect(rect);
node->setTexture(texture); node->setTexture(texture);
if (m_ownerElement->smooth()) { if (m_ownerElement->smooth())
node->setFiltering(QSGTexture::Linear); node->setFiltering(QSGTexture::Linear);
node->setMipmapFiltering(QSGTexture::Linear);
}
appendChildNode(node); appendChildNode(node);
node->update(); node->update();
} }

View File

@ -423,7 +423,10 @@ void QQuickTextNodeEngine::addImage(const QRectF &rect, const QImage &image, qre
QRectF searchRect = rect; QRectF searchRect = rect;
if (layoutPosition == QTextFrameFormat::InFlow) { if (layoutPosition == QTextFrameFormat::InFlow) {
if (m_currentLineTree.isEmpty()) { if (m_currentLineTree.isEmpty()) {
searchRect.moveTopLeft(m_position + m_currentLine.position() + QPointF(0,1)); if (m_currentTextDirection == Qt::RightToLeft)
searchRect.moveTopRight(m_position + m_currentLine.rect().topRight() + QPointF(0, 1));
else
searchRect.moveTopLeft(m_position + m_currentLine.position() + QPointF(0,1));
} else { } else {
const BinaryTreeNode *lastNode = m_currentLineTree.data() + m_currentLineTree.size() - 1; const BinaryTreeNode *lastNode = m_currentLineTree.data() + m_currentLineTree.size() - 1;
if (lastNode->glyphRun.isRightToLeft()) { if (lastNode->glyphRun.isRightToLeft()) {
@ -952,6 +955,8 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1; int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
#endif #endif
setCurrentTextDirection(block.textDirection());
QVarLengthArray<QTextLayout::FormatRange> colorChanges; QVarLengthArray<QTextLayout::FormatRange> colorChanges;
mergeFormats(block.layout(), &colorChanges); mergeFormats(block.layout(), &colorChanges);

View File

@ -144,7 +144,11 @@ public:
int selectionState; int selectionState;
}; };
QQuickTextNodeEngine() : m_hasSelection(false), m_hasContents(false) {} QQuickTextNodeEngine()
: m_currentTextDirection(Qt::LeftToRight)
, m_hasSelection(false)
, m_hasContents(false)
{}
bool hasContents() const { return m_hasContents; } bool hasContents() const { return m_hasContents; }
void addTextBlock(QTextDocument *, const QTextBlock &, const QPointF &position, const QColor &textColor, const QColor& anchorColor, int selectionStart, int selectionEnd); void addTextBlock(QTextDocument *, const QTextBlock &, const QPointF &position, const QColor &textColor, const QColor& anchorColor, int selectionStart, int selectionEnd);
@ -158,6 +162,11 @@ public:
m_currentLine = currentLine; m_currentLine = currentLine;
} }
void setCurrentTextDirection(Qt::LayoutDirection textDirection)
{
m_currentTextDirection = textDirection;
}
void addBorder(const QRectF &rect, qreal border, QTextFrameFormat::BorderStyle borderStyle, void addBorder(const QRectF &rect, qreal border, QTextFrameFormat::BorderStyle borderStyle,
const QBrush &borderBrush); const QBrush &borderBrush);
void addFrameDecorations(QTextDocument *document, QTextFrame *frame); void addFrameDecorations(QTextDocument *document, QTextFrame *frame);
@ -247,6 +256,7 @@ private:
QPointF m_position; QPointF m_position;
QTextLine m_currentLine; QTextLine m_currentLine;
Qt::LayoutDirection m_currentTextDirection;
QList<QPair<QRectF, QColor> > m_backgrounds; QList<QPair<QRectF, QColor> > m_backgrounds;
QList<QRectF> m_selectionRects; QList<QRectF> m_selectionRects;

View File

@ -111,14 +111,14 @@ void QQuickViewPrivate::execute()
} }
void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change, void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
const QRectF &diff) const QRectF &oldGeometry)
{ {
Q_Q(QQuickView); Q_Q(QQuickView);
if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) { if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) {
// wait for both width and height to be changed // wait for both width and height to be changed
resizetimer.start(0,q); resizetimer.start(0,q);
} }
QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff); QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
} }
/*! /*!

View File

@ -3125,10 +3125,12 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) { if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
QSGNode *before = qquickitem_before_paintNode(itemPriv); QSGNode *before = qquickitem_before_paintNode(itemPriv);
if (before) if (before && before->parent()) {
Q_ASSERT(before->parent() == itemPriv->childContainerNode());
itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, before); itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, before);
else } else {
itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode); itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
}
} }
} else if (itemPriv->paintNode) { } else if (itemPriv->paintNode) {
delete itemPriv->paintNode; delete itemPriv->paintNode;

View File

@ -215,7 +215,7 @@ QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() c
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
{ {
if (resource == Painter && window && window->isSceneGraphInitialized()) if (resource == PainterResource && window && window->isSceneGraphInitialized())
return static_cast<QSGSoftwareRenderContext *>(QQuickWindowPrivate::get(window)->context)->m_activePainter; return static_cast<QSGSoftwareRenderContext *>(QQuickWindowPrivate::get(window)->context)->m_activePainter;
return nullptr; return nullptr;

View File

@ -90,7 +90,7 @@ DECLARE_DEBUG_VAR(noclip)
static QElapsedTimer qsg_renderer_timer; static QElapsedTimer qsg_renderer_timer;
#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling()) #define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild; child; child = child->nextSibling) #define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
static inline int size_of_type(GLenum type) static inline int size_of_type(GLenum type)
{ {
@ -510,7 +510,7 @@ void Updater::updateRootTransforms(Node *node, Node *root, const QMatrix4x4 &com
while (n != root) { while (n != root) {
if (n->type() == QSGNode::TransformNodeType) if (n->type() == QSGNode::TransformNodeType)
m = static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m; m = static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
n = n->parent; n = n->parent();
} }
m = combined * m; m = combined * m;
@ -1013,16 +1013,8 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
Node *snode = m_nodeAllocator.allocate(); Node *snode = m_nodeAllocator.allocate();
snode->sgNode = node; snode->sgNode = node;
m_nodes.insert(node, snode); m_nodes.insert(node, snode);
if (shadowParent) { if (shadowParent)
snode->parent = shadowParent; shadowParent->append(snode);
if (shadowParent->lastChild) {
shadowParent->lastChild->nextSibling = snode;
shadowParent->lastChild = snode;
} else {
shadowParent->firstChild = snode;
shadowParent->lastChild = snode;
}
}
if (node->type() == QSGNode::GeometryNodeType) { if (node->type() == QSGNode::GeometryNodeType) {
snode->data = m_elementAllocator.allocate(); snode->data = m_elementAllocator.allocate();
@ -1054,17 +1046,12 @@ void Renderer::nodeWasRemoved(Node *node)
// here, because we delete 'child' (when recursed, down below), so we'd // here, because we delete 'child' (when recursed, down below), so we'd
// have a use-after-free. // have a use-after-free.
{ {
Node *child = node->firstChild; Node *child = node->firstChild();
Node *nextChild = 0;
while (child) { while (child) {
// Get the next child now before we proceed
nextChild = child->nextSibling;
// Remove (and delete) child // Remove (and delete) child
node->remove(child);
nodeWasRemoved(child); nodeWasRemoved(child);
child = node->firstChild();
child = nextChild;
} }
} }
@ -1110,6 +1097,7 @@ void Renderer::nodeWasRemoved(Node *node)
} }
Q_ASSERT(m_nodes.contains(node->sgNode)); Q_ASSERT(m_nodes.contains(node->sgNode));
m_nodeAllocator.release(m_nodes.take(node->sgNode)); m_nodeAllocator.release(m_nodes.take(node->sgNode));
} }
@ -1120,13 +1108,13 @@ void Renderer::turnNodeIntoBatchRoot(Node *node)
node->isBatchRoot = true; node->isBatchRoot = true;
node->becameBatchRoot = true; node->becameBatchRoot = true;
Node *p = node->parent; Node *p = node->parent();
while (p) { while (p) {
if (p->type() == QSGNode::ClipNodeType || p->isBatchRoot) { if (p->type() == QSGNode::ClipNodeType || p->isBatchRoot) {
registerBatchRoot(node, p); registerBatchRoot(node, p);
break; break;
} }
p = p->parent; p = p->parent();
} }
SHADOWNODE_TRAVERSE(node) SHADOWNODE_TRAVERSE(node)
@ -1255,33 +1243,18 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
| QSGNode::DirtyForceUpdate); | QSGNode::DirtyForceUpdate);
if (dirtyChain != 0) { if (dirtyChain != 0) {
dirtyChain = QSGNode::DirtyState(dirtyChain << 16); dirtyChain = QSGNode::DirtyState(dirtyChain << 16);
Node *sn = shadowNode->parent; Node *sn = shadowNode->parent();
while (sn) { while (sn) {
sn->dirtyState |= dirtyChain; sn->dirtyState |= dirtyChain;
sn = sn->parent; sn = sn->parent();
} }
} }
// Delete happens at the very end because it deletes the shadownode. // Delete happens at the very end because it deletes the shadownode.
if (state & QSGNode::DirtyNodeRemoved) { if (state & QSGNode::DirtyNodeRemoved) {
Node *parent = shadowNode->parent; Node *parent = shadowNode->parent();
if (parent) { if (parent)
Q_ASSERT(parent->firstChild); parent->remove(shadowNode);
Q_ASSERT(parent->lastChild);
shadowNode->parent = 0;
Node *child = parent->firstChild;
if (child == shadowNode) {
parent->firstChild = shadowNode->nextSibling;
if (parent->lastChild == shadowNode)
parent->lastChild = 0;
} else {
while (child->nextSibling != shadowNode)
child = child->nextSibling;
child->nextSibling = shadowNode->nextSibling;
if (shadowNode == parent->lastChild)
parent->lastChild = child;
}
}
nodeWasRemoved(shadowNode); nodeWasRemoved(shadowNode);
Q_ASSERT(m_nodes.value(node) == 0); Q_ASSERT(m_nodes.value(node) == 0);
} }

View File

@ -451,11 +451,73 @@ struct Batch
struct Node struct Node
{ {
QSGNode *sgNode; QSGNode *sgNode;
Node *parent;
void *data; void *data;
Node *firstChild;
Node *nextSibling; Node *m_parent;
Node *lastChild; Node *m_child;
Node *m_next;
Node *m_prev;
Node *parent() const { return m_parent; }
void append(Node *child) {
Q_ASSERT(child);
Q_ASSERT(!hasChild(child));
Q_ASSERT(child->m_parent == 0);
Q_ASSERT(child->m_next == 0);
Q_ASSERT(child->m_prev == 0);
if (!m_child) {
child->m_next = child;
child->m_prev = child;
m_child = child;
} else {
m_child->m_prev->m_next = child;
child->m_prev = m_child->m_prev;
m_child->m_prev = child;
child->m_next = m_child;
}
child->setParent(this);
}
void remove(Node *child) {
Q_ASSERT(child);
Q_ASSERT(hasChild(child));
// only child..
if (child->m_next == child) {
m_child = 0;
} else {
if (m_child == child)
m_child = child->m_next;
child->m_next->m_prev = child->m_prev;
child->m_prev->m_next = child->m_next;
}
child->m_next = 0;
child->m_prev = 0;
child->setParent(0);
}
Node *firstChild() const { return m_child; }
Node *sibling() const {
Q_ASSERT(m_parent);
return m_next == m_parent->m_child ? 0 : m_next;
}
void setParent(Node *p) {
Q_ASSERT(m_parent == 0 || p == 0);
m_parent = p;
}
bool hasChild(Node *child) const {
Node *n = m_child;
while (n && n != child)
n = n->sibling();
return n;
}
QSGNode::DirtyState dirtyState; QSGNode::DirtyState dirtyState;

View File

@ -81,10 +81,10 @@ QT_BEGIN_NAMESPACE
/*! /*!
\enum QSGRendererInterface::Resource \enum QSGRendererInterface::Resource
\value Device The graphics device, when applicable. \value DeviceResource The graphics device, when applicable.
\value CommandQueue The graphics command queue used by the scenegraph, when applicable. \value CommandQueueResource The graphics command queue used by the scenegraph, when applicable.
\value CommandList The command list or buffer used by the scenegraph, when applicable. \value CommandListResource The command list or buffer used by the scenegraph, when applicable.
\value Painter The active QPainter used by the scenegraph, when running with the software backend. \value PainterResource The active QPainter used by the scenegraph, when running with the software backend.
*/ */
/*! /*!

View File

@ -57,10 +57,10 @@ public:
}; };
enum Resource { enum Resource {
Device, DeviceResource,
CommandQueue, CommandQueueResource,
CommandList, CommandListResource,
Painter PainterResource
}; };
enum ShaderType { enum ShaderType {

View File

@ -117,8 +117,9 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) { if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) {
if (!m_atlas) if (!m_atlas)
m_atlas = new Atlas(m_atlas_size); m_atlas = new Atlas(m_atlas_size);
// t may be null for atlas allocation failure
t = m_atlas->create(image); t = m_atlas->create(image);
if (!hasAlphaChannel && t->hasAlphaChannel()) if (t && !hasAlphaChannel && t->hasAlphaChannel())
t->setHasAlphaChannel(false); t->setHasAlphaChannel(false);
} }
return t; return t;

View File

@ -173,33 +173,4 @@ bool QSGDefaultImageNode::ownsTexture() const
return m_ownsTexture; return m_ownsTexture;
} }
void QSGDefaultImageNode::rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
QRectF sourceRect,
TextureCoordinatesTransformMode texCoordMode)
{
if (!texture)
return;
if (!sourceRect.width() || !sourceRect.height()) {
QSize ts = texture->textureSize();
sourceRect = QRectF(0, 0, ts.width(), ts.height());
}
// Maybe transform the texture coordinates
if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) {
float tmp = sourceRect.left();
sourceRect.setLeft(sourceRect.right());
sourceRect.setRight(tmp);
}
if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) {
float tmp = sourceRect.top();
sourceRect.setTop(sourceRect.bottom());
sourceRect.setBottom(tmp);
}
QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -85,12 +85,6 @@ public:
void setOwnsTexture(bool owns) override; void setOwnsTexture(bool owns) override;
bool ownsTexture() const override; bool ownsTexture() const override;
static void rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
QRectF sourceRect,
TextureCoordinatesTransformMode texCoordMode);
private: private:
QSGGeometry m_geometry; QSGGeometry m_geometry;
QSGOpaqueTextureMaterial m_opaque_material; QSGOpaqueTextureMaterial m_opaque_material;

View File

@ -81,56 +81,4 @@ void QSGDefaultNinePatchNode::update()
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
} }
void QSGDefaultNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
const QRectF &bounds, qreal dpr)
{
if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) {
geometry->allocate(4, 0);
QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect());
return;
}
QRectF tc = texture->normalizedTextureSubRect();
QSize ts = texture->textureSize();
ts.setHeight(ts.height() / dpr);
ts.setWidth(ts.width() / dpr);
qreal invtw = tc.width() / ts.width();
qreal invth = tc.height() / ts.height();
struct Coord { qreal p; qreal t; };
Coord cx[4] = { { bounds.left(), tc.left() },
{ bounds.left() + padding.x(), tc.left() + padding.x() * invtw },
{ bounds.right() - padding.z(), tc.right() - padding.z() * invtw },
{ bounds.right(), tc.right() }
};
Coord cy[4] = { { bounds.top(), tc.top() },
{ bounds.top() + padding.y(), tc.top() + padding.y() * invth },
{ bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth },
{ bounds.bottom(), tc.bottom() }
};
geometry->allocate(16, 28);
QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D();
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t);
++v;
}
}
quint16 *i = geometry->indexDataAsUShort();
for (int r = 0; r < 3; ++r) {
if (r > 0)
*i++ = 4 * r;
for (int c = 0; c < 4; ++c) {
i[0] = 4 * r + c;
i[1] = 4 * r + c + 4;
i += 2;
}
if (r < 2)
*i++ = 4 * r + 3 + 4;
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -70,9 +70,6 @@ public:
void setPadding(qreal left, qreal top, qreal right, qreal bottom) override; void setPadding(qreal left, qreal top, qreal right, qreal bottom) override;
void update() override; void update() override;
static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
const QRectF &bounds, qreal dpr);
private: private:
QRectF m_bounds; QRectF m_bounds;
qreal m_devicePixelRatio; qreal m_devicePixelRatio;

View File

@ -84,32 +84,12 @@ QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager()
QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font) QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font)
{ {
return m_caches.value(fontKey(font), 0); return m_caches.value(font, 0);
} }
void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache) void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache)
{ {
m_caches.insert(fontKey(font), cache); m_caches.insert(font, cache);
}
QString QSGDistanceFieldGlyphCacheManager::fontKey(const QRawFont &font)
{
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
QByteArray keyName = fe->faceId().filename;
if (font.style() != QFont::StyleNormal)
keyName += QByteArray(" I");
if (font.weight() != QFont::Normal)
keyName += ' ' + QByteArray::number(font.weight());
keyName += QByteArray(" DF");
return QString::fromUtf8(keyName);
} else {
return QString::fromLatin1("%1_%2_%3_%4")
.arg(font.familyName())
.arg(font.styleName())
.arg(font.weight())
.arg(font.style());
}
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -80,9 +80,7 @@ public:
void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; } void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
private: private:
static QString fontKey(const QRawFont &font); QHash<QRawFont, QSGDistanceFieldGlyphCache *> m_caches;
QHash<QString, QSGDistanceFieldGlyphCache *> m_caches;
ThresholdFunc m_threshold_func; ThresholdFunc m_threshold_func;
AntialiasingSpreadFunc m_antialiasingSpread_func; AntialiasingSpreadFunc m_antialiasingSpread_func;

View File

@ -187,4 +187,33 @@ QT_BEGIN_NAMESPACE
\return \c true if the node takes ownership of the texture; otherwise \c false. \return \c true if the node takes ownership of the texture; otherwise \c false.
*/ */
void QSGImageNode::rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
QRectF sourceRect,
TextureCoordinatesTransformMode texCoordMode)
{
if (!texture)
return;
if (!sourceRect.width() || !sourceRect.height()) {
QSize ts = texture->textureSize();
sourceRect = QRectF(0, 0, ts.width(), ts.height());
}
// Maybe transform the texture coordinates
if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) {
float tmp = sourceRect.left();
sourceRect.setLeft(sourceRect.right());
sourceRect.setRight(tmp);
}
if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) {
float tmp = sourceRect.top();
sourceRect.setTop(sourceRect.bottom());
sourceRect.setBottom(tmp);
}
QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -79,6 +79,12 @@ public:
virtual void setOwnsTexture(bool owns) = 0; virtual void setOwnsTexture(bool owns) = 0;
virtual bool ownsTexture() const = 0; virtual bool ownsTexture() const = 0;
static void rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
QRectF sourceRect,
TextureCoordinatesTransformMode texCoordMode);
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(QSGImageNode::TextureCoordinatesTransformMode) Q_DECLARE_OPERATORS_FOR_FLAGS(QSGImageNode::TextureCoordinatesTransformMode)

View File

@ -74,4 +74,56 @@ QT_BEGIN_NAMESPACE
\internal \internal
*/ */
void QSGNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
const QRectF &bounds, qreal dpr)
{
if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) {
geometry->allocate(4, 0);
QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect());
return;
}
QRectF tc = texture->normalizedTextureSubRect();
QSize ts = texture->textureSize();
ts.setHeight(ts.height() / dpr);
ts.setWidth(ts.width() / dpr);
qreal invtw = tc.width() / ts.width();
qreal invth = tc.height() / ts.height();
struct Coord { qreal p; qreal t; };
Coord cx[4] = { { bounds.left(), tc.left() },
{ bounds.left() + padding.x(), tc.left() + padding.x() * invtw },
{ bounds.right() - padding.z(), tc.right() - padding.z() * invtw },
{ bounds.right(), tc.right() }
};
Coord cy[4] = { { bounds.top(), tc.top() },
{ bounds.top() + padding.y(), tc.top() + padding.y() * invth },
{ bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth },
{ bounds.bottom(), tc.bottom() }
};
geometry->allocate(16, 28);
QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D();
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t);
++v;
}
}
quint16 *i = geometry->indexDataAsUShort();
for (int r = 0; r < 3; ++r) {
if (r > 0)
*i++ = 4 * r;
for (int c = 0; c < 4; ++c) {
i[0] = 4 * r + c;
i[1] = 4 * r + c + 4;
i += 2;
}
if (r < 2)
*i++ = 4 * r + 3 + 4;
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -55,6 +55,10 @@ public:
virtual void setDevicePixelRatio(qreal ratio) = 0; virtual void setDevicePixelRatio(qreal ratio) = 0;
virtual void setPadding(qreal left, qreal top, qreal right, qreal bottom) = 0; virtual void setPadding(qreal left, qreal top, qreal right, qreal bottom) = 0;
virtual void update() = 0; virtual void update() = 0;
static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry,
const QVector4D &padding,
const QRectF &bounds, qreal dpr);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -245,14 +245,14 @@ void QQuickWidgetPrivate::execute()
} }
void QQuickWidgetPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change, void QQuickWidgetPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
const QRectF &diff) const QRectF &oldGeometry)
{ {
Q_Q(QQuickWidget); Q_Q(QQuickWidget);
if (resizeItem == root && resizeMode == QQuickWidget::SizeViewToRootObject) { if (resizeItem == root && resizeMode == QQuickWidget::SizeViewToRootObject) {
// wait for both width and height to be changed // wait for both width and height to be changed
resizetimer.start(0,q); resizetimer.start(0,q);
} }
QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff); QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
} }
void QQuickWidgetPrivate::render(bool needsSync) void QQuickWidgetPrivate::render(bool needsSync)

View File

@ -87,7 +87,7 @@ public:
~QQuickWidgetPrivate(); ~QQuickWidgetPrivate();
void execute(); void execute();
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE; void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void initResize(); void initResize();
void updateSize(); void updateSize();
void updatePosition(); void updatePosition();

View File

@ -13,14 +13,3 @@
); );
%deprecatedheaders = ( %deprecatedheaders = (
); );
# Module dependencies.
# Every module that is required to build this module should have one entry.
# Each of the module version specifiers can take one of the following values:
# - A specific Git revision.
# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
# - an empty string to use the same branch under test (dependencies will become "refs/heads/master" if we are in the master branch)
#
%dependencies = (
"qtbase" => "",
"qtxmlpatterns" => "",
);

View File

@ -1372,6 +1372,33 @@ void tst_QJSValue::hasProperty_changePrototype()
QVERIFY(obj.hasOwnProperty("foo")); QVERIFY(obj.hasOwnProperty("foo"));
} }
void tst_QJSValue::hasProperty_QTBUG56830_data()
{
QTest::addColumn<QString>("key");
QTest::addColumn<QString>("lookup");
QTest::newRow("bugreport-1") << QStringLiteral("240000000000") << QStringLiteral("3776798720");
QTest::newRow("bugreport-2") << QStringLiteral("240000000001") << QStringLiteral("3776798721");
QTest::newRow("biggest-ok-before-bug") << QStringLiteral("238609294221") << QStringLiteral("2386092941");
QTest::newRow("smallest-bugged") << QStringLiteral("238609294222") << QStringLiteral("2386092942");
QTest::newRow("biggest-bugged") << QStringLiteral("249108103166") << QStringLiteral("12884901886");
QTest::newRow("smallest-ok-after-bug") << QStringLiteral("249108103167") << QStringLiteral("12884901887");
}
void tst_QJSValue::hasProperty_QTBUG56830()
{
QFETCH(QString, key);
QFETCH(QString, lookup);
QJSEngine eng;
const QJSValue value(42);
QJSValue obj = eng.newObject();
obj.setProperty(key, value);
QVERIFY(obj.hasProperty(key));
QVERIFY(!obj.hasProperty(lookup));
}
void tst_QJSValue::deleteProperty_basic() void tst_QJSValue::deleteProperty_basic()
{ {
QJSEngine eng; QJSEngine eng;

View File

@ -92,6 +92,8 @@ private slots:
void hasProperty_basic(); void hasProperty_basic();
void hasProperty_globalObject(); void hasProperty_globalObject();
void hasProperty_changePrototype(); void hasProperty_changePrototype();
void hasProperty_QTBUG56830_data();
void hasProperty_QTBUG56830();
void deleteProperty_basic(); void deleteProperty_basic();
void deleteProperty_globalObject(); void deleteProperty_globalObject();

View File

@ -0,0 +1,9 @@
import QtQuick 2.0
Item {
width: 50
property bool tested: false
Connections { onWidthChanged: tested = true }
}

View File

@ -52,6 +52,7 @@ private slots:
void rewriteErrors(); void rewriteErrors();
void singletonTypeTarget(); void singletonTypeTarget();
void enableDisable_QTBUG_36350(); void enableDisable_QTBUG_36350();
void clearImplicitTarget();
private: private:
QQmlEngine engine; QQmlEngine engine;
@ -352,6 +353,32 @@ void tst_qqmlconnections::enableDisable_QTBUG_36350()
delete item; delete item;
} }
//QTBUG-56499
void tst_qqmlconnections::clearImplicitTarget()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("test-connection-implicit.qml"));
QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
QVERIFY(item != 0);
// normal case: fire Connections
item->setWidth(100.);
QCOMPARE(item->property("tested").toBool(), true);
item->setProperty("tested", false);
// clear the implicit target
QQmlConnections *connections = item->findChild<QQmlConnections*>();
QVERIFY(connections);
connections->setTarget(0);
// target cleared: no longer fire Connections
item->setWidth(150.);
QCOMPARE(item->property("tested").toBool(), false);
delete item;
}
QTEST_MAIN(tst_qqmlconnections) QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc" #include "tst_qqmlconnections.moc"

View File

@ -2726,9 +2726,9 @@ struct TestListener : public QQuickItemChangeListener
{ {
TestListener(bool remove = false) : remove(remove) { } TestListener(bool remove = false) : remove(remove) { }
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &diff) override void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &oldGeometry) override
{ {
record(item, QQuickItemPrivate::Geometry, diff); record(item, QQuickItemPrivate::Geometry, oldGeometry);
} }
void itemSiblingOrderChanged(QQuickItem *item) override void itemSiblingOrderChanged(QQuickItem *item) override
{ {
@ -2810,20 +2810,20 @@ void tst_QQuickItem::changeListener()
item->setImplicitWidth(10); item->setImplicitWidth(10);
QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1); QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1); QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0))); QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,0)));
item->setImplicitHeight(20); item->setImplicitHeight(20);
QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1); QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2); QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,20))); QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0)));
item->setWidth(item->width() + 30); item->setWidth(item->width() + 30);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3); QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,30,0))); QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,20)));
item->setHeight(item->height() + 40); item->setHeight(item->height() + 40);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4); QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,40))); QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,40,20)));
item->setOpacity(0.5); item->setOpacity(0.5);
QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1); QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1);

View File

@ -0,0 +1,20 @@
import QtQuick 2.0
Rectangle {
width: 300
height: 300
color: "white"
TextEdit {
objectName: "textEditObject"
width: 300
height: 300
text: "<span style=\"font-size:20pt;\">Blah</span><br>blah"
textFormat: TextEdit.RichText
cursorDelegate: Rectangle {
objectName: "cursorInstance"
color: "red"
width: 2
}
}
}

View File

@ -140,6 +140,7 @@ private slots:
void cursorVisible(); void cursorVisible();
void delegateLoading_data(); void delegateLoading_data();
void delegateLoading(); void delegateLoading();
void cursorDelegateHeight();
void navigation(); void navigation();
void readOnly(); void readOnly();
#ifndef QT_NO_CLIPBOARD #ifndef QT_NO_CLIPBOARD
@ -2848,6 +2849,43 @@ void tst_qquicktextedit::delegateLoading()
//QVERIFY(!delegate); //QVERIFY(!delegate);
} }
void tst_qquicktextedit::cursorDelegateHeight()
{
QQuickView view(testFileUrl("cursorHeight.qml"));
view.show();
view.requestActivate();
QTest::qWaitForWindowActive(&view);
QQuickTextEdit *textEditObject = view.rootObject()->findChild<QQuickTextEdit*>("textEditObject");
QVERIFY(textEditObject);
// Delegate creation is deferred until focus in or cursor visibility is forced.
QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
QVERIFY(!textEditObject->isCursorVisible());
// Test that the delegate gets created.
textEditObject->setFocus(true);
QVERIFY(textEditObject->isCursorVisible());
QQuickItem* delegateObject = textEditObject->findChild<QQuickItem*>("cursorInstance");
QVERIFY(delegateObject);
const int largerHeight = textEditObject->cursorRectangle().height();
textEditObject->setCursorPosition(0);
QCOMPARE(delegateObject->x(), textEditObject->cursorRectangle().x());
QCOMPARE(delegateObject->y(), textEditObject->cursorRectangle().y());
QCOMPARE(delegateObject->height(), textEditObject->cursorRectangle().height());
// Move the cursor to the next line, which has a smaller font.
textEditObject->setCursorPosition(5);
QCOMPARE(delegateObject->x(), textEditObject->cursorRectangle().x());
QCOMPARE(delegateObject->y(), textEditObject->cursorRectangle().y());
QVERIFY(textEditObject->cursorRectangle().height() < largerHeight);
QCOMPARE(delegateObject->height(), textEditObject->cursorRectangle().height());
// Test that the delegate gets deleted
textEditObject->setCursorDelegate(0);
QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
}
/* /*
TextEdit element should only handle left/right keys until the cursor reaches TextEdit element should only handle left/right keys until the cursor reaches
the extent of the text, then they should ignore the keys. the extent of the text, then they should ignore the keys.

View File

@ -0,0 +1,14 @@
import QtQuick 2.0
Item {
width: 320
height: 480
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 16
textFormat: Text.RichText
text: "<img width=16 height=16 src=\"data/logo.png\" />This image is in the start of the text"
}
}

View File

@ -0,0 +1,14 @@
import QtQuick 2.0
Item {
width: 320
height: 480
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 16
textFormat: Text.RichText
text: "<img width=16 height=16 src=\"data/logo.png\" />هو أمّا حكومة"
}
}

View File

@ -453,6 +453,7 @@ int main(int argc, char *argv[])
app->setApplicationName("Qml Runtime"); app->setApplicationName("Qml Runtime");
app->setOrganizationName("QtProject"); app->setOrganizationName("QtProject");
app->setOrganizationDomain("qt-project.org"); app->setOrganizationDomain("qt-project.org");
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration"); qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration");
qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene"); qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene");

View File

@ -33,6 +33,7 @@
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
MainWindow mainWindow; MainWindow mainWindow;
mainWindow.show(); mainWindow.show();

View File

@ -485,6 +485,7 @@ QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, const QString
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QStringList args = app.arguments(); QStringList args = app.arguments();
const QString appName = QFileInfo(app.applicationFilePath()).baseName(); const QString appName = QFileInfo(app.applicationFilePath()).baseName();
if (args.size() < 2) { if (args.size() < 2) {
@ -529,7 +530,12 @@ int main(int argc, char *argv[])
if (arg.startsWith(QLatin1Char('-')) && arg != QLatin1String("-")) if (arg.startsWith(QLatin1Char('-')) && arg != QLatin1String("-"))
break; break;
++i; ++i;
*argReceiver += arg; if (!QFile::exists(arg)) {
std::cerr << "No such file or directory: \"" << qPrintable(arg) << "\"\n";
return 1;
} else {
*argReceiver += arg;
}
} }
} }

View File

@ -135,6 +135,7 @@ static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exceptio
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QStringList args = app.arguments(); QStringList args = app.arguments();
args.removeFirst(); args.removeFirst();

View File

@ -533,6 +533,7 @@ static void usage(bool showHelp = false)
int runQmlmin(int argc, char *argv[]) int runQmlmin(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList args = app.arguments(); const QStringList args = app.arguments();

View File

@ -987,6 +987,7 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList args = app.arguments(); const QStringList args = app.arguments();
const QString appName = QFileInfo(app.applicationFilePath()).baseName(); const QString appName = QFileInfo(app.applicationFilePath()).baseName();
if (args.size() < 2) { if (args.size() < 2) {

View File

@ -467,6 +467,7 @@ int main(int argc, char ** argv)
app.setApplicationName("QtQmlViewer"); app.setApplicationName("QtQmlViewer");
app.setOrganizationName("QtProject"); app.setOrganizationName("QtProject");
app.setOrganizationDomain("qt-project.org"); app.setOrganizationDomain("qt-project.org");
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList arguments = QCoreApplication::arguments(); const QStringList arguments = QCoreApplication::arguments();
for (int i = 1, size = arguments.size(); i < size; ++i) { for (int i = 1, size = arguments.size(); i < size; ++i) {

View File

@ -205,6 +205,7 @@ void usage(const char *name)
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
qmlRegisterType<Timer>("QmlTime", 1, 0, "Timer"); qmlRegisterType<Timer>("QmlTime", 1, 0, "Timer");