Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: I1359574c7d89aaf3328958e2f667ba1e599ff7f1
This commit is contained in:
Qt Forward Merge Bot 2019-10-11 01:00:18 +02:00
commit 66db74e53e
38 changed files with 431 additions and 51 deletions

View File

@ -1,3 +1,5 @@
!win32: error("This example requires Windows")
QT += qml quick
HEADERS += d3d11squircle.h

View File

@ -1,3 +1,5 @@
!macos: error("This example requires macOS")
QT += qml quick
HEADERS += metaltextureimport.h

View File

@ -1,3 +1,5 @@
!macos: error("This example requires macOS")
QT += qml quick
HEADERS += metalsquircle.h

View File

@ -1,3 +1,5 @@
!qtConfig(vulkan): error("This example requires Qt built with Vulkan support")
QT += qml quick
HEADERS += vulkansquircle.h

View File

@ -87,7 +87,7 @@
\section1 Packages
\e Packages uses the \l Package type to transition delegates between
\e Packages use the \l [QML]{Package} type to transition delegates between
two views.
It has a Package object which defines delegate items for each view and an

View File

@ -94,7 +94,7 @@
\sa ColumnLayout
\sa GridLayout
\sa RowLayout
\sa StackView
\sa {QtQuick.Controls::StackView}{StackView}
*/
QT_BEGIN_NAMESPACE

View File

@ -76,6 +76,7 @@ void QSGOpenVGRenderContext::initialize(const QSGRenderContext::InitParams *para
m_vgContext = vgparams->context;
QSGRenderContext::initialize(params);
emit initialized();
}
void QSGOpenVGRenderContext::invalidate()
@ -84,6 +85,7 @@ void QSGOpenVGRenderContext::invalidate()
delete m_glyphCacheManager;
m_glyphCacheManager = nullptr;
QSGRenderContext::invalidate();
emit invalidated();
}
void QSGOpenVGRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId)

View File

@ -211,21 +211,14 @@ void QSGOpenVGInternalRectangleNode::render()
} else {
vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();
if (m_radius > 0) {
// Fallback to rendering to an image for rounded rects with perspective transforms
if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))) {
delete m_offscreenSurface;
m_offscreenSurface = new QOpenVGOffscreenSurface(QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height())));
}
m_offscreenSurface->makeCurrent();
} else if (m_offscreenSurface) {
// Fallback to rendering to an image for rounded rects with perspective transforms
if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))) {
delete m_offscreenSurface;
m_offscreenSurface = nullptr;
m_offscreenSurface = new QOpenVGOffscreenSurface(QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height())));
}
m_offscreenSurface->makeCurrent();
}
// If path is dirty
if (m_pathDirty) {
vgClearPath(m_rectanglePath, VG_PATH_CAPABILITY_APPEND_TO);
@ -291,7 +284,7 @@ void QSGOpenVGInternalRectangleNode::render()
vgDrawPath(m_rectanglePath, VG_FILL_PATH);
}
if (!transform().isAffine() && m_radius > 0) {
if (!transform().isAffine()) {
m_offscreenSurface->doneCurrent();
// Render offscreen surface
vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);

View File

@ -187,6 +187,7 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
data.updatePending = false;
if (!data.grabOnly) {
cd->flushFrameSynchronousEvents();
// Event delivery/processing triggered the window to be deleted or stop rendering.
if (!m_windows.contains(window))
return;

View File

@ -52,7 +52,7 @@ QSGOpenVGSpriteNode::QSGOpenVGSpriteNode()
QSGOpenVGSpriteNode::~QSGOpenVGSpriteNode()
{
delete m_texture;
}
void QSGOpenVGSpriteNode::setTexture(QSGTexture *texture)

View File

@ -66,7 +66,7 @@ public:
void render() override;
private:
QSGOpenVGTexture *m_texture;
QSGOpenVGTexture *m_texture = nullptr;
float m_time;
QPoint m_sourceA;
QPoint m_sourceB;

View File

@ -144,14 +144,17 @@ A JavaScript resource may import a QML module in the following fashion:
.import TypeNamespace MajorVersion.MinorVersion as Qualifier
\endcode
For example:
Below you can see an example that also shows how to use the QML types from a
module imported in javascript:
\code
.import Qt.test 1.0 as JsQtTest
var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3
\endcode
In particular, this may be useful in order to access functionality provided
via a singleton type; see qmlRegisterSingletonType() for more information.
\note The .import syntax doesn't work for scripts used in the \l {WorkerScript}
*/

View File

@ -294,13 +294,28 @@ static double MakeDay(double year, double month, double day)
if (month < 0)
month += 12.0;
double d = DayFromYear(year);
bool leap = InLeapYear(d*msPerDay);
/* Quoting the spec:
d += DayFromMonth(month, leap);
d += day - 1;
Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn
and DateFromTime(t) is 1; but if this is not possible (because some
argument is out of range), return NaN.
*/
double first = DayFromYear(year);
/* Beware floating-point glitches: don't test the first millisecond of a
* year, month or day when we could test a moment firmly in the interior of
* the interval. A rounding glitch might give the first millisecond to the
* preceding interval.
*/
bool leap = InLeapYear((first + 60) * msPerDay);
return d;
first += DayFromMonth(month, leap);
const double t = first * msPerDay + msPerDay / 2; // Noon on the first of the month
Q_ASSERT(Day(t) == first);
if (YearFromTime(t) != year || MonthFromTime(t) != month || DateFromTime(t) != 1) {
qWarning("Apparently out-of-range date %.0f-%02.0f-%02.0f", year, month, day);
return qt_qnan();
}
return first + day - 1;
}
static inline double MakeDate(double day, double time)

View File

@ -634,7 +634,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
mo->updateValues(*roles);
}
void ListModel::set(int elementIndex, QV4::Object *object)
void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement reason)
{
if (!object)
return;
@ -684,7 +684,7 @@ void ListModel::set(int elementIndex, QV4::Object *object)
} else if (QV4::DateObject *date = propertyValue->as<QV4::DateObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
if (r.type == ListLayout::Role::DateTime) {
QDateTime dt = date->toQDateTime();;
QDateTime dt = date->toQDateTime();
e->setDateTimePropertyFast(r, dt);
}
} else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
@ -699,9 +699,16 @@ void ListModel::set(int elementIndex, QV4::Object *object)
e->setVariantMapFast(role, o);
}
} else if (propertyValue->isNullOrUndefined()) {
const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
if (r)
e->clearProperty(*r);
if (reason == SetElement::WasJustInserted) {
QQmlError err;
auto memberName = propertyName->toString(m_modelCache->engine())->toQString();
err.setDescription(QString::fromLatin1("%1 is %2. Adding an object with a %2 member does not create a role for it.").arg(memberName, propertyValue->isNull() ? QLatin1String("null") : QLatin1String("undefined")));
qmlWarning(nullptr, err);
} else {
const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
if (r)
e->clearProperty(*r);
}
}
}
}
@ -725,13 +732,13 @@ QVector<std::function<void()>> ListModel::remove(int index, int count)
void ListModel::insert(int elementIndex, QV4::Object *object)
{
insertElement(elementIndex);
set(elementIndex, object);
set(elementIndex, object, SetElement::WasJustInserted);
}
int ListModel::append(QV4::Object *object)
{
int elementIndex = appendElement();
set(elementIndex, object);
set(elementIndex, object, SetElement::WasJustInserted);
return elementIndex;
}

View File

@ -381,8 +381,10 @@ public:
return elements.count();
}
enum class SetElement {WasJustInserted, IsCurrentlyUpdated};
void set(int elementIndex, QV4::Object *object, QVector<int> *roles);
void set(int elementIndex, QV4::Object *object);
void set(int elementIndex, QV4::Object *object, SetElement reason = SetElement::IsCurrentlyUpdated);
int append(QV4::Object *object);
void insert(int elementIndex, QV4::Object *object);

View File

@ -38,7 +38,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtquick/qtquick.tags
depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols1 qtquickcontrols qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns
depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns
headerdirs += ..\
../../quick \

View File

@ -676,13 +676,13 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
int xOffset = 0;
if (d->hAlign == QQuickImage::AlignHCenter)
xOffset = qCeil((width() - pixWidth) / 2.);
xOffset = (width() - pixWidth) / 2;
else if (d->hAlign == QQuickImage::AlignRight)
xOffset = qCeil(width() - pixWidth);
int yOffset = 0;
if (d->vAlign == QQuickImage::AlignVCenter)
yOffset = qCeil((height() - pixHeight) / 2.);
yOffset = (height() - pixHeight) / 2;
else if (d->vAlign == QQuickImage::AlignBottom)
yOffset = qCeil(height() - pixHeight);

View File

@ -587,6 +587,7 @@ void QQuickItemView::setHighlightRangeMode(HighlightRangeMode mode)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
emit highlightRangeModeChanged();
@ -609,8 +610,10 @@ void QQuickItemView::setPreferredHighlightBegin(qreal start)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightBeginChanged();
}
@ -624,8 +627,10 @@ void QQuickItemView::resetPreferredHighlightBegin()
d->highlightRangeStart = 0;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightBeginChanged();
}
@ -646,8 +651,10 @@ void QQuickItemView::setPreferredHighlightEnd(qreal end)
d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightEndChanged();
}
@ -661,8 +668,10 @@ void QQuickItemView::resetPreferredHighlightEnd()
d->highlightRangeEnd = 0;
if (isComponentComplete()) {
d->updateViewport();
if (!isMoving() && !isFlicking())
if (!isMoving() && !isFlicking()) {
d->moveReason = QQuickItemViewPrivate::Other;
d->fixupPosition();
}
}
emit preferredHighlightEndChanged();
}

View File

@ -275,6 +275,7 @@ void QQuickRenderControl::polishItems()
if (!d->window)
return;
cd->polishItems();
emit d->window->afterAnimating();
}
/*!

View File

@ -49,6 +49,11 @@ QSGSoftwareSpriteNode::QSGSoftwareSpriteNode()
setGeometry((QSGGeometry*)1);
}
QSGSoftwareSpriteNode::~QSGSoftwareSpriteNode()
{
delete m_texture;
}
void QSGSoftwareSpriteNode::setTexture(QSGTexture *texture)
{
m_texture = qobject_cast<QSGSoftwarePixmapTexture*>(texture);

View File

@ -64,6 +64,7 @@ class QSGSoftwareSpriteNode : public QSGSpriteNode
{
public:
QSGSoftwareSpriteNode();
~QSGSoftwareSpriteNode() override;
void setTexture(QSGTexture *texture) override;
void setTime(float time) override;
@ -81,7 +82,7 @@ public:
private:
QSGSoftwarePixmapTexture *m_texture;
QSGSoftwarePixmapTexture *m_texture = nullptr;
float m_time;
QPoint m_sourceA;
QPoint m_sourceB;

View File

@ -0,0 +1,12 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
// QTBUG-78996
dateProperty = new Date(2019, 9, 3)
boolProperty = (dateProperty.getFullYear() == 2019
&& dateProperty.getMonth() == 9
&& dateProperty.getDate() == 3)
}
}

View File

@ -0,0 +1,11 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateProperty = new Date(2019, 2, 0) // Feb 28th
boolProperty = (dateProperty.getFullYear() == 2019
&& dateProperty.getMonth() == 1
&& dateProperty.getDate() == 28)
}
}

View File

@ -0,0 +1,11 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateProperty = new Date(2019, 1, 29) // March 1st
boolProperty = (dateProperty.getFullYear() == 2019
&& dateProperty.getMonth() == 2
&& dateProperty.getDate() == 1)
}
}

View File

@ -0,0 +1,11 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateProperty = new Date(2020, 2, 0) // Feb 29th
boolProperty = (dateProperty.getFullYear() == 2020
&& dateProperty.getMonth() == 1
&& dateProperty.getDate() == 29)
}
}

View File

@ -0,0 +1,11 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateProperty = new Date(2017, 40, -61) // 2020, Feb 29th
boolProperty = (dateProperty.getFullYear() == 2020
&& dateProperty.getMonth() == 1
&& dateProperty.getDate() == 29)
}
}

View File

@ -0,0 +1,11 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateProperty = new Date(2019, 12, 0) // Dec 31
boolProperty = (dateProperty.getFullYear() == 2019
&& dateProperty.getMonth() == 11
&& dateProperty.getDate() == 31)
}
}

View File

@ -0,0 +1,16 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
// QTBUG-78996
dateTimeProperty = new Date(2019, 9, 3, 12)
boolProperty = (dateTimeProperty.getFullYear() == 2019
&& dateTimeProperty.getMonth() == 9
&& dateTimeProperty.getDate() == 3
&& dateTimeProperty.getHours() == 12
&& dateTimeProperty.getMinutes() == 0
&& dateTimeProperty.getSeconds() == 0
&& dateTimeProperty.getMilliseconds() == 0)
}
}

View File

@ -0,0 +1,15 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateTimeProperty = new Date(2019, 1, 28, 23, 59, 59, 1001) // 2019-3-1 0:0:0.001
boolProperty = (dateTimeProperty.getFullYear() == 2019
&& dateTimeProperty.getMonth() == 2
&& dateTimeProperty.getDate() == 1
&& dateTimeProperty.getHours() == 0
&& dateTimeProperty.getMinutes() == 0
&& dateTimeProperty.getSeconds() == 0
&& dateTimeProperty.getMilliseconds() == 1)
}
}

View File

@ -0,0 +1,15 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateTimeProperty = new Date(2019, 11, 31, 1440) // 2020-2-29 0:0:0
boolProperty = (dateTimeProperty.getFullYear() == 2020
&& dateTimeProperty.getMonth() == 1
&& dateTimeProperty.getDate() == 29
&& dateTimeProperty.getHours() == 0
&& dateTimeProperty.getMinutes() == 0
&& dateTimeProperty.getSeconds() == 0
&& dateTimeProperty.getMilliseconds() == 0)
}
}

View File

@ -0,0 +1,15 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateTimeProperty = new Date(2020, 2, 1, 0, 0, 0, -1) // 2020-2-29 23:59:59.999
boolProperty = (dateTimeProperty.getFullYear() == 2020
&& dateTimeProperty.getMonth() == 1
&& dateTimeProperty.getDate() == 29
&& dateTimeProperty.getHours() == 23
&& dateTimeProperty.getMinutes() == 59
&& dateTimeProperty.getSeconds() == 59
&& dateTimeProperty.getMilliseconds() == 999)
}
}

View File

@ -0,0 +1,15 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateTimeProperty = new Date(2020, 1, 28, 0, 1440) // 2020-2-29 0:0:0
boolProperty = (dateTimeProperty.getFullYear() == 2020
&& dateTimeProperty.getMonth() == 1
&& dateTimeProperty.getDate() == 29
&& dateTimeProperty.getHours() == 0
&& dateTimeProperty.getMinutes() == 0
&& dateTimeProperty.getSeconds() == 0
&& dateTimeProperty.getMilliseconds() == 0)
}
}

View File

@ -0,0 +1,15 @@
import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
Component.onCompleted: {
dateTimeProperty = new Date(2020, 1, 28, 23, 0, 3600) // 2020-2-29 0:0:0
boolProperty = (dateTimeProperty.getFullYear() == 2020
&& dateTimeProperty.getMonth() == 1
&& dateTimeProperty.getDate() == 29
&& dateTimeProperty.getHours() == 0
&& dateTimeProperty.getMinutes() == 0
&& dateTimeProperty.getSeconds() == 0
&& dateTimeProperty.getMilliseconds() == 0)
}
}

View File

@ -79,6 +79,10 @@ private slots:
void assignDate();
void exportDate_data();
void exportDate();
void checkDate_data();
void checkDate();
void checkDateTime_data();
void checkDateTime();
void idShortcutInvalidates();
void boolPropertiesEvaluateAsBool();
void methods();
@ -568,6 +572,82 @@ void tst_qqmlecmascript::exportDate()
QCOMPARE(object->boolProperty(), true);
}
void tst_qqmlecmascript::checkDate_data()
{
QTest::addColumn<QUrl>("source");
QTest::addColumn<QDate>("date");
// NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12.
QTest::newRow("denormal-March")
<< testFileUrl("checkDate-denormal-March.qml")
<< QDate(2019, 3, 1);
QTest::newRow("denormal-leap")
<< testFileUrl("checkDate-denormal-leap.qml")
<< QDate(2020, 2, 29);
QTest::newRow("denormal-Feb")
<< testFileUrl("checkDate-denormal-Feb.qml")
<< QDate(2019, 2, 28);
QTest::newRow("denormal-year")
<< testFileUrl("checkDate-denormal-year.qml")
<< QDate(2019, 12, 31);
QTest::newRow("denormal-wrap")
<< testFileUrl("checkDate-denormal-wrap.qml")
<< QDate(2020, 2, 29);
QTest::newRow("October")
<< testFileUrl("checkDate-October.qml")
<< QDate(2019, 10, 3);
}
void tst_qqmlecmascript::checkDate()
{
QFETCH(const QUrl, source);
QFETCH(const QDate, date);
QQmlEngine e;
QQmlComponent component(&e, source);
QScopedPointer<QObject> obj(component.create());
MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
QVERIFY(object != nullptr);
QCOMPARE(object->dateProperty(), date);
QVERIFY(object->boolProperty());
}
void tst_qqmlecmascript::checkDateTime_data()
{
QTest::addColumn<QUrl>("source");
QTest::addColumn<QDateTime>("when");
// NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12.
QTest::newRow("denormal-March")
<< testFileUrl("checkDateTime-denormal-March.qml")
<< QDateTime(QDate(2019, 3, 1), QTime(0, 0, 0, 1), Qt::LocalTime);
QTest::newRow("denormal-leap")
<< testFileUrl("checkDateTime-denormal-leap.qml")
<< QDateTime(QDate(2020, 2, 29), QTime(23, 59, 59, 999), Qt::LocalTime);
QTest::newRow("denormal-hours")
<< testFileUrl("checkDateTime-denormal-hours.qml")
<< QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
QTest::newRow("denormal-minutes")
<< testFileUrl("checkDateTime-denormal-minutes.qml")
<< QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
QTest::newRow("denormal-seconds")
<< testFileUrl("checkDateTime-denormal-seconds.qml")
<< QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
QTest::newRow("October")
<< testFileUrl("checkDateTime-October.qml")
<< QDateTime(QDate(2019, 10, 3), QTime(12, 0), Qt::LocalTime);
}
void tst_qqmlecmascript::checkDateTime()
{
QFETCH(const QUrl, source);
QFETCH(const QDateTime, when);
QQmlEngine e;
QQmlComponent component(&e, source);
QScopedPointer<QObject> obj(component.create());
MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
QVERIFY(object != nullptr);
QCOMPARE(object->dateTimeProperty(), when);
QVERIFY(object->boolProperty());
}
void tst_qqmlecmascript::idShortcutInvalidates()
{
QQmlEngine engine;

View File

@ -129,6 +129,7 @@ private slots:
void crash_append_empty_array();
void dynamic_roles_crash_QTBUG_38907();
void nestedListModelIteration();
void undefinedAppendShouldCauseError();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@ -1694,6 +1695,35 @@ void tst_qqmllistmodel::nestedListModelIteration()
QScopedPointer<QObject>(component.create());
}
// QTBUG-63569
void tst_qqmllistmodel::undefinedAppendShouldCauseError()
{
QQmlEngine engine;
QQmlComponent component(&engine);
component.setData(
R"(import QtQuick 2.5
Item {
width: 640
height: 480
ListModel {
id : model
}
Component.onCompleted: {
var tempData = {
faulty: undefined
}
model.insert(0, tempData)
tempData.faulty = null
model.insert(0, tempData)
}
})",
QUrl());
QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: faulty is undefined. Adding an object with a undefined member does not create a role for it.");
QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: faulty is null. Adding an object with a null member does not create a role for it.");
QScopedPointer<QObject>(component.create());
}
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 basysKom GmbH.
** Contact: https://www.qt.io/licensing/
**
@ -110,8 +111,8 @@ void tst_qv4identifiertable::sweepCenterEntryInBucket()
table.asPropertyKey(entry2);
table.asPropertyKey(entry3);
QCOMPARE(table.size, 3);
QCOMPARE(table.alloc, 5);
QCOMPARE(table.size, 3u);
QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@ -153,8 +154,8 @@ void tst_qv4identifiertable::sweepLastEntryInBucket()
table.asPropertyKey(entry2);
table.asPropertyKey(entry3);
QCOMPARE(table.size, 3);
QCOMPARE(table.alloc, 5);
QCOMPARE(table.size, 3u);
QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@ -193,8 +194,8 @@ void tst_qv4identifiertable::sweepFirstEntryInSameBucketWithDifferingHash()
table.asPropertyKey(entry1);
table.asPropertyKey(entry2);
QCOMPARE(table.size, 2);
QCOMPARE(table.alloc, 5);
QCOMPARE(table.size, 2u);
QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@ -231,8 +232,8 @@ void tst_qv4identifiertable::dontSweepAcrossBucketBoundaries()
table.asPropertyKey(entry1);
table.asPropertyKey(entry2);
QCOMPARE(table.size, 2);
QCOMPARE(table.alloc, 5);
QCOMPARE(table.size, 2u);
QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@ -279,8 +280,8 @@ void tst_qv4identifiertable::sweepAcrossBucketBoundariesIfFirstBucketFull()
table.asPropertyKey(entry3);
table.asPropertyKey(entry4);
QCOMPARE(table.size, 4);
QCOMPARE(table.alloc, 11);
QCOMPARE(table.size, 4u);
QCOMPARE(table.alloc, 11u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@ -336,8 +337,8 @@ void tst_qv4identifiertable::sweepBucketGap()
table.asPropertyKey(entry3);
table.asPropertyKey(entry4);
QCOMPARE(table.size, 4);
QCOMPARE(table.alloc, 11);
QCOMPARE(table.size, 4u);
QCOMPARE(table.alloc, 11u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);

View File

@ -1946,6 +1946,31 @@ void tst_QQuickListView::enforceRange()
QTRY_COMPARE(listview->currentIndex(), 6);
// Test for [QTBUG-77418] {
// explicit set current index
listview->setCurrentIndex(5);
QTRY_COMPARE(listview->contentY(), 0);
// then check if contentY changes if the highlight range is changed
listview->setPreferredHighlightBegin(80);
listview->setPreferredHighlightEnd(80);
QTRY_COMPARE(listview->contentY(), 20);
// verify that current index does not change with no highlight
listview->setHighlightRangeMode(QQuickListView::NoHighlightRange);
listview->setContentY(100);
QTRY_COMPARE(listview->currentIndex(), 5);
// explicit set current index, contentY should not change now
listview->setCurrentIndex(6);
QTRY_COMPARE(listview->contentY(), 100);
QTest::qWait(50); // This was needed in order to reproduce a failure for the following test
// verify that contentY changes if we turn on highlight again
listview->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
QTRY_COMPARE(listview->contentY(), 40);
// } Test for [QTBUG-77418]
// change model
QaimModel model2;
for (int i = 0; i < 5; i++)

View File

@ -1616,16 +1616,55 @@ void tst_QQuickPathView::flickNClick() // QTBUG-77173
QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject());
QVERIFY(pathview != nullptr);
QSignalSpy movingChangedSpy(pathview, SIGNAL(movingChanged()));
QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged()));
QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted()));
QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded()));
QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged()));
QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted()));
QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded()));
QSignalSpy flickingSpy(pathview, SIGNAL(flickingChanged()));
QSignalSpy flickStartedSpy(pathview, SIGNAL(flickStarted()));
QSignalSpy flickEndedSpy(pathview, SIGNAL(flickEnded()));
for (int duration = 100; duration > 0; duration -= 20) {
movingChangedSpy.clear();
draggingSpy.clear();
dragStartedSpy.clear();
dragEndedSpy.clear();
currentIndexSpy.clear();
moveStartedSpy.clear();
moveEndedSpy.clear();
flickingSpy.clear();
flickStartedSpy.clear();
flickEndedSpy.clear();
// Dragging the child mouse area should animate the PathView (MA has no drag target)
flick(window.data(), QPoint(200,200), QPoint(400,200), duration);
QVERIFY(pathview->isMoving());
QCOMPARE(movingChangedSpy.count(), 1);
QCOMPARE(draggingSpy.count(), 2);
QCOMPARE(dragStartedSpy.count(), 1);
QCOMPARE(dragEndedSpy.count(), 1);
QVERIFY(currentIndexSpy.count() > 0);
QCOMPARE(moveStartedSpy.count(), 1);
QCOMPARE(moveEndedSpy.count(), 0);
QCOMPARE(flickingSpy.count(), 1);
QCOMPARE(flickStartedSpy.count(), 1);
QCOMPARE(flickEndedSpy.count(), 0);
// Now while it's still moving, click it.
// The PathView should stop at a position such that offset is a whole number.
QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(200, 200));
QTRY_VERIFY(!pathview->isMoving());
QCOMPARE(movingChangedSpy.count(), 2); // QTBUG-78926
QCOMPARE(draggingSpy.count(), 2);
QCOMPARE(dragStartedSpy.count(), 1);
QCOMPARE(dragEndedSpy.count(), 1);
QCOMPARE(moveStartedSpy.count(), 1);
QCOMPARE(moveEndedSpy.count(), 1);
QCOMPARE(flickingSpy.count(), 2);
QCOMPARE(flickStartedSpy.count(), 1);
QCOMPARE(flickEndedSpy.count(), 1);
QVERIFY(qFuzzyIsNull(pathview->offset() - int(pathview->offset())));
}
}