Fix QListWidget scrolling with keys when there are hidden items

If the selected item is scrolled with keyboard keys the selected item
will go outside the visible area. The scrolling did not take hidden
items into account when calculating the amount to be scrolled.

Task-number: QTBUG-21804
Change-Id: I63da0248cec43be464898f9dc8167e739f00ccd0
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
bb10
Jani Honkonen 2012-08-01 14:55:51 +03:00 committed by Qt by Nokia
parent f20472efa7
commit d4385e48b8
2 changed files with 62 additions and 3 deletions

View File

@ -2533,13 +2533,21 @@ int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int view
{
if (index < 0)
return scrollValue;
QVector<int> visibleFlowPositions;
visibleFlowPositions.reserve(flowPositions.count() - 1);
for (int i = 0; i < flowPositions.count() - 1; i++) { // flowPositions count is +1 larger than actual row count
if (!isHidden(i))
visibleFlowPositions.append(flowPositions.at(i));
}
if (!wrap) {
int topIndex = index;
const int bottomIndex = topIndex;
const int bottomCoordinate = flowPositions.at(index);
const int bottomCoordinate = visibleFlowPositions.at(index);
while (topIndex > 0 &&
(bottomCoordinate - flowPositions.at(topIndex-1) + itemExtent) <= (viewportSize)) {
(bottomCoordinate - visibleFlowPositions.at(topIndex - 1) + itemExtent) <= (viewportSize)) {
topIndex--;
}
@ -2559,7 +2567,7 @@ int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int view
? Qt::Horizontal : Qt::Vertical);
if (flowOrientation == orientation) { // scrolling in the "flow" direction
// ### wrapped scrolling in the flow direction
return flowPositions.at(index); // ### always pixel based for now
return visibleFlowPositions.at(index); // ### always pixel based for now
} else if (!segmentStartRows.isEmpty()) { // we are scrolling in the "segment" direction
int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.count() - 1);
int leftSegment = segment;

View File

@ -136,6 +136,8 @@ private slots:
void taskQTBUG_21115_scrollToAndHiddenItems();
void draggablePaintPairs_data();
void draggablePaintPairs();
void taskQTBUG_21804_hiddenItemsAndScrollingWithKeys_data();
void taskQTBUG_21804_hiddenItemsAndScrollingWithKeys();
};
// Testing get/set functions
@ -2156,6 +2158,55 @@ void tst_QListView::draggablePaintPairs()
}
}
void tst_QListView::taskQTBUG_21804_hiddenItemsAndScrollingWithKeys_data()
{
QTest::addColumn<int>("flow");
QTest::newRow("flow TopToBottom") << static_cast<int>(QListView::TopToBottom);
QTest::newRow("flow LeftToRight") << static_cast<int>(QListView::LeftToRight);
}
void tst_QListView::taskQTBUG_21804_hiddenItemsAndScrollingWithKeys()
{
QFETCH(int, flow);
// create some items to show
QStringListModel model;
QStringList list;
for (int i = 0; i < 60; i++)
list << QString::number(i);
model.setStringList(list);
// create listview
QListView lv;
lv.setFlow(static_cast<QListView::Flow>(flow));
lv.setModel(&model);
lv.show();
QTest::qWaitForWindowShown(&lv);
// hide every odd number row
for (int i = 1; i < model.rowCount(); i+=2)
lv.setRowHidden(i, true);
// scroll forward and check that selected item is visible always
for (int i = 0; i < model.rowCount()/2; i++) {
if (flow == QListView::TopToBottom)
QTest::keyClick(&lv, Qt::Key_Down);
else
QTest::keyClick(&lv, Qt::Key_Right);
QTest::qWait(100);
QVERIFY(lv.rect().contains(lv.visualRect(lv.currentIndex())));
}
// scroll backward
for (int i = 0; i < model.rowCount()/2; i++) {
if (flow == QListView::TopToBottom)
QTest::keyClick(&lv, Qt::Key_Up);
else
QTest::keyClick(&lv, Qt::Key_Left);
QTest::qWait(100);
QVERIFY(lv.rect().contains(lv.visualRect(lv.currentIndex())));
}
}
QTEST_MAIN(tst_QListView)
#include "tst_qlistview.moc"