summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/itemviews/qlistview.cpp24
-rw-r--r--src/gui/itemviews/qlistview_p.h1
-rw-r--r--tests/auto/qlistview/tst_qlistview.cpp25
3 files changed, 43 insertions, 7 deletions
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 1d9b6e0..88002e0 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -1900,7 +1900,7 @@ void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
&& ((flow() == QListView::TopToBottom && !isWrapping())
|| (flow() == QListView::LeftToRight && isWrapping()))) {
- const int steps = (flow() == QListView::TopToBottom ? flowPositions : segmentPositions).count() - 1;
+ const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1;
if (steps > 0) {
const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
verticalScrollBar()->setSingleStep(1);
@@ -1939,7 +1939,7 @@ int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hi
bool above, bool below, const QRect &area, const QRect &rect) const
{
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int value = qBound(0, verticalScrollBar()->value(), flowPositions.count() - 1);
+ int value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()), flowPositions.count() - 1);
if (above)
hint = QListView::PositionAtTop;
else if (below)
@@ -1986,9 +1986,9 @@ int QListModeViewBase::verticalOffset() const
}
} else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
int value = verticalScrollBar()->value();
- if (value > flowPositions.count())
+ if (value > scrollValueMap.count())
return 0;
- return flowPositions.at(value) - spacing();
+ return flowPositions.at(scrollValueMap.at(value)) - spacing();
}
}
return QCommonListViewBase::verticalOffset();
@@ -2043,8 +2043,8 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
if (vertical && flow() == QListView::TopToBottom && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = flowPositions.at(currentValue);
- int previousCoordinate = flowPositions.at(previousValue);
+ int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
+ int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
dy = previousCoordinate - currentCoordinate;
} else if (horizontal && flow() == QListView::LeftToRight && dx != 0) {
int currentValue = qBound(0, horizontalValue, max);
@@ -2113,6 +2113,7 @@ QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
segmentPositions.clear();
segmentStartRows.clear();
segmentExtents.clear();
+ scrollValueMap.clear();
x = info.bounds.left() + info.spacing;
y = info.bounds.top() + info.spacing;
segmentPositions.append(info.flow == QListView::LeftToRight ? y : x);
@@ -2204,6 +2205,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
deltaSegPosition = 0;
}
// save the flow position of this item
+ scrollValueMap.append(flowPositions.count());
flowPositions.append(flowPosition);
// prepare for the next item
deltaSegPosition = qMax(deltaSegHint, deltaSegPosition);
@@ -2229,6 +2231,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
// if it is the last batch, save the end of the segments
if (info.last == info.max) {
segmentExtents.append(flowPosition);
+ scrollValueMap.append(flowPositions.count());
flowPositions.append(flowPosition);
segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX);
}
@@ -2306,7 +2309,14 @@ QRect QListModeViewBase::mapToViewport(const QRect &rect) const
int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
{
- const QVector<int> positions = (wrap ? segmentPositions : flowPositions);
+ QVector<int> positions;
+ if (wrap)
+ positions = segmentPositions;
+ else {
+ positions.reserve(scrollValueMap.size());
+ foreach (int itemShown, scrollValueMap)
+ positions.append(flowPositions.at(itemShown));
+ }
if (positions.isEmpty() || bounds <= length)
return positions.count();
if (uniformItemSizes()) {
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index b6785da..de4c7f3 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -205,6 +205,7 @@ public:
QVector<int> segmentPositions;
QVector<int> segmentStartRows;
QVector<int> segmentExtents;
+ QVector<int> scrollValueMap;
// used when laying out in batches
int batchSavedPosition;
diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp
index 3ee6889..ed02317 100644
--- a/tests/auto/qlistview/tst_qlistview.cpp
+++ b/tests/auto/qlistview/tst_qlistview.cpp
@@ -117,6 +117,7 @@ private slots:
void shiftSelectionWithNonUniformItemSizes();
void clickOnViewportClearsSelection();
void task262152_setModelColumnNavigate();
+ void taskQTBUG_2233_scrollHiddenRows();
};
// Testing get/set functions
@@ -1790,7 +1791,31 @@ void tst_QListView::task262152_setModelColumnNavigate()
}
+void tst_QListView::taskQTBUG_2233_scrollHiddenRows()
+{
+ const int rowCount = 200;
+
+ QListView view;
+ QStringListModel model(&view);
+ QStringList list;
+ for (int i = 0; i < rowCount; ++i)
+ list << QString::fromAscii("Item %1").arg(i);
+
+ model.setStringList(list);
+ view.setModel(&model);
+ view.setViewMode(QListView::ListMode);
+ view.setFlow(QListView::TopToBottom);
+ for (int i = 0; i < rowCount / 2; ++i)
+ view.setRowHidden(2 * i, true);
+ view.resize(250, 130);
+ for (int i = 0; i < 10; ++i) {
+ view.verticalScrollBar()->setValue(i);
+ QModelIndex index = view.indexAt(QPoint(20,0));
+ QVERIFY(index.isValid());
+ QCOMPARE(index.row(), 2 * i + 1);
+ }
+}
QTEST_MAIN(tst_QListView)
#include "tst_qlistview.moc"