summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativelistview/data/qtbug14821.qml31
-rw-r--r--tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp21
3 files changed, 60 insertions, 0 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 6be49ba..450b6af 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -183,6 +183,7 @@ public:
, ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false)
, correctFlick(false), inFlickCorrection(false), lazyRelease(false)
, deferredRelease(false), layoutScheduled(false), currentIndexCleared(false)
+ , inViewportMoved(false)
, minExtentDirty(true), maxExtentDirty(true)
{}
@@ -503,6 +504,7 @@ public:
bool deferredRelease : 1;
bool layoutScheduled : 1;
bool currentIndexCleared : 1;
+ bool inViewportMoved : 1;
mutable bool minExtentDirty : 1;
mutable bool maxExtentDirty : 1;
};
@@ -2281,6 +2283,10 @@ void QDeclarativeListView::viewportMoved()
QDeclarativeFlickable::viewportMoved();
if (!d->itemCount)
return;
+ // Recursion can occur due to refill changing the content size.
+ if (d->inViewportMoved)
+ return;
+ d->inViewportMoved = true;
d->lazyRelease = true;
refill();
if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
@@ -2294,6 +2300,7 @@ void QDeclarativeListView::viewportMoved()
pos = viewPos + d->highlightRangeEnd - d->highlight->size();
if (pos < viewPos + d->highlightRangeStart)
pos = viewPos + d->highlightRangeStart;
+ d->highlightPosAnimator->stop();
d->highlight->setPosition(qRound(pos));
// update current index
@@ -2341,6 +2348,7 @@ void QDeclarativeListView::viewportMoved()
}
d->inFlickCorrection = false;
}
+ d->inViewportMoved = false;
}
qreal QDeclarativeListView::minYExtent() const
diff --git a/tests/auto/declarative/qdeclarativelistview/data/qtbug14821.qml b/tests/auto/declarative/qdeclarativelistview/data/qtbug14821.qml
new file mode 100644
index 0000000..e0303ec
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistview/data/qtbug14821.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+
+ListView {
+ id: view
+ width: 300; height: 200
+ focus: true
+ keyNavigationWraps: true
+
+ model: 100
+
+ preferredHighlightBegin: 90
+ preferredHighlightEnd: 110
+
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ highlight: Component {
+ Rectangle {
+ border.color: "blue"
+ border.width: 3
+ color: "transparent"
+ width: 300; height: 15
+ }
+ }
+
+ delegate: Component {
+ Item {
+ height: 15 + (view.currentIndex == index ? 20 : 0)
+ width: 200
+ Text { text: 'Index: ' + index; anchors.verticalCenter: parent.verticalCenter }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
index a4b4f21..37d836d 100644
--- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -101,6 +101,7 @@ private slots:
void footer();
void resizeView();
void sizeLessThan1();
+ void QTBUG_14821();
private:
template <class T> void items();
@@ -1768,6 +1769,26 @@ void tst_QDeclarativeListView::sizeLessThan1()
delete canvas;
}
+void tst_QDeclarativeListView::QTBUG_14821()
+{
+ QDeclarativeView *canvas = createView();
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug14821.qml"));
+ qApp->processEvents();
+
+ QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(canvas->rootObject());
+ QVERIFY(listview != 0);
+
+ QDeclarativeItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ listview->decrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 99);
+
+ listview->incrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 0);
+}
+
void tst_QDeclarativeListView::qListModelInterface_items()
{
items<TestModel>();