From 5539b4ab311501821eb0e971432d769a25000032 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Sat, 13 Jun 2009 12:23:35 +0200 Subject: Fix for selection with Shift-Arrow/Shift-Click in QListView's IconMode This addresses the selection of items using Shift-Arrow or Shift-Click in QListView's IconMode if the items are in a grid layout. In the case that the items do not have the same size (e.g., because their text is wrapped), this commit prevents the unexpected selection of additional items. New unit tests are included. Merge-request: 666 Reviewed-by: Olivier Goffart --- src/gui/itemviews/qlistview.cpp | 10 ++++- tests/auto/qlistview/tst_qlistview.cpp | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 40f28d4..148d204 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1563,7 +1563,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl } // middle rectangle if (top.bottom() < bottom.top()) { - middle.setTop(top.bottom() + 1); + if (gridSize().isValid() && !gridSize().isNull()) + middle.setTop(top.top() + gridSize().height()); + else + middle.setTop(top.bottom() + 1); middle.setLeft(qMin(top.left(), bottom.left())); middle.setBottom(bottom.top() - 1); middle.setRight(qMax(top.right(), bottom.right())); @@ -1590,7 +1593,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl // only set middle if the middle.setTop(0); middle.setBottom(ch); - middle.setLeft(left.right() + 1); + if (gridSize().isValid() && !gridSize().isNull()) + middle.setLeft(left.left() + gridSize().width()); + else + middle.setLeft(left.right() + 1); middle.setRight(right.left() - 1); } else if (left.bottom() < right.top()) { left.setBottom(right.top() - 1); diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index a18f037..cc80931 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -110,6 +110,7 @@ private slots: void task196118_visualRegionForSelection(); void task254449_draggingItemToNegativeCoordinates(); void keyboardSearch(); + void shiftSelectionWithNonUniformItemSizes(); }; // Testing get/set functions @@ -1656,5 +1657,71 @@ void tst_QListView::keyboardSearch() QCOMPARE(view.currentIndex() , model.index(6,0)); //KONQUEROR } +void tst_QListView::shiftSelectionWithNonUniformItemSizes() +{ + // This checks that no items are selected unexpectedly by Shift-Arrow + // when items with non-uniform sizes are laid out in a grid + { // First test: QListView::LeftToRight flow + QStringList items; + items << "Long\nText" << "Text" << "Text" << "Text"; + QStringListModel model(items); + + QListView view; + view.setFixedSize(250, 250); + view.setFlow(QListView::LeftToRight); + view.setGridSize(QSize(100, 100)); + view.setSelectionMode(QListView::ExtendedSelection); + view.setViewMode(QListView::IconMode); + view.setModel(&model); + view.show(); + QTest::qWait(30); + + // Verfify that item sizes are non-uniform + QVERIFY(view.sizeHintForIndex(model.index(0, 0)).height() > view.sizeHintForIndex(model.index(1, 0)).height()); + + QModelIndex index = model.index(3, 0); + view.setCurrentIndex(index); + QCOMPARE(view.currentIndex(), index); + + QTest::keyClick(&view, Qt::Key_Up, Qt::ShiftModifier); + QTest::qWait(10); + QCOMPARE(view.currentIndex(), model.index(1, 0)); + + QModelIndexList selected = view.selectionModel()->selectedIndexes(); + QCOMPARE(selected.count(), 3); + QVERIFY(!selected.contains(model.index(0, 0))); + } + { // Second test: QListView::TopToBottom flow + QStringList items; + items << "ab" << "a" << "a" << "a"; + QStringListModel model(items); + + QListView view; + view.setFixedSize(250, 250); + view.setFlow(QListView::TopToBottom); + view.setGridSize(QSize(100, 100)); + view.setSelectionMode(QListView::ExtendedSelection); + view.setViewMode(QListView::IconMode); + view.setModel(&model); + view.show(); + QTest::qWait(30); + + // Verfify that item sizes are non-uniform + QVERIFY(view.sizeHintForIndex(model.index(0, 0)).width() > view.sizeHintForIndex(model.index(1, 0)).width()); + + QModelIndex index = model.index(3, 0); + view.setCurrentIndex(index); + QCOMPARE(view.currentIndex(), index); + + QTest::keyClick(&view, Qt::Key_Left, Qt::ShiftModifier); + QTest::qWait(10); + QCOMPARE(view.currentIndex(), model.index(1, 0)); + + QModelIndexList selected = view.selectionModel()->selectedIndexes(); + QCOMPARE(selected.count(), 3); + QVERIFY(!selected.contains(model.index(0, 0))); + } +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" -- cgit v0.12