From da44e5e0b2237fa1019caeecf854aa95a4b360d8 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Tue, 9 Nov 2010 08:23:33 +0000 Subject: [PATCH] Add unit test for bug 217447. To make it work, I had to make DolphinTreeView::indexAt public, but this method is public in the base class anyway. svn path=/trunk/KDE/kdebase/apps/; revision=1194511 --- src/tests/dolphindetailsviewtest.cpp | 91 ++++++++++++++++++++++++++++ src/views/dolphintreeview.h | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/tests/dolphindetailsviewtest.cpp b/src/tests/dolphindetailsviewtest.cpp index bf77830f7..323806a0e 100644 --- a/src/tests/dolphindetailsviewtest.cpp +++ b/src/tests/dolphindetailsviewtest.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include #include "kdebug.h" @@ -42,6 +44,7 @@ private slots: void initTestCase(); + void bug217447_shiftArrowSelection(); void bug234600_overlappingIconsWhenZooming(); }; @@ -53,6 +56,94 @@ void DolphinDetailsViewTest::initTestCase() qputenv("KDE_DEBUG_TIMESTAMP", QByteArray("1")); } +/** + * When the first item in the view is active and Shift is held while the "arrow down" + * key is pressed repeatedly, the selection should grow by one item for each key press. + * A change in Qt 4.6 revealed a bug in DolphinDetailsView which broke this, see + * + * https://bugs.kde.org/show_bug.cgi?id=217447 + * + * The problem was that DolphinDetailsView, which uses not the full width of the "Name" + * column for an item, but only the width of the actual file name, did not reimplement + * QTreeView::visualRect(). This caused item selection to fail because QAbstractItemView + * uses the center of the visualRect of an item internally. If the width of the file name + * is less than half the width of the "Name" column, the center of an item's visualRect + * was therefore outside the space that DolphinDetailsView actually assigned to the + * item, and this led to unexpected deselection of items. + * + * TODO: To make the test more reliable, one could adjust the width of the "Name" + * column before the test in order to really make sure that the column is more than twice + * as wide as the space actually occupied by the file names (this triggers the bug). + */ + +void DolphinDetailsViewTest::bug217447_shiftArrowSelection() +{ + for (int i = 0; i < 100; i++) { + createFile(QString("%1").arg(i)); + } + + m_view->setMode(DolphinView::DetailsView); + DolphinDetailsView* detailsView = qobject_cast(itemView()); + QVERIFY(detailsView); + m_view->resize(1000, 400); + m_view->show(); + QTest::qWaitForWindowShown(m_view); + + // We have to make sure that the view has loaded the directory before we start the test. + // TODO: This will be needed frequently. Maybe move to TestHelper. + QSignalSpy finished(m_view, SIGNAL(finishedPathLoading(const KUrl&))); + m_view->reload(); + while (finished.count() != 1) { + QTest::qWait(50); + } + + // Select the first item + QModelIndex index0 = detailsView->model()->index(0, 0); + detailsView->setCurrentIndex(index0); + QCOMPARE(detailsView->currentIndex(), index0); + + // Before we test Shift-selection, we verify that the root cause is fixed a bit more + // directly: we check that passing the corners or the center of an item's visualRect + // to itemAt() returns the item (and not an invalid model index). + QRect rect = detailsView->visualRect(index0); + QCOMPARE(detailsView->indexAt(rect.center()), index0); + QCOMPARE(detailsView->indexAt(rect.topLeft()), index0); + QCOMPARE(detailsView->indexAt(rect.topRight()), index0); + QCOMPARE(detailsView->indexAt(rect.bottomLeft()), index0); + QCOMPARE(detailsView->indexAt(rect.bottomRight()), index0); + + // Another way to test this is to Ctrl-click the center of the visualRect. + // The selection state of the item should be toggled. + detailsView->clearSelection(); + QItemSelectionModel* selectionModel = detailsView->selectionModel(); + QCOMPARE(selectionModel->selectedIndexes().count(), 0); + + QTest::mouseClick(detailsView->viewport(), Qt::LeftButton, Qt::ControlModifier, rect.center()); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + QCOMPARE(selectedIndexes.count(), 1); + QVERIFY(selectedIndexes.contains(index0)); + + // Now we go down item by item using Shift+Down. In each step, we check that the current item + // is added to the selection and that the size of the selection grows by one. + + int current = 1; + + while (current < 100) { + QTest::keyClick(detailsView->viewport(), Qt::Key_Down, Qt::ShiftModifier); + QModelIndex currentIndex = detailsView->model()->index(current, 0); + QCOMPARE(detailsView->currentIndex(), currentIndex); + + selectedIndexes = selectionModel->selectedIndexes(); + QCOMPARE(selectedIndexes.count(), current + 1); + QVERIFY(selectedIndexes.contains(currentIndex)); + + current++; + } + + m_view->hide(); + cleanupTestDir(); +} + /** * When the icon size is changed, we have to make sure that the maximumSize given * to KFileItemDelegate for rendering each item is updated correctly. If this is not diff --git a/src/views/dolphintreeview.h b/src/views/dolphintreeview.h index 67f8eedf2..4eb00c101 100644 --- a/src/views/dolphintreeview.h +++ b/src/views/dolphintreeview.h @@ -40,6 +40,7 @@ public: explicit DolphinTreeView(QWidget* parent = 0); virtual ~DolphinTreeView(); + virtual QModelIndex indexAt (const QPoint& point) const; virtual QRegion visualRegionForSelection(const QItemSelection& selection) const; protected: @@ -62,7 +63,6 @@ protected: virtual void keyPressEvent(QKeyEvent* event); virtual void keyReleaseEvent(QKeyEvent* event); virtual void currentChanged(const QModelIndex& current, const QModelIndex& previous); - virtual QModelIndex indexAt (const QPoint& point) const; virtual void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command); virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible); -- 2.47.3