Fix PathView not updating after all items are removed from the model.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Fri, 25 May 2012 01:41:17 +0000 (11:41 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 28 May 2012 03:30:34 +0000 (05:30 +0200)
Always clear the layoutScheduled flag on a refill even if there are no
items to create, otherwise future layouts won't be scheduled because
it appears one is already pending.

Fixes an issue in the dragselection example where items that should
have moved to the PathView instead disappeared.

Change-Id: I4302b5b43184c697a78f5c09dc3811326e2271ca
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/quick/items/qquickpathview.cpp
tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
tests/auto/quick/qquickpositioners/qquickpositioners.pro
tests/auto/quick/shared/util.pri
tests/auto/quick/shared/viewtestutil.h
tests/auto/quick/shared/visualtestutil.h

index 1561dbc..08d20ac 100644 (file)
@@ -1573,10 +1573,12 @@ void QQuickPathView::componentComplete()
 void QQuickPathView::refill()
 {
     Q_D(QQuickPathView);
+
+    d->layoutScheduled = false;
+
     if (!d->isValid() || !isComponentComplete())
         return;
 
-    d->layoutScheduled = false;
     bool currentVisible = false;
 
     // first move existing items and remove items off path
index 2a67405..8d4453a 100644 (file)
@@ -46,7 +46,6 @@
 #include <QtQml/qqmlcontext.h>
 #include <QtQml/qqmlexpression.h>
 #include <QtQml/qqmlincubator.h>
-#include <QtQuick/private/qquickitem_p.h>
 #include <QtQuick/private/qquicklistview_p.h>
 #include <QtQuick/private/qquicktext_p.h>
 #include <QtQuick/private/qquickvisualitemmodel_p.h>
index 057eb2c..ec863d8 100644 (file)
@@ -63,6 +63,7 @@
 using namespace QQuickViewTestUtil;
 using namespace QQuickVisualTestUtil;
 
+Q_DECLARE_METATYPE(QQuickPathView::HighlightRangeMode)
 
 static void initStandardTreeModel(QStandardItemModel *model)
 {
@@ -101,6 +102,8 @@ private slots:
     void removeModel();
     void moveModel_data();
     void moveModel();
+    void consecutiveModelChanges_data();
+    void consecutiveModelChanges();
     void path();
     void pathMoved();
     void setCurrentIndex();
@@ -529,6 +532,127 @@ void tst_QQuickPathView::moveModel()
     delete canvas;
 }
 
+void tst_QQuickPathView::consecutiveModelChanges_data()
+{
+    QTest::addColumn<QQuickPathView::HighlightRangeMode>("mode");
+    QTest::addColumn<QList<ListChange> >("changes");
+    QTest::addColumn<int>("count");
+    QTest::addColumn<qreal>("offset");
+
+    QTest::newRow("no range - insert after, insert before")
+            << QQuickPathView::NoHighlightRange
+            << (QList<ListChange>()
+                << ListChange::insert(7, 2)
+                << ListChange::insert(1, 3))
+            << 13
+            << 6.;
+    QTest::newRow("no range - remove after, remove before")
+            << QQuickPathView::NoHighlightRange
+            << (QList<ListChange>()
+                << ListChange::remove(6, 2)
+                << ListChange::remove(1, 3))
+            << 3
+            << 2.;
+
+    QTest::newRow("no range - remove after, insert before")
+            << QQuickPathView::NoHighlightRange
+            << (QList<ListChange>()
+                << ListChange::remove(5, 2)
+                << ListChange::insert(1, 3))
+            << 9
+            << 2.;
+
+    QTest::newRow("no range - insert after, remove before")
+            << QQuickPathView::NoHighlightRange
+            << (QList<ListChange>()
+                << ListChange::insert(6, 2)
+                << ListChange::remove(1, 3))
+            << 7
+            << 6.;
+
+    QTest::newRow("no range - insert, remove all, polish, insert")
+            << QQuickPathView::NoHighlightRange
+            << (QList<ListChange>()
+                << ListChange::insert(3, 1)
+                << ListChange::remove(0, 9)
+                << ListChange::polish()
+                << ListChange::insert(0, 3))
+            << 3
+            << 0.;
+}
+
+void tst_QQuickPathView::consecutiveModelChanges()
+{
+    QFETCH(QQuickPathView::HighlightRangeMode, mode);
+    QFETCH(QList<ListChange>, changes);
+    QFETCH(int, count);
+    QFETCH(qreal, offset);
+
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    QaimModel model;
+    model.addItem("Ben", "12345");
+    model.addItem("Bohn", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Bill", "4321");
+    model.addItem("Jinny", "679");
+    model.addItem("Milly", "73378");
+    model.addItem("Jimmy", "3535");
+    model.addItem("Barb", "9039");
+
+    QQmlContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(testFileUrl("pathview0.qml"));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+    QVERIFY(pathview != 0);
+
+    pathview->setHighlightRangeMode(mode);
+
+    pathview->setCurrentIndex(4);
+    if (mode == QQuickPathView::StrictlyEnforceRange)
+        QTRY_COMPARE(pathview->offset(), 4.0);
+    else
+        pathview->setOffset(4);
+
+    for (int i=0; i<changes.count(); i++) {
+        switch (changes[i].type) {
+            case ListChange::Inserted:
+            {
+                QList<QPair<QString, QString> > items;
+                for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
+                    items << qMakePair(QString("new item %1").arg(j), QString::number(j));
+                model.insertItems(changes[i].index, items);
+                break;
+            }
+            case ListChange::Removed:
+                model.removeItems(changes[i].index, changes[i].count);
+                break;
+            case ListChange::Moved:
+                model.moveItems(changes[i].index, changes[i].to, changes[i].count);
+                break;
+            case ListChange::SetCurrent:
+                pathview->setCurrentIndex(changes[i].index);
+                break;
+        case ListChange::Polish:
+                QQUICK_VERIFY_POLISH(pathview);
+                break;
+            default:
+                continue;
+        }
+    }
+    QQUICK_VERIFY_POLISH(pathview);
+
+    QCOMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), count);
+    QCOMPARE(pathview->count(), count);
+    QTRY_COMPARE(pathview->offset(), offset);
+
+    delete canvas;
+}
+
 void tst_QQuickPathView::path()
 {
     QQmlEngine engine;
index e4fce55..2092b1a 100644 (file)
@@ -11,4 +11,4 @@ macx:CONFIG -= app_bundle
 TESTDATA = data/*
 
 CONFIG += parallel_test
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += testlib
index aa79c7c..28036f1 100644 (file)
@@ -1,4 +1,6 @@
 
+QT += core-private gui-private v8-private qml-private quick-private
+
 HEADERS += $$PWD/visualtestutil.h \
            $$PWD/viewtestutil.h
 SOURCES += $$PWD/visualtestutil.cpp \
index 06efd9c..10ecd6a 100644 (file)
@@ -60,7 +60,7 @@ namespace QQuickViewTestUtil
     QList<int> adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count);
 
     struct ListChange {
-        enum { Inserted, Removed, Moved, SetCurrent, SetContentY } type;
+        enum { Inserted, Removed, Moved, SetCurrent, SetContentY, Polish } type;
         int index;
         int count;
         int to;     // Move
@@ -71,6 +71,7 @@ namespace QQuickViewTestUtil
         static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to, 0.0 }; return c; }
         static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1, 0.0 }; return c; }
         static ListChange setContentY(qreal pos) { ListChange c = { SetContentY, -1, -1, -1, pos }; return c; }
+        static ListChange polish() { ListChange c = { Polish, -1, -1, -1, 0.0 }; return c; }
     };
 
     class QmlListModel : public QListModelInterface
index 9407ff8..c2fc9cc 100644 (file)
@@ -45,6 +45,8 @@
 #include <QtQuick/QQuickItem>
 #include <QtQml/QQmlExpression>
 
+#include <QtQuick/private/qquickitem_p.h>
+
 namespace QQuickVisualTestUtil
 {
     QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName);
@@ -106,7 +108,9 @@ namespace QQuickVisualTestUtil
             items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i]));
         return items;
     }
-
 }
 
+#define QQUICK_VERIFY_POLISH(item) \
+    QTRY_COMPARE(QQuickItemPrivate::get(item)->polishScheduled, false)
+
 #endif // QQUICKVISUALTESTUTIL_H