From cfc3564328c9545a9eed4aca02f99dac5e0e4390 Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Tue, 31 Aug 2010 12:38:12 +1000
Subject: Ensure Flickable visibleArea is updated when view height changes

Task-number: QTBUG-13095
---
 .../graphicsitems/qdeclarativeflickable.cpp        |  4 ++
 .../graphicsitems/qdeclarativelistview.cpp         | 10 +++++
 .../graphicsitems/qdeclarativelistview_p.h         |  1 +
 .../qdeclarativelistview/data/listviewtest.qml     |  6 +++
 .../tst_qdeclarativelistview.cpp                   | 43 ++++++++++++++++++++++
 5 files changed, 64 insertions(+)

diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index a710190..63a2a77 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -1001,12 +1001,16 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
 
     bool changed = false;
     if (newGeometry.width() != oldGeometry.width()) {
+        if (xflick())
+            changed = true;
         if (d->hData.viewSize < 0) {
             d->contentItem->setWidth(width());
             emit contentWidthChanged();
         }
     }
     if (newGeometry.height() != oldGeometry.height()) {
+        if (yflick())
+            changed = true;
         if (d->vData.viewSize < 0) {
             d->contentItem->setHeight(height());
             emit contentHeightChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index d3d46f7..ef28ab2 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -2454,6 +2454,16 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event)
     QDeclarativeFlickable::keyPressEvent(event);
 }
 
+void QDeclarativeListView::geometryChanged(const QRectF &newGeometry,
+                             const QRectF &oldGeometry)
+{
+    Q_D(QDeclarativeListView);
+    d->maxExtentDirty = true;
+    d->minExtentDirty = true;
+    QDeclarativeFlickable::geometryChanged(newGeometry, oldGeometry);
+}
+
+
 /*!
     \qmlmethod ListView::incrementCurrentIndex()
 
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 8fbff49..735b248 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -246,6 +246,7 @@ protected:
     virtual qreal minXExtent() const;
     virtual qreal maxXExtent() const;
     virtual void keyPressEvent(QKeyEvent *);
+    virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
     virtual void componentComplete();
 
 private Q_SLOTS:
diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml
index 3b2db5e..d5d3365 100644
--- a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml
+++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml
@@ -4,6 +4,12 @@ Rectangle {
     width: 240
     height: 320
     color: "#ffffff"
+
+    property real hr: list.visibleArea.heightRatio
+    function heightRatio() {
+        return list.visibleArea.heightRatio
+    }
+
     function checkProperties() {
         testObject.error = false;
         if (list.model != testModel) {
diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
index bf4754d..377a9e5 100644
--- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -98,6 +98,7 @@ private slots:
     void manualHighlight();
     void QTBUG_11105();
     void footer();
+    void resizeView();
 
 private:
     template <class T> void items();
@@ -1591,6 +1592,48 @@ void tst_QDeclarativeListView::footer()
     QTRY_COMPARE(footer->y(), 0.0);
 }
 
+void tst_QDeclarativeListView::resizeView()
+{
+    QDeclarativeView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 40; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+    qApp->processEvents();
+
+    QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QDeclarativeItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    QVariant heightRatio;
+    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
+    QCOMPARE(heightRatio.toReal(), 0.4);
+
+    listview->setHeight(200);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
+    QCOMPARE(heightRatio.toReal(), 0.25);
+}
+
 void tst_QDeclarativeListView::qListModelInterface_items()
 {
     items<TestModel>();
-- 
cgit v0.12