From b65b6bd5a6d571ad7047d85508f85c62ca9ad8ce Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 6 Jul 2016 11:14:17 +0200 Subject: Fix QQuickDefaultClipNode::updateGeometry() There are segments top + border and for each segment 2 points -> 4. Change-Id: I6df11e557054e4b942de430bd2cad8e2f798b0db Task-number: QTBUG-51894 Reviewed-by: Robin Burchell Reviewed-by: Laszlo Agocs --- src/quick/items/qquickclipnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickclipnode.cpp b/src/quick/items/qquickclipnode.cpp index a46f758c3b..3b5933d910 100644 --- a/src/quick/items/qquickclipnode.cpp +++ b/src/quick/items/qquickclipnode.cpp @@ -87,7 +87,7 @@ void QQuickDefaultClipNode::updateGeometry() int segments = qMin(30, qCeil(radius)); // Number of segments per corner. - g->allocate((segments + 1) * 2); + g->allocate((segments + 1) * 4); QVector2D *vertices = (QVector2D *)g->vertexData(); -- cgit v1.2.3 From ebf07c3f68415099132856b2831633c310bc3395 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 14 Apr 2015 14:55:24 +0200 Subject: Flickable: avoid infinite velocity during release after drag It sometimes happens on touchscreens that mouse events occur too close together. We cannot calculate velocity based on zero elapsed time, so just ignore the event. Task-number: QTBUG-45527 Change-Id: I120e73cfa60e2fcc594cb1f3b69f530e746abddd Reviewed-by: Timur Pocheptsov --- src/quick/items/qquickflickable.cpp | 8 ++++++-- tests/auto/qmltest/listview/tst_listview.qml | 4 ++++ tests/auto/quick/qquickflickable/tst_qquickflickable.cpp | 1 + .../tst_qquickmultipointtoucharea.cpp | 8 ++++++++ tests/auto/quick/touchmouse/tst_touchmouse.cpp | 13 +++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index b0980cd2c1..760eeed452 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1224,13 +1224,17 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) return; qint64 currentTimestamp = computeCurrentTime(event); - qreal elapsed = qreal(currentTimestamp - (lastPos.isNull() ? lastPressTime : lastPosTime)) / 1000.; QVector2D deltas = QVector2D(event->localPos() - pressPos); bool overThreshold = false; QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event); // TODO guarantee that events always have velocity so that it never needs to be computed here - if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) + if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) { + qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime); + if (currentTimestamp == lastTimestamp) + return; // events are too close together: velocity would be infinite + qreal elapsed = qreal(currentTimestamp - lastTimestamp) / 1000.; velocity = QVector2D(event->localPos() - (lastPos.isNull() ? pressPos : lastPos)) / elapsed; + } if (q->yflick()) overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, event); diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index a3cae7fce2..ef9f73e005 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -304,9 +304,13 @@ Item { function test_listInteractiveCurrentIndexEnforce() { mousePress(listInteractiveCurrentIndexEnforce, 10, 50); + wait(1); // because Flickable pays attention to velocity, we need some time between movements mouseMove(listInteractiveCurrentIndexEnforce, 10, 40); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 30); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 20); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 10); compare(listInteractiveCurrentIndexEnforce.interactive, false); mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10); diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 2e134ff5ad..294f7069c0 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -1466,6 +1466,7 @@ void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *tou for (int i = 1; i <= 8; ++i) { QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements } QTest::touchEvent(window, touchDevice).release(0, to, window); QQuickTouchUtils::flush(window); diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 2f432e57bc..d3b576e092 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -601,18 +601,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); @@ -788,18 +792,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QCOMPARE(point11->pressed(), true); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index e14b7d7c84..0608af7cd4 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -591,10 +591,13 @@ void tst_TouchMouse::buttonOnFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); @@ -676,10 +679,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); QVERIFY(flickable->isMovingVertically()); @@ -871,15 +877,19 @@ void tst_TouchMouse::pinchOnFlickable() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); QTest::touchEvent(window, device).release(0, p, window); @@ -1092,13 +1102,16 @@ void tst_TouchMouse::mouseOnFlickableOnPinch() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); QGuiApplication::processEvents(); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); -- cgit v1.2.3 From f2d174012bcaa88e90a80ec2120182ad9e6e8f48 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 4 Aug 2016 23:03:23 +0200 Subject: tst_creation: Remove redundant widgets dependency Absolutely no need for this. Change-Id: I06ca2dab157fecf2c585b9f863d9893cd4ce7300 Reviewed-by: Simon Hausmann --- tests/benchmarks/qml/creation/creation.pro | 2 +- tests/benchmarks/qml/creation/tst_creation.cpp | 2 -- tests/benchmarks/qml/qml.pro | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/benchmarks/qml/creation/creation.pro b/tests/benchmarks/qml/creation/creation.pro index c6f0bf7e17..8f5c2edc1d 100644 --- a/tests/benchmarks/qml/creation/creation.pro +++ b/tests/benchmarks/qml/creation/creation.pro @@ -1,7 +1,7 @@ CONFIG += benchmark TEMPLATE = app TARGET = tst_creation -QT += core-private gui-private qml-private quick-private widgets testlib +QT += core-private gui-private qml-private quick-private testlib macx:CONFIG -= app_bundle SOURCES += tst_creation.cpp diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index 38ab577120..b6e2801c99 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/tests/benchmarks/qml/qml.pro b/tests/benchmarks/qml/qml.pro index 5d48ec0067..87779bee0a 100644 --- a/tests/benchmarks/qml/qml.pro +++ b/tests/benchmarks/qml/qml.pro @@ -11,9 +11,9 @@ SUBDIRS += \ qqmlmetaproperty \ librarymetrics_performance \ # script \ ### FIXME: doesn't build - js + js \ + creation qtHaveModule(opengl): SUBDIRS += painting qquickwindow -qtHaveModule(widgets): SUBDIRS += creation include(../trusted-benchmarks.pri) -- cgit v1.2.3 From 3631c77ff01f40f83fa59a90c28d69ee9953c327 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Fri, 5 Aug 2016 00:07:45 +0200 Subject: tst_creation: Remove qobject_alloc benchmark This is literally just testing operator new and delete, with a little PLT overhead. It is not useful as a result (not a real-world scenario, and obscenely variant thanks to allocators not being predictable in behavior). Change-Id: I42f758c503b37ff880fc4f0e38c220d0638356e9 Reviewed-by: Simon Hausmann --- tests/benchmarks/qml/creation/tst_creation.cpp | 30 -------------------------- 1 file changed, 30 deletions(-) diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index b6e2801c99..595b8346ca 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -50,7 +50,6 @@ private slots: void qobject_cpp(); void qobject_qml(); void qobject_qmltype(); - void qobject_alloc(); void qobject_10flat_qml(); void qobject_10flat_cpp(); @@ -206,35 +205,6 @@ void tst_creation::qobject_qmltype() } } -struct QObjectFakeData { - char data[sizeof(QObjectPrivate)]; -}; - -struct QObjectFake { - QObjectFake(); - virtual ~QObjectFake(); -private: - QObjectFakeData *d; -}; - -QObjectFake::QObjectFake() -{ - d = new QObjectFakeData; -} - -QObjectFake::~QObjectFake() -{ - delete d; -} - -void tst_creation::qobject_alloc() -{ - QBENCHMARK { - QObjectFake *obj = new QObjectFake; - delete obj; - } -} - struct QQmlGraphics_Derived : public QObject { void setParent_noEvent(QObject *parent) { -- cgit v1.2.3 From e0e591fb80ab86f6044e5140ddbbc979c0c8d380 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Fri, 5 Aug 2016 00:22:27 +0200 Subject: tst_creation: Remove tst_creation::elements There is no real sense in testing what boils down to operator new/delete plus a little PLT overhead. For one thing, the allocator is too variant to test at such a level. For another, it's not representative of any real-world scenario. Change-Id: Ib455bb00839ff4e25099977059759a7b328db306 Reviewed-by: Simon Hausmann --- tests/benchmarks/qml/creation/tst_creation.cpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index 595b8346ca..dbda07be5a 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -64,9 +64,6 @@ private slots: void itemtree_qml(); void itemtree_scene_cpp(); - void elements_data(); - void elements(); - void itemtests_qml_data(); void itemtests_qml(); @@ -299,28 +296,6 @@ void tst_creation::itemtree_scene_cpp() delete root; } -void tst_creation::elements_data() -{ - QTest::addColumn("type"); - - QList types = QQmlMetaType::qmlTypeNames(); - foreach (QString type, types) - QTest::newRow(type.toLatin1()) << type; -} - -void tst_creation::elements() -{ - QFETCH(QString, type); - QQmlType *t = QQmlMetaType::qmlType(type, 2, 0); - if (!t || !t->isCreatable()) - QSKIP("Non-creatable type"); - - QBENCHMARK { - QObject *obj = t->create(); - delete obj; - } -} - void tst_creation::itemtests_qml_data() { QTest::addColumn("filepath"); -- cgit v1.2.3 From fde6e1fe83e049de4441494d32bbcf88c13517a8 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Fri, 5 Aug 2016 00:28:58 +0200 Subject: benchmarks: Remove odd qqmlimage benchmark I have no idea what this was theoretically supposed to be testing, but it looks completely bogus (not representative of a real world scenario), is subject to massive variance thanks to memory allocation, and generally doesn't seem useful Change-Id: Ib7adc8a4753e49d2a3bd9515273bca79a88a5749 Reviewed-by: Simon Hausmann --- tests/benchmarks/qml/qml.pro | 1 - tests/benchmarks/qml/qqmlimage/image.png | Bin 611 -> 0 bytes tests/benchmarks/qml/qqmlimage/qqmlimage.pro | 12 --- tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp | 100 ----------------------- 4 files changed, 113 deletions(-) delete mode 100644 tests/benchmarks/qml/qqmlimage/image.png delete mode 100644 tests/benchmarks/qml/qqmlimage/qqmlimage.pro delete mode 100644 tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp diff --git a/tests/benchmarks/qml/qml.pro b/tests/benchmarks/qml/qml.pro index 87779bee0a..2cf2dff413 100644 --- a/tests/benchmarks/qml/qml.pro +++ b/tests/benchmarks/qml/qml.pro @@ -7,7 +7,6 @@ SUBDIRS += \ holistic \ qqmlchangeset \ qqmlcomponent \ - qqmlimage \ qqmlmetaproperty \ librarymetrics_performance \ # script \ ### FIXME: doesn't build diff --git a/tests/benchmarks/qml/qqmlimage/image.png b/tests/benchmarks/qml/qqmlimage/image.png deleted file mode 100644 index 623d36233d..0000000000 Binary files a/tests/benchmarks/qml/qqmlimage/image.png and /dev/null differ diff --git a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro deleted file mode 100644 index dfe0027ab4..0000000000 --- a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += benchmark -TEMPLATE = app -TARGET = tst_qqmlimage -QT += qml quick-private testlib -macx:CONFIG -= app_bundle -CONFIG += release - -SOURCES += tst_qqmlimage.cpp - -DEFINES += SRCDIR=\\\"$$PWD\\\" - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp b/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp deleted file mode 100644 index 992ad5de67..0000000000 --- a/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -class tst_qmlgraphicsimage : public QObject -{ - Q_OBJECT -public: - tst_qmlgraphicsimage() {} - -private slots: - void qmlgraphicsimage(); - void qmlgraphicsimage_file(); - void qmlgraphicsimage_url(); - -private: - QQmlEngine engine; -}; - -void tst_qmlgraphicsimage::qmlgraphicsimage() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - delete image; - } -} - -void tst_qmlgraphicsimage::qmlgraphicsimage_file() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - //get rid of initialization effects - { - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url); - } - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url); - delete image; - } -} - -void tst_qmlgraphicsimage::qmlgraphicsimage_url() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url2); - delete image; - } -} - -QTEST_MAIN(tst_qmlgraphicsimage) - -#include "tst_qqmlimage.moc" -- cgit v1.2.3 From 7377e8f950d550d8823914588c35e541c48ab3ce Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Fri, 5 Aug 2016 11:41:52 +0200 Subject: tst_librarymetrics_performance: Use QBENCHMARK macro instead of rolling our own This means we now respect -callgrind to show instruction counts (for instance). If benchmarks don't already throw out outliers and perform averaging, we should roll those features into testlib, not replace it. Change-Id: I21a3c4b41ec80a49b5b61bfe957f1165ac865010 Reviewed-by: Simon Hausmann --- .../tst_librarymetrics_performance.cpp | 147 ++------------------- 1 file changed, 14 insertions(+), 133 deletions(-) diff --git a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp index ad72ebc6f0..4b69975dac 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp +++ b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp @@ -41,9 +41,6 @@ // for the standard set of elements, properties and expressions which // are provided in the QtDeclarative library (QtQml and QtQuick). -#define AVERAGE_OVER_N 10 -#define IGNORE_N_OUTLIERS 2 - class ModuleApi : public QObject { Q_OBJECT @@ -219,123 +216,37 @@ void tst_librarymetrics_performance::compilation() } } - QList nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::instantiation_cached() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList nResults; - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { - QElapsedTimer et; - et.start(); + QBENCHMARK { QQmlComponent c(e, this); c.loadUrl(qmlfile); // just compile. QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); delete o; } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); - } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::instantiation() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - delete o; - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. + QObject *o = c.create(); + delete o; } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::positioners_data() @@ -356,43 +267,13 @@ void tst_librarymetrics_performance::positioners() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - delete o; - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. + QObject *o = c.create(); + delete o; } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } QTEST_MAIN(tst_librarymetrics_performance) -- cgit v1.2.3 From 837c5d6284eeec8adb9b2caa3a0ce82b0da019a1 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Fri, 5 Aug 2016 13:18:44 +0200 Subject: Fix crash when cache property can not be found For some reason if a cache property is not found this cause an application crash instead of just reporting an error. Now instead of a crash we get this kind of error visible: qrc:///the_file.qml line 64 column 30: Cannot assign object to property Change-Id: Ic420713df30603f1d164da439cba30a18af8f2bc Reviewed-by: Simon Hausmann --- src/qml/compiler/qqmltypecompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 7e4ee344ff..82332dfc35 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1414,7 +1414,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI continue; QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType); - const QMetaObject *mo = pc->firstCppMetaObject(); + const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0; while (mo) { if (mo == &QQmlComponent::staticMetaObject) break; -- cgit v1.2.3 From ff645deb25c18eeae3d248a6a60bc2954129ee28 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 2 Aug 2016 11:52:58 +0200 Subject: Remove artifacts in font rendering The distancefield cache did not clear the textures before using them. Hence, random values could leak through in the edges of the distancefields, leading to random pixels at the edges of the rendered glyphs. This issue was rarely visible before, because of the way the glyphs were stacked on the textures. That stacking was changed as a result of 7190aa26f65ab97b4f54c156a107ed7748a11df5, which made the issue happen more often, so it was detected by lancelot. Change-Id: Ibe7a20dd7ba557ab92966e714c25a100e218ed24 Reviewed-by: Yoann Lopes --- src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 728d8b6541..31275b304d 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -253,7 +253,8 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int const GLenum format = GL_ALPHA; #endif - m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, 0); + QByteArray zeroBuf(width * height, 0); + m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, zeroBuf.constData()); texInfo->size = QSize(width, height); -- cgit v1.2.3 From 68bfc9332cd65c1eb88d1ec87164447b0db43237 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 25 Jul 2016 16:07:16 +0200 Subject: Fix crash with Component.onDestruction A call to a handler of Component.onDestruction may end up causing WeakValues such as QQmlData::jsWrapper to be set again, even though they've been set to undefined in an earlier iteration of the loop that walks through the weak references. That in turn may result in invalid object references to objects that are scheduled for destruction by the collector. So after calling all destroy handlers for QObjects, reset all of the weak values again. Task-number: QTBUG-54939 Change-Id: I00ebabb76274e296fb1bd90d8d3e21dbbb920b57 Reviewed-by: Lars Knoll --- src/qml/memory/qv4mm.cpp | 13 ++- .../qml/qqmlecmascript/data/DestructionHelper.qml | 3 + .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 102 +++++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 7ab6d15041..4592dd5c9b 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -428,7 +428,7 @@ void MemoryManager::sweep(bool lastSweep) Managed *m = (*it).as(); if (m->markBit()) continue; - // we need to call detroyObject on qobjectwrappers now, so that they can emit the destroyed + // we need to call destroyObject on qobjectwrappers now, so that they can emit the destroyed // signal before we start sweeping the heap if (QObjectWrapper *qobjectWrapper = (*it).as()) qobjectWrapper->destroyObject(lastSweep); @@ -436,6 +436,17 @@ void MemoryManager::sweep(bool lastSweep) (*it) = Primitive::undefinedValue(); } + // onDestruction handlers may have accessed other QObject wrappers and reset their value, so ensure + // that they are all set to undefined. + for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { + if (!(*it).isManaged()) + continue; + Managed *m = (*it).as(); + if (m->markBit()) + continue; + (*it) = Primitive::undefinedValue(); + } + // Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed const int pendingCount = m_pendingFreedObjectWrapperValue.count(); if (pendingCount) { diff --git a/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml new file mode 100644 index 0000000000..8bb0a3554e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml @@ -0,0 +1,3 @@ +import Test 1.0 +WeakReferenceMutator { +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index b3b31e1a73..d65cec843c 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -49,6 +49,8 @@ #include #include #include +#include +#include #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -287,6 +289,7 @@ private slots: void replaceBinding(); void deleteRootObjectInCreation(); void onDestruction(); + void onDestructionViaGC(); void bindingSuppression(); void signalEmitted(); void threadSignal(); @@ -7157,6 +7160,105 @@ void tst_qqmlecmascript::onDestruction() } } +class WeakReferenceMutator : public QObject +{ + Q_OBJECT +public: + WeakReferenceMutator() + : resultPtr(Q_NULLPTR) + , weakRef(Q_NULLPTR) + {} + + void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr) + { + QV4::QObjectWrapper::wrap(v4, this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + + this->resultPtr = resultPtr; + this->weakRef = weakRef; + + QObject::connect(QQmlComponent::qmlAttachedProperties(this), &QQmlComponentAttached::destruction, this, &WeakReferenceMutator::reviveFirstWeakReference); + } + +private slots: + void reviveFirstWeakReference() { + *resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined(); + if (!*resultPtr) + return; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this)); + weakRef->set(v4, v4->newObject()); + *resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined(); + } + +public: + bool *resultPtr; + + QV4::WeakValue *weakRef; +}; + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +namespace Heap { +struct WeakReferenceSentinel : public Object { + WeakReferenceSentinel(WeakValue *weakRef, bool *resultPtr) + : weakRef(weakRef) + , resultPtr(resultPtr) { + + } + + ~WeakReferenceSentinel() { + *resultPtr = weakRef->isNullOrUndefined(); + } + + WeakValue *weakRef; + bool *resultPtr; +}; +} // namespace Heap + +struct WeakReferenceSentinel : public Object { + V4_OBJECT2(WeakReferenceSentinel, Object) + V4_NEEDS_DESTROY +}; + +} // namespace QV4 + +QT_END_NAMESPACE + +DEFINE_OBJECT_VTABLE(QV4::WeakReferenceSentinel); + +void tst_qqmlecmascript::onDestructionViaGC() +{ + qmlRegisterType("Test", 1, 0, "WeakReferenceMutator"); + + QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); + + QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml")); + + QScopedPointer weakRef; + + bool mutatorResult = false; + bool sentinelResult = false; + + { + weakRef.reset(new QV4::WeakValue); + weakRef->set(v4, v4->newObject()); + QVERIFY(!weakRef->isNullOrUndefined()); + + QPointer weakReferenceMutator = qobject_cast(component.create()); + QVERIFY2(!weakReferenceMutator.isNull(), qPrintable(component.errorString())); + weakReferenceMutator->init(v4, weakRef.data(), &mutatorResult); + + v4->memoryManager->allocObject(weakRef.data(), &sentinelResult); + } + gc(engine); + + QVERIFY2(mutatorResult, "We failed to re-assign the weak reference a new value during GC"); + QVERIFY2(sentinelResult, "The weak reference was not cleared properly"); +} + struct EventProcessor : public QObject { Q_OBJECT -- cgit v1.2.3 From 13a427475d3638de843f33145378587037841a86 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 5 Aug 2016 12:33:03 +0200 Subject: Clarify doc on modification of the global object in JS imported by QML Currently, reading the documentation for modification of the global object in JavaScript can be confusing. http://doc.qt.io/qt-5/qtqml-javascript-hostenvironment.html says: JavaScript code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. ... Any attempt to modify the global object - either implicitly or explicitly - will cause an exception. If uncaught, this will result in a warning being printed, that includes the file and line number of the offending code. http://doc.qt.io/qt-5/qjsengine.html#globalObject says: Returns this engine's Global Object. By default, the Global Object contains the built-in objects that are part of ECMA-262, such as Math, Date and String. Additionally, you can set properties of the Global Object to make your own extensions available to all script code. Non-local variables in script code will be created as properties of the Global Object, as well as local variables in global code. If QQmlEngine "is-a" QJSEngine, and QJSEngine can have its global object modified, it might seem reasonable to expect that imported JavaScript code should be able to modify the global object. This patch aims to be more explicit about the restrictions and give examples of how libraries should expose their APIs correctly for use by QML code. Change-Id: I11beb894a88d52038be90ffe6baa9337943810db Reviewed-by: Simon Hausmann --- src/qml/doc/src/javascript/hostenvironment.qdoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index de8b967d72..1e33f2f641 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -80,7 +80,10 @@ Note that QML makes the following modifications to native objects: QML implements the following restrictions for JavaScript code: \list -\li JavaScript code cannot modify the global object. +\li JavaScript code written in a \c .qml file cannot modify the global object. + JavaScript code in a .js file can modify the global object, + and those modifications will be visible to the .qml file when + \l {Importing a JavaScript Resource from a QML Document}{imported}. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. -- cgit v1.2.3 From 31ca52cee47f189ee1c80245f7b114c29ac7c675 Mon Sep 17 00:00:00 2001 From: Eike Hein Date: Thu, 4 Jun 2015 21:25:32 +0200 Subject: Don't accept left clicks when text format is plain. Text elements may contain rich text with embedded links, and need to accept left clicks to open them. However, setting the textFormat to PlainText can disable mouse handling entirely, as it is not required. Accepting left clicks if there can be nothing to interact with is unexpected and surprising, and can cause bugs in code that performs child event filtering and doesn't expect Text elements to produce child events. Change-Id: Ibd5b9cf8d06fd30ea26f78b5393cc43e94646e73 Reviewed-by: Marco Martin Reviewed-by: Kai Uwe Broulik Reviewed-by: Robin Burchell Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/quick/items/qquicktext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index e67e2cee9c..ea2d2f3133 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2013,6 +2013,7 @@ void QQuickText::setTextFormat(TextFormat format) } d->updateLayout(); setAcceptHoverEvents(d->richText || d->styledText); + setAcceptedMouseButtons(d->richText || d->styledText ? Qt::LeftButton : Qt::NoButton); emit textFormatChanged(d->format); } -- cgit v1.2.3 From 35597f301480ffc59f598be4de2c2074543725be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 2 Jun 2016 12:08:29 +0200 Subject: Fix char conversions in QML This is a partial revert of 90b06e2773842, as it had unwanted side effects. The original intention was to make assignment from char to string possible, or more specifically, we wanted a solution where a QChar could be assigned to a QString, as a character and not a string representation of its value. While this behavior is desirable for QChar, we most likely want the opposite for the regular character types. Task-number: QTBUG-49232 Change-Id: I82d5f72b900fe984c4db1478fd52a9eb69ad2ee6 Reviewed-by: Michael Brasser Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 13 +++++--- src/qml/qml/qqmlproperty.cpp | 25 ++------------ tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp | 29 ++++++++++++++++ tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 42 ++---------------------- 4 files changed, 43 insertions(+), 66 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 5dc3e6151f..557b678ef8 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1143,8 +1143,13 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return value.integerValue(); if (value.isNumber()) return value.asDouble(); - if (value.isString()) - return value.stringValue()->toQString(); + if (value.isString()) { + const QString &str = value.toQString(); + // QChars are stored as a strings + if (typeHint == QVariant::Char && str.size() == 1) + return str.at(0); + return str; + } if (const QV4::QQmlLocaleData *ld = value.as()) return ld->d()->locale; if (const QV4::DateObject *d = value.as()) @@ -1284,9 +1289,9 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::UShort: return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::Char: - return newString(QChar::fromLatin1(*reinterpret_cast(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::UChar: - return newString(QChar::fromLatin1(*reinterpret_cast(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::QChar: return newString(*reinterpret_cast(ptr))->asReturnedValue(); case QMetaType::QDateTime: diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 1b78ada698..1eaff6b600 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1327,29 +1327,8 @@ bool QQmlPropertyPrivate::write(QObject *object, bool ok = false; QVariant v; - if (variantType == QVariant::String) { - const QString &str = value.toString(); - const bool targetIsChar = (propertyType == qMetaTypeId() - || propertyType == qMetaTypeId() - || propertyType == qMetaTypeId()); - // If the string contains only one character and the target is a char, try converting it. - if (targetIsChar) { - if (str.size() != 1) - return false; // We can only convert if the string contains exactly one character. - - const QChar &qChar = str.at(0); - if (propertyType == qMetaTypeId()) { - v = qChar; - ok = true; - } else if (propertyType == qMetaTypeId() || propertyType == qMetaTypeId()) { - const char c = qChar.toLatin1(); - v = c; - ok = (qChar == c); - } - } else { - v = QQmlStringConverters::variantFromString(str, propertyType, &ok); - } - } + if (variantType == QVariant::String) + v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok); if (!ok) { v = value; diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index d338e6f5ad..739af3782e 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -66,6 +66,7 @@ private slots: void qtbug_22535(); void evalAfterInvalidate(); void qobjectDerived(); + void qtbug_49232(); private: QQmlEngine engine; @@ -205,6 +206,8 @@ class TestObject : public QObject Q_PROPERTY(int a READ a NOTIFY aChanged) Q_PROPERTY(int b READ b NOTIFY bChanged) Q_PROPERTY(int c READ c NOTIFY cChanged) + Q_PROPERTY(char d READ d NOTIFY dChanged) + Q_PROPERTY(uchar e READ e NOTIFY eChanged) public: TestObject() : _a(10), _b(10), _c(10) {} @@ -218,15 +221,25 @@ public: int c() const { return _c; } void setC(int c) { _c = c; emit cChanged(); } + char d() const { return _d; } + void setD(char d) { _d = d; emit dChanged(); } + + uchar e() const { return _e; } + void setE(uchar e) { _e = e; emit eChanged(); } + signals: void aChanged(); void bChanged(); void cChanged(); + void dChanged(); + void eChanged(); private: int _a; int _b; int _c; + char _d; + uchar _e; }; #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ @@ -699,6 +712,22 @@ void tst_qqmlcontext::qobjectDerived() QCOMPARE(command.count, 2); } +void tst_qqmlcontext::qtbug_49232() +{ + TestObject testObject; + testObject.setD('a'); + testObject.setE(97); + + QQmlEngine engine; + engine.rootContext()->setContextProperty("TestObject", &testObject); + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property int valueOne: TestObject.d; property int valueTwo: TestObject.e }", QUrl()); + QScopedPointer obj(component.create()); + + QCOMPARE(obj->property("valueOne"), QVariant('a')); + QCOMPARE(obj->property("valueTwo"), QVariant(97)); +} + QTEST_MAIN(tst_qqmlcontext) #include "tst_qqmlcontext.moc" diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 6ada14ce79..86c13065fa 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -329,11 +329,8 @@ class PropertyObject : public QObject Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject) Q_PROPERTY(MyQObject *qObject READ qObject WRITE setQObject NOTIFY qObjectChanged) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) - Q_PROPERTY(char charProperty READ charProperty WRITE setCharProperty) Q_PROPERTY(QChar qcharProperty READ qcharProperty WRITE setQcharProperty) Q_PROPERTY(QChar constQChar READ constQChar STORED false CONSTANT FINAL) - Q_PROPERTY(char constChar READ constChar STORED false CONSTANT FINAL) - Q_PROPERTY(int constInt READ constInt STORED false CONSTANT FINAL) Q_CLASSINFO("DefaultProperty", "defaultProperty") public: @@ -370,15 +367,11 @@ public: } QString stringProperty() const { return m_stringProperty;} - char charProperty() const { return m_charProperty; } QChar qcharProperty() const { return m_qcharProperty; } QChar constQChar() const { return 0x25cf; /* Unicode: black circle */ } - char constChar() const { return 'A'; } - int constInt() const { return 123456; } void setStringProperty(QString arg) { m_stringProperty = arg; } - void setCharProperty(char arg) { m_charProperty = arg; } void setQcharProperty(QChar arg) { m_qcharProperty = arg; } signals: @@ -395,7 +388,6 @@ private: MyQmlObject m_qmlObject; MyQObject *m_qObject; QString m_stringProperty; - char m_charProperty; QChar m_qcharProperty; }; @@ -1408,23 +1400,14 @@ void tst_qqmlproperty::write() // Char/string-property { PropertyObject o; - QQmlProperty charProperty(&o, "charProperty"); QQmlProperty qcharProperty(&o, "qcharProperty"); QQmlProperty stringProperty(&o, "stringProperty"); const int black_circle = 0x25cf; - QCOMPARE(charProperty.write(QString("foo")), false); - QCOMPARE(charProperty.write('Q'), true); - QCOMPARE(charProperty.read(), QVariant('Q')); - QCOMPARE(charProperty.write(QString("t")), true); - QCOMPARE(charProperty.read(), QVariant('t')); - QCOMPARE(qcharProperty.write(QString("foo")), false); QCOMPARE(qcharProperty.write('Q'), true); QCOMPARE(qcharProperty.read(), QVariant('Q')); - QCOMPARE(qcharProperty.write(QString("t")), true); - QCOMPARE(qcharProperty.read(), QVariant('t')); QCOMPARE(qcharProperty.write(QChar(black_circle)), true); QCOMPARE(qcharProperty.read(), QVariant(QChar(black_circle))); @@ -1433,19 +1416,10 @@ void tst_qqmlproperty::write() QCOMPARE(o.stringProperty(), QString("bar")); QCOMPARE(stringProperty.write(QVariant(1234)), true); QCOMPARE(stringProperty.read().toString(), QString::number(1234)); + QCOMPARE(stringProperty.write('A'), true); + QCOMPARE(stringProperty.read().toString(), QString::number('A')); QCOMPARE(stringProperty.write(QChar(black_circle)), true); - QCOMPARE(stringProperty.read(), QVariant(QString(QChar(black_circle)))); - - { // char -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constChar }", QUrl()); - PropertyObject *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString(obj->constChar()))); - } - } + QCOMPARE(stringProperty.read(), QVariant(QChar(black_circle))); { // QChar -> QString QQmlComponent component(&engine); @@ -1458,16 +1432,6 @@ void tst_qqmlproperty::write() } } - { // int -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constInt }", QUrl()); - PropertyObject *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString::number(obj->constInt()))); - } - } } // VariantMap-property -- cgit v1.2.3 From 4493524ec24afb946eba3942f48d9fc1ff3192c1 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 9 Aug 2016 10:49:22 +0200 Subject: V4: Align stack on 16 byte boundaries in the YarrJIT This is the required alignment for Aarch64, and a number of other ABIs prefer this size too when calling into system libraries. Change-Id: Ie38cabb77cf83543b915553e69c5c5728a67503b Reviewed-by: Simon Hausmann --- src/3rdparty/masm/yarr/YarrJIT.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp index 5664c585b9..d8211ec4b2 100644 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp @@ -338,17 +338,31 @@ class YarrGenerator : private MacroAssembler { jump(Address(stackPointerRegister, frameLocation * sizeof(void*))); } + unsigned alignCallFrameSizeInBytes(unsigned callFrameSize) + { + callFrameSize *= sizeof(void*); + if (callFrameSize / sizeof(void*) != m_pattern.m_body->m_callFrameSize) + CRASH(); + // Originally, the code was: +// callFrameSize = (callFrameSize + 0x3f) & ~0x3f; + // However, 64 bytes is a bit surprising. The biggest "alignment" requirement is on Aarch64, where: + // "SP mod 16 = 0. The stack must be quad-word aligned." (IHI0055B_aapcs64.pdf) + callFrameSize = (callFrameSize + 0xf) & ~0xf; + if (!callFrameSize) + CRASH(); + return callFrameSize; + } void initCallFrame() { unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; if (callFrameSize) - subPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); + subPtr(Imm32(alignCallFrameSizeInBytes(callFrameSize)), stackPointerRegister); } void removeCallFrame() { unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; if (callFrameSize) - addPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); + addPtr(Imm32(alignCallFrameSizeInBytes(callFrameSize)), stackPointerRegister); } // Used to record subpatters, should only be called if compileMode is IncludeSubpatterns. @@ -2565,6 +2579,10 @@ class YarrGenerator : private MacroAssembler { if (compileMode == IncludeSubpatterns) loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif +#elif CPU(ARM64) + // The ABI doesn't guarantee the upper bits are zero on unsigned arguments, so clear them ourselves. + zeroExtend32ToPtr(index, index); + zeroExtend32ToPtr(length, length); #elif CPU(ARM) push(ARMRegisters::r4); push(ARMRegisters::r5); -- cgit v1.2.3 From 5e7720d3fba1865439bf21fd564152b8b9a70f13 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 22 Jul 2016 09:25:06 +0200 Subject: qmlplugindump: fix regexp for plugins.qmltypes The latest plugins.qmltypes files contain whitespace after "dependencies:". Furthermore, just for the sake of correctness, escape dots in the QtQuick.tooling module import URI and version. Change-Id: I54fa288bc530f7852747c75b4d656e789d519cf2 Reviewed-by: Mitch Curtis Reviewed-by: Thomas Hartmann Reviewed-by: Marco Benelli --- tools/qmlplugindump/qmltypereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qmlplugindump/qmltypereader.cpp b/tools/qmlplugindump/qmltypereader.cpp index 67ba415388..9dfb6fc1e0 100644 --- a/tools/qmlplugindump/qmltypereader.cpp +++ b/tools/qmlplugindump/qmltypereader.cpp @@ -40,7 +40,7 @@ #include QStringList readQmlTypes(const QString &filename) { - QRegularExpression re("import QtQuick.tooling 1.2.*Module {\\s*dependencies:\\[([^\\]]*)\\](.*)}", + QRegularExpression re("import QtQuick\\.tooling 1\\.2.*Module {\\s*dependencies:\\s*\\[([^\\]]*)\\](.*)}", QRegularExpression::DotMatchesEverythingOption); if (!QFileInfo(filename).exists()) { std::cerr << "Non existing file: " << filename.toStdString() << std::endl; -- cgit v1.2.3 From eea2754976a6b4363be7575c7082a4df92e1217e Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Mon, 2 May 2016 17:29:40 +0200 Subject: Added Logging Category support to QML New Logging Categories can be defined by using the LoggingCategory type and define a name for the category When the id of a valid LoggingCategory is provided as the first argument to console.log and friends the LoggingCategory is used instead of the default "qml" LoggingCategory [ChangeLog][QML Elements] Added a LoggingCategory type and added support for it to the console object Change-Id: Ifaeed5f71de6ea6d8172d8c838d6e7789c4d6b9d Reviewed-by: Simon Hausmann --- src/qml/qml/qml.pri | 6 +- src/qml/qml/qqmlengine.cpp | 2 + src/qml/qml/qqmlloggingcategory.cpp | 128 +++++++++++++++++++++ src/qml/qml/qqmlloggingcategory_p.h | 89 ++++++++++++++ src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 25 +++- .../qml/qqmlconsole/data/categorized_logging.qml | 65 +++++++++++ tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp | 36 ++++++ tests/auto/shared/util.cpp | 11 +- tests/auto/shared/util.h | 5 +- 9 files changed, 358 insertions(+), 9 deletions(-) create mode 100644 src/qml/qml/qqmlloggingcategory.cpp create mode 100644 src/qml/qml/qqmlloggingcategory_p.h create mode 100644 tests/auto/qml/qqmlconsole/data/categorized_logging.qml diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index 87be140cbb..4244b16210 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -49,7 +49,8 @@ SOURCES += \ $$PWD/qqmlfileselector.cpp \ $$PWD/qqmlobjectcreator.cpp \ $$PWD/qqmldirparser.cpp \ - $$PWD/qqmldelayedcallqueue.cpp + $$PWD/qqmldelayedcallqueue.cpp \ + $$PWD/qqmlloggingcategory.cpp HEADERS += \ $$PWD/qqmlglobal_p.h \ @@ -121,7 +122,8 @@ HEADERS += \ $$PWD/qqmlfileselector.h \ $$PWD/qqmlobjectcreator_p.h \ $$PWD/qqmldirparser_p.h \ - $$PWD/qqmldelayedcallqueue_p.h + $$PWD/qqmldelayedcallqueue_p.h \ + $$PWD/qqmlloggingcategory_p.h include(ftw/ftw.pri) include(v8/v8.pri) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 48832f3b07..4acc74ee43 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -89,6 +89,7 @@ #include #include #include +#include #ifdef Q_OS_WIN // for %APPDATA% # include @@ -184,6 +185,7 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int qmlRegisterType(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1 qmlRegisterCustomType(uri, versionMajor, versionMinor,"Connections", new QQmlConnectionsParser); qmlRegisterType(); + qmlRegisterType(uri, versionMajor, (versionMinor < 8 ? 8 : versionMinor), "LoggingCategory"); //Only available in >=2.8 } diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp new file mode 100644 index 0000000000..88cf14cba0 --- /dev/null +++ b/src/qml/qml/qqmlloggingcategory.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlloggingcategory_p.h" + +#include + +/*! + \qmltype LoggingCategory + \ingroup qml-utility-elements + \inqmlmodule QtQml + \brief Defines a logging category in QML + \since 5.8 + + A logging category can be passed to console.log() and friends as the first argument. + If supplied to to the logger the LoggingCategory's name will be used as Logging Category + otherwise the default logging category will be used. + + \qml + import QtQuick 2.8 + + Item { + LoggingCategory { + id: category + name: "com.qt.category" + } + + Component.onCompleted: { + console.log(category, "message"); + } + } + \endqml + + \note As the creation of objects is expensive, it is encouraged to put the needed + LoggingCategory definitions into a singleton and import this where needed. + + \sa QLoggingCategory +*/ + +/*! + \qmlproperty string QtQml::LoggingCategory::name + + Holds the name of the logging category. + + \note This property needs to be set when declaring the LoggingCategory + and cannot be changed later. + + \sa QLoggingCategory::name() +*/ + +QQmlLoggingCategory::QQmlLoggingCategory(QObject *parent) + : QObject(parent) + , m_initialized(false) +{ +} + +QQmlLoggingCategory::~QQmlLoggingCategory() +{ +} + +QString QQmlLoggingCategory::name() const +{ + return QString::fromUtf8(m_name); +} + +QLoggingCategory *QQmlLoggingCategory::category() const +{ + return m_category.data(); +} + +void QQmlLoggingCategory::classBegin() +{ +} + +void QQmlLoggingCategory::componentComplete() +{ + m_initialized = true; + if (m_name.isNull()) + qmlInfo(this) << QString(QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !")); +} + +void QQmlLoggingCategory::setName(const QString &name) +{ + if (m_initialized) { + qmlInfo(this) << QString(QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created")); + return; + } + + m_name = name.toUtf8(); + QScopedPointer category(new QLoggingCategory(m_name.constData())); + m_category.swap(category); +} diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h new file mode 100644 index 0000000000..2b7f2f5b53 --- /dev/null +++ b/src/qml/qml/qqmlloggingcategory_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLLOGGINGCATEGORY_P_H +#define QQMLLOGGINGCATEGORY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQmlLoggingCategory : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + + Q_PROPERTY(QString name READ name WRITE setName) + +public: + QQmlLoggingCategory(QObject *parent = 0); + virtual ~QQmlLoggingCategory(); + + QString name() const; + void setName(const QString &name); + + QLoggingCategory *category() const; + + void classBegin() override; + void componentComplete() override; + +private: + QByteArray m_name; + QScopedPointer m_category; + bool m_initialized; +}; + +QT_END_NAMESPACE + +#endif // QQMLLOGGINGCATEGORY_H diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 76a900c846..edc83b3bf1 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE using namespace QV4; @@ -1464,11 +1467,26 @@ static QString jsStack(QV4::ExecutionEngine *engine) { static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *ctx, bool printStack = false) { + QLoggingCategory *loggingCategory = 0; QString result; QV4::ExecutionEngine *v4 = ctx->d()->engine; - for (int i = 0; i < ctx->argc(); ++i) { - if (i != 0) + int start = 0; + if (ctx->argc() > 0) { + if (const QObjectWrapper* wrapper = ctx->args()[0].as()) { + if (QQmlLoggingCategory* category = qobject_cast(wrapper->object())) { + if (category->category()) + loggingCategory = category->category(); + else + V4THROW_ERROR("A QmlLoggingCatgory was provided without a valid name"); + start = 1; + } + } + } + + + for (int i = start; i < ctx->argc(); ++i) { + if (i != start) result.append(QLatin1Char(' ')); if (ctx->args()[i].as()) @@ -1485,7 +1503,8 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c static QLoggingCategory qmlLoggingCategory("qml"); static QLoggingCategory jsLoggingCategory("js"); - QLoggingCategory *loggingCategory = v4->qmlEngine() ? &qmlLoggingCategory : &jsLoggingCategory; + if (!loggingCategory) + loggingCategory = v4->qmlEngine() ? &qmlLoggingCategory : &jsLoggingCategory; QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); const QByteArray baFunction = frame.function.toUtf8(); diff --git a/tests/auto/qml/qqmlconsole/data/categorized_logging.qml b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml new file mode 100644 index 0000000000..d19b6ecc41 --- /dev/null +++ b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.8 + +Item { + id:root + + LoggingCategory { + id: testCategory + name: "qt.test" + } + + LoggingCategory { + id: emptyCategory + } + + Component.onCompleted: { + console.debug(testCategory, "console.debug"); + console.log(testCategory, "console.log"); + console.info(testCategory, "console.info"); + console.warn(testCategory, "console.warn"); + console.error(testCategory, "console.error"); + + testCategory.name = "qt.test2"; + + console.error(emptyCategory, "console.error"); + } +} diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp index f12656c5fe..f832143935 100644 --- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp +++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp @@ -40,6 +40,7 @@ public: private slots: void logging(); + void categorized_logging(); void tracing(); void profiling(); void testAssert(); @@ -87,6 +88,41 @@ void tst_qqmlconsole::logging() delete object; } +void tst_qqmlconsole::categorized_logging() +{ + QUrl testUrl = testFileUrl("categorized_logging.qml"); + QQmlTestMessageHandler messageHandler; + messageHandler.setIncludeCategoriesEnabled(true); + + QLoggingCategory testCategory("qt.test"); + testCategory.setEnabled(QtDebugMsg, true); + QVERIFY(testCategory.isDebugEnabled()); + QVERIFY(testCategory.isWarningEnabled()); + QVERIFY(testCategory.isCriticalEnabled()); + + QQmlComponent component(&engine, testUrl); + QObject *object = component.create(); + QVERIFY2(object != 0, component.errorString().toUtf8()); + + QVERIFY(messageHandler.messages().contains("qt.test: console.info")); + QVERIFY(messageHandler.messages().contains("qt.test: console.warn")); + QVERIFY(messageHandler.messages().contains("qt.test: console.error")); + + QString emptyCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(50).arg(5) + + "QML LoggingCategory: Declaring the name of the LoggingCategory is mandatory and cannot be changed later !"; + QVERIFY(messageHandler.messages().contains(emptyCategory)); + + QString changedCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) + + "QML LoggingCategory: The name of a LoggingCategory cannot be changed after the Item is created"; + QVERIFY(messageHandler.messages().contains(changedCategory)); + + QString useEmptyCategory = "default: " + QString::fromLatin1("%1:%2: ").arg(testUrl.toString()).arg(63) + + "Error: A QmlLoggingCatgory was provided without a valid name"; + QVERIFY(messageHandler.messages().contains(useEmptyCategory)); + + delete object; +} + void tst_qqmlconsole::tracing() { QUrl testUrl = testFileUrl("tracing.qml"); diff --git a/tests/auto/shared/util.cpp b/tests/auto/shared/util.cpp index 55041eeb4d..96beb51612 100644 --- a/tests/auto/shared/util.cpp +++ b/tests/auto/shared/util.cpp @@ -101,11 +101,15 @@ Q_GLOBAL_STATIC(QMutex, qQmlTestMessageHandlerMutex) QQmlTestMessageHandler *QQmlTestMessageHandler::m_instance = 0; -void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &, const QString &message) +void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message) { QMutexLocker locker(qQmlTestMessageHandlerMutex()); - if (QQmlTestMessageHandler::m_instance) - QQmlTestMessageHandler::m_instance->m_messages.push_back(message); + if (QQmlTestMessageHandler::m_instance) { + if (QQmlTestMessageHandler::m_instance->m_includeCategories) + QQmlTestMessageHandler::m_instance->m_messages.push_back(QString("%1: %2").arg(context.category, message)); + else + QQmlTestMessageHandler::m_instance->m_messages.push_back(message); + } } QQmlTestMessageHandler::QQmlTestMessageHandler() @@ -114,6 +118,7 @@ QQmlTestMessageHandler::QQmlTestMessageHandler() Q_ASSERT(!QQmlTestMessageHandler::m_instance); QQmlTestMessageHandler::m_instance = this; m_oldHandler = qInstallMessageHandler(messageHandler); + m_includeCategories = false; } QQmlTestMessageHandler::~QQmlTestMessageHandler() diff --git a/tests/auto/shared/util.h b/tests/auto/shared/util.h index 47a4aae231..33d7cbd1d0 100644 --- a/tests/auto/shared/util.h +++ b/tests/auto/shared/util.h @@ -87,12 +87,15 @@ public: void clear() { m_messages.clear(); } + void setIncludeCategoriesEnabled(bool enabled) { m_includeCategories = enabled; } + private: - static void messageHandler(QtMsgType, const QMessageLogContext &, const QString &message); + static void messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message); static QQmlTestMessageHandler *m_instance; QStringList m_messages; QtMessageHandler m_oldHandler; + bool m_includeCategories; }; #endif // QQMLTESTUTILS_H -- cgit v1.2.3 From 580f2872f09cf7ad83ec9ae5dca686683a3cac80 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 9 Aug 2016 15:14:55 +0200 Subject: TextInput: fix horizontal alignment when implicit resizing is disabled By default, TextInput updates its implicit width to match the content width. This implies that when TextInput does not have an explicit width set, there is no need to handle horizontal alignment. TextField wants to override the default implicit width, so it disables the "implicit resizing" feature of TextInput. In this scenario, the implicit width does not match the content width. Therefore the text layouting code should also treat the item as if it had an explicit width set to achieve the correct horizontal alignment. Task-number: QTBUG-55138 Change-Id: I8c04971a6aff44c6f1734df50153a9788849e98a Reviewed-by: Mitch Curtis --- src/quick/items/qquicktextinput.cpp | 2 +- .../quick/qquicktextinput/tst_qquicktextinput.cpp | 35 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 03c6b892c4..63e8505ffa 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2916,7 +2916,7 @@ void QQuickTextInputPrivate::updateLayout() if (inLayout) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect. } - qreal lineWidth = q->widthValid() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX; + qreal lineWidth = q->widthValid() || !isImplicitResizeEnabled() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX; qreal height = 0; qreal width = 0; do { diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 18ccd81633..ea88f9dadb 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -200,6 +200,8 @@ private slots: void implicitSize(); void implicitSizeBinding_data(); void implicitSizeBinding(); + void implicitResize_data(); + void implicitResize(); void negativeDimensions(); @@ -5967,6 +5969,39 @@ void tst_qquicktextinput::implicitSizeBinding() QCOMPARE(textObject->height(), textObject->implicitHeight()); } +void tst_qquicktextinput::implicitResize_data() +{ + QTest::addColumn("alignment"); + QTest::newRow("left") << int(Qt::AlignLeft); + QTest::newRow("center") << int(Qt::AlignHCenter); + QTest::newRow("right") << int(Qt::AlignRight); +} + +void tst_qquicktextinput::implicitResize() +{ + QFETCH(int, alignment); + + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0\nTextInput { }", QUrl::fromLocalFile("")); + + QScopedPointer textInput(qobject_cast(component.create())); + QVERIFY(!textInput.isNull()); + + QScopedPointer textField(qobject_cast(component.create())); + QVERIFY(!textField.isNull()); + QQuickTextInputPrivate::get(textField.data())->setImplicitResizeEnabled(false); + + textInput->setWidth(200); + textField->setImplicitWidth(200); + + textInput->setHAlign(QQuickTextInput::HAlignment(alignment)); + textField->setHAlign(QQuickTextInput::HAlignment(alignment)); + + textInput->setText("Qt"); + textField->setText("Qt"); + + QCOMPARE(textField->positionToRectangle(0), textInput->positionToRectangle(0)); +} void tst_qquicktextinput::negativeDimensions() { -- cgit v1.2.3 From fdd8bf7dbf91b8e8ce84c990a03767c0b8ba064a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 8 Jun 2016 10:02:29 +0200 Subject: QQmlObjectCreator: initialize _bindingTarget Coverity (CID 163180) noticed _bindingTarget wasn't initialized. Change-Id: Ia727d00a161e514c437a72084b6ef01a7ebf4abc Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlobjectcreator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0c13a7a017..c06e1827ac 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -114,6 +114,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) context = 0; _qobject = 0; _scopeObject = 0; + _bindingTarget = 0; _valueTypeProperty = 0; _compiledObject = 0; _compiledObjectIndex = -1; -- cgit v1.2.3 From b054a700576f61d9fbd196987f42fdea7a806db1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 8 Jun 2016 10:03:37 +0200 Subject: QQmlObjectCreator: prefer initializer syntax over assignment Greater uniformity; also opens the door to potential const-ing, should this ever be worht considering. Change-Id: I91b44472cb7d84f85b3033f14a763beeea837459 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlobjectcreator.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index c06e1827ac..8fa1f48d18 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -68,12 +68,12 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(new QQmlObjectCreatorSharedState) + , topLevelCreator(true) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); - sharedState = new QQmlObjectCreatorSharedState; - topLevelCreator = true; sharedState->componentAttached = 0; sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount); sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount); @@ -93,12 +93,11 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(inheritedSharedState) + , topLevelCreator(false) , activeVMEDataForRootContext(0) { init(parentContext); - - sharedState = inheritedSharedState; - topLevelCreator = false; } void QQmlObjectCreator::init(QQmlContextData *providedParentContext) -- cgit v1.2.3 From e0acbde6da2127d9fa75aa6c032682086295ce27 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 30 May 2016 11:15:01 +0200 Subject: Shader examples: initialize all members Coverity (CIDs 161677, 161674) caught us setting a bad example in our example code. Change-Id: I395f689586f9a6ad783328b9258096cbc9ccd692 Reviewed-by: Gunnar Sletta --- examples/quick/scenegraph/graph/linenode.cpp | 2 +- examples/quick/scenegraph/graph/noisynode.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/quick/scenegraph/graph/linenode.cpp b/examples/quick/scenegraph/graph/linenode.cpp index 473be7da17..992e2d44c9 100644 --- a/examples/quick/scenegraph/graph/linenode.cpp +++ b/examples/quick/scenegraph/graph/linenode.cpp @@ -56,7 +56,7 @@ class LineShader : public QSGSimpleMaterialShader QSG_DECLARE_SIMPLE_SHADER(LineShader, LineMaterial) public: - LineShader() { + LineShader() : id_color(-1), id_spread(-1), id_size(-1) { setShaderSourceFile(QOpenGLShader::Vertex, ":/scenegraph/graph/shaders/line.vsh"); setShaderSourceFile(QOpenGLShader::Fragment, ":/scenegraph/graph/shaders/line.fsh"); } diff --git a/examples/quick/scenegraph/graph/noisynode.cpp b/examples/quick/scenegraph/graph/noisynode.cpp index bc273cf632..834151599b 100644 --- a/examples/quick/scenegraph/graph/noisynode.cpp +++ b/examples/quick/scenegraph/graph/noisynode.cpp @@ -61,7 +61,7 @@ class NoisyShader : public QSGSimpleMaterialShader QSG_DECLARE_SIMPLE_SHADER(NoisyShader, NoisyMaterial) public: - NoisyShader() { + NoisyShader() : id_color(-1), id_texture(-1), id_textureSize(-1) { setShaderSourceFile(QOpenGLShader::Vertex, ":/scenegraph/graph/shaders/noisy.vsh"); setShaderSourceFile(QOpenGLShader::Fragment, ":/scenegraph/graph/shaders/noisy.fsh"); } -- cgit v1.2.3 From b4327851a4895b28b2c60ca51e77eca3ee0a1b4e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Aug 2016 08:02:37 +0200 Subject: Move the moth stack slot allocator into qmldevtools This way it's accessible to the QML compiler. Change-Id: I3918a796c698fc75e134b29a61eed2ec028bc851 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4isel_moth.cpp | 163 +------------------------------------- src/qml/compiler/qv4ssa_p.h | 163 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 162 deletions(-) diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index afb36c5f14..f87cbe3f1b 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -143,167 +143,6 @@ inline bool isBoolType(IR::Expr *e) return (e->type == IR::BoolType); } -/* - * stack slot allocation: - * - * foreach bb do - * foreach stmt do - * if the current statement is not a phi-node: - * purge ranges that end before the current statement - * check for life ranges to activate, and if they don't have a stackslot associated then allocate one - * renumber temps to stack - * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated - * if it's a jump: - * foreach phi node in the successor: - * allocate slots for each temp (both sources and targets) if they don't have one allocated already - * insert moves before the jump - */ -class AllocateStackSlots: protected ConvertTemps -{ - IR::LifeTimeIntervals::Ptr _intervals; - QVector _unhandled; - QVector _live; - QBitArray _slotIsInUse; - IR::Function *_function; - - int defPosition(IR::Stmt *s) const - { - return usePosition(s) + 1; - } - - int usePosition(IR::Stmt *s) const - { - return _intervals->positionForStatement(s); - } - -public: - AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) - : _intervals(intervals) - , _slotIsInUse(intervals->size(), false) - , _function(0) - { - _live.reserve(8); - _unhandled = _intervals->intervals(); - } - - void forFunction(IR::Function *function) - { - IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); - _function = function; - toStackSlots(function); - } - -protected: - virtual int allocateFreeSlot() - { - for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { - if (!_slotIsInUse[i]) { - if (_nextUnusedStackSlot <= i) { - Q_ASSERT(_nextUnusedStackSlot == i); - _nextUnusedStackSlot = i + 1; - } - _slotIsInUse[i] = true; - return i; - } - } - - Q_UNREACHABLE(); - return -1; - } - - virtual void process(IR::Stmt *s) - { -// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); - - if (IR::Phi *phi = s->asPhi()) { - visitPhi(phi); - } else { - // purge ranges no longer alive: - for (int i = 0; i < _live.size(); ) { - const IR::LifeTimeInterval *lti = _live.at(i); - if (lti->end() < usePosition(s)) { -// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; - _live.remove(i); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); - _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; - continue; - } else { - ++i; - } - } - - // active new ranges: - while (!_unhandled.isEmpty()) { - IR::LifeTimeInterval *lti = _unhandled.last(); - if (lti->start() > defPosition(s)) - break; // we're done - Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); - _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); -// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; - _live.append(lti); - _unhandled.removeLast(); - } - - s->accept(this); - } - - if (IR::Jump *jump = s->asJump()) { - IR::MoveMapping moves; - foreach (IR::Stmt *succStmt, jump->target->statements()) { - if (IR::Phi *phi = succStmt->asPhi()) { - forceActivation(*phi->targetTemp); - for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) { - IR::Expr *e = phi->d->incoming[i]; - if (IR::Temp *t = e->asTemp()) { - forceActivation(*t); - } - if (jump->target->in[i] == _currentBasicBlock) - moves.add(phi->d->incoming[i], phi->targetTemp); - } - } else { - break; - } - } - moves.order(); - QList newMoves = moves.insertMoves(_currentBasicBlock, _function, true); - foreach (IR::Move *move, newMoves) - move->accept(this); - } - } - - void forceActivation(const IR::Temp &t) - { - if (_stackSlotForTemp.contains(t.index)) - return; - - int i = _unhandled.size() - 1; - for (; i >= 0; --i) { - IR::LifeTimeInterval *lti = _unhandled[i]; - if (lti->temp() == t) { - _live.append(lti); - _unhandled.remove(i); - break; - } - } - Q_ASSERT(i >= 0); // check that we always found the entry - - _stackSlotForTemp[t.index] = allocateFreeSlot(); -// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; - } - - virtual void visitPhi(IR::Phi *phi) - { - Q_UNUSED(phi); -#if !defined(QT_NO_DEBUG) - Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); - foreach (IR::Expr *e, phi->d->incoming) { - if (IR::Temp *t = e->asTemp()) - Q_ASSERT(_stackSlotForTemp.contains(t->index)); - } -#endif // defined(QT_NO_DEBUG) - } -}; } // anonymous namespace InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) @@ -353,7 +192,7 @@ void InstructionSelection::run(int functionIndex) qEnvironmentVariableIsEmpty("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION"); if (doStackSlotAllocation) { - AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); + IR::AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); } else { opt.convertOutOfSSA(); ConvertTemps().toStackSlots(_function); diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index d06774e803..c5690a8581 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -46,6 +46,7 @@ // #include "qv4jsir_p.h" +#include "qv4isel_util_p.h" #include QT_BEGIN_NAMESPACE @@ -271,6 +272,168 @@ private: QList &swaps) const; }; +/* + * stack slot allocation: + * + * foreach bb do + * foreach stmt do + * if the current statement is not a phi-node: + * purge ranges that end before the current statement + * check for life ranges to activate, and if they don't have a stackslot associated then allocate one + * renumber temps to stack + * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated + * if it's a jump: + * foreach phi node in the successor: + * allocate slots for each temp (both sources and targets) if they don't have one allocated already + * insert moves before the jump + */ +class AllocateStackSlots: protected ConvertTemps +{ + IR::LifeTimeIntervals::Ptr _intervals; + QVector _unhandled; + QVector _live; + QBitArray _slotIsInUse; + IR::Function *_function; + + int defPosition(IR::Stmt *s) const + { + return usePosition(s) + 1; + } + + int usePosition(IR::Stmt *s) const + { + return _intervals->positionForStatement(s); + } + +public: + AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) + : _intervals(intervals) + , _slotIsInUse(intervals->size(), false) + , _function(0) + { + _live.reserve(8); + _unhandled = _intervals->intervals(); + } + + void forFunction(IR::Function *function) + { + IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); + _function = function; + toStackSlots(function); + } + +protected: + virtual int allocateFreeSlot() + { + for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { + if (!_slotIsInUse[i]) { + if (_nextUnusedStackSlot <= i) { + Q_ASSERT(_nextUnusedStackSlot == i); + _nextUnusedStackSlot = i + 1; + } + _slotIsInUse[i] = true; + return i; + } + } + + Q_UNREACHABLE(); + return -1; + } + + virtual void process(IR::Stmt *s) + { +// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); + + if (IR::Phi *phi = s->asPhi()) { + visitPhi(phi); + } else { + // purge ranges no longer alive: + for (int i = 0; i < _live.size(); ) { + const IR::LifeTimeInterval *lti = _live.at(i); + if (lti->end() < usePosition(s)) { +// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; + _live.remove(i); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); + _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; + continue; + } else { + ++i; + } + } + + // active new ranges: + while (!_unhandled.isEmpty()) { + IR::LifeTimeInterval *lti = _unhandled.last(); + if (lti->start() > defPosition(s)) + break; // we're done + Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); + _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); +// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; + _live.append(lti); + _unhandled.removeLast(); + } + + s->accept(this); + } + + if (IR::Jump *jump = s->asJump()) { + IR::MoveMapping moves; + foreach (IR::Stmt *succStmt, jump->target->statements()) { + if (IR::Phi *phi = succStmt->asPhi()) { + forceActivation(*phi->targetTemp); + for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) { + IR::Expr *e = phi->d->incoming[i]; + if (IR::Temp *t = e->asTemp()) { + forceActivation(*t); + } + if (jump->target->in[i] == _currentBasicBlock) + moves.add(phi->d->incoming[i], phi->targetTemp); + } + } else { + break; + } + } + moves.order(); + QList newMoves = moves.insertMoves(_currentBasicBlock, _function, true); + foreach (IR::Move *move, newMoves) + move->accept(this); + } + } + + void forceActivation(const IR::Temp &t) + { + if (_stackSlotForTemp.contains(t.index)) + return; + + int i = _unhandled.size() - 1; + for (; i >= 0; --i) { + IR::LifeTimeInterval *lti = _unhandled[i]; + if (lti->temp() == t) { + _live.append(lti); + _unhandled.remove(i); + break; + } + } + Q_ASSERT(i >= 0); // check that we always found the entry + + _stackSlotForTemp[t.index] = allocateFreeSlot(); +// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; + } + + virtual void visitPhi(IR::Phi *phi) + { + Q_UNUSED(phi); +#if !defined(QT_NO_DEBUG) + Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); + foreach (IR::Expr *e, phi->d->incoming) { + if (IR::Temp *t = e->asTemp()) + Q_ASSERT(_stackSlotForTemp.contains(t->index)); + } +#endif // defined(QT_NO_DEBUG) + } +}; + } // IR namespace } // QV4 namespace -- cgit v1.2.3 From 273e5b0bdc1239df77e2e5694fdd5ad068595be3 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 24 May 2016 12:21:39 +0300 Subject: PathView: fix item creation First call of QQuickPathView::refill() did not use currentIndex for item prepending and there was situation when items were not created, e.g.: PathView with current item in center and currentIndex was set so that item with index 0 was after current item and before path end. The result of this situation: items from path begin to current item were not created. The reason was that idx always equaled (modelCount-1) for item prepending. Now first filling uses currentIndex to calculate valid idx. Task-number: QTBUG-53464 Change-Id: I7e343b0712c9c5c5cd56b1d8e020cf8c0f6e6301 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 16 ++++- .../auto/quick/qquickpathview/data/qtbug53464.qml | 77 ++++++++++++++++++++++ .../quick/qquickpathview/tst_qquickpathview.cpp | 24 +++++++ 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 tests/auto/quick/qquickpathview/data/qtbug53464.qml diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 7e1fa95692..1dbdd10303 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1854,6 +1854,14 @@ void QQuickPathView::updatePolish() refill(); } +static inline int currentIndexRemainder(int currentIndex, int modelCount) Q_DECL_NOTHROW +{ + if (currentIndex < 0) + return modelCount + currentIndex % modelCount; + else + return currentIndex % modelCount; +} + void QQuickPathView::componentComplete() { Q_D(QQuickPathView); @@ -1865,7 +1873,7 @@ void QQuickPathView::componentComplete() if (d->model) { d->modelCount = d->model->count(); if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex - d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount); + d->offset = qmlMod(d->modelCount - currentIndexRemainder(d->currentIndex, d->modelCount), d->modelCount); } d->createHighlight(); @@ -1939,7 +1947,8 @@ void QQuickPathView::refill() qreal endPos; int startIdx = 0; qreal startPos = 0.0; - if (d->items.count()) { + const bool wasEmpty = d->items.isEmpty(); + if (!wasEmpty) { //Find the beginning and end, items may not be in sorted order endPos = -1.0; startPos = 2.0; @@ -1998,7 +2007,8 @@ void QQuickPathView::refill() } //Prepend - idx = startIdx - 1; + idx = (wasEmpty ? d->calcCurrentIndex() : startIdx) - 1; + if (idx < 0) idx = d->modelCount - 1; nextPos = d->positionOfIndex(idx); diff --git a/tests/auto/quick/qquickpathview/data/qtbug53464.qml b/tests/auto/quick/qquickpathview/data/qtbug53464.qml new file mode 100644 index 0000000000..d30d404e68 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug53464.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Netris +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 600 + height: 400 + PathView { + objectName: "pathView" + model: 10 + anchors.fill: parent + pathItemCount: 5 + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + currentIndex: 8 + + path: Path { + startX: 0 + startY: 50 + PathLine { + x: 600 + y: 50 + } + } + + delegate: Component { + Text { + width: 50 + height: 50 + text: index + objectName: "delegate" + index + font.pixelSize: 24 + color: PathView.isCurrentItem ? "green" : "black" + } + } + } +} + diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index fc5dd3bbca..2046391d02 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -141,6 +141,7 @@ private slots: void flickableDelegate(); void jsArrayChange(); void qtbug42716(); + void qtbug53464(); void addCustomAttribute(); }; @@ -2381,6 +2382,29 @@ void tst_QQuickPathView::qtbug42716() QVERIFY(!itemMiss); } +void tst_QQuickPathView::qtbug53464() +{ + QScopedPointer window(createView()); + + window->setSource(testFileUrl("qtbug53464.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickPathView *pathView = findItem(window->rootObject(), "pathView"); + QVERIFY(pathView != Q_NULLPTR); + const int currentIndex = pathView->currentIndex(); + QCOMPARE(currentIndex, 8); + + const int pathItemCount = pathView->pathItemCount(); + int totalCount = 0; + foreach (QQuickItem *item, pathView->childItems()) { + if (item->objectName().startsWith(QLatin1String("delegate"))) + ++totalCount; + } + QCOMPARE(pathItemCount, totalCount); +} + void tst_QQuickPathView::addCustomAttribute() { const QScopedPointer window(createView()); -- cgit v1.2.3 From 9010dd0e767c407f107aacfe6be145229e3ba793 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Fri, 12 Aug 2016 13:38:54 +0200 Subject: Fix test failure: wait between mouse events the proper way Apparently, QTest::mouseEvent() disregards the wall time for the time stamps for events, but synthesizes the timestamps instead. The proper way is to specify the waiting time in the delay argument. This will adjust both the timestamp and perform a qWait() before the event handler is called. Without this patch, the qWait(doubleClickInterval) was disregarded, which lead to that a doubleclick event was generated, and it failed with the following message: Actual (((window->rootObject()->property("doubleClicks").toInt()))): 2 Expected (1) : 1 tst_qquickmousearea.cpp(1105) : failure location Change-Id: Ieda3b670d3cda0bd522db2f9677dad5745c88a21 Reviewed-by: Shawn Rutledge --- .../quick/qquickmousearea/tst_qquickmousearea.cpp | 31 +++++++++------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 9cdfd21f9c..d51c228b7c 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -1032,17 +1032,17 @@ void tst_QQuickMouseArea::clickThrough() QVERIFY(QTest::qWaitForWindowExposed(window.data())); QVERIFY(window->rootObject() != 0); + // to avoid generating a double click. + const int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10; + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTRY_COMPARE(window->rootObject()->property("presses").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1); - // to avoid generating a double click. - int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10; - QTest::qWait(doubleClickInterval); - - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QCOMPARE(window->rootObject()->property("doubleClicks").toInt(), 0); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); @@ -1072,9 +1072,7 @@ void tst_QQuickMouseArea::clickThrough() QCOMPARE(window->rootObject()->property("presses").toInt(), 0); QCOMPARE(window->rootObject()->property("clicks").toInt(), 0); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1093,15 +1091,13 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("letThrough", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("presses").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1120,12 +1116,10 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("noPropagation", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1146,7 +1140,7 @@ void tst_QQuickMouseArea::clickThrough() QVERIFY(QTest::qWaitForWindowExposed(window.data())); QVERIFY(window->rootObject() != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("clicksEnabled").toInt(), 1); @@ -1154,8 +1148,7 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("disableLower", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("clicksEnabled").toInt(), 2); -- cgit v1.2.3 From 6f15de1d2da9c83d7fca1d5c8243c0d69a1390ee Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 26 May 2016 14:45:31 +0300 Subject: PathView: fix infinite construction/destruction loop ... when all (or almost all) items are in the cache. When all items are in cache, check lower bound is equal to upper_bound. In rare cases, especially when almost all items are in cache, the inserting code was used (not only appending and prepending). In this code there was not bound check before creation of item and there was such situation: 1. Create item by inserting code (without bound check) 2. At the next call of refill() remove this item by life cycle because this item does not meet the conditions. And go to step 1. In other words at the first call we create some item, at the second remove this item. And again. So we had infinite construction/destruction loop. To break it we should check position of new item before creation in inserting code too (like we do in appending and prepending code). Task-number: QTBUG-37815 Change-Id: I015cdeb67ca5fcd06c34b3145b49cbd3e38d4078 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 44 ++++++++----- .../auto/quick/qquickpathview/data/qtbug37815.qml | 77 ++++++++++++++++++++++ .../quick/qquickpathview/tst_qquickpathview.cpp | 26 ++++++++ 3 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 tests/auto/quick/qquickpathview/data/qtbug37815.qml diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 1dbdd10303..f858b18c84 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -289,6 +289,8 @@ qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const // account the circular space. bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower, qreal upper) const { + if (lower == upper) + return true; if (lower > upper) { if (position > upper && position > lower) position -= mappedRange; @@ -2047,27 +2049,33 @@ void QQuickPathView::refill() idx = startIdx; QQuickItem *lastItem = d->items[0]; while (idx != endIdx) { - //This gets the reference from the delegate model, and will not re-create - QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); - if (!item) { - waiting = true; - break; - } - if (!d->items.contains(item)) { //We found a hole - nextPos = d->positionOfIndex(idx); - qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count(); - if (d->currentIndex == idx) { - currentVisible = true; - d->currentItemOffset = nextPos; + nextPos = d->positionOfIndex(idx); + if (d->isInBound(nextPos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) { + //This gets the reference from the delegate model, and will not re-create + QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); + if (!item) { + waiting = true; + break; } - int lastListIdx = d->items.indexOf(lastItem); - d->items.insert(lastListIdx + 1, item); - d->updateItem(item, nextPos); - } else { - d->releaseItem(item); + + if (!d->items.contains(item)) { //We found a hole + qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos + << (d->currentIndex == idx ? "current" : "") + << "items count was" << d->items.count(); + if (d->currentIndex == idx) { + currentVisible = true; + d->currentItemOffset = nextPos; + } + int lastListIdx = d->items.indexOf(lastItem); + d->items.insert(lastListIdx + 1, item); + d->updateItem(item, nextPos); + } else { + d->releaseItem(item); + } + + lastItem = item; } - lastItem = item; ++idx; if (idx >= d->modelCount) idx = 0; diff --git a/tests/auto/quick/qquickpathview/data/qtbug37815.qml b/tests/auto/quick/qquickpathview/data/qtbug37815.qml new file mode 100644 index 0000000000..3fd4daca63 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug37815.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Netris +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 600 + height: 400 + PathView { + objectName: "pathView" + model: 10 + anchors.fill: parent + pathItemCount: 5 + cacheItemCount: 5 + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + + path: Path { + startX: 0 + startY: 50 + PathLine { + x: 600 + y: 50 + } + } + + delegate: Component { + Text { + width: 50 + height: 50 + text: index + objectName: "delegate" + index + font.pixelSize: 24 + color: PathView.isCurrentItem ? "green" : "black" + } + } + } +} + diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 2046391d02..493af97521 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -140,6 +140,7 @@ private slots: void nestedinFlickable(); void flickableDelegate(); void jsArrayChange(); + void qtbug37815(); void qtbug42716(); void qtbug53464(); void addCustomAttribute(); @@ -2334,6 +2335,31 @@ void tst_QQuickPathView::jsArrayChange() QCOMPARE(spy.count(), 1); } +void tst_QQuickPathView::qtbug37815() +{ + QScopedPointer window(createView()); + + window->setSource(testFileUrl("qtbug37815.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + // cache items will be created async. Let's wait... + QTest::qWait(1000); + + QQuickPathView *pathView = findItem(window->rootObject(), "pathView"); + QVERIFY(pathView != Q_NULLPTR); + + const int pathItemCount = pathView->pathItemCount(); + const int cacheItemCount = pathView->cacheItemCount(); + int totalCount = 0; + foreach (QQuickItem *item, pathView->childItems()) { + if (item->objectName().startsWith(QLatin1String("delegate"))) + ++totalCount; + } + QCOMPARE(pathItemCount + cacheItemCount, totalCount); +} + /* This bug was one where if you jump the list such that the sole missing item needed to be * added in the middle of the list, it would instead move an item somewhere else in the list * to the middle (messing it up very badly). -- cgit v1.2.3 From 16834ed8cb68b5aa5efecf5c670d971a59e2419c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 12 Aug 2016 16:46:20 +0200 Subject: autotests: remove qWait(1) in touch sequences After d04982dc84d66bec92b4b3767538676cf925ef17 in qtbase, QTest::touchEvent() and QTouchEventSequence::commit() slow down every sequence of touch events, so we don't need to do it in individual tests. Change-Id: Id8133b100797d4bd2d7282ee874dbb81ed2cab47 Reviewed-by: Liang Qi --- tests/auto/quick/qquickflickable/tst_qquickflickable.cpp | 1 - .../tst_qquickmultipointtoucharea.cpp | 8 -------- tests/auto/quick/touchmouse/tst_touchmouse.cpp | 13 ------------- 3 files changed, 22 deletions(-) diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 4a0b8a8bdf..96fe97f372 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -1461,7 +1461,6 @@ void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *tou for (int i = 1; i <= 8; ++i) { QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window); QQuickTouchUtils::flush(window); - QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements } QTest::touchEvent(window, touchDevice).release(0, to, window); QQuickTouchUtils::flush(window); diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 1b32e6c4ab..c3981c466f 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -596,22 +596,18 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); @@ -787,22 +783,18 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QCOMPARE(point11->pressed(), true); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); - QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index a2a23031e1..15d7ffd9d9 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -586,13 +586,10 @@ void tst_TouchMouse::buttonOnFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); - QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); @@ -674,13 +671,10 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); QVERIFY(flickable->isMovingVertically()); @@ -872,19 +866,15 @@ void tst_TouchMouse::pinchOnFlickable() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); - QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); QTest::touchEvent(window, device).release(0, p, window); @@ -1097,16 +1087,13 @@ void tst_TouchMouse::mouseOnFlickableOnPinch() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); - QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); - QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); QGuiApplication::processEvents(); p -= QPoint(10, 0); - QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); -- cgit v1.2.3 From c0f3c8ae5cee3ecda1ac8829336aa95cbe4d330e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 14 Aug 2016 12:20:45 +0200 Subject: Doc: mention when Flickable.AutoFlickIfNeeded was added Change-Id: Icf72c05c9573715771353bd03735f64eadd808f2 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 03b2a8128c..870a0268e1 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -886,7 +886,7 @@ QQuickFlickableVisibleArea *QQuickFlickable::visibleArea() \li Flickable.AutoFlickIfNeeded - allows flicking vertically if the \e contentHeight is greater than the \e height of the Flickable. Allows flicking horizontally if the \e contentWidth is greater than - to the \e width of the Flickable. + to the \e width of the Flickable. (since \c{QtQuick 2.7}) \li Flickable.HorizontalFlick - allows flicking horizontally. \li Flickable.VerticalFlick - allows flicking vertically. \li Flickable.HorizontalAndVerticalFlick - allows flicking in both directions. -- cgit v1.2.3 From 2e277da4d17cbb4da04d34b260ee157aedf60f3f Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 12 Aug 2016 10:57:39 +0200 Subject: Doc: Change instances of 'OS X' to 'macOS' As of version 10.12 (Sierra), the name of Apple's desktop operating system will be macOS. Change all occurrences where the Mac platform is discussed to use the macro \macos (defined in the documentation configuration in qtbase). Change-Id: Iea114ac73c01d74401bcd77373b41a825d2636c9 Reviewed-by: Leena Miettinen Reviewed-by: Jake Petroules --- src/imports/settings/qqmlsettings.cpp | 2 +- src/qml/doc/src/cppintegration/extending-tutorial.qdoc | 2 +- src/qml/qml/qqmlengine.cpp | 2 +- src/qml/qml/qqmlimport.cpp | 2 +- src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc | 2 +- src/quick/items/qquickevents.cpp | 2 +- src/quick/items/qquickpincharea.cpp | 2 +- src/quick/items/qquicktextinput.cpp | 2 +- src/quick/util/qquickshortcut.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp index 954161b60b..8db998fefb 100644 --- a/src/imports/settings/qqmlsettings.cpp +++ b/src/imports/settings/qqmlsettings.cpp @@ -208,7 +208,7 @@ QT_BEGIN_NAMESPACE instance, even if they are referring to the same setting in the same category. The information is stored in the system registry on Windows, and in XML - preferences files on OS X. On other Unix systems, in the absence of a + preferences files on \macos. On other Unix systems, in the absence of a standard, INI text files are used. See \l QSettings documentation for more details. diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index c0cfc3e1aa..58cc650e01 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -389,7 +389,7 @@ directory. When building this example on Windows or Linux, the \c Charts directory will be located at the same level as the application that uses our new import module. This way, the QML engine will find our module as the default search path for QML -imports includes the directory of the application executable. On OS X, the +imports includes the directory of the application executable. On \macos, the plugin binary is copied to \c Contents/PlugIns in the the application bundle; this path is set in \l {tutorials/extending-qml/chapter6-plugins/app.pro} {chapter6-plugins/app.pro}: diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9a06f6b055..8f22533472 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -398,7 +398,7 @@ The following functions are also on the Qt object. \li \c "blackberry" - BlackBerry OS \li \c "ios" - iOS \li \c "linux" - Linux - \li \c "osx" - OS X + \li \c "osx" - \macos \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows \li \c "wince" - Windows CE diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index c4e0c7b778..dfdf2edbe0 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1658,7 +1658,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, \header \li Platform \li Valid suffixes \row \li Windows \li \c .dll \row \li Unix/Linux \li \c .so - \row \li OS X \li \c .dylib, \c .bundle, \c .so + \row \li \macos \li \c .dylib, \c .bundle, \c .so \endtable Version number on unix are ignored. diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index caedd72dc5..e5cd7e2424 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -263,7 +263,7 @@ animations, process events, etc. \endlist The threaded renderer is currently used by default on Windows with -opengl32.dll, Linux with non-Mesa based drivers, OS X, mobile +opengl32.dll, Linux with non-Mesa based drivers, \macos, mobile platforms, and Embedded Linux with EGLFS but this is subject to change. It is possible to force use of the threaded renderer by setting \c {QSG_RENDER_LOOP=threaded} in the environment. diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 88deefbd9a..23a99ba616 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -323,7 +323,7 @@ Item { \qmlproperty point QtQuick::WheelEvent::pixelDelta This property holds the delta in screen pixels and is available in platforms that - have high-resolution trackpads, such as OS X. + have high-resolution trackpads, such as \macos. The x and y cordinate of this property holds the delta in horizontal and vertical orientation. The value should be used directly to scroll content on screen. diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index f419d570f3..70b3ca6450 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -239,7 +239,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() \since 5.5 This signal is emitted when the pinch area detects the smart zoom gesture. - This gesture occurs only on certain operating systems such as OS X. + This gesture occurs only on certain operating systems such as \macos. The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture, including the location where the gesture occurred. \c pinch.scale diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index ffc94dfd46..f3b217dd7f 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -78,7 +78,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) and setting \l echoMode to an appropriate value enables TextInput to be used for a password input field. - On OS X, the Up/Down key bindings for Home/End are explicitly disabled. + On \macos, the Up/Down key bindings for Home/End are explicitly disabled. If you want such bindings (on any platform), you will need to construct them in QML. \sa TextEdit, Text diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index e6f66f7bf1..d47f2282b7 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -138,7 +138,7 @@ void QQuickShortcut::setSequence(const QVariant &sequence) \since 5.6 This property provides the shortcut's key sequence as a platform specific - string. This means that it will be shown translated, and on OS X it will + string. This means that it will be shown translated, and on \macos it will resemble a key sequence from the menu bar. It is best to display this text to the user (for example, on a tooltip). -- cgit v1.2.3 From b1eeb7cdde17f70e8e9ad3c610d6492f3ca70717 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jun 2016 10:12:39 +0200 Subject: Update .gitignore Added the target wrappers shell scripts generated by commit 282f15feaae4c525602d537ab65cb61987eb5f7f from qtbase to the list of ignored files. Similarly the config.log is also not desirable for version tracking. Change-Id: I5cf832ea706f2109d2935cc6a086ece0979cc588 Reviewed-by: Simon Hausmann --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index e949cddb22..504317b59e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,17 @@ config.tests/*/*/* !config.tests/*/*/*[.]* config.tests/*/*/*[.]app +config.log callgrind.out.* pcviewer.cfg *~ *.a *.la +*_wrapper.sh +*_wrapper.bat +wrapper.sh +wrapper.bat *.core *.moc *.o -- cgit v1.2.3 From b7c4d7a25f6327657258acae46bd55a7e62b9b4e Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 12 Aug 2016 14:13:29 +0200 Subject: Fix exponential signal emission growth Commit 9ab8b9e4 (QML: Do not register static QML dependencies on every call., 2016-04-05) introduced a new concept of separating guards into permanent and active containers. When a property is 'captured' it is added to one or other container. However, while one of the captureProperty overloads added the guards to the correct container, the other overload adds to the wrong container. Presumably this means that a binding can be invoked C+2^N times if the condition for invoking it changes N times. Task-number: QTBUG-55280 Change-Id: I51a31b3dd95825304ba208252289cc5abc744d21 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmljavascriptexpression.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 5d96240e5b..efa824dfae 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -235,7 +235,7 @@ void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration) g->connect(n); } - if (duration == OnlyOnce) + if (duration == Permanently) expression->permanentGuards.prepend(g); else expression->activeGuards.prepend(g); -- cgit v1.2.3 From 8b8492d3ffdcdba9e9decb6d9ae8b7939be6c7f2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 11 Aug 2016 15:37:21 +0200 Subject: Fix throwing an exception inside a finally block with a return in catch When exiting a catch block with a return statement, we'll unwind the exception handling manually and emit finally statements right before jumping to the exit block. If we throw an exception in the final block, we'll end up using the exception handler of the catch block that contains the return statement, which means we'll end up popping the exception scope one too many times, once through ScopeAndFinally::CatchScope in unwindException() and then when executing the exception handler block. The latter we should not be executing, instead we should jump straight to the exit block. Therefore any statements emitted as part of the manual exception unwinding (finally block here) need to be part of a new basic block with no exception handler. This bug became visible in debug builds where the Scope destructor compares the scope mark against the engine stack top to ensure correct cleanup order (which was wrong). However that in turn was hidden in debug builds again due to an accidental = instead of == in a Q_ASSERT. With the Q_ASSERT fixed this use-case is covered by ch12/12.14/S12.14_A13_T3 Change-Id: Id74a1b2bb3e063871b89cc05353b601dd60df08e Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 7 +++++++ src/qml/jsruntime/qv4runtime.cpp | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 6bf931c882..d29b11ac84 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2506,6 +2506,13 @@ bool Codegen::visit(ReturnStatement *ast) Result expr = expression(ast->expression); move(_block->TEMP(_returnAddress), *expr); } + + // Since we're leaving, don't let any finally statements we emit as part of the unwinding + // jump to exception handlers at run-time if they throw. + IR::BasicBlock *unwindBlock = _function->newBasicBlock(/*no exception handler*/Q_NULLPTR); + _block->JUMP(unwindBlock); + _block = unwindBlock; + unwindException(0); _block->JUMP(_exitBlock); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index d8ae7d4e92..0a05c50432 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1204,19 +1204,19 @@ ReturnedValue Runtime::unwindException(ExecutionEngine *engine) void Runtime::pushWithScope(const Value &o, ExecutionEngine *engine) { engine->pushContext(engine->currentContext->newWithContext(o.toObject(engine))); - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); } void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex) { ExecutionContext *c = engine->currentContext; engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0))); - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); } void Runtime::popScope(ExecutionEngine *engine) { - Q_ASSERT(engine->jsStackTop = engine->currentContext + 2); + Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); engine->popContext(); engine->jsStackTop -= 2; } -- cgit v1.2.3 From 12c7f225e6072264964bd3a0cbec834c5382031e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 16 Aug 2016 17:56:46 +0200 Subject: QV4Object: fix GCC 6.1 tautologial compare warning GCC warned: qtdeclarative/src/imports/localstorage/plugin.cpp:152:126: error: self-comparison always evaluates to true [-Werror=tautological-compare] Fix by comparing the types for equality instead of the addresses of their static_vtbls. Task-number: QTBUG-53373 Change-Id: Idd1598610ad6381c03c3a46abe56a332726bd6a0 Reviewed-by: Thiago Macieira Reviewed-by: Shawn Rutledge --- src/qml/jsruntime/qv4object_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 5c660f7e3f..4e39ccaf99 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -51,6 +51,8 @@ #include "qv4scopedvalue_p.h" #include "qv4value_p.h" +#include + QT_BEGIN_NAMESPACE @@ -125,7 +127,7 @@ struct ObjectVTable #define DEFINE_OBJECT_VTABLE(classname) \ const QV4::ObjectVTable classname::static_vtbl = \ { \ - DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.vTable), \ + DEFINE_MANAGED_VTABLE_INT(classname, (QT_PREPEND_NAMESPACE(QtPrivate)::is_same::value) ? Q_NULLPTR : &classname::SuperClass::static_vtbl.vTable), \ call, \ construct, \ get, \ -- cgit v1.2.3 From b03c85de2ab337858b44bf0a21692d7b544313a5 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Tue, 16 Aug 2016 13:10:51 +0200 Subject: Doc: Remove references to Windows CE The platform is not supported since Qt 5.7 Task-number: QTBUG-55331 Change-Id: I5a38940bd8ebf7dd62d04015e1738ee23ac65bb2 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 28f8bf4855..dd54760760 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -409,7 +409,6 @@ The following functions are also on the Qt object. \li \c "osx" - OS X \li \c "unix" - Other Unix-based OS \li \c "windows" - Windows - \li \c "wince" - Windows CE \li \c "winrt" - Windows Runtime \li \c "winphone" - Windows Phone \endlist -- cgit v1.2.3 From 6b8c845001a33bbcfbf20496bd933588cbe9d7ea Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 17 Aug 2016 15:01:55 +0200 Subject: Improve Direct3D documentation Mention the required value of the environment variable and fix typo. Change-Id: Ied5259b968988a434c2783acc22f0d2f3fb39ddf Reviewed-by: Laszlo Agocs --- src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc index bbc64f1484..9ce26e1bb8 100644 --- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc @@ -150,7 +150,7 @@ develpoment files are present. In practice this currently means Visual Studio The adaptation is available both in normal, OpenGL-enabled Qt builds and also when Qt was configured with \c{-no-opengl}. However, it is never the default, meaning the user or the application has to explicitly request it by setting the -\c{QT_QUICK_BACKEND} environment variable or by calling +\c{QT_QUICK_BACKEND} environment variable to \c{d3d12} or by calling QQuickWindow::setSceneGraphBackend(). \section2 Motivation @@ -165,7 +165,7 @@ vendor-supported solution. This means that there are fewer problems anticipated with drivers, operations like window resizes, and special events like graphics device loss caused by device resets or graphics driver updates. -Peformance-wise the general expectation is a somewhat lower CPU usage compared +Performance-wise the general expectation is a somewhat lower CPU usage compared to OpenGL due to lower driver overhead, and a higher GPU utilization with less wasted idle time. The backend does not heavily utilize threads yet, which means there are opportunities for further improvements in the future, for example to -- cgit v1.2.3 From d4e09df44d55572ef4f0c3c159b214edba9033cd Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Aug 2016 12:41:57 +0200 Subject: winrt: Make certification pass on D3D12 backend D3D12GetDebugInterface is not allowed to be used in a package to be uploaded to the store. However, keep it enabled for debug to still access information provided by it. Change-Id: Ie19167b4000b85d519d9726a66a42c6f1ef6ce4c Reviewed-by: Laszlo Agocs --- src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp index 87215d5b54..9aae3fd8cd 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp @@ -736,9 +736,13 @@ void QSGD3D12EnginePrivate::initialize(WId w, const QSize &size, float dpr, int const bool debugLayer = qEnvironmentVariableIntValue("QT_D3D_DEBUG") != 0; if (debugLayer) { qCDebug(QSG_LOG_INFO_GENERAL, "Enabling debug layer"); +#if !defined(Q_OS_WINRT) || !defined(NDEBUG) ComPtr debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) debugController->EnableDebugLayer(); +#else + qCDebug(QSG_LOG_INFO_GENERAL, "Using DebugInterface will not allow certification to pass"); +#endif } QSGD3D12DeviceManager *dev = deviceManager(); -- cgit v1.2.3 From 4840bc0c207aa09b4332842c67e65bc92f43d3bd Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:13:04 +0300 Subject: QQuickPathView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: I61f42076d36265b58dcc598394c6b3576b02dd60 Reviewed-by: Shawn Rutledge Reviewed-by: Venugopal Shivashankar --- src/quick/items/qquickpathview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index f858b18c84..07a33db231 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1459,7 +1459,7 @@ void QQuickPathView::positionViewAtIndex(int index, int mode) } /*! - \qmlmethod int QtQuick::PathView::indexAt(int x, int y) + \qmlmethod int QtQuick::PathView::indexAt(real x, real y) Returns the index of the item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, -1 is returned. @@ -1483,7 +1483,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const } /*! - \qmlmethod Item QtQuick::PathView::itemAt(int x, int y) + \qmlmethod Item QtQuick::PathView::itemAt(real x, real y) Returns the item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, null is returned. -- cgit v1.2.3 From f2ba71dd55736fc2ff1d817c19d5295d70b49c07 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 17:19:29 +0300 Subject: QQuickPathView: port some loops to 'range for' The 'range for' works with pointer increments and the generated code is less, so we save some text size. Change-Id: I66a2827c9a342d9453a52028d3ec76a91a19a606 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 0d047bc882..ef6a45b014 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -244,10 +244,9 @@ void QQuickPathViewPrivate::clear() releaseItem(currentItem); currentItem = 0; } - for (int i=0; i= 0) { if (model) model->cancel(requestedIndex); @@ -417,12 +416,9 @@ void QQuickPathViewPrivate::setHighlightPosition(qreal pos) void QQuickPathView::pathUpdated() { Q_D(QQuickPathView); - QList::iterator it = d->items.begin(); - while (it != d->items.end()) { - QQuickItem *item = *it; + for (QQuickItem *item : qAsConst(d->items)) { if (QQuickPathViewAttached *att = d->attached(item)) att->m_percent = -1; - ++it; } refill(); } @@ -1521,8 +1517,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const if (!d->isValid()) return -1; - for (int idx = 0; idx < d->items.count(); ++idx) { - QQuickItem *item = d->items.at(idx); + for (QQuickItem *item : d->items) { QPointF p = item->mapFromItem(this, QPointF(x, y)); if (item->contains(p)) return d->model->indexOf(item, 0); @@ -1545,8 +1540,7 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const if (!d->isValid()) return 0; - for (int idx = 0; idx < d->items.count(); ++idx) { - QQuickItem *item = d->items.at(idx); + for (QQuickItem *item : d->items) { QPointF p = item->mapFromItem(this, QPointF(x, y)); if (item->contains(p)) return item; -- cgit v1.2.3 From 286dbc48bd345d75f61fc3d64ce3d5495d602cb9 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 17 Aug 2016 08:42:37 +0200 Subject: softwarerenderer example: fix ambiguous reference to QQuickItem GCC 6 says (with paths trimmed) In file included from customrenderitem.cpp:47:0: softwarerenderer.h:51:35: error: expected ')' before '*' token softwarerenderer.h:61:5: error: reference to 'QQuickItem' is ambiguous Change-Id: I70b328426ac48f5f6140d1ad4f015858979b99a5 Reviewed-by: Laszlo Agocs --- examples/quick/scenegraph/rendernode/softwarerenderer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.h b/examples/quick/scenegraph/rendernode/softwarerenderer.h index 5b2a475ed8..e91ca92d88 100644 --- a/examples/quick/scenegraph/rendernode/softwarerenderer.h +++ b/examples/quick/scenegraph/rendernode/softwarerenderer.h @@ -42,8 +42,7 @@ #define SOFTWARERENDERER_H #include - -class QQuickItem; +#include class SoftwareRenderNode : public QSGRenderNode { -- cgit v1.2.3 From 4354588f556953a357d23bd303a8d85296b44457 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 17:41:23 +0300 Subject: QQuickPathView: de-duplicate code of indexAt() Re-use itemAt() method. Change-Id: Ic3673fe4d9fd3f27abc90c9436e99e0da9821cdb Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index ef6a45b014..1533a14831 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1514,16 +1514,8 @@ void QQuickPathView::positionViewAtIndex(int index, int mode) int QQuickPathView::indexAt(qreal x, qreal y) const { Q_D(const QQuickPathView); - if (!d->isValid()) - return -1; - - for (QQuickItem *item : d->items) { - QPointF p = item->mapFromItem(this, QPointF(x, y)); - if (item->contains(p)) - return d->model->indexOf(item, 0); - } - - return -1; + QQuickItem *item = itemAt(x, y); + return item ? d->model->indexOf(item, 0) : -1; } /*! -- cgit v1.2.3 From b095e0a85b1caef592f01f9786c56ac301a42dcf Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 18:41:48 +0300 Subject: QQuickPathView: de-duplicate calls and cache results Change-Id: I4b49b912c068fd5c76a2c2c8580f616cb42e9bdb Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 1533a14831..c061c8159a 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1543,8 +1543,9 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const { - qreal samples = qMin(path->path().length()/5, qreal(500.0)); - qreal res = path->path().length()/samples; + const auto pathLength = path->path().length(); + qreal samples = qMin(pathLength / 5, qreal(500.0)); + qreal res = pathLength / samples; qreal mindist = 1e10; // big number QPointF nearPoint = path->pointAt(0); @@ -1741,12 +1742,13 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *) qreal velocity = calcVelocity(); qreal count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount); - qreal pixelVelocity = (path->path().length()/count) * velocity; + const auto averageItemLength = path->path().length() / count; + qreal pixelVelocity = averageItemLength * velocity; if (qAbs(pixelVelocity) > MinimumFlickVelocity) { if (qAbs(pixelVelocity) > maximumFlickVelocity || snapMode == QQuickPathView::SnapOneItem) { // limit velocity qreal maxVel = velocity < 0 ? -maximumFlickVelocity : maximumFlickVelocity; - velocity = maxVel / (path->path().length()/count); + velocity = maxVel / averageItemLength; } // Calculate the distance to be travelled qreal v2 = velocity*velocity; -- cgit v1.2.3 From e330198669f8897212912caee65ae8910ad77519 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:21:22 +0300 Subject: QQuickListView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: Ieb4ea8396876f237adedf5df8ab5aeec1055229f Reviewed-by: Shawn Rutledge --- src/quick/items/qquicklistview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index b324e00cac..9f126525d6 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3318,7 +3318,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex */ /*! - \qmlmethod int QtQuick::ListView::indexAt(int x, int y) + \qmlmethod int QtQuick::ListView::indexAt(real x, real y) Returns the index of the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is @@ -3331,7 +3331,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex */ /*! - \qmlmethod Item QtQuick::ListView::itemAt(int x, int y) + \qmlmethod Item QtQuick::ListView::itemAt(real x, real y) Returns the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is -- cgit v1.2.3 From 24e6df252dc6118541d064835cea6ee470985dae Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 17 Aug 2016 13:20:16 +0300 Subject: QQuickGridView: fix doc for itemAt() and indexAt() These methods have real arguments. Change-Id: I5362a407b8417b62bb27bb313dccce8611b5e316 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickgridview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 6e5710a97b..e78ad07548 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2586,7 +2586,7 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co */ /*! - \qmlmethod int QtQuick::GridView::indexAt(int x, int y) + \qmlmethod int QtQuick::GridView::indexAt(real x, real y) Returns the index of the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is @@ -2599,7 +2599,7 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co */ /*! - \qmlmethod Item QtQuick::GridView::itemAt(int x, int y) + \qmlmethod Item QtQuick::GridView::itemAt(real x, real y) Returns the visible item containing the point \a x, \a y in content coordinates. If there is no item at the point specified, or the item is -- cgit v1.2.3 From 7b2d2d773594bde1b67ef068edef7a6ef920cf9c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Aug 2016 18:27:44 +0300 Subject: QQuickPathView: optimize releasing of cache items Release all cache items, and then clean container. Avoid quadratic complexity. Change-Id: I61f3e43aa070c0be074c3804a83f2ff1de9a398d Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index c061c8159a..660ed9db16 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -2152,8 +2152,9 @@ void QQuickPathView::refill() if (QQuickPathViewAttached *att = d->attached(d->highlightItem)) att->setOnPath(currentVisible); } - while (d->itemCache.count()) - d->releaseItem(d->itemCache.takeLast()); + for (QQuickItem *item : qAsConst(d->itemCache)) + d->releaseItem(item); + d->itemCache.clear(); d->inRefill = false; if (currentChanged) @@ -2237,8 +2238,9 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) d->items.clear(); if (!d->modelCount) { - while (d->itemCache.count()) - d->releaseItem(d->itemCache.takeLast()); + for (QQuickItem * item : qAsConst(d->itemCache)) + d->releaseItem(item); + d->itemCache.clear(); d->offset = 0; changedOffset = true; d->tl.reset(d->moveOffset); -- cgit v1.2.3 From a61dafa2f5cb09c4357dad3f804a16398bd69e31 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 15 Aug 2016 14:33:55 +0300 Subject: qmlimportscanner: use QStringLiteral more judiciously Replace it with QL1S or with QL1C in QStringBuilder expressions Change-Id: I894c546d2d010a713cc476d60b7966e77df996af Reviewed-by: Shawn Rutledge --- tools/qmlimportscanner/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index 2371057878..e6c0aaae53 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -117,7 +117,7 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con // Read the qmldir file, extract a list of plugins by // parsing the "plugin" and "classname" lines. QVariantMap pluginsForModulePath(const QString &modulePath) { - QFile qmldirFile(modulePath + QStringLiteral("/qmldir")); + QFile qmldirFile(modulePath + QLatin1String("/qmldir")); if (!qmldirFile.exists()) return QVariantMap(); @@ -141,7 +141,7 @@ QVariantMap pluginsForModulePath(const QString &modulePath) { if (dep.length() != 3) std::cerr << "depends: expected 2 arguments: module identifier and version" << std::endl; else - dependencies << QString::fromUtf8(dep[1]) + QStringLiteral(" ") + QString::fromUtf8(dep[2]).simplified(); + dependencies << QString::fromUtf8(dep[1]) + QLatin1Char(' ') + QString::fromUtf8(dep[2]).simplified(); } } while (line.length() > 0); -- cgit v1.2.3 From 707b9be53cef30ea9b7029945ef70e3d769b4e78 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 8 Aug 2016 11:49:04 +0200 Subject: QML: Change storage types of QQmlPropertyRawData fields By getting rid of the unions, all "features" (like accessors and notify indices) can now be used for all properties or functions. Other fields are trimmed to the size as used in other parts of QML. Now the size of QQmlPropertyRawData is 24 bytes on 32bit platforms, and 32 bytes on 64bit platforms. Change-Id: Ie2f22eb60e6119c93e3d3ea32a2974a718d45e91 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlpropertycache_p.h | 96 ++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 8a1f3810aa..480f1dcf40 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -168,20 +168,45 @@ public: bool isCloned() const { return _flags.isCloned; } bool isConstructor() const { return _flags.isConstructor; } - bool hasOverride() const { return !(_flags.hasAccessors) && - overrideIndex() >= 0; } - bool hasRevision() const { return !(_flags.hasAccessors) && revision() != 0; } + bool hasOverride() const { return overrideIndex() >= 0; } + bool hasRevision() const { return revision() != 0; } bool isFullyResolved() const { return !_flags.notFullyResolved; } int propType() const { Q_ASSERT(isFullyResolved()); return _propType; } - void setPropType(int pt) { _propType = pt; } + void setPropType(int pt) + { + Q_ASSERT(pt >= 0); + Q_ASSERT(pt <= std::numeric_limits::max()); + _propType = quint16(pt); + } int notifyIndex() const { return _notifyIndex; } - void setNotifyIndex(int idx) { _notifyIndex = idx; } + void setNotifyIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _notifyIndex = qint16(idx); + } - QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; } - void setArguments(QQmlPropertyCacheMethodArguments *args) { _arguments = args; } + bool overrideIndexIsProperty() const { return _flags.overrideIndexIsProperty; } + void setOverrideIndexIsProperty(bool onoff) { _flags.overrideIndexIsProperty = onoff; } + + int overrideIndex() const { return _overrideIndex; } + void setOverrideIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _overrideIndex = qint16(idx); + } + + int coreIndex() const { return _coreIndex; } + void setCoreIndex(int idx) + { + Q_ASSERT(idx >= std::numeric_limits::min()); + Q_ASSERT(idx <= std::numeric_limits::max()); + _coreIndex = qint16(idx); + } int revision() const { return _revision; } void setRevision(int rev) @@ -191,6 +216,9 @@ public: _revision = qint16(rev); } + QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; } + void setArguments(QQmlPropertyCacheMethodArguments *args) { _arguments = args; } + int metaObjectOffset() const { return _metaObjectOffset; } void setMetaObjectOffset(int off) { @@ -199,51 +227,35 @@ public: _metaObjectOffset = qint16(off); } - bool overrideIndexIsProperty() const { return _flags.overrideIndexIsProperty; } - void setOverrideIndexIsProperty(bool onoff) { _flags.overrideIndexIsProperty = onoff; } - - int overrideIndex() const { return _overrideIndex; } - void setOverrideIndex(int idx) - { - Q_ASSERT(idx >= std::numeric_limits::min()); - Q_ASSERT(idx <= std::numeric_limits::max()); - _overrideIndex = idx; - } - QQmlAccessors *accessors() const { return _accessors; } void setAccessors(QQmlAccessors *acc) { _accessors = acc; } - int coreIndex() const { return _coreIndex; } - void setCoreIndex(int idx) { _coreIndex = idx; } - private: - int _propType; // When !NotFullyResolved - union { - // The notify index is in the range returned by QObjectPrivate::signalIndex(). - // This is different from QMetaMethod::methodIndex(). - int _notifyIndex; // When !IsFunction - QQmlPropertyCacheMethodArguments *_arguments; // When IsFunction && HasArguments - }; + Flags _flags; + qint16 _coreIndex; + quint16 _propType; - union { - struct { // When !HasAccessors - qint16 _revision; - qint16 _metaObjectOffset; + // The notify index is in the range returned by QObjectPrivate::signalIndex(). + // This is different from QMetaMethod::methodIndex(). + qint16 _notifyIndex; + qint16 _overrideIndex; - signed int _overrideIndex; // When !IsValueTypeVirtual - }; - struct { // When HasAccessors - QQmlAccessors *_accessors; - }; - }; + qint16 _revision; + qint16 _metaObjectOffset; - int _coreIndex; - Flags _flags; + QQmlPropertyCacheMethodArguments *_arguments; + QQmlAccessors *_accessors; friend class QQmlPropertyData; friend class QQmlPropertyCache; }; +#if QT_POINTER_SIZE == 4 +Q_STATIC_ASSERT(sizeof(QQmlPropertyRawData) == 24); +#else // QT_POINTER_SIZE == 8 +Q_STATIC_ASSERT(sizeof(QQmlPropertyRawData) == 32); +#endif + class QQmlPropertyData : public QQmlPropertyRawData { public: @@ -619,12 +631,14 @@ void QQmlPropertyRawData::Flags::copyPropertyTypeFlags(QQmlPropertyRawData::Flag QQmlPropertyData::QQmlPropertyData() { + setCoreIndex(-1); setPropType(0); setNotifyIndex(-1); setOverrideIndex(-1); setRevision(0); setMetaObjectOffset(-1); - setCoreIndex(-1); + setArguments(nullptr); + setAccessors(nullptr); } QQmlPropertyData::QQmlPropertyData(const QQmlPropertyRawData &d) -- cgit v1.2.3 From 31650bc49b64c8ee6e14094a4d869afe08c5c25d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Aug 2016 16:57:29 +0200 Subject: Minor binding code cleanup Remove the QQmlBinding *binding argument as it is always the this pointer. Change-Id: I76ccf64a1d37ce32089c81f60466dce79b9fa5bf Reviewed-by: Lars Knoll --- src/qml/qml/qqmlbinding.cpp | 11 ++++++----- src/qml/qml/qqmlbinding_p.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 8ed7641610..d944857fc1 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -191,7 +191,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) flags.setFlag(QQmlPropertyData::BypassInterceptor); QQmlBindingProfiler prof(ep->profiler, this, f); - doUpdate(this, watcher, flags, scope, f); + doUpdate(watcher, flags, scope, f); if (!watcher.wasDeleted()) setUpdatingFlag(false); @@ -205,14 +205,15 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) class QQmlBindingBinding: public QQmlBinding { protected: - void doUpdate(QQmlBinding *binding, const DeleteWatcher &, + void doUpdate(const DeleteWatcher &, QQmlPropertyData::WriteFlags flags, QV4::Scope &, const QV4::ScopedFunctionObject &) Q_DECL_OVERRIDE Q_DECL_FINAL { Q_ASSERT(!m_targetIndex.hasValueTypeIndex()); QQmlPropertyData *pd = nullptr; getPropertyData(&pd, nullptr); - pd->writeProperty(*m_target, &binding, flags); + QQmlBinding *thisPtr = this; + pd->writeProperty(*m_target, &thisPtr, flags); } }; @@ -221,7 +222,7 @@ protected: class QQmlNonbindingBinding: public QQmlBinding { protected: - void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, + void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) Q_DECL_OVERRIDE Q_DECL_FINAL { @@ -231,7 +232,7 @@ protected: bool isUndefined = false; QV4::ScopedCallData callData(scope); - binding->QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); + QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); bool error = false; if (!watcher.wasDeleted() && isAddedToObject() && !hasError()) diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 1801c3040c..6d42a8ea8a 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -102,7 +102,7 @@ public: void expressionChanged() Q_DECL_OVERRIDE; protected: - virtual void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, + virtual void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) = 0; -- cgit v1.2.3 From b35858d4b8371adb030bc17f4aa161ce60e5984e Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 9 Aug 2016 16:41:33 +0300 Subject: Quick: replace 'foreach' with 'range for' Change-Id: I3493b16a184fc811289db9e98eff37bb987113a3 Reviewed-by: Shawn Rutledge --- src/quick/accessible/qaccessiblequickitem.cpp | 4 ++-- .../designer/qquickdesignercustomobjectdata.cpp | 4 ++-- src/quick/designer/qquickdesignersupport.cpp | 7 ++++--- src/quick/designer/qquickdesignersupportitems.cpp | 14 ++++++++------ src/quick/items/qquickdroparea.cpp | 2 +- src/quick/items/qquickitem.cpp | 3 ++- src/quick/items/qquickitemview.cpp | 4 ++-- src/quick/items/qquickmultipointtoucharea.cpp | 20 ++++++++++---------- src/quick/items/qquickpathview.cpp | 13 ++++++++----- src/quick/items/qquickrepeater.cpp | 4 ++-- src/quick/items/qquickspriteengine.cpp | 19 ++++++++++--------- src/quick/items/qquickspriteengine_p.h | 2 +- src/quick/items/qquicktext.cpp | 11 ++++++----- src/quick/items/qquicktextdocument.cpp | 2 +- src/quick/items/qquicktextedit.cpp | 4 ++-- src/quick/items/qquickview.cpp | 12 ++++++------ src/quick/qtquick2.cpp | 2 +- src/quick/scenegraph/coreapi/qsgmaterial.cpp | 4 ++-- src/quick/util/qquickanimation.cpp | 2 +- src/quick/util/qquickanimatorcontroller.cpp | 20 ++++++++++---------- src/quick/util/qquickpath.cpp | 14 +++++++------- src/quick/util/qquickpixmapcache.cpp | 2 +- src/quick/util/qquickpropertychanges.cpp | 2 +- src/quick/util/qquickstate.cpp | 4 ++-- src/quick/util/qquicktransitionmanager.cpp | 10 +++++----- 25 files changed, 97 insertions(+), 88 deletions(-) diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index a56d098717..acea958e20 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -160,9 +160,9 @@ int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const static void unignoredChildren(QQuickItem *item, QList *items, bool paintOrder) { - QList childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems() + const QList childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems() : item->childItems(); - Q_FOREACH (QQuickItem *child, childItems) { + for (QQuickItem *child : childItems) { if (QQuickItemPrivate::get(child)->isAccessible) { items->append(child); } else { diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp index 3c8f4b281c..e37254d165 100644 --- a/src/quick/designer/qquickdesignercustomobjectdata.cpp +++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp @@ -145,10 +145,10 @@ void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QObject *obje void QQuickDesignerCustomObjectData::populateResetHashes() { - QQuickDesignerSupport::PropertyNameList propertyNameList = + const QQuickDesignerSupport::PropertyNameList propertyNameList = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object()); - Q_FOREACH (const QQuickDesignerSupport::PropertyName &propertyName, propertyNameList) { + for (const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) { QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object())); QQmlAbstractBinding::Ptr binding = QQmlAbstractBinding::Ptr(QQmlPropertyPrivate::binding(property)); diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index f063cd3a81..44be12bb78 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -236,7 +236,8 @@ bool QQuickDesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toIte bool QQuickDesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem) { - Q_FOREACH (QQuickItem *childItem, fromItem->childItems()) { + const auto childItems = fromItem->childItems(); + for (QQuickItem *childItem : childItems) { if (childItem) { if (isAnchoredTo(childItem, toItem)) return true; @@ -392,10 +393,10 @@ void QQuickDesignerSupport::emitComponentCompleteSignalForAttachedProperty(QQuic QList QQuickDesignerSupport::statesForItem(QQuickItem *item) { QList objectList; - QList stateList = QQuickItemPrivate::get(item)->_states()->states(); + const QList stateList = QQuickItemPrivate::get(item)->_states()->states(); objectList.reserve(stateList.size()); - Q_FOREACH (QQuickState* state, stateList) + for (QQuickState* state : stateList) objectList.append(state); return objectList; diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 544ca04754..2003b484ad 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -118,16 +118,16 @@ static void allSubObjects(QObject *object, QObjectList &objectList) } // search recursive in object children list - Q_FOREACH (QObject *childObject, object->children()) { + for (QObject *childObject : object->children()) { allSubObjects(childObject, objectList); } // search recursive in quick item childItems list QQuickItem *quickItem = qobject_cast(object); if (quickItem) { - Q_FOREACH (QQuickItem *childItem, quickItem->childItems()) { + const auto childItems = quickItem->childItems(); + for (QQuickItem *childItem : childItems) allSubObjects(childItem, objectList); - } } } @@ -135,7 +135,7 @@ void QQuickDesignerSupportItems::tweakObjects(QObject *object) { QObjectList objectList; allSubObjects(object, objectList); - Q_FOREACH (QObject* childObject, objectList) { + for (QObject* childObject : qAsConst(objectList)) { stopAnimation(childObject); if (fixResourcePathsForObjectCallBack) fixResourcePathsForObjectCallBack(childObject); @@ -254,7 +254,8 @@ QObject *QQuickDesignerSupportItems::createComponent(const QUrl &componentUrl, Q if (component.isError()) { qWarning() << "Error in:" << Q_FUNC_INFO << componentUrl; - Q_FOREACH (const QQmlError &error, component.errors()) + const auto errors = component.errors(); + for (const QQmlError &error : errors) qWarning() << error; } return object; @@ -282,7 +283,8 @@ void QQuickDesignerSupportItems::disableNativeTextRendering(QQuickItem *item) void QQuickDesignerSupportItems::disableTextCursor(QQuickItem *item) { - Q_FOREACH (QQuickItem *childItem, item->childItems()) + const auto childItems = item->childItems(); + for (QQuickItem *childItem : childItems) disableTextCursor(childItem); QQuickTextInput *textInput = qobject_cast(item); diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index 1701441240..8dcc13971e 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -235,7 +235,7 @@ bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const return true; QRegExp copy = keyRegExp; - foreach (const QString &key, keys) { + for (const QString &key : keys) { if (copy.exactMatch(key)) return true; } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 84f9b0f169..bb5ed60e68 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4106,7 +4106,8 @@ bool QQuickItem::childMouseEventFilter(QQuickItem *item, QEvent *event) */ void QQuickItem::windowDeactivateEvent() { - foreach (QQuickItem* item, childItems()) { + const auto children = childItems(); + for (QQuickItem* item : children) { item->windowDeactivateEvent(); } } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index d3f045f35c..fa874d631c 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -181,7 +181,7 @@ void QQuickItemViewChangeSet::applyChanges(const QQmlChangeSet &changeSet) int moveId = -1; int moveOffset = 0; - foreach (const QQmlChangeSet::Change &r, changeSet.removes()) { + for (const QQmlChangeSet::Change &r : changeSet.removes()) { itemCount -= r.count; if (moveId == -1 && newCurrentIndex >= r.index + r.count) { newCurrentIndex -= r.count; @@ -200,7 +200,7 @@ void QQuickItemViewChangeSet::applyChanges(const QQmlChangeSet &changeSet) currentChanged = true; } } - foreach (const QQmlChangeSet::Change &i, changeSet.inserts()) { + for (const QQmlChangeSet::Change &i : changeSet.inserts()) { if (moveId == -1) { if (itemCount && newCurrentIndex >= i.index) { newCurrentIndex += i.count; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index d31807de7f..d68cb8e3f6 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -362,7 +362,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent) QQuickMultiPointTouchArea::~QQuickMultiPointTouchArea() { clearTouchLists(); - foreach (QObject *obj, _touchPoints) { + for (QObject *obj : qAsConst(_touchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) delete dtp; @@ -524,7 +524,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) } int numTouchPoints = touchPoints.count(); //always remove released touches, and make sure we handle all releases before adds. - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { Qt::TouchPointState touchPointState = p.state(); int id = p.id(); if (touchPointState & Qt::TouchPointReleased) { @@ -539,7 +539,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) } } if (numTouchPoints >= _minimumTouchPoints && numTouchPoints <= _maximumTouchPoints) { - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { Qt::TouchPointState touchPointState = p.state(); int id = p.id(); if (touchPointState & Qt::TouchPointReleased) { @@ -565,7 +565,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) if (!_stealMouse /* !ignoring gesture*/) { bool offerGrab = false; const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); - foreach (const QTouchEvent::TouchPoint &p, touchPoints) { + for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) { if (p.state() == Qt::TouchPointReleased) continue; const QPointF ¤tPos = p.scenePos(); @@ -599,7 +599,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) void QQuickMultiPointTouchArea::clearTouchLists() { - foreach (QObject *obj, _releasedTouchPoints) { + for (QObject *obj : qAsConst(_releasedTouchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) { _touchPoints.remove(dtp->pointId()); @@ -616,7 +616,7 @@ void QQuickMultiPointTouchArea::clearTouchLists() void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) { QQuickTouchPoint *dtp = 0; - foreach (QQuickTouchPoint* tp, _touchPrototypes) { + for (QQuickTouchPoint* tp : qAsConst(_touchPrototypes)) { if (!tp->inUse()) { tp->setInUse(true); dtp = tp; @@ -636,7 +636,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p) void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) { QQuickTouchPoint *dtp = 0; - foreach (QQuickTouchPoint *tp, _touchPrototypes) + for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) if (!tp->inUse()) { tp->setInUse(true); dtp = tp; @@ -782,11 +782,11 @@ void QQuickMultiPointTouchArea::ungrab() ungrabTouchPoints(); if (_touchPoints.count()) { - foreach (QObject *obj, _touchPoints) + for (QObject *obj : qAsConst(_touchPoints)) static_cast(obj)->setPressed(false); emit canceled(_touchPoints.values()); clearTouchLists(); - foreach (QObject *obj, _touchPoints) { + for (QObject *obj : qAsConst(_touchPoints)) { QQuickTouchPoint *dtp = static_cast(obj); if (!dtp->isQmlDefined()) delete dtp; @@ -901,7 +901,7 @@ bool QQuickMultiPointTouchArea::shouldFilter(QEvent *event) case QEvent::TouchUpdate: case QEvent::TouchEnd: { QTouchEvent *te = static_cast(event); - foreach (const QTouchEvent::TouchPoint &point, te->touchPoints()) { + for (const QTouchEvent::TouchPoint &point : te->touchPoints()) { if (contains(mapFromScene(point.scenePos()))) { containsPoint = true; break; diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 660ed9db16..af895570a8 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -191,7 +191,8 @@ void QQuickPathView::initItem(int index, QObject *object) att->m_view = this; qreal percent = d->positionOfIndex(index); if (percent < 1.0 && d->path) { - foreach (const QString &attr, d->path->attributes()) + const auto attributes = d->path->attributes(); + for (const QString &attr : attributes) att->setValue(attr.toUtf8(), d->path->attributeAt(attr, percent)); item->setZ(d->requestedZ); } @@ -230,7 +231,8 @@ QQmlOpenMetaObjectType *QQuickPathViewPrivate::attachedType() // pre-create one metatype to share with all attached objects attType = new QQmlOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q)); if (path) { - foreach (const QString &attr, path->attributes()) + const auto attributes = path->attributes(); + for (const QString &attr : attributes) attType->createProperty(attr.toUtf8()); } } @@ -431,7 +433,8 @@ void QQuickPathViewPrivate::updateItem(QQuickItem *item, qreal percent) if (qFuzzyCompare(att->m_percent, percent)) return; att->m_percent = percent; - foreach (const QString &attr, path->attributes()) + const auto attributes = path->attributes(); + for (const QString &attr : attributes) att->setValue(attr.toUtf8(), path->attributeAt(attr, percent)); att->setOnPath(percent < 1.0); } @@ -2182,7 +2185,7 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) int moveOffset = 0; bool currentChanged = false; bool changedOffset = false; - foreach (const QQmlChangeSet::Change &r, changeSet.removes()) { + for (const QQmlChangeSet::Change &r : changeSet.removes()) { if (moveId == -1 && d->currentIndex >= r.index + r.count) { d->currentIndex -= r.count; currentChanged = true; @@ -2208,7 +2211,7 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) } d->modelCount -= r.count; } - foreach (const QQmlChangeSet::Change &i, changeSet.inserts()) { + for (const QQmlChangeSet::Change &i : changeSet.inserts()) { if (d->modelCount) { if (moveId == -1 && i.index <= d->currentIndex) { d->currentIndex += i.count; diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 198573fda5..4f46f41b0d 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -461,7 +461,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) int difference = 0; QHash > > moved; - foreach (const QQmlChangeSet::Change &remove, changeSet.removes()) { + for (const QQmlChangeSet::Change &remove : changeSet.removes()) { int index = qMin(remove.index, d->deletables.count()); int count = qMin(remove.index + remove.count, d->deletables.count()) - index; if (remove.isMove()) { @@ -483,7 +483,7 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) difference -= remove.count; } - foreach (const QQmlChangeSet::Change &insert, changeSet.inserts()) { + for (const QQmlChangeSet::Change &insert : changeSet.inserts()) { int index = qMin(insert.index, d->deletables.count()); if (insert.isMove()) { QVector > items = moved.value(insert.moveId); diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index db04a83afc..10e0d51709 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -110,10 +110,10 @@ QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent) { } -QQuickSpriteEngine::QQuickSpriteEngine(QList sprites, QObject *parent) +QQuickSpriteEngine::QQuickSpriteEngine(const QList &sprites, QObject *parent) : QQuickSpriteEngine(parent) { - foreach (QQuickSprite* sprite, sprites) + for (QQuickSprite* sprite : sprites) m_states << (QQuickStochasticState*)sprite; } @@ -329,7 +329,7 @@ QQuickPixmap::Status QQuickSpriteEngine::status()//Composed status of all Sprite return QQuickPixmap::Null; int null, loading, ready; null = loading = ready = 0; - foreach (QQuickSprite* s, m_sprites) { + for (QQuickSprite* s : qAsConst(m_sprites)) { switch (s->m_pix.status()) { // ### Maybe add an error message here, because this null shouldn't be reached but when it does, the image fails without an error message. case QQuickPixmap::Null : null++; break; @@ -358,7 +358,7 @@ void QQuickSpriteEngine::startAssemblingImage() QList removals; - foreach (QQuickStochasticState* s, m_states){ + for (QQuickStochasticState* s : qAsConst(m_states)) { QQuickSprite* sprite = qobject_cast(s); if (sprite) { m_sprites << sprite; @@ -367,7 +367,7 @@ void QQuickSpriteEngine::startAssemblingImage() qDebug() << "Error: Non-sprite in QQuickSpriteEngine"; } } - foreach (QQuickStochasticState* s, removals) + for (QQuickStochasticState* s : qAsConst(removals)) m_states.removeAll(s); m_startedImageAssembly = true; } @@ -376,7 +376,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) { QQuickPixmap::Status stat = status(); if (!m_errorsPrinted && stat == QQuickPixmap::Error) { - foreach (QQuickSprite* s, m_sprites) + for (QQuickSprite* s : qAsConst(m_sprites)) if (s->m_pix.isError()) qmlInfo(s) << s->m_pix.error(); m_errorsPrinted = true; @@ -390,7 +390,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) m_maxFrames = 0; m_imageStateCount = 0; - foreach (QQuickSprite* state, m_sprites){ + for (QQuickSprite* state : qAsConst(m_sprites)) { if (state->frames() > m_maxFrames) m_maxFrames = state->frames(); @@ -441,7 +441,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) image.fill(0); QPainter p(&image); int y = 0; - foreach (QQuickSprite* state, m_sprites){ + for (QQuickSprite* state : qAsConst(m_sprites)) { QImage img(state->m_pix.image()); int frameWidth = state->m_frameWidth; int frameHeight = state->m_frameHeight; @@ -665,7 +665,8 @@ uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a lis m_timeOffset = time; m_addAdvance = false; while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.constFirst().first){ - foreach (int idx, m_stateUpdates.constFirst().second) + const auto copy = m_stateUpdates.constFirst().second; + for (int idx : copy) advance(idx); m_stateUpdates.pop_front(); } diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h index 424fa18a54..485afc16e5 100644 --- a/src/quick/items/qquickspriteengine_p.h +++ b/src/quick/items/qquickspriteengine_p.h @@ -266,7 +266,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine Q_PROPERTY(QQmlListProperty sprites READ sprites) public: explicit QQuickSpriteEngine(QObject *parent = 0); - QQuickSpriteEngine(QList sprites, QObject *parent=0); + QQuickSpriteEngine(const QList &sprites, QObject *parent = 0); ~QQuickSpriteEngine(); QQmlListProperty sprites() { diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 9494a55c2d..14268b472e 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -322,7 +322,7 @@ void QQuickText::imageDownloadFinished() if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) { bool needToUpdateLayout = false; - foreach (QQuickStyledTextImgTag *img, d->extra->visibleImgTags) { + for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) { if (!img->size.isValid()) { img->size = img->pix->implicitSize(); needToUpdateLayout = true; @@ -1115,7 +1115,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal QList imagesInLine; if (extra.isAllocated()) { - foreach (QQuickStyledTextImgTag *image, extra->imgTags) { + for (QQuickStyledTextImgTag *image : qAsConst(extra->imgTags)) { if (image->position >= line.textStart() && image->position < line.textStart() + line.textLength()) { @@ -1152,7 +1152,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal } } - foreach (QQuickStyledTextImgTag *image, imagesInLine) { + for (QQuickStyledTextImgTag *image : qAsConst(imagesInLine)) { totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height()); const int leadX = line.cursorToX(image->position); const int trailX = line.cursorToX(image->position, QTextLine::Trailing); @@ -2342,7 +2342,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data node->addTextLayout(QPointF(dx, dy), d->elideLayout, color, d->style, styleColor, linkColor); if (d->extra.isAllocated()) { - foreach (QQuickStyledTextImgTag *img, d->extra->visibleImgTags) { + for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) { QQuickPixmap *pix = img->pix; if (pix && pix->isReady()) node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image()); @@ -2596,7 +2596,8 @@ QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mo QTextLine line = layout->lineAt(i); if (line.naturalTextRect().contains(mousePos)) { int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter); - foreach (const QTextLayout::FormatRange &formatRange, layout->formats()) { + const auto formats = layout->formats(); + for (const QTextLayout::FormatRange &formatRange : formats) { if (formatRange.format.isAnchor() && charPos >= formatRange.start && charPos < formatRange.start + formatRange.length) { diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp index 3eacfd61bc..1dc54eb107 100644 --- a/src/quick/items/qquicktextdocument.cpp +++ b/src/quick/items/qquicktextdocument.cpp @@ -219,7 +219,7 @@ QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap( void QQuickTextDocumentWithImageResources::clearResources() { - foreach (QQuickPixmap *pixmap, m_resources) + for (QQuickPixmap *pixmap : qAsConst(m_resources)) pixmap->clear(this); qDeleteAll(m_resources); m_resources.clear(); diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index d6d9d53a3b..c81544cbdb 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -2065,7 +2065,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Having nodes spanning across frame boundaries will break the current bookkeeping mechanism. We need to prevent that. QList frameBoundaries; frameBoundaries.reserve(frames.size()); - Q_FOREACH (QTextFrame *frame, frames) + for (QTextFrame *frame : qAsConst(frames)) frameBoundaries.append(frame->firstPosition()); std::sort(frameBoundaries.begin(), frameBoundaries.end()); @@ -2499,7 +2499,7 @@ void QQuickTextEdit::updateWholeDocument() { Q_D(QQuickTextEdit); if (!d->textNodeMap.isEmpty()) { - Q_FOREACH (TextNode* node, d->textNodeMap) + for (TextNode* node : qAsConst(d->textNodeMap)) node->setDirty(); } diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 8b74d26576..d79d8ba3cd 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -264,8 +264,8 @@ void QQuickView::setContent(const QUrl& url, QQmlComponent *component, QObject* d->component = component; if (d->component && d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } @@ -475,8 +475,8 @@ void QQuickView::continueExecute() disconnect(d->component, SIGNAL(statusChanged(QQmlComponent::Status)), this, SLOT(continueExecute())); if (d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } @@ -487,8 +487,8 @@ void QQuickView::continueExecute() QObject *obj = d->component->create(); if (d->component->isError()) { - QList errorList = d->component->errors(); - foreach (const QQmlError &error, errorList) { + const QList errorList = d->component->errors(); + for (const QQmlError &error : errorList) { QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning() << error; } diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp index c36adf56ec..9a50250ebb 100644 --- a/src/quick/qtquick2.cpp +++ b/src/quick/qtquick2.cpp @@ -133,7 +133,7 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, typedef QPointer QuickStatePointer; QObject *object = property.object(); QString propertyName = property.name(); - foreach (const QuickStatePointer& statePointer, m_allStates) { + for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) { if (QQuickState *state = statePointer.data()) { // here we assume that the revert list on itself defines the base state if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 42a4c4abd3..4bec7b19f4 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -67,9 +67,9 @@ void qsg_set_material_failure() #ifndef QT_NO_OPENGL const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const { - QStringList files = m_sourceFiles[type]; + const QStringList files = m_sourceFiles[type]; QSGShaderSourceBuilder builder; - Q_FOREACH (const QString &file, files) + for (const QString &file : files) builder.appendSourceFile(file); m_sources[type] = builder.source(); return m_sources[type].constData(); diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index d782f9309f..206b92eb81 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -2643,7 +2643,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA } if (!successfullyCreatedDefaultProperty) { - foreach (const QString &errorMessage, errorMessages) + for (const QString &errorMessage : qAsConst(errorMessages)) qmlInfo(this) << errorMessage; } } diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index eb902b2972..6d8167413e 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -69,14 +69,14 @@ QQuickAnimatorController::~QQuickAnimatorController() { // The proxy job might already have been deleted, in which case we // need to avoid calling functions on them. Then delete the job. - foreach (QAbstractAnimationJob *job, m_deleting) { + for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { m_starting.take(job); m_stopping.take(job); m_animatorRoots.take(job); delete job; } - foreach (QQuickAnimatorProxyJob *proxy, m_animatorRoots) + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_animatorRoots)) proxy->controllerWasDeleted(); for (auto it = m_animatorRoots.keyBegin(), end = m_animatorRoots.keyEnd(); it != end; ++it) delete *it; @@ -171,7 +171,7 @@ static void qquick_initialize_helper(QAbstractAnimationJob *job, QQuickAnimatorC void QQuickAnimatorController::beforeNodeSync() { - foreach (QAbstractAnimationJob *job, m_deleting) { + for (QAbstractAnimationJob *job : qAsConst(m_deleting)) { m_starting.take(job); m_stopping.take(job); m_animatorRoots.take(job); @@ -182,7 +182,7 @@ void QQuickAnimatorController::beforeNodeSync() if (m_starting.size()) m_window->update(); - foreach (QQuickAnimatorProxyJob *proxy, m_starting) { + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_starting)) { QAbstractAnimationJob *job = proxy->job(); job->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); qquick_initialize_helper(job, this, true); @@ -192,7 +192,7 @@ void QQuickAnimatorController::beforeNodeSync() } m_starting.clear(); - foreach (QQuickAnimatorProxyJob *proxy, m_stopping) { + for (QQuickAnimatorProxyJob *proxy : qAsConst(m_stopping)) { QAbstractAnimationJob *job = proxy->job(); job->stop(); } @@ -208,7 +208,7 @@ void QQuickAnimatorController::beforeNodeSync() m_nodesAreInvalid = false; } - foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { + for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { if (!job->target()) continue; else if (m_deletedSinceLastFrame.contains(job->target())) @@ -218,7 +218,7 @@ void QQuickAnimatorController::beforeNodeSync() xform->transformHelper()->sync(); } } - foreach (QQuickItem *wiped, m_deletedSinceLastFrame) { + for (QQuickItem *wiped : qAsConst(m_deletedSinceLastFrame)) { QQuickTransformAnimatorJob::Helper *helper = m_transforms.take(wiped); // Helper will now already have been reset in all animators referencing it. delete helper; @@ -229,7 +229,7 @@ void QQuickAnimatorController::beforeNodeSync() void QQuickAnimatorController::afterNodeSync() { - foreach (QQuickAnimatorJob *job, m_activeLeafAnimations) { + for (QQuickAnimatorJob *job : qAsConst(m_activeLeafAnimations)) { if (job->target()) job->afterNodeSync(); } @@ -249,10 +249,10 @@ void QQuickAnimatorController::stopProxyJobs() // to be outside the lock. It is also safe because deletion of // proxies happens on the GUI thread, where this code is also executing. lock(); - QSet jobs = m_proxiesToStop; + const QSet jobs = m_proxiesToStop; m_proxiesToStop.clear(); unlock(); - foreach (QQuickAnimatorProxyJob *p, jobs) + for (QQuickAnimatorProxyJob *p : jobs) p->stop(); } diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index dfed4c1885..25a4433a9b 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -358,7 +358,7 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en bool usesPercent = false; int index = 0; - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) { if (QQuickCurve *curve = qobject_cast(pathElement)) { QQuickPathData data; data.index = index; @@ -432,17 +432,17 @@ void QQuickPath::classBegin() void QQuickPath::disconnectPathElements() { - Q_D(QQuickPath); + Q_D(const QQuickPath); - foreach (QQuickPathElement *pathElement, d->_pathElements) + for (QQuickPathElement *pathElement : d->_pathElements) disconnect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); } void QQuickPath::connectPathElements() { - Q_D(QQuickPath); + Q_D(const QQuickPath); - foreach (QQuickPathElement *pathElement, d->_pathElements) + for (QQuickPathElement *pathElement : d->_pathElements) connect(pathElement, SIGNAL(changed()), this, SLOT(processPath())); } @@ -453,7 +453,7 @@ void QQuickPath::gatherAttributes() QSet attributes; // First gather up all the attributes - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) { if (QQuickCurve *curve = qobject_cast(pathElement)) d->_pathCurves.append(curve); else if (QQuickPathAttribute *attribute = qobject_cast(pathElement)) @@ -488,7 +488,7 @@ QStringList QQuickPath::attributes() const QSet attrs; // First gather up all the attributes - foreach (QQuickPathElement *pathElement, d->_pathElements) { + for (QQuickPathElement *pathElement : d->_pathElements) { if (QQuickPathAttribute *attribute = qobject_cast(pathElement)) attrs.insert(attribute->name()); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 49956de822..9722bf544b 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -448,7 +448,7 @@ QQuickPixmapReader::~QQuickPixmapReader() mutex.lock(); // manually cancel all outstanding jobs. - foreach (QQuickPixmapReply *reply, jobs) { + for (QQuickPixmapReply *reply : qAsConst(jobs)) { if (reply->data && reply->data->reply == reply) reply->data->reply = 0; delete reply; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 555533a44e..37a910876e 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -256,7 +256,7 @@ void QQuickPropertyChangesPrivate::decode() if (decoded) return; - foreach (const QV4::CompiledData::Binding *binding, bindings) + for (const QV4::CompiledData::Binding *binding : qAsConst(bindings)) decodeBinding(QString(), compilationUnit->data, binding); bindings.clear(); diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 947a5b6e4e..2d3934cce8 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -334,7 +334,7 @@ QQuickStatePrivate::generateActionList() const } } - foreach(QQuickStateOperation *op, operations) + for (QQuickStateOperation *op : operations) applyList << op->actions(); inState = false; @@ -676,7 +676,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) #ifndef QT_NO_DEBUG_STREAM // Output for debugging if (stateChangeDebug()) { - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) qWarning() << " QQuickStateAction event:" << action.event->type(); else diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 60f710549b..714e6d62b6 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -106,7 +106,7 @@ void QQuickTransitionManager::complete() void QQuickTransitionManagerPrivate::applyBindings() { - foreach(const QQuickStateAction &action, bindingsList) { + for (const QQuickStateAction &action : qAsConst(bindingsList)) { if (action.toBinding) { QQmlPropertyPrivate::setBinding(action.toBinding.data()); } else if (action.event) { @@ -133,7 +133,7 @@ void QQuickTransitionManager::transition(const QList &list, QQuickStateOperation::ActionList applyList = list; // Determine which actions are binding changes and disable any current bindings - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.toBinding) d->bindingsList << action; if (action.fromBinding) @@ -184,7 +184,7 @@ void QQuickTransitionManager::transition(const QList &list, } // Revert back to the original values - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) { if (action.event->isReversable()) { action.event->clearBindings(); @@ -239,7 +239,7 @@ void QQuickTransitionManager::transition(const QList &list, // be applied immediately. We skip applying bindings, as they are all // applied at the end in applyBindings() to avoid any nastiness mid // transition - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event && !action.event->changesBindings()) { if (action.event->isReversable() && action.reverseEvent) action.event->reverse(); @@ -251,7 +251,7 @@ void QQuickTransitionManager::transition(const QList &list, } #ifndef QT_NO_DEBUG_STREAM if (stateChangeDebug()) { - foreach(const QQuickStateAction &action, applyList) { + for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.event) qWarning() << " No transition for event:" << action.event->type(); else -- cgit v1.2.3 From 696e12d137fbe479f79a2b1132a7a5fb952e71d8 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 15 Aug 2016 12:10:18 +0300 Subject: qmlimportscanner: fix MSVC build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSVC does not like QStringLiteral in operator[]. And the follow-up patch, which replaces 'foreach' with 'range for' triggers this MSVC bug. So this prequel patch resolves 2 issues: 1. fix MSVC build - the main issue. 2. de-duplicate QStringLiteral data (.rodata) - as drive-by issue. Change-Id: Ic6607edf324e9330d2b8dccd34561abb90f79cf1 Reviewed-by: Shawn Rutledge Reviewed-by: Jan Arve Sæther --- tools/qmlimportscanner/main.cpp | 72 +++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index e6c0aaae53..4a77623d28 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -55,6 +55,14 @@ QT_USE_NAMESPACE QStringList g_qmlImportPaths; +static inline QString typeLiteral() { return QStringLiteral("type"); } +static inline QString versionLiteral() { return QStringLiteral("version"); } +static inline QString nameLiteral() { return QStringLiteral("name"); } +static inline QString pluginsLiteral() { return QStringLiteral("plugins"); } +static inline QString pathLiteral() { return QStringLiteral("path"); } +static inline QString classnamesLiteral() { return QStringLiteral("classnames"); } +static inline QString dependenciesLiteral() { return QStringLiteral("dependencies"); } + static void printUsage(const QString &appNameIn) { const std::wstring appName = appNameIn.toStdWString(); @@ -84,14 +92,14 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con // handle directory imports if (!importNode->fileName.isEmpty()) { QString name = importNode->fileName.toString(); - import[QStringLiteral("name")] = name; + import[nameLiteral()] = name; if (name.endsWith(QLatin1String(".js"))) { - import[QStringLiteral("type")] = QStringLiteral("javascript"); + import[typeLiteral()] = QStringLiteral("javascript"); } else { - import[QStringLiteral("type")] = QStringLiteral("directory"); + import[typeLiteral()] = QStringLiteral("directory"); } - import[QStringLiteral("path")] = QDir::cleanPath(path + QLatin1Char('/') + name); + import[pathLiteral()] = QDir::cleanPath(path + QLatin1Char('/') + name); } else { // Walk the id chain ("Foo" -> "Bar" -> etc) QString name; @@ -103,9 +111,9 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con } name.chop(1); // remove trailing "." if (!name.isEmpty()) - import[QStringLiteral("name")] = name; - import[QStringLiteral("type")] = QStringLiteral("module"); - import[QStringLiteral("version")] = code.mid(importNode->versionToken.offset, importNode->versionToken.length); + import[nameLiteral()] = name; + import[typeLiteral()] = QStringLiteral("module"); + import[versionLiteral()] = code.mid(importNode->versionToken.offset, importNode->versionToken.length); } imports.append(import); @@ -147,10 +155,10 @@ QVariantMap pluginsForModulePath(const QString &modulePath) { } while (line.length() > 0); QVariantMap pluginInfo; - pluginInfo[QStringLiteral("plugins")] = plugins.simplified(); - pluginInfo[QStringLiteral("classnames")] = classnames.simplified(); + pluginInfo[pluginsLiteral()] = plugins.simplified(); + pluginInfo[classnamesLiteral()] = classnames.simplified(); if (dependencies.length()) - pluginInfo[QStringLiteral("dependencies")] = dependencies; + pluginInfo[dependenciesLiteral()] = dependencies; return pluginInfo; } @@ -210,25 +218,25 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) for (int i = 0; i < importsCopy.length(); ++i) { QVariantMap import = qvariant_cast(importsCopy[i]); - if (import[QStringLiteral("type")] == QLatin1String("module")) { - QString path = resolveImportPath(import.value(QStringLiteral("name")).toString(), import.value(QStringLiteral("version")).toString()); + if (import[typeLiteral()] == QLatin1String("module")) { + QString path = resolveImportPath(import.value(nameLiteral()).toString(), import.value(versionLiteral()).toString()); if (!path.isEmpty()) - import[QStringLiteral("path")] = path; - QVariantMap plugininfo = pluginsForModulePath(import.value(QStringLiteral("path")).toString()); - QString plugins = plugininfo.value(QStringLiteral("plugins")).toString(); - QString classnames = plugininfo.value(QStringLiteral("classnames")).toString(); + import[pathLiteral()] = path; + QVariantMap plugininfo = pluginsForModulePath(import.value(pathLiteral()).toString()); + QString plugins = plugininfo.value(pluginsLiteral()).toString(); + QString classnames = plugininfo.value(classnamesLiteral()).toString(); if (!plugins.isEmpty()) - import[QStringLiteral("plugin")] = plugins; + import.insert(QStringLiteral("plugin"), plugins); if (!classnames.isEmpty()) - import[QStringLiteral("classname")] = classnames; - if (plugininfo.contains(QStringLiteral("dependencies"))) { - QStringList dependencies = plugininfo.value(QStringLiteral("dependencies")).toStringList(); + import.insert(QStringLiteral("classname"), classnames); + if (plugininfo.contains(dependenciesLiteral())) { + QStringList dependencies = plugininfo.value(dependenciesLiteral()).toStringList(); foreach (const QString &line, dependencies) { const auto dep = line.splitRef(QLatin1Char(' ')); QVariantMap depImport; - depImport[QStringLiteral("type")] = QStringLiteral("module"); - depImport[QStringLiteral("name")] = dep[0].toString(); - depImport[QStringLiteral("version")] = dep[1].toString(); + depImport[typeLiteral()] = QStringLiteral("module"); + depImport[nameLiteral()] = dep[0].toString(); + depImport[versionLiteral()] = dep[1].toString(); importsCopy.append(depImport); } } @@ -277,8 +285,8 @@ struct ImportCollector : public QQmlJS::Directives virtual void importFile(const QString &jsfile, const QString &module, int line, int column) { QVariantMap entry; - entry[QLatin1String("type")] = QStringLiteral("javascript"); - entry[QLatin1String("path")] = jsfile; + entry[typeLiteral()] = QStringLiteral("javascript"); + entry[pathLiteral()] = jsfile; imports << entry; Q_UNUSED(module); @@ -290,12 +298,12 @@ struct ImportCollector : public QQmlJS::Directives { QVariantMap entry; if (uri.contains(QLatin1Char('/'))) { - entry[QLatin1String("type")] = QStringLiteral("directory"); - entry[QLatin1String("name")] = uri; + entry[typeLiteral()] = QStringLiteral("directory"); + entry[nameLiteral()] = uri; } else { - entry[QLatin1String("type")] = QStringLiteral("module"); - entry[QLatin1String("name")] = uri; - entry[QLatin1String("version")] = version; + entry[typeLiteral()] = QStringLiteral("module"); + entry[nameLiteral()] = uri; + entry[versionLiteral()] = version; } imports << entry; @@ -424,8 +432,8 @@ QSet importModulePaths(QVariantList imports) { QSet ret; foreach (const QVariant &importVariant, imports) { QVariantMap import = qvariant_cast(importVariant); - QString path = import.value(QStringLiteral("path")).toString(); - QString type = import.value(QStringLiteral("type")).toString(); + QString path = import.value(pathLiteral()).toString(); + QString type = import.value(typeLiteral()).toString(); if (type == QLatin1String("module") && !path.isEmpty()) ret.insert(QDir(path).canonicalPath()); } -- cgit v1.2.3 From 2a4f543ca2b0f90262184fa97f9c386737ec6dd1 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 17 Aug 2016 14:58:40 +0200 Subject: QML: Do not register dependencies of deleted binding Because it can lead to a use-after-free. Change-Id: I6701b370c0ecee4967e5f749f673a6f9ee3d504c Reviewed-by: Simon Hausmann --- src/qml/qml/qqmljavascriptexpression.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 5938ebf5d7..cd2f120218 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -296,7 +296,7 @@ void QQmlPropertyCapture::registerQmlDependencies(QV4::ExecutionEngine *engine, if (!ep) return; QQmlPropertyCapture *capture = ep->propertyCapture; - if (!capture) + if (!capture || capture->watcher->wasDeleted()) return; QV4::Scope scope(engine); -- cgit v1.2.3 From 32a980a86257021247a742b2b8c0b4aafe6e9035 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 17 Aug 2016 11:02:28 +0200 Subject: Revert "localstorage: disable warning about tautological comparison" After 12c7f22, the comparison should now be done at compile time. This reverts commit a858ce0039cb63a6a0afdfabab80ad4adc98ce17. Task-number: QTBUG-53373 Change-Id: I79d2c8aaabba8a2676df6da64206fefc9cdef3b2 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/imports/localstorage/plugin.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index fbcb6ddea5..a043af6b46 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -149,12 +149,7 @@ public: using namespace QV4; -QT_WARNING_PUSH -#if (Q_CC_GNU >= 600) -QT_WARNING_DISABLE_GCC("-Wtautological-compare") -#endif DEFINE_OBJECT_VTABLE(QV4::QQmlSqlDatabaseWrapper); -QT_WARNING_POP -- cgit v1.2.3 From b5f9c1e6e7f3a6881874e4ec2f43cea68107a06b Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 8 Aug 2016 11:58:30 +0200 Subject: QML: Remove hasAccessors flag from QQmlPropertyRawData We can now always check if the pointer is null (no accessors) or not. Change-Id: Ie9abf2f8930ea1f75a6d637a47f7f9c4fbab1151 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlpropertycache.cpp | 1 - src/qml/qml/qqmlpropertycache_p.h | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 7cb1425725..5c53e342f3 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -678,7 +678,6 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, Q_ASSERT(accessorProperty == 0 || (old == 0 && data->revision() == 0)); if (accessorProperty) { - data->_flags.hasAccessors = true; data->setAccessors(accessorProperty->accessors); } else if (old) { data->markAsOverrideOf(old); diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 480f1dcf40..63a9c63d90 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -108,7 +108,6 @@ public: unsigned isFinal : 1; // Has FINAL flag unsigned isOverridden : 1; // Is overridden by a extension property unsigned isDirect : 1; // Exists on a C++ QMetaObject - unsigned hasAccessors : 1; // Has property accessors unsigned type : 4; // stores an entry of Types @@ -127,7 +126,7 @@ public: unsigned notFullyResolved : 1; // True if the type data is to be lazily resolved unsigned overrideIndexIsProperty: 1; - unsigned _padding : 9; // align to 32 bits + unsigned _padding : 10; // align to 32 bits inline Flags(); inline bool operator==(const Flags &other) const; @@ -147,7 +146,7 @@ public: bool isFinal() const { return _flags.isFinal; } bool isOverridden() const { return _flags.isOverridden; } bool isDirect() const { return _flags.isDirect; } - bool hasAccessors() const { return _flags.hasAccessors; } + bool hasAccessors() const { return accessors() != nullptr; } bool isFunction() const { return _flags.type == Flags::FunctionType; } bool isQObject() const { return _flags.type == Flags::QObjectDerivedType; } bool isEnum() const { return _flags.type == Flags::EnumType; } @@ -576,7 +575,6 @@ QQmlPropertyRawData::Flags::Flags() , isFinal(false) , isOverridden(false) , isDirect(false) - , hasAccessors(false) , type(OtherType) , isVMEFunction(false) , hasArguments(false) @@ -600,7 +598,6 @@ bool QQmlPropertyRawData::Flags::operator==(const QQmlPropertyRawData::Flags &ot isAlias == other.isAlias && isFinal == other.isFinal && isOverridden == other.isOverridden && - hasAccessors == other.hasAccessors && type == other.type && isVMEFunction == other.isVMEFunction && hasArguments == other.hasArguments && -- cgit v1.2.3 From 96bd2337a98c892b5def555163c491507dce7185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Wed, 21 Oct 2015 22:13:19 +0300 Subject: Flickable: Fixed rounding errors with contentX/Y contentX/Y are qreals, but they are rounded using qRound/qFloor/qCeil which will limit the values to 2^31 needlessly. This fix will use (std::)round, std::floor and std::ceil instead to allow bigger values for contentX and contentY. Change-Id: I35ad4bcfa3b8bbc21e90768d348d3002ca400081 Task-number: QTBUG-48018 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 35 ++++++++++++++++------ .../auto/quick/qquickflickable/data/contentXY.qml | 6 ++++ .../quick/qquickflickable/tst_qquickflickable.cpp | 21 +++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 tests/auto/quick/qquickflickable/data/contentXY.qml diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 31581c0f07..0333f6b9bd 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -55,6 +55,8 @@ #include #include "qplatformdefs.h" +#include + QT_BEGIN_NAMESPACE // FlickThreshold determines how far the "mouse" must have moved @@ -69,6 +71,21 @@ static const int RetainGrabVelocity = 100; static const int MovementEndingTimerInterval = 100; #endif +// Currently std::round can't be used on Android when using ndk g++, so +// use C version instead. We could just define two versions of Round, one +// for float and one for double, but then only one of them would be used +// and compiler would trigger a warning about unused function. +// +// See https://code.google.com/p/android/issues/detail?id=54418 +template +static T Round(T t) { + return round(t); +} +template<> +Q_DECL_UNUSED float Round(float f) { + return roundf(f); +} + static qreal EaseOvershoot(qreal t) { return qAtan(t); } @@ -351,7 +368,7 @@ bool QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExt qreal dist = v2 / (accel * 2.0); if (v > 0) dist = -dist; - qreal target = -qRound(-(data.move.value() - dist)); + qreal target = -Round(-(data.move.value() - dist)); dist = -target + data.move.value(); accel = v2 / (2.0f * qAbs(dist)); @@ -455,18 +472,18 @@ void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExt } else if (data.move.value() <= maxExtent) { resetTimeline(data); adjustContentPos(data, maxExtent); - } else if (-qRound(-data.move.value()) != data.move.value()) { + } else if (-Round(-data.move.value()) != data.move.value()) { // We could animate, but since it is less than 0.5 pixel it's probably not worthwhile. resetTimeline(data); qreal val = data.move.value(); - if (qAbs(-qRound(-val) - val) < 0.25) // round small differences - val = -qRound(-val); + if (std::abs(-Round(-val) - val) < 0.25) // round small differences + val = -Round(-val); else if (data.smoothVelocity.value() > 0) // continue direction of motion for larger - val = -qFloor(-val); + val = -std::floor(-val); else if (data.smoothVelocity.value() < 0) - val = -qCeil(-val); + val = -std::ceil(-val); else // otherwise round - val = -qRound(-val); + val = -Round(-val); timeline.set(data.move, val); } data.inOvershoot = false; @@ -1553,12 +1570,12 @@ void QQuickFlickablePrivate::replayDelayedPress() //XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned. void QQuickFlickablePrivate::setViewportX(qreal x) { - contentItem->setX(pixelAligned ? -qRound(-x) : x); + contentItem->setX(pixelAligned ? -Round(-x) : x); } void QQuickFlickablePrivate::setViewportY(qreal y) { - contentItem->setY(pixelAligned ? -qRound(-y) : y); + contentItem->setY(pixelAligned ? -Round(-y) : y); } void QQuickFlickable::timerEvent(QTimerEvent *event) diff --git a/tests/auto/quick/qquickflickable/data/contentXY.qml b/tests/auto/quick/qquickflickable/data/contentXY.qml new file mode 100644 index 0000000000..8215976949 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/contentXY.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Flickable { + width: 400; height: 400 + contentWidth: 1e11; contentHeight: 1e11 +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index e1678b9acd..a03e3b8170 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -91,6 +91,7 @@ private slots: void cleanup(); void contentSize(); void ratios_smallContent(); + void contentXYNotTruncatedToInt(); private: void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to); @@ -1841,6 +1842,26 @@ void tst_qquickflickable::ratios_smallContent() QCOMPARE(obj->property("widthRatioIs").toDouble(), 1.); } +// QTBUG-48018 +void tst_qquickflickable::contentXYNotTruncatedToInt() +{ + QScopedPointer window(new QQuickView); + window->setSource(testFileUrl("contentXY.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window.data()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickFlickable *flickable = qobject_cast(window->rootObject()); + QVERIFY(flickable); + + flickable->setContentX(1e10); + flick(window.data(), QPoint(200, 100), QPoint(100, 100), 50); + + // make sure we are not clipped at 2^31 + QVERIFY(flickable->contentX() > qreal(1e10)); +} QTEST_MAIN(tst_qquickflickable) -- cgit v1.2.3 From 4a9635b0bfdc6a189375bc48e68b00bd05e15c82 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Wed, 10 Aug 2016 15:49:43 +0200 Subject: Remove some double-meaning text from documentation Change-Id: I9b69dbe929947795bdfbff4e0e3a16a47fa94197 Reviewed-by: Simon Hausmann --- src/qml/doc/src/cppintegration/exposecppattributes.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc index c7e4930bfb..f5aea0b01a 100644 --- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -73,7 +73,7 @@ convert them as appropriately when used from QML. Additionally, C++ classes that are \l{Registering C++ types with the QML type system}{registered} with the QML type system can be can be used as data types, as can their enums if appropriately registered. See \l{qtqml-cppintegration-data.html}{Data Type -Conversion Between QML and C++} for details for further information. +Conversion Between QML and C++} for further information. Additionally, data ownership rules are taken into consideration when data is transferred from C++ to QML. See \l {Data Ownership} for more details. -- cgit v1.2.3 From 79cdb4bd45944cce9bb389bebf49917775898ca2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 18 Aug 2016 16:08:54 +0200 Subject: Remove unused delete watcher class Change-Id: I8ccb3ae9029d17dcb4d60239d225393b1da88993 Reviewed-by: Erik Verbruggen --- src/qml/qml/ftw/ftw.pri | 1 - src/qml/qml/ftw/qdeletewatcher_p.h | 111 ------------------------------------- src/qml/qml/qqmlexpression_p.h | 1 - 3 files changed, 113 deletions(-) delete mode 100644 src/qml/qml/ftw/qdeletewatcher_p.h diff --git a/src/qml/qml/ftw/ftw.pri b/src/qml/qml/ftw/ftw.pri index 2d4a82e2f4..bb2374d1fa 100644 --- a/src/qml/qml/ftw/ftw.pri +++ b/src/qml/qml/ftw/ftw.pri @@ -8,7 +8,6 @@ HEADERS += \ $$PWD/qqmlthread_p.h \ $$PWD/qfinitestack_p.h \ $$PWD/qrecursionwatcher_p.h \ - $$PWD/qdeletewatcher_p.h \ $$PWD/qrecyclepool_p.h \ $$PWD/qflagpointer_p.h \ $$PWD/qlazilyallocated_p.h \ diff --git a/src/qml/qml/ftw/qdeletewatcher_p.h b/src/qml/qml/ftw/qdeletewatcher_p.h deleted file mode 100644 index d4c0c6dfb2..0000000000 --- a/src/qml/qml/ftw/qdeletewatcher_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDELETEWATCHER_P_H -#define QDELETEWATCHER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QDeleteWatchable -{ -public: - inline QDeleteWatchable(); - inline ~QDeleteWatchable(); -private: - friend class QDeleteWatcher; - bool *_w; -}; - -class QDeleteWatcher { -public: - inline QDeleteWatcher(QDeleteWatchable *data); - inline ~QDeleteWatcher(); - inline bool wasDeleted() const; -private: - void *operator new(size_t); - bool *_w; - bool _s; - QDeleteWatchable *m_d; -}; - -QDeleteWatchable::QDeleteWatchable() -: _w(0) -{ -} - -QDeleteWatchable::~QDeleteWatchable() -{ - if (_w) *_w = true; -} - -QDeleteWatcher::QDeleteWatcher(QDeleteWatchable *data) -: _s(false), m_d(data) -{ - if (!m_d->_w) - m_d->_w = &_s; - _w = m_d->_w; -} - -QDeleteWatcher::~QDeleteWatcher() -{ - if (false == *_w && &_s == m_d->_w) - m_d->_w = 0; -} - -bool QDeleteWatcher::wasDeleted() const -{ - return *_w; -} - -QT_END_NAMESPACE - -#endif // QDELETEWATCHER_P_H diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 741c25e206..809a57b169 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -56,7 +56,6 @@ #include #include #include -#include #include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 863a76281cefd19d7e339a78a63c86dff0f9dcce Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 18 Aug 2016 13:42:40 -0700 Subject: Have proper OpenGL checks in QQuickFBO and image particles These use custom materials that can crash when running with the D3D12 backend. We prefer handling such situations gracefully, with the application surviving. Therefore check the backend in use, and skip creating a scenegraph node when the backend is not OpenGL. Task-number: QTBUG-55353 Change-Id: I0be326fd2eacb0be604a0f111fa916558376c75a Reviewed-by: Friedemann Kleint --- src/particles/qquickimageparticle.cpp | 10 ++++++++++ src/quick/items/qquickframebufferobject.cpp | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 07cbee1383..c68153aca8 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1469,8 +1470,17 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) update(); } +static inline bool isOpenGL(QSGRenderContext *rc) +{ + QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc); + return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL; +} + QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) { + if (!node && !isOpenGL(QQuickItemPrivate::get(this)->sceneGraphRenderContext())) + return 0; + if (m_pleaseReset){ if (node) delete node; diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index d8147a48a5..857cd44b15 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -260,6 +261,12 @@ public: int devicePixelRatio; }; +static inline bool isOpenGL(QSGRenderContext *rc) +{ + QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc); + return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL; +} + /*! * \internal */ @@ -278,6 +285,8 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode Q_D(QQuickFramebufferObject); if (!n) { + if (!isOpenGL(d->sceneGraphRenderContext())) + return 0; if (!d->node) d->node = new QSGFramebufferObjectNode; n = d->node; @@ -360,6 +369,8 @@ QSGTextureProvider *QQuickFramebufferObject::textureProvider() const qWarning("QQuickFramebufferObject::textureProvider: can only be queried on the rendering thread of an exposed window"); return 0; } + if (!isOpenGL(d->sceneGraphRenderContext())) + return 0; if (!d->node) d->node = new QSGFramebufferObjectNode; return d->node; -- cgit v1.2.3 From be846890f3b34343c139baa99e10d0f9a25fcea3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 Aug 2016 09:31:50 +0200 Subject: Adjust decarative after qtConfig changes in qtbase Most of the changes are optional, but cleanup our QT_CONFIG usage. Change-Id: I5253d53f72f6fb03c2cfedae1e17d94f424a6bbb Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- examples/quick/quick.pro | 2 +- examples/quick/scenegraph/scenegraph.pro | 2 +- src/imports/imports.pro | 6 ++---- src/qml/qml/ftw/ftw.pri | 2 +- src/quick/items/items.pri | 2 +- src/quick/quick.pro | 2 +- src/quick/scenegraph/scenegraph.pri | 10 ++++------ src/src.pro | 3 +-- tests/auto/auto.pro | 2 +- tests/auto/particles/particles.pro | 3 +-- tests/auto/qml/debugger/debugger.pro | 4 ++-- tests/auto/qml/qml.pro | 3 +-- tests/auto/qmldevtools/compile/compile.pro | 2 +- tests/auto/qmldevtools/qmldevtools.pro | 6 ++---- tests/auto/quick/quick.pro | 6 +++--- tests/benchmarks/benchmarks.pro | 4 ++-- tools/tools.pro | 2 +- 17 files changed, 26 insertions(+), 35 deletions(-) diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro index b164bf4f5b..445dfb0fab 100644 --- a/examples/quick/quick.pro +++ b/examples/quick/quick.pro @@ -27,7 +27,7 @@ SUBDIRS = quick-accessibility \ demos #OpenGL Support Required -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SUBDIRS += \ textureprovider \ rendercontrol diff --git a/examples/quick/scenegraph/scenegraph.pro b/examples/quick/scenegraph/scenegraph.pro index 1015d7be3d..e13e8198b0 100644 --- a/examples/quick/scenegraph/scenegraph.pro +++ b/examples/quick/scenegraph/scenegraph.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SUBDIRS += \ graph \ simplematerial \ diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 9e3cdf3f42..affc1db2c0 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -16,10 +16,8 @@ qtHaveModule(quick) { window \ testlib - contains(QT_CONFIG, opengl(es1|es2)?) { - SUBDIRS += \ - particles - } + qtConfig(opengl(es1|es2)?): \ + SUBDIRS += particles } qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel diff --git a/src/qml/qml/ftw/ftw.pri b/src/qml/qml/ftw/ftw.pri index bb2374d1fa..87d80d04bc 100644 --- a/src/qml/qml/ftw/ftw.pri +++ b/src/qml/qml/ftw/ftw.pri @@ -21,4 +21,4 @@ SOURCES += \ # mirrors logic in $$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri # clock_gettime() is implemented in librt on these systems -contains(QT_CONFIG, clock-gettime):linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt +qtConfig(clock-gettime):linux-*|hpux-*|solaris-*:LIBS_PRIVATE *= -lrt diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index beaf3540bc..d91705451e 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -147,7 +147,7 @@ SOURCES += \ $$PWD/qquickanimatedsprite.cpp # Items that depend on OpenGL Renderer -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SOURCES += \ $$PWD/qquickopenglinfo.cpp \ $$PWD/qquickopenglshadereffect.cpp \ diff --git a/src/quick/quick.pro b/src/quick/quick.pro index f74a554aa9..4909f7fce8 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -33,7 +33,7 @@ include(util/util.pri) include(scenegraph/scenegraph.pri) include(items/items.pri) include(designer/designer.pri) -contains(QT_CONFIG, accessibility) { +qtConfig(accessibility) { include(accessible/accessible.pri) } diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 4ef8b0f638..a659ca5e10 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -1,5 +1,3 @@ -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # DEFINES += QSG_SEPARATE_INDEX_BUFFER # DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG @@ -29,7 +27,7 @@ SOURCES += \ $$PWD/coreapi/qsgrendernode.cpp \ $$PWD/coreapi/qsgrendererinterface.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { HEADERS += \ $$PWD/coreapi/qsgbatchrenderer_p.h SOURCES += \ @@ -73,7 +71,7 @@ SOURCES += \ $$PWD/util/qsgimagenode.cpp \ $$PWD/util/qsgninepatchnode.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { HEADERS += \ $$PWD/util/qsgdepthstencilbuffer_p.h \ $$PWD/util/qsgshadersourcebuilder_p.h \ @@ -104,7 +102,7 @@ SOURCES += \ $$PWD/qsgbasicglyphnode.cpp \ $$PWD/qsgrenderloop.cpp -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { SOURCES += \ $$PWD/qsgdefaultglyphnode.cpp \ $$PWD/qsgdefaultglyphnode_p.cpp \ @@ -150,7 +148,7 @@ RESOURCES += \ $$PWD/scenegraph.qrc # OpenGL Shaders -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { OTHER_FILES += \ $$PWD/shaders/24bittextmask.frag \ $$PWD/shaders/8bittextmask.frag \ diff --git a/src/src.pro b/src/src.pro index fbc4feaec4..fc1cea67cd 100644 --- a/src/src.pro +++ b/src/src.pro @@ -5,9 +5,8 @@ SUBDIRS += \ quick \ qmltest -qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { +qtHaveModule(gui):qtConfig(opengl(es1|es2)?): \ SUBDIRS += particles -} qtHaveModule(gui): qtHaveModule(widgets): SUBDIRS += quickwidgets diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index b72a43d742..7b13cb2b6d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -8,7 +8,7 @@ SUBDIRS=\ installed_cmake \ toolsupport -qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { +qtHaveModule(gui):qtConfig(opengl(es1|es2)?) { SUBDIRS += particles qtHaveModule(widgets): SUBDIRS += quickwidgets diff --git a/tests/auto/particles/particles.pro b/tests/auto/particles/particles.pro index 265a1eabc7..6ee1290dbb 100644 --- a/tests/auto/particles/particles.pro +++ b/tests/auto/particles/particles.pro @@ -25,6 +25,5 @@ PRIVATETESTS += \ qquickturbulence \ qquickwander -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS -} diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro index ccb2d71c53..a50411e18b 100644 --- a/tests/auto/qml/debugger/debugger.pro +++ b/tests/auto/qml/debugger/debugger.pro @@ -20,6 +20,6 @@ PRIVATETESTS += \ SUBDIRS += $$PUBLICTESTS -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS -} + diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index a1daa7a0c4..fae1b6f58b 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -79,9 +79,8 @@ SUBDIRS += $$METATYPETESTS SUBDIRS += qmllint } -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS -} qtNomakeTools( \ qmlplugindump \ diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro index 54430eb668..832700698f 100644 --- a/tests/auto/qmldevtools/compile/compile.pro +++ b/tests/auto/qmldevtools/compile/compile.pro @@ -5,7 +5,7 @@ force_bootstrap { !build_pass: CONFIG += release } else { QT = core - !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release + !build_pass:qtConfig(debug_and_release): CONFIG += release } QT += qmldevtools-private macx:CONFIG -= app_bundle diff --git a/tests/auto/qmldevtools/qmldevtools.pro b/tests/auto/qmldevtools/qmldevtools.pro index a0ca1bff87..a9352d4df3 100644 --- a/tests/auto/qmldevtools/qmldevtools.pro +++ b/tests/auto/qmldevtools/qmldevtools.pro @@ -1,6 +1,4 @@ TEMPLATE = subdirs -contains(QT_CONFIG, private_tests) { - SUBDIRS += \ - compile -} +qtConfig(private_tests): \ + SUBDIRS += compile diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 70e5b8ef6a..c7ba4de86c 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -4,7 +4,7 @@ PUBLICTESTS += \ geometry \ qquickpixmapcache -contains(QT_CONFIG, opengl(es1|es2)?) { +qtConfig(opengl(es1|es2)?) { PUBLICTESTS += \ rendernode qtHaveModule(widgets): PUBLICTESTS += nodes @@ -88,9 +88,9 @@ QUICKTESTS = \ SUBDIRS += $$PUBLICTESTS -!contains(QT_CONFIG, accessibility):QUICKTESTS -= qquickaccessible +!qtConfig(accessibility):QUICKTESTS -= qquickaccessible -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += $$PRIVATETESTS SUBDIRS += $$QUICKTESTS } diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index bd071ecf5c..5e6bc65815 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs SUBDIRS = qml script -contains(QT_CONFIG, private_tests) { - contains(QT_CONFIG, opengl(es1|es2)?):SUBDIRS += particles +qtConfig(private_tests) { + qtConfig(opengl(es1|es2)?):SUBDIRS += particles } diff --git a/tools/tools.pro b/tools/tools.pro index 18bfe28a8a..5f72588a7e 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -23,7 +23,7 @@ qmlimportscanner.CONFIG = host_build qtHaveModule(widgets): SUBDIRS += qmleasing } qtHaveModule(qmltest): SUBDIRS += qmltestrunner - contains(QT_CONFIG, private_tests): SUBDIRS += qmljs + qtConfig(private_tests): SUBDIRS += qmljs } qml.depends = qmlimportscanner -- cgit v1.2.3 From 01a9c006b0cb3f9ec7c140d25e6bfa3ca6250a4c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 19 Aug 2016 10:01:30 +0200 Subject: TestCase::mouseDrag: set mouse move delay >= 1 ms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Infinite-speed drags do not work well with velocity-sensitive components like Flickable. As with change d04982dc on qtbase, adding a short delay helps to stabilize tests. To keep it flexible, we make QTest::defaultMouseDelay() available via the qtest_events.defaultMouseDelay property. So the delay can be increased by passing a larger delay value to mouseDrag, or by changing the QTEST_MOUSEEVENT_DELAY environment variable (as before). Task-number: QTBUG-55382 Change-Id: I8f8088758a206be104a439ee0d1832eeca574e8c Reviewed-by: Liang Qi Reviewed-by: Jan Arve Sæther --- src/imports/testlib/TestCase.qml | 9 +++++---- src/qmltest/quicktestevent.cpp | 13 +++++++++---- src/qmltest/quicktestevent_p.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index c736a1a93a..46a395308d 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -1047,6 +1047,7 @@ Item { modifiers = Qt.NoModifier if (delay == undefined) delay = -1 + var moveDelay = Math.max(1, delay === -1 ? qtest_events.defaultMouseDelay : delay) // Divide dx and dy to have intermediate mouseMove while dragging // Fractions of dx/dy need be superior to the dragThreshold @@ -1060,12 +1061,12 @@ Item { mousePress(item, x, y, button, modifiers, delay) //trigger dragging - mouseMove(item, x + util.dragThreshold + 1, y + util.dragThreshold + 1, delay, button) + mouseMove(item, x + util.dragThreshold + 1, y + util.dragThreshold + 1, moveDelay, button) if (ddx > 0 || ddy > 0) { - mouseMove(item, x + ddx, y + ddy, delay, button) - mouseMove(item, x + 2*ddx, y + 2*ddy, delay, button) + mouseMove(item, x + ddx, y + ddy, moveDelay, button) + mouseMove(item, x + 2*ddx, y + 2*ddy, moveDelay, button) } - mouseMove(item, x + dx, y + dy, delay, button) + mouseMove(item, x + dx, y + dy, moveDelay, button) mouseRelease(item, x + dx, y + dy, button, modifiers, delay) } diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp index cfa80c4f19..e71b4f8f54 100644 --- a/src/qmltest/quicktestevent.cpp +++ b/src/qmltest/quicktestevent.cpp @@ -39,6 +39,10 @@ QT_BEGIN_NAMESPACE +namespace QTest { + extern int Q_TESTLIB_EXPORT defaultMouseDelay(); +} + QuickTestEvent::QuickTestEvent(QObject *parent) : QObject(parent) { @@ -48,6 +52,11 @@ QuickTestEvent::~QuickTestEvent() { } +int QuickTestEvent::defaultMouseDelay() const +{ + return QTest::defaultMouseDelay(); +} + bool QuickTestEvent::keyPress(int key, int modifiers, int delay) { QWindow *window = activeWindow(); @@ -105,10 +114,6 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d return true; } -namespace QTest { - extern int Q_TESTLIB_EXPORT defaultMouseDelay(); -}; - namespace QtQuickTest { enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove, MouseDoubleClickSequence }; diff --git a/src/qmltest/quicktestevent_p.h b/src/qmltest/quicktestevent_p.h index 0cba644cba..0a08347db8 100644 --- a/src/qmltest/quicktestevent_p.h +++ b/src/qmltest/quicktestevent_p.h @@ -53,9 +53,11 @@ QT_BEGIN_NAMESPACE class Q_QUICK_TEST_EXPORT QuickTestEvent : public QObject { Q_OBJECT + Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL) public: QuickTestEvent(QObject *parent = 0); ~QuickTestEvent(); + int defaultMouseDelay() const; public Q_SLOTS: bool keyPress(int key, int modifiers, int delay); -- cgit v1.2.3 From b8f145547e5477cd67f464c2d834f60a84f4aad6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 19 Aug 2016 14:42:31 +0200 Subject: Fix race-condition crash on shut-down in QtWebEngine If a QQuickWidget is somehow deleted below a QApplication post-routine it may end up being deleted after QQuickRenderControlPrivate::cleanup(), which means its QSGContext is deleted. Change-Id: I396d236f997b7b68a96f8fdddd7d6c3fe31c10b0 Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/qsgcontext_p.h | 3 ++- src/quick/scenegraph/qsgdefaultrendercontext.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 43cf1c28ab..899278843e 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -139,7 +139,8 @@ public Q_SLOTS: void textureFactoryDestroyed(QObject *o); protected: - QSGContext *m_sg; + // Hold m_sg with QPointer in the rare case it gets deleted before us. + QPointer m_sg; QMutex m_mutex; QHash m_textures; diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 4fcc81fb18..6f10611ba3 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -70,6 +70,9 @@ QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context) */ void QSGDefaultRenderContext::initialize(void *context) { + if (!m_sg) + return; + QOpenGLContext *openglContext = static_cast(context); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); @@ -163,7 +166,8 @@ void QSGDefaultRenderContext::invalidate() m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); m_gl = 0; - m_sg->renderContextInvalidated(this); + if (m_sg) + m_sg->renderContextInvalidated(this); emit invalidated(); } -- cgit v1.2.3 From bf3b596066af733c04b5ed3ef2dc9ec753a41e79 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 17:21:33 +0300 Subject: QQuickItemView: use reverse iterators more Since qt5.6 we can use reverse iterators. Change-Id: Ibf78b937e793c868ecc40710ef74c25308cc39bf Reviewed-by: Shawn Rutledge --- src/quick/items/qquickitemview.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index fa874d631c..e017d6564a 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1622,12 +1622,10 @@ qreal QQuickItemViewPrivate::contentStartOffset() const int QQuickItemViewPrivate::findLastVisibleIndex(int defaultValue) const { - if (visibleItems.count()) { - int i = visibleItems.count() - 1; - while (i > 0 && visibleItems.at(i)->index == -1) - --i; - if (visibleItems.at(i)->index != -1) - return visibleItems.at(i)->index; + for (auto it = visibleItems.rbegin(), end = visibleItems.rend(); it != end; ++it) { + auto item = *it; + if (item->index != -1) + return item->index; } return defaultValue; } @@ -1658,9 +1656,10 @@ FxViewItem *QQuickItemViewPrivate::firstVisibleItem() const { int QQuickItemViewPrivate::findLastIndexInView() const { const qreal viewEndPos = isContentFlowReversed() ? -position() : position() + size(); - for (int i=visibleItems.count() - 1; i>=0; i--) { - if (visibleItems.at(i)->position() <= viewEndPos && visibleItems.at(i)->index != -1) - return visibleItems.at(i)->index; + for (auto it = visibleItems.rbegin(), end = visibleItems.rend(); it != end; ++it) { + auto item = *it; + if (item->index != -1 && item->position() <= viewEndPos) + return item->index; } return -1; } -- cgit v1.2.3 From 23527754d60780ac4830f1acd6a54d3487a2c362 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 1 Aug 2016 13:39:37 +0200 Subject: Fix crash in tst_qqmlextensionplugin on shutdown On shutdown the test will unload all the plugins it loaded. In the case of the QtQuick2 plugin we only loaded it but never called registerTypes, as the test merely sees if the plugin can be instantiated. Consequently the attempt at unregistering the value type providers will fail because it was previously never defined. Note: We can't just let the QQmlValueTypeProvider destructor take care of the deregistration, as we do not truly unload plugins anymore (thankfully). However the plugin object will be destroyed and along with it we should correctly de-register the things we registered earlier, otherwise when initializing the plugin again, we'll register handers multiple times. Change-Id: Id778890bcd3f1fab16eb312a01de7d423ea3aa22 Reviewed-by: Ulf Hermann --- src/imports/qtquick2/plugin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp index e56027c1bb..d16467a5bb 100644 --- a/src/imports/qtquick2/plugin.cpp +++ b/src/imports/qtquick2/plugin.cpp @@ -61,13 +61,17 @@ public: { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick")); Q_UNUSED(uri); + moduleDefined = true; QQmlQtQuick2Module::defineModule(); } ~QtQuick2Plugin() { - QQmlQtQuick2Module::undefineModule(); + if (moduleDefined) + QQmlQtQuick2Module::undefineModule(); } + + bool moduleDefined = false; }; //![class decl] -- cgit v1.2.3 From 25c2cfc143ffbee16acea55394c0d8752beb31ea Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 19 Aug 2016 00:42:59 -0700 Subject: Exclude tests that require features not present on UIKit platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0398bf60fa150e9e03822938a2a6bedf280d7750 Reviewed-by: Oswald Buddenhagen Reviewed-by: Tor Arne Vestbø --- tests/auto/auto.pro | 3 +++ tests/auto/qml/qml.pro | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 7b13cb2b6d..556f5ddc7a 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -14,6 +14,9 @@ qtHaveModule(gui):qtConfig(opengl(es1|es2)?) { } +# console applications not supported +uikit: SUBDIRS -= qmltest + qmldevtools.CONFIG = host_build installed_cmake.depends = cmake diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index fae1b6f58b..68a2eace19 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -8,7 +8,6 @@ PUBLICTESTS += \ qjsvalueiterator \ qjsonbinding \ qmlmin \ - qmlplugindump \ qqmlcomponent \ qqmlconsole \ qqmlengine \ @@ -74,9 +73,9 @@ qtHaveModule(widgets) { SUBDIRS += $$PUBLICTESTS \ qqmlextensionplugin SUBDIRS += $$METATYPETESTS -!winrt { # no QProcess on winrt +!uikit:!winrt { # no QProcess on uikit/winrt !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger - SUBDIRS += qmllint + SUBDIRS += qmllint qmlplugindump } qtConfig(private_tests): \ -- cgit v1.2.3 From 6ade9e9ed945fff4ff588be6fdd294912addcd2b Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 11:14:31 +0300 Subject: benchmarks: replace 'foreach' with 'range for' Change-Id: Ibdb6daf0e09e01186478602287e2a6a143e09951 Reviewed-by: Shawn Rutledge --- tests/benchmarks/particles/affectors/tst_affectors.cpp | 4 ++-- tests/benchmarks/particles/emission/tst_emission.cpp | 2 +- tests/benchmarks/qml/animation/tst_animation.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/benchmarks/particles/affectors/tst_affectors.cpp b/tests/benchmarks/particles/affectors/tst_affectors.cpp index 475b8d28ec..99d175564b 100644 --- a/tests/benchmarks/particles/affectors/tst_affectors.cpp +++ b/tests/benchmarks/particles/affectors/tst_affectors.cpp @@ -86,7 +86,7 @@ void tst_affectors::test_basic() int stillAlive = 0; QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible. - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -126,7 +126,7 @@ void tst_affectors::test_filtered() int stillAlive = 0; QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 1000, 10));//Small simulation variance is permissible. - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/benchmarks/particles/emission/tst_emission.cpp b/tests/benchmarks/particles/emission/tst_emission.cpp index b107120a28..fe08305f68 100644 --- a/tests/benchmarks/particles/emission/tst_emission.cpp +++ b/tests/benchmarks/particles/emission/tst_emission.cpp @@ -79,7 +79,7 @@ void tst_emission::test_basic() int stillAlive = 0; QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible. - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/benchmarks/qml/animation/tst_animation.cpp b/tests/benchmarks/qml/animation/tst_animation.cpp index 4f693f9fa8..59f5a57f5c 100644 --- a/tests/benchmarks/qml/animation/tst_animation.cpp +++ b/tests/benchmarks/qml/animation/tst_animation.cpp @@ -107,8 +107,8 @@ void tst_animation::animationelements_data() { QTest::addColumn("type"); - QSet types = QQmlMetaType::qmlTypeNames().toSet(); - foreach (const QString &type, types) { + const QSet types = QQmlMetaType::qmlTypeNames().toSet(); + for (const QString &type : types) { if (type.contains(QLatin1String("Animation"))) QTest::newRow(type.toLatin1()) << type; } -- cgit v1.2.3 From 19baf625b984b4fafa28c4fc9bb8e5f8f0390d71 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 15:45:00 +0300 Subject: Imports: replace 'foreach' with 'range for' Change-Id: I283ce40b52de2371550dab7a54cdce89c78cdc68 Reviewed-by: Shawn Rutledge --- src/imports/folderlistmodel/fileinfothread.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp index 5d911eec1e..0b62935f87 100644 --- a/src/imports/folderlistmodel/fileinfothread.cpp +++ b/src/imports/folderlistmodel/fileinfothread.cpp @@ -260,14 +260,13 @@ void FileInfoThread::getFileInfos(const QString &path) sortFlags = sortFlags | QDir::DirsFirst; QDir currentDir(path, QString(), sortFlags); - QFileInfoList fileInfoList; QList filePropertyList; - fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags); + const QFileInfoList fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags); if (!fileInfoList.isEmpty()) { filePropertyList.reserve(fileInfoList.count()); - foreach (const QFileInfo &info, fileInfoList) { + for (const QFileInfo &info : fileInfoList) { //qDebug() << "Adding file : " << info.fileName() << "to list "; filePropertyList << FileProperty(info); } -- cgit v1.2.3 From e923ac48a5bfdef206f6fdf0e194db976f2af8ee Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:28:16 +0300 Subject: Particles: fix incorrect usage of 'range for' with Qt containers Change-Id: Ibe750b068bc8d4c33272a65dafcc398239d7d591 Reviewed-by: Shawn Rutledge --- src/particles/qquickparticlepainter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp index d6303eb219..0c2521cd9e 100644 --- a/src/particles/qquickparticlepainter.cpp +++ b/src/particles/qquickparticlepainter.cpp @@ -103,7 +103,8 @@ void QQuickParticlePainter::recalculateGroupIds() const m_groupIdsNeedRecalculation = false; m_groupIds.clear(); - for (const QString &str : groups()) { + const auto groupList = groups(); + for (const QString &str : groupList) { QQuickParticleGroupData::ID groupId = m_system->groupIds.value(str, QQuickParticleGroupData::InvalidID); if (groupId == QQuickParticleGroupData::InvalidID) { // invalid data, not finished setting up, or whatever. Fallback: do not cache. -- cgit v1.2.3 From cd3380862b312a2d349bb72522f0751622448404 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:23:37 +0300 Subject: QQuickWidget: fix incorrect usage of 'range for' with Qt containers Change-Id: Ifd95a2076c6f5330820dc0eb4890636f83b93794 Reviewed-by: Shawn Rutledge --- src/quickwidgets/qquickwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index b8c5b900c9..c608697c94 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1603,7 +1603,8 @@ void QQuickWidget::paintEvent(QPaintEvent *event) painter.drawImage(rect(), d->softwareImage); } else { //Paint only the updated areas - for (auto targetRect : d->updateRegion.rects()) { + const auto rects = d->updateRegion.rects(); + for (auto targetRect : rects) { auto sourceRect = QRect(targetRect.topLeft() * devicePixelRatio(), targetRect.size() * devicePixelRatio()); painter.drawImage(targetRect, d->softwareImage, sourceRect); } -- cgit v1.2.3 From e9667491d82985f86ff98426b6948a65af94a611 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 13:03:15 +0300 Subject: Quick: fix incorrect usage of 'range for' with Qt containers Also port remaining foreach to 'range for'. Change-Id: I20296bb3bb6d63f144ebddaba02cabeb16b7d734 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickitem.cpp | 3 ++- src/quick/items/qquickwindow.cpp | 14 ++++++++------ .../adaptations/software/qsgabstractsoftwarerenderer.cpp | 4 +--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index bb5ed60e68..4c6b0b4167 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -98,7 +98,8 @@ void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1) << item->hasActiveFocus() << item->isFocusScope() << item; - for (QQuickItem *child : item->childItems()) { + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { debugFocusTree( child, item->isFocusScope() || !scope ? item : scope, diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index f958d1a087..a54d6daf9c 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -764,7 +764,8 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector ungrab; for (int i = 0; i < ids.count(); ++i) { // FIXME: deprecate this function, we need a device - for (auto device: QQuickPointerDevice::touchDevices()) { + const auto touchDevices = QQuickPointerDevice::touchDevices(); + for (auto device : touchDevices) { auto point = device->pointerEvent()->pointById(ids.at(i)); if (!point) continue; @@ -783,7 +784,7 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVectortouchUngrabEvent(); } @@ -791,7 +792,8 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to { Q_Q(QQuickWindow); if (Q_LIKELY(touch)) { - for (auto device: QQuickPointerDevice::touchDevices()) { + const auto touchDevices = QQuickPointerDevice::touchDevices(); + for (auto device : touchDevices) { auto pointerEvent = device->pointerEvent(); for (int i = 0; i < pointerEvent->pointCount(); ++i) { if (pointerEvent->point(i)->grabber() == grabber) { @@ -1477,7 +1479,7 @@ bool QQuickWindowPrivate::clearHover(ulong timestamp) QPointF pos = q->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()); bool accepted = false; - foreach (QQuickItem* item, hoverItems) + for (QQuickItem* item : qAsConst(hoverItems)) accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), timestamp, true) || accepted; hoverItems.clear(); return accepted; @@ -2199,9 +2201,9 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event) // Deliver touch points to existing grabbers bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet *hasFiltered) { - for (auto grabber: event->grabbers()) { + const auto grabbers = event->grabbers(); + for (auto grabber : grabbers) deliverMatchingPointsToItem(grabber, event, hasFiltered); - } return false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index a6cb99ae05..2ff180ea99 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -67,9 +67,7 @@ QSGAbstractSoftwareRenderer::~QSGAbstractSoftwareRenderer() // Cleanup RenderableNodes delete m_background; - for (QSGSoftwareRenderableNode *node : m_nodes.values()) { - delete node; - } + qDeleteAll(m_nodes); delete m_nodeUpdater; } -- cgit v1.2.3 From c5218430ed419dc22582f38c0a82580fbcca8d42 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 18 Aug 2016 18:10:59 +0300 Subject: auto tests: Particles: replace 'foreach' with 'range for' Change-Id: I69c5e0d076fcb68261ea2b0fb5bee485751f6ddd Reviewed-by: Shawn Rutledge --- tests/auto/particles/qquickage/tst_qquickage.cpp | 8 ++++---- .../qquickangleddirection/tst_qquickangleddirection.cpp | 2 +- .../tst_qquickcumulativedirection.cpp | 2 +- .../qquickcustomaffector/tst_qquickcustomaffector.cpp | 4 ++-- .../qquickcustomparticle/tst_qquickcustomparticle.cpp | 2 +- .../qquickellipseextruder/tst_qquickellipseextruder.cpp | 4 ++-- tests/auto/particles/qquickfriction/tst_qquickfriction.cpp | 6 +++--- tests/auto/particles/qquickgravity/tst_qquickgravity.cpp | 2 +- tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp | 2 +- .../qquickimageparticle/tst_qquickimageparticle.cpp | 12 ++++++------ .../particles/qquickitemparticle/tst_qquickitemparticle.cpp | 2 +- .../particles/qquicklineextruder/tst_qquicklineextruder.cpp | 4 ++-- .../particles/qquickmaskextruder/tst_qquickmaskextruder.cpp | 2 +- .../qquickparticlegroup/tst_qquickparticlegroup.cpp | 2 +- .../qquickparticlesystem/tst_qquickparticlesystem.cpp | 2 +- .../qquickpointattractor/tst_qquickpointattractor.cpp | 2 +- .../qquickpointdirection/tst_qquickpointdirection.cpp | 2 +- .../qquickrectangleextruder/tst_qquickrectangleextruder.cpp | 4 ++-- .../auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp | 2 +- .../qquicktargetdirection/tst_qquicktargetdirection.cpp | 2 +- .../particles/qquicktrailemitter/tst_qquicktrailemitter.cpp | 4 ++-- .../auto/particles/qquickturbulence/tst_qquickturbulence.cpp | 2 +- tests/auto/particles/qquickwander/tst_qquickwander.cpp | 2 +- 23 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/auto/particles/qquickage/tst_qquickage.cpp b/tests/auto/particles/qquickage/tst_qquickage.cpp index 04c6fbd9e4..a233b30043 100644 --- a/tests/auto/particles/qquickage/tst_qquickage.cpp +++ b/tests/auto/particles/qquickage/tst_qquickage.cpp @@ -61,7 +61,7 @@ void tst_qquickage::test_kill() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -86,7 +86,7 @@ void tst_qquickage::test_jump() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -112,7 +112,7 @@ void tst_qquickage::test_onceOff() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -138,7 +138,7 @@ void tst_qquickage::test_sustained() //TODO: Ensure some particles have lived to 0.4s point despite unified timer //Can't verify size, because particles never die. It will constantly grow. - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp index 4ff72f159d..b3fc01caa6 100644 --- a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp +++ b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp @@ -58,7 +58,7 @@ void tst_qquickangleddirection::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp index 795fcaf42e..360b222367 100644 --- a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp +++ b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp @@ -57,7 +57,7 @@ void tst_qquickcumulativedirection::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp index fb15af4dd1..ee05fb29c9 100644 --- a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp +++ b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp @@ -59,7 +59,7 @@ void tst_qquickcustomaffector::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused //in CI the whole simulation often happens at once, so dead particles end up missing out @@ -92,7 +92,7 @@ void tst_qquickcustomaffector::test_move() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused if (!d->stillAlive(system)) diff --git a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp index a722508a3e..60c6a37899 100644 --- a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp +++ b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp @@ -60,7 +60,7 @@ void tst_qquickcustomparticle::test_basic() bool oneNonZero = false; QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp index ac8e2bac49..a1fe5b225d 100644 --- a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp +++ b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp @@ -74,7 +74,7 @@ void tst_qquickellipseextruder::test_basic() //Filled QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -91,7 +91,7 @@ void tst_qquickellipseextruder::test_basic() //Just border QCOMPARE(system->groupData[1]->size(), 500); - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp index 70e0291330..ab682c591e 100644 --- a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp +++ b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp @@ -59,7 +59,7 @@ void tst_qquickfriction::test_basic() //Default is just slowed a little QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -76,7 +76,7 @@ void tst_qquickfriction::test_basic() //Nondefault comes to a complete stop within the first half of its life QCOMPARE(system->groupData[1]->size(), 500); - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused @@ -103,7 +103,7 @@ void tst_qquickfriction::test_threshold() //Velocity capped at 50, but it might take a frame or two to get there QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1.0f) continue; //Particle data unused if (myFuzzyGEQ(d->t, ((qreal)system->timeInt/1000.0) - 0.1)) diff --git a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp index 8ef075dc9b..34566b90eb 100644 --- a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp +++ b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp @@ -58,7 +58,7 @@ void tst_qquickgravity::test_basic() QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); float mag = 707.10678f; - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1 || !d->stillAlive(system)) continue; //Particle data unused or dead diff --git a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp index fc270b991f..1228b4cc68 100644 --- a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp +++ b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp @@ -58,7 +58,7 @@ void tst_qquickgroupgoal::test_instantTransition() ensureAnimTime(600, system->m_animation); QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp index cd684ec59b..7e07878d39 100644 --- a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp +++ b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp @@ -72,7 +72,7 @@ void tst_qquickimageparticle::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -116,7 +116,7 @@ void tst_qquickimageparticle::test_colored() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -160,7 +160,7 @@ void tst_qquickimageparticle::test_colorVariance() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -205,7 +205,7 @@ void tst_qquickimageparticle::test_deformed() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -249,7 +249,7 @@ void tst_qquickimageparticle::test_tabled() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -294,7 +294,7 @@ void tst_qquickimageparticle::test_sprite() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp index 98aac71e93..d9791cdb33 100644 --- a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp +++ b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp @@ -60,7 +60,7 @@ void tst_qquickitemparticle::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp index 1f36874f0f..6baf8539d3 100644 --- a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp +++ b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp @@ -57,7 +57,7 @@ void tst_qquicklineextruder::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -73,7 +73,7 @@ void tst_qquicklineextruder::test_basic() } QCOMPARE(system->groupData[1]->size(), 500); - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp index a3d0988019..d8481efc47 100644 --- a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp +++ b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp @@ -57,7 +57,7 @@ void tst_qquickmaskextruder::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp index 8b7224623a..8791d19db6 100644 --- a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp +++ b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp @@ -58,7 +58,7 @@ void tst_qquickparticlegroup::test_instantTransition() //A frame or two worth of particles will be missed, the transition doesn't take effect on the frame it's spawned (QTBUG-21781) QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp index 4a3c5cdc74..5c82b946e5 100644 --- a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp +++ b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp @@ -58,7 +58,7 @@ void tst_qquickparticlesystem::test_basic() QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); int stillAlive = 0; - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp index 99a8530d3a..c0d7d38512 100644 --- a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp +++ b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp @@ -57,7 +57,7 @@ void tst_qquickpointattractor::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp index 0d150fb86d..5cc23e0306 100644 --- a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp +++ b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp @@ -57,7 +57,7 @@ void tst_qquickpointdirection::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp index 24b30bf9ab..414e2d36f7 100644 --- a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp +++ b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp @@ -57,7 +57,7 @@ void tst_qquickrectangleextruder::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -76,7 +76,7 @@ void tst_qquickrectangleextruder::test_basic() } QCOMPARE(system->groupData[1]->size(), 500); - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp index 8249159e43..ca5d9171f9 100644 --- a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp +++ b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp @@ -57,7 +57,7 @@ void tst_qquickspritegoal::test_instantTransition() ensureAnimTime(600, system->m_animation); QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp index 8d9556fdac..2f45263c37 100644 --- a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp +++ b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp @@ -57,7 +57,7 @@ void tst_qquicktargetdirection::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp index 99ecd7a06a..27d9bf01c9 100644 --- a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp +++ b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp @@ -57,7 +57,7 @@ void tst_qquicktrailemitter::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused @@ -74,7 +74,7 @@ void tst_qquicktrailemitter::test_basic() } QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[1]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[1]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp index c8024470e4..74fafdc1d2 100644 --- a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp +++ b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp @@ -59,7 +59,7 @@ void tst_qquickturbulence::test_basic() //Note that the noise image built-in provides the 'randomness', so this test should be stable so long as it and the size //of the Turbulence item remain the same QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused diff --git a/tests/auto/particles/qquickwander/tst_qquickwander.cpp b/tests/auto/particles/qquickwander/tst_qquickwander.cpp index 6e37fc648c..51ef7a272e 100644 --- a/tests/auto/particles/qquickwander/tst_qquickwander.cpp +++ b/tests/auto/particles/qquickwander/tst_qquickwander.cpp @@ -61,7 +61,7 @@ void tst_qquickwander::test_basic() //the 500 was randomly changed from 0.0 in velocity bool vxChanged = false; bool vyChanged = false; - foreach (QQuickParticleData *d, system->groupData[0]->data) { + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { if (d->t == -1) continue; //Particle data unused -- cgit v1.2.3 From c754b71eb4a141536dfb3e6697fbd089f4cba8e9 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 19 Aug 2016 11:20:43 +0300 Subject: manual tests: replace 'foreach' with 'range for' Change-Id: I21d17b7770246888b1de71d54a6a1babd0726b8a Reviewed-by: Shawn Rutledge --- tests/manual/qmlplugindump/tst_qmlplugindump.cpp | 11 ++++++----- tests/manual/scenegraph_lancelot/scenegrabber/main.cpp | 4 ++-- .../manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/manual/qmlplugindump/tst_qmlplugindump.cpp b/tests/manual/qmlplugindump/tst_qmlplugindump.cpp index ed00682a83..1bedd4427b 100644 --- a/tests/manual/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/manual/qmlplugindump/tst_qmlplugindump.cpp @@ -92,7 +92,7 @@ public: { QRegularExpression re; QRegularExpressionMatch m; - Q_FOREACH (const QString &e, m_expected) { + for (const QString &e : m_expected) { re.setPattern(e); m = re.match(QString::fromLatin1(buffer)); if (!m.hasMatch()) { @@ -187,7 +187,8 @@ Test createTest(const QString &id, const QJsonObject &def) return Test(id); } QStringList patterns; - Q_FOREACH (const QJsonValue &x, expected.toArray()) { + const auto expectedArray = expected.toArray(); + for (const QJsonValue &x : expectedArray) { if (!x.isString()) { qWarning() << "Wrong definition for test: " << id << "."; return Test(id); @@ -331,7 +332,7 @@ void tst_qmlplugindump::plugin_data() QTest::addColumn("version"); QTest::addColumn("expected"); - Q_FOREACH (const Test &t, tests) { + for (const Test &t : qAsConst(tests)) { if (t.isNull()) QSKIP("Errors in test definition."); QTest::newRow(t.id.toLatin1().data()) << t.project << t.version << t.expected; @@ -357,9 +358,9 @@ void tst_qmlplugindump::plugin() void tst_qmlplugindump::cleanupTestCase() { QSet projects; - Q_FOREACH (const Test &t, tests) + for (const Test &t : qAsConst(tests)) projects.insert(t.project); - Q_FOREACH (const QString &p, projects) { + for (const QString &p : qAsConst(projects)) { if (!cleanUpSample(p)) qWarning() << "Error in cleaning up project" << p << "."; } diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp index 5098d51134..886cfc6599 100644 --- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp +++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp @@ -183,8 +183,8 @@ int main(int argc, char *argv[]) v.setSource(QUrl::fromLocalFile(ifile)); if (noText) { - QList items = v.rootObject()->findChildren(); - foreach (QQuickItem *item, items) { + const QList items = v.rootObject()->findChildren(); + for (QQuickItem *item : items) { if (QByteArray(item->metaObject()->className()).contains("Text")) item->setVisible(false); } diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp index 426e06ccc2..3f28d90e7b 100644 --- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp +++ b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp @@ -156,7 +156,7 @@ void tst_Scenegraph::setupTestSuite(const QByteArray& filter) } std::sort(itemFiles.begin(), itemFiles.end()); - foreach (const QString &filePath, itemFiles) { + for (const QString &filePath : qAsConst(itemFiles)) { QByteArray itemName = filePath.mid(testSuitePath.length() + 1).toLatin1(); QBaselineTest::newRow(itemName, checksumFileOrDir(filePath)) << filePath; numItems++; @@ -238,7 +238,9 @@ quint16 tst_Scenegraph::checksumFileOrDir(const QString &path) if (fi.isDir()) { static const QStringList nameFilters = QStringList() << "*.qml" << "*.cpp" << "*.png" << "*.jpg"; quint16 cs = 0; - foreach (QString item, QDir(fi.filePath()).entryList(nameFilters, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) + const auto entryList = QDir(fi.filePath()).entryList(nameFilters, + QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); + for (const QString &item : entryList) cs ^= checksumFileOrDir(path + QLatin1Char('/') + item); return cs; } -- cgit v1.2.3 From 3ef4fac9ff3f785d3ccbda4b28ec2c0ea2ee1b59 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 11 Aug 2016 13:08:00 +0300 Subject: tools: replace 'foreach' with 'range for' Mark some local variables or parameters as const to prevent detach()'ing. Use qAsConst where is not possible mark as const. Change-Id: I0a777c3bd855abd3bb1ad0907152360cf4a1050e Reviewed-by: Shawn Rutledge --- tools/qml/main.cpp | 8 ++--- tools/qmleasing/splineeditor.cpp | 2 +- tools/qmlimportscanner/main.cpp | 18 +++++------ tools/qmljs/qmljs.cpp | 4 +-- tools/qmlmin/main.cpp | 2 +- tools/qmlplugindump/main.cpp | 48 ++++++++++++++-------------- tools/qmlplugindump/qmlstreamwriter.cpp | 2 +- tools/qmlprofiler/qmlprofilerapplication.cpp | 4 +-- tools/qmlprofiler/qmlprofilerdata.cpp | 2 +- tools/qmlscene/main.cpp | 16 +++++----- 10 files changed, 53 insertions(+), 53 deletions(-) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index d718067616..be62500858 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -192,7 +192,7 @@ public Q_SLOTS: checkForWindow(o); haveOne = true; if (conf && qae) - foreach (PartialScene *ps, conf->completers) + for (PartialScene *ps : qAsConst(conf->completers)) if (o->inherits(ps->itemType().toUtf8().constData())) contain(o, ps->container()); } @@ -413,8 +413,8 @@ static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory) QObject *dummyData = comp.create(); if (comp.isError()) { - QList errors = comp.errors(); - foreach (const QQmlError &error, errors) + const QList errors = comp.errors(); + for (const QQmlError &error : errors) qWarning() << error; } @@ -566,7 +566,7 @@ int main(int argc, char *argv[]) if (!dummyDir.isEmpty() && QFileInfo (dummyDir).isDir()) loadDummyDataFiles(e, dummyDir); - foreach (const QString &path, files) { + for (const QString &path : qAsConst(files)) { //QUrl::fromUserInput doesn't treat no scheme as relative file paths #ifndef QT_NO_REGULAREXPRESSION QRegularExpression urlRe("[[:word:]]+://.*"); diff --git a/tools/qmleasing/splineeditor.cpp b/tools/qmleasing/splineeditor.cpp index ee55931a46..6fee013c62 100644 --- a/tools/qmleasing/splineeditor.cpp +++ b/tools/qmleasing/splineeditor.cpp @@ -288,7 +288,7 @@ QHash SplineEditor::presets() const QString SplineEditor::generateCode() { QString s = QLatin1String("["); - foreach (const QPointF &point, m_controlPoints) { + for (const QPointF &point : qAsConst(m_controlPoints)) { s += QString::number(point.x(), 'g', 2) + QLatin1Char(',') + QString::number(point.y(), 'g', 3) + QLatin1Char(','); } diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index 4a77623d28..f7f5a5e4e4 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -171,7 +171,7 @@ QString resolveImportPath(const QString &uri, const QString &version) QString ver = version; while (true) { - foreach (const QString &qmlImportPath, g_qmlImportPaths) { + for (const QString &qmlImportPath : qAsConst(g_qmlImportPaths)) { // Search for the most specific version first, and search // also for the version in parent modules. For example: // - qml/QtQml/Models.2.0 @@ -230,8 +230,8 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) if (!classnames.isEmpty()) import.insert(QStringLiteral("classname"), classnames); if (plugininfo.contains(dependenciesLiteral())) { - QStringList dependencies = plugininfo.value(dependenciesLiteral()).toStringList(); - foreach (const QString &line, dependencies) { + const QStringList dependencies = plugininfo.value(dependenciesLiteral()).toStringList(); + for (const QString &line : dependencies) { const auto dep = line.splitRef(QLatin1Char(' ')); QVariantMap depImport; depImport[typeLiteral()] = QStringLiteral("module"); @@ -362,7 +362,7 @@ QVariantList findQmlImportsInFile(const QString &filePath) QVariantList mergeImports(const QVariantList &a, const QVariantList &b) { QVariantList merged = a; - foreach (const QVariant &variant, b) { + for (const QVariant &variant : b) { if (!merged.contains(variant)) merged.append(variant); } @@ -421,16 +421,16 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir) continue; } - foreach (const QFileInfo &x, entries) + for (const QFileInfo &x : entries) if (x.isFile()) ret = mergeImports(ret, findQmlImportsInFile(x.absoluteFilePath())); } return ret; } -QSet importModulePaths(QVariantList imports) { +QSet importModulePaths(const QVariantList &imports) { QSet ret; - foreach (const QVariant &importVariant, imports) { + for (const QVariant &importVariant : imports) { QVariantMap import = qvariant_cast(importVariant); QString path = import.value(pathLiteral()).toString(); QString type = import.value(typeLiteral()).toString(); @@ -448,13 +448,13 @@ QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, const QString QVariantList ret; // scan all app root qml directories for imports - foreach (const QString &qmlDir, qmlDirs) { + for (const QString &qmlDir : qmlDirs) { QVariantList imports = findQmlImportsInDirectory(qmlDir); ret = mergeImports(ret, imports); } // scan app qml files for imports - foreach (const QString &file, scanFiles) { + for (const QString &file : scanFiles) { QVariantList imports = findQmlImportsInFile(file); ret = mergeImports(ret, imports); } diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp index 4f79546bcc..964afc265b 100644 --- a/tools/qmljs/qmljs.cpp +++ b/tools/qmljs/qmljs.cpp @@ -118,7 +118,7 @@ static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exceptio std::cerr << "Uncaught exception: " << qPrintable(message->toQStringNoThrow()) << std::endl; } - foreach (const QV4::StackFrame &frame, trace) { + for (const QV4::StackFrame &frame : trace) { std::cerr << " at " << qPrintable(frame.function) << " (" << qPrintable(frame.source); if (frame.line >= 0) std::cerr << ':' << frame.line; @@ -188,7 +188,7 @@ int main(int argc, char *argv[]) QV4::ScopedObject gc(scope, vm.memoryManager->allocObject(ctx)); vm.globalObject->put(QV4::ScopedString(scope, vm.newIdentifier(QStringLiteral("gc"))).getPointer(), gc); - foreach (const QString &fn, args) { + for (const QString &fn : qAsConst(args)) { QFile file(fn); if (file.open(QFile::ReadOnly)) { const QString code = QString::fromUtf8(file.readAll()); diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp index 2b18a8442b..d2bad9d0d5 100644 --- a/tools/qmlmin/main.cpp +++ b/tools/qmlmin/main.cpp @@ -120,7 +120,7 @@ protected: static QString quote(const QString &string) { QString quotedString; - foreach (const QChar &ch, string) { + for (const QChar &ch : string) { if (ch == QLatin1Char('"')) quotedString += QLatin1String("\\\""); else { diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 0e5d3646c2..ceffebf14b 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -248,15 +248,15 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, QSet baseExports = qmlTypesByCppName.value(it.key()); const QSet extensionCppNames = it.value(); - foreach (const QByteArray &extensionCppName, extensionCppNames) { + for (const QByteArray &extensionCppName : extensionCppNames) { const QSet extensionExports = qmlTypesByCppName.value(extensionCppName); // remove extension exports from base imports // unfortunately the QQmlType pointers don't match, so can't use QSet::subtract QSet newBaseExports; - foreach (const QQmlType *baseExport, baseExports) { + for (const QQmlType *baseExport : qAsConst(baseExports)) { bool match = false; - foreach (const QQmlType *extensionExport, extensionExports) { + for (const QQmlType *extensionExport : extensionExports) { if (baseExport->qmlTypeName() == extensionExport->qmlTypeName() && baseExport->majorVersion() == extensionExport->majorVersion() && baseExport->minorVersion() == extensionExport->minorVersion()) { @@ -469,7 +469,7 @@ public: void dumpComposite(QQmlEngine *engine, const QSet &compositeType, QSet &defaultReachableNames) { - foreach (const QQmlType *type, compositeType) + for (const QQmlType *type : compositeType) dumpCompositeItem(engine, type, defaultReachableNames); } @@ -518,7 +518,7 @@ public: } } - foreach (const QMetaObject *meta, objectsToMerge) + for (const QMetaObject *meta : qAsConst(objectsToMerge)) writeMetaContent(meta, &knownAttributes); qml->writeEndObject(); @@ -542,11 +542,11 @@ public: if (meta->superClass()) qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()))); - QSet qmlTypes = qmlTypesByCppName.value(meta->className()); + const QSet qmlTypes = qmlTypesByCppName.value(meta->className()); if (!qmlTypes.isEmpty()) { QHash exports; - foreach (const QQmlType *qmlTy, qmlTypes) { + for (const QQmlType *qmlTy : qmlTypes) { const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion()); exports.insert(exportString, qmlTy); } @@ -564,7 +564,7 @@ public: // write meta object revisions QStringList metaObjectRevisions; - foreach (const QString &exportString, exportStrings) { + for (const QString &exportString : qAsConst(exportStrings)) { int metaObjectRevision = exports[exportString]->metaObjectRevision(); metaObjectRevisions += QString::number(metaObjectRevision); } @@ -749,7 +749,7 @@ static bool readDependenciesData(QString dependenciesFile, const QByteArray &fil if (verbose) { std::cerr << "parsing " << qPrintable( dependenciesFile ) << " skipping"; - foreach (const QString &uriToSkip, urisToSkip) + for (const QString &uriToSkip : urisToSkip) std::cerr << ' ' << qPrintable(uriToSkip); std::cerr << std::endl; } @@ -763,13 +763,13 @@ static bool readDependenciesData(QString dependenciesFile, const QByteArray &fil return false; } if (doc.isArray()) { - QStringList requiredKeys = QStringList() << QStringLiteral("name") - << QStringLiteral("type") - << QStringLiteral("version"); + const QStringList requiredKeys = QStringList() << QStringLiteral("name") + << QStringLiteral("type") + << QStringLiteral("version"); foreach (const QJsonValue &dep, doc.array()) { if (dep.isObject()) { QJsonObject obj = dep.toObject(); - foreach (const QString &requiredKey, requiredKeys) + for (const QString &requiredKey : requiredKeys) if (!obj.contains(requiredKey) || obj.value(requiredKey).isString()) continue; if (obj.value(QStringLiteral("type")).toString() != QLatin1String("module")) @@ -850,7 +850,7 @@ static bool getDependencies(const QQmlEngine &engine, const QString &pluginImpor if (!importScanner.waitForFinished()) { std::cerr << "failure to start " << qPrintable(command); - foreach (const QString &arg, commandArgs) + for (const QString &arg : qAsConst(commandArgs)) std::cerr << ' ' << qPrintable(arg); std::cerr << std::endl; return false; @@ -863,7 +863,7 @@ static bool getDependencies(const QQmlEngine &engine, const QString &pluginImpor } QStringList aux; - foreach (const QString &str, *dependencies) { + for (const QString &str : qAsConst(*dependencies)) { if (!str.startsWith("Qt.test.qtestroot")) aux += str; } @@ -1124,7 +1124,7 @@ int main(int argc, char *argv[]) // load the QtQml builtins and the dependencies { QByteArray code(qtQmlImportString.toUtf8()); - foreach (const QString &moduleToImport, dependencies) { + for (const QString &moduleToImport : qAsConst(dependencies)) { code.append("\nimport "); code.append(moduleToImport.toUtf8()); } @@ -1154,7 +1154,7 @@ int main(int argc, char *argv[]) QSet metas; if (action == Builtins) { - foreach (const QMetaObject *m, defaultReachable) { + for (const QMetaObject *m : qAsConst(defaultReachable)) { if (m->className() == QLatin1String("Qt")) { metas.insert(m); break; @@ -1175,7 +1175,7 @@ int main(int argc, char *argv[]) return EXIT_INVALIDARGUMENTS; } metas = defaultReachable; - foreach (const QMetaObject *m, defaultReachable) { + for (const QMetaObject *m : qAsConst(defaultReachable)) { if (m->className() == QLatin1String("Qt")) { metas.remove(m); break; @@ -1196,7 +1196,7 @@ int main(int argc, char *argv[]) QString::number(qtObjectType->minorVersion())).toUtf8(); } // avoid importing dependencies? - foreach (const QString &moduleToImport, dependencies) { + for (const QString &moduleToImport : qAsConst(dependencies)) { importCode.append("\nimport "); importCode.append(moduleToImport.toUtf8()); } @@ -1231,9 +1231,9 @@ int main(int argc, char *argv[]) // Also eliminate meta objects with the same classname. // This is required because extended objects seem not to share // a single meta object instance. - foreach (const QMetaObject *mo, defaultReachable) + for (const QMetaObject *mo : qAsConst(defaultReachable)) defaultReachableNames.insert(QByteArray(mo->className())); - foreach (const QMetaObject *mo, candidates) { + for (const QMetaObject *mo : qAsConst(candidates)) { if (!defaultReachableNames.contains(mo->className())) metas.insert(mo); } @@ -1265,19 +1265,19 @@ int main(int argc, char *argv[]) compactDependencies(&dependencies); QStringList quotedDependencies; - foreach (const QString &dep, dependencies) + for (const QString &dep : qAsConst(dependencies)) quotedDependencies << enquote(dep); qml.writeArrayBinding("dependencies", quotedDependencies); // put the metaobjects into a map so they are always dumped in the same order QMap nameToMeta; - foreach (const QMetaObject *meta, metas) + for (const QMetaObject *meta : qAsConst(metas)) nameToMeta.insert(convertToId(meta), meta); Dumper dumper(&qml); if (relocatable) dumper.setRelocatableModuleUri(pluginImportUri); - foreach (const QMetaObject *meta, nameToMeta) { + for (const QMetaObject *meta : qAsConst(nameToMeta)) { dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta)); } diff --git a/tools/qmlplugindump/qmlstreamwriter.cpp b/tools/qmlplugindump/qmlstreamwriter.cpp index dd3c188fe4..3632cee60d 100644 --- a/tools/qmlplugindump/qmlstreamwriter.cpp +++ b/tools/qmlplugindump/qmlstreamwriter.cpp @@ -179,7 +179,7 @@ void QmlStreamWriter::flushPotentialLinesWithNewlines() { if (m_maybeOneline) m_stream->write("\n"); - foreach (const QByteArray &line, m_pendingLines) { + for (const QByteArray &line : qAsConst(m_pendingLines)) { writeIndent(); m_stream->write(line); m_stream->write("\n"); diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index 45c32487a2..033492b516 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -274,8 +274,8 @@ quint64 QmlProfilerApplication::parseFeatures(const QStringList &featureList, co bool exclude) { quint64 features = exclude ? std::numeric_limits::max() : 0; - QStringList givenFeatures = values.split(QLatin1Char(',')); - foreach (const QString &f, givenFeatures) { + const QStringList givenFeatures = values.split(QLatin1Char(',')); + for (const QString &f : givenFeatures) { int index = featureList.indexOf(f); if (index < 0) { logError(tr("Unknown feature '%1'").arg(f)); diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp index b651b2724f..048c92bb93 100644 --- a/tools/qmlprofiler/qmlprofilerdata.cpp +++ b/tools/qmlprofiler/qmlprofilerdata.cpp @@ -572,7 +572,7 @@ bool QmlProfilerData::save(const QString &filename) stream.writeEndElement(); // eventData stream.writeStartElement(QStringLiteral("profilerDataModel")); - foreach (const QmlRangeEventStartInstance &event, d->startInstanceList) { + for (const QmlRangeEventStartInstance &event : qAsConst(d->startInstanceList)) { stream.writeStartElement(QStringLiteral("range")); stream.writeAttribute(QStringLiteral("startTime"), QString::number(event.startTime)); if (event.duration >= 0) diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 0e542ab0c8..9e1002166d 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -175,10 +175,10 @@ QFileInfoList findQmlFiles(const QString &dirName) QFileInfoList ret; if (dir.exists()) { - QFileInfoList fileInfos = dir.entryInfoList(QStringList() << "*.qml", - QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot); + const QFileInfoList fileInfos = dir.entryInfoList(QStringList() << "*.qml", + QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot); - foreach (QFileInfo fileInfo, fileInfos) { + for (const QFileInfo &fileInfo : fileInfos) { if (fileInfo.isDir()) ret += findQmlFiles(fileInfo.filePath()); else if (fileInfo.fileName().length() > 0 && fileInfo.fileName().at(0).isLower()) @@ -196,9 +196,9 @@ static int displayOptionsDialog(Options *options) QFormLayout *layout = new QFormLayout(&dialog); QComboBox *qmlFileComboBox = new QComboBox(&dialog); - QFileInfoList fileInfos = findQmlFiles(":/bundle") + findQmlFiles("./qmlscene-resources"); + const QFileInfoList fileInfos = findQmlFiles(":/bundle") + findQmlFiles("./qmlscene-resources"); - foreach (QFileInfo fileInfo, fileInfos) + for (const QFileInfo &fileInfo : fileInfos) qmlFileComboBox->addItem(fileInfo.dir().dirName() + QLatin1Char('/') + fileInfo.fileName(), QVariant::fromValue(fileInfo)); QCheckBox *originalCheckBox = new QCheckBox(&dialog); @@ -319,8 +319,8 @@ static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory) QObject *dummyData = comp.create(); if(comp.isError()) { - QList errors = comp.errors(); - foreach (const QQmlError &error, errors) + const QList errors = comp.errors(); + for (const QQmlError &error : errors) fprintf(stderr, "%s\n", qPrintable(error.toString())); } @@ -457,7 +457,7 @@ int main(int argc, char ** argv) options.applicationAttributes.append(Qt::AA_DisableHighDpiScaling); } - foreach (Qt::ApplicationAttribute a, options.applicationAttributes) + for (Qt::ApplicationAttribute a : qAsConst(options.applicationAttributes)) QCoreApplication::setAttribute(a); #ifdef QT_WIDGETS_LIB QApplication app(argc, argv); -- cgit v1.2.3