Parent:     f5a4e984 (QQuickTextInputPrivate: refactor getImplicitWidth() to calculateImplicitWidth())
Author:     David Redondo <qt@david-redondo.de>
AuthorDate: 2020-05-13 11:04:23 +0200
Commit:     Mitch Curtis <mitch.curtis@qt.io>
CommitDate: 2020-05-25 10:58:35 +0200

QQuickItemView: Fix max(X/Y)Extent()

QQuickFlickable maxXExtent() and maxYExtent() return the amount of space
that is not shown when inside a ScrollView. QQuickItemView however just
returned width() if vertical and height() if horizontal. In these cases
just defer to the QQuickFlickable base implementation like minXExtent()
and minYExtent() already do.

This change also adds tst_qquicklistview2 to speed up development.
tst_QQuickListView is almost 9000 lines long, and compiling it
is slow. In addition, a similar approach (creating a second test to
avoid the slowness of a massive one) already exists for QQuickItem
tests.

Fixes: QTBUG-83890
Pick-to: 5.15
Change-Id: I7f4060c2f46ae07611bedceca0d322c5f7f6affb
========================================================================================================================
Index: qtdeclarative-everywhere-src-5.15.2/src/quick/items/qquickitemview.cpp
===================================================================
--- qtdeclarative-everywhere-src-5.15.2.orig/src/quick/items/qquickitemview.cpp
+++ qtdeclarative-everywhere-src-5.15.2/src/quick/items/qquickitemview.cpp
@@ -1393,7 +1393,7 @@ qreal QQuickItemView::maxYExtent() const
 {
     Q_D(const QQuickItemView);
     if (d->layoutOrientation() == Qt::Horizontal)
-        return height();
+        return QQuickFlickable::maxYExtent();
 
     if (d->vData.maxExtentDirty) {
         d->maxExtent = d->maxExtentForAxis(d->vData, false);
@@ -1421,7 +1421,7 @@ qreal QQuickItemView::maxXExtent() const
 {
     Q_D(const QQuickItemView);
     if (d->layoutOrientation() == Qt::Vertical)
-        return width();
+        return QQuickFlickable::maxXExtent();
 
     if (d->hData.maxExtentDirty) {
         d->maxExtent = d->maxExtentForAxis(d->hData, true);
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
===================================================================
--- qtdeclarative-everywhere-src-5.15.2.orig/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -73,6 +73,8 @@ public:
     tst_QQuickListView();
 
 private slots:
+    // WARNING: please add new tests to tst_qquicklistview2; this file is too slow to work with.
+
     void init();
     void cleanupTestCase();
     // Test QAbstractItemModel model types
@@ -299,6 +301,8 @@ private slots:
     void requiredObjectListModel();
     void clickHeaderAndFooterWhenClip();
 
+    // WARNING: please add new tests to tst_qquicklistview2; this file is too slow to work with.
+
 private:
     template <class T> void items(const QUrl &source);
     template <class T> void changed(const QUrl &source);
@@ -10094,6 +10098,8 @@ void tst_QQuickListView::clickHeaderAndF
     QVERIFY(root->property("footerPressed").toBool());
 }
 
+// WARNING: please add new tests to tst_qquicklistview2; this file is too slow to work with.
+
 QTEST_MAIN(tst_QQuickListView)
 
 #include "tst_qquicklistview.moc"
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/data/maxXExtent.qml
===================================================================
--- /dev/null
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/data/maxXExtent.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+Item {
+    property alias view: view
+
+    ListView {
+        id: view
+        model: 10
+        width: 200
+        height: 200
+
+        Rectangle {
+            anchors.fill: parent
+            color: "transparent"
+            border.color: "darkorange"
+        }
+
+        delegate: Rectangle {
+            width: 100
+            height: 100
+            Text {
+                text: modelData
+            }
+        }
+    }
+}
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/data/maxYExtent.qml
===================================================================
--- /dev/null
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/data/maxYExtent.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+Item {
+    property alias view: view
+
+    ListView {
+        id: view
+        model: 10
+        width: 200
+        height: 200
+        orientation: ListView.Horizontal
+
+        Rectangle {
+            anchors.fill: parent
+            color: "transparent"
+            border.color: "darkorange"
+        }
+
+        delegate: Rectangle {
+            width: 100
+            height: 100
+            Text {
+                text: modelData
+            }
+        }
+    }
+}
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/qquicklistview2.pro
===================================================================
--- /dev/null
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/qquicklistview2.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquicklistview2
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquicklistview2.cpp
+
+include (../../shared/util.pri)
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += core-private gui-private qml-private quick-private testlib qmltest
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
===================================================================
--- /dev/null
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtQuickTest/QtQuickTest>
+#include <QtQml/qqmlapplicationengine.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/private/qquicklistview_p.h>
+
+#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
+
+using namespace QQuickViewTestUtil;
+
+class tst_QQuickListView2 : public QQmlDataTest
+{
+    Q_OBJECT
+
+public:
+    tst_QQuickListView2();
+
+private slots:
+    void maxExtent_data();
+    void maxExtent();
+};
+
+tst_QQuickListView2::tst_QQuickListView2()
+{
+}
+
+class FriendlyItemView : public QQuickItemView
+{
+    friend class ItemViewAccessor;
+};
+
+class ItemViewAccessor
+{
+public:
+    ItemViewAccessor(QQuickItemView *itemView) :
+        mItemView(reinterpret_cast<FriendlyItemView*>(itemView))
+    {
+    }
+
+    qreal maxXExtent() const
+    {
+        return mItemView->maxXExtent();
+    }
+
+    qreal maxYExtent() const
+    {
+        return mItemView->maxYExtent();
+    }
+
+private:
+    FriendlyItemView *mItemView = nullptr;
+};
+
+void tst_QQuickListView2::maxExtent_data()
+{
+    QTest::addColumn<QString>("qmlFilePath");
+
+    QTest::addRow("maxXExtent") << "maxXExtent.qml";
+    QTest::addRow("maxYExtent") << "maxYExtent.qml";
+}
+
+void tst_QQuickListView2::maxExtent()
+{
+    QFETCH(QString, qmlFilePath);
+
+    QScopedPointer<QQuickView> window(createView());
+    QVERIFY(window);
+    window->setSource(testFileUrl(qmlFilePath));
+    QVERIFY2(window->status() == QQuickView::Ready, qPrintable(QDebug::toString(window->errors())));
+    window->resize(640, 480);
+    window->show();
+    QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+    QQuickListView *view = window->rootObject()->property("view").value<QQuickListView*>();
+    QVERIFY(view);
+    ItemViewAccessor viewAccessor(view);
+    if (view->orientation() == QQuickListView::Vertical)
+        QCOMPARE(viewAccessor.maxXExtent(), 0);
+    else if (view->orientation() == QQuickListView::Horizontal)
+        QCOMPARE(viewAccessor.maxYExtent(), 0);
+}
+
+QTEST_MAIN(tst_QQuickListView2)
+
+#include "tst_qquicklistview2.moc"
Index: qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/quick.pro
===================================================================
--- qtdeclarative-everywhere-src-5.15.2.orig/tests/auto/quick/quick.pro
+++ qtdeclarative-everywhere-src-5.15.2/tests/auto/quick/quick.pro
@@ -67,6 +67,7 @@ QUICKTESTS += \
     qquickitem2 \
     qquickitemlayer \
     qquicklistview \
+    qquicklistview2 \
     qquicktableview \
     qquickloader \
     qquickmousearea \
