diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-05-28 16:32:52 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-06-03 19:37:46 +0200 |
commit | 17c1ebf8bfd254ff75cc55e335d1c1fb01da547f (patch) | |
tree | 6af3a26a7addc528b0379b81510d7ad751f73ec5 /tests/auto/widgets | |
parent | 491ea140df524a8ea6bafe08b5375583113e5248 (diff) |
QAbstractItemView: don't block dragging after double click
After d6551fe12520 it was no longer possible to start a drag with a
double click (where the first click selects an item, and the second
press+move starts the drag). Resetting the pressedItem variable to block
the emission of the clicked() signal had this unwanted side effect.
Instead, use an explicit boolean to store that the next release event
will be the result of a double click, so that the clicked() signal is not
emitted again (preventing the double-emission was the purpose of change
d6551fe12520).
Task-number: QTBUG-77771
Fixes: QTBUG-94087
Pick-to: 6.1 5.15
Change-Id: I082c5169d89eb980dcd7985ef3d302b6ff060fb9
Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Reviewed-by: Olivier BARTHELEMY <perso.olivier.barthelemy@gmail.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r-- | tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 10320c80d6..3d851dc10c 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -154,6 +154,8 @@ private slots: void checkFocusAfterActivationChanges_data(); void checkFocusAfterActivationChanges(); void dragSelectAfterNewPress(); + void dragWithSecondClick_data(); + void dragWithSecondClick(); void selectionCommand_data(); void selectionCommand(); private: @@ -2600,6 +2602,99 @@ void tst_QAbstractItemView::dragSelectAfterNewPress() QVERIFY(selected.contains(model.index(i, 0))); } +void tst_QAbstractItemView::dragWithSecondClick_data() +{ + QTest::addColumn<QString>("viewClass"); + QTest::addColumn<bool>("doubleClick"); + for (QString viewClass : {"QListView", "QTreeView"}) { + QTest::addRow("DoubleClick") << viewClass << true; + QTest::addRow("Two Single Clicks") << viewClass << false; + } +} + +// inject the ability to record which indexes get dragged into any QAbstractItemView class +struct DragRecorder +{ + virtual ~DragRecorder() = default; + bool dragStarted = false; + QModelIndexList draggedIndexes; + QAbstractItemView *view; +}; + +template<class ViewClass> +class DragRecorderView : public ViewClass, public DragRecorder +{ +public: + DragRecorderView() + { view = this; } +protected: + void startDrag(Qt::DropActions) override + { + draggedIndexes = ViewClass::selectedIndexes(); + dragStarted = true; + } +}; + +void tst_QAbstractItemView::dragWithSecondClick() +{ + QFETCH(QString, viewClass); + QFETCH(bool, doubleClick); + + QStandardItemModel model; + QStandardItem *parentItem = model.invisibleRootItem(); + for (int i = 0; i < 10; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + item->setDragEnabled(true); + item->setEditable(false); + parentItem->appendRow(item); + } + + std::unique_ptr<DragRecorder> dragRecorder; + if (viewClass == "QTreeView") + dragRecorder.reset(new DragRecorderView<QTreeView>); + else if (viewClass == "QListView") + dragRecorder.reset(new DragRecorderView<QListView>); + + QAbstractItemView *view = dragRecorder->view; + view->setModel(&model); + view->setFixedSize(160, 650); // Minimum width for windows with frame on Windows 8 + view->setSelectionMode(QAbstractItemView::MultiSelection); + view->setDragDropMode(QAbstractItemView::InternalMove); + centerOnScreen(view); + moveCursorAway(view); + view->show(); + QVERIFY(QTest::qWaitForWindowExposed(view)); + + QModelIndex index0 = model.index(0, 0); + QModelIndex index1 = model.index(1, 0); + // Select item 0 using a single click + QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, + view->visualRect(index0).center()); + QCOMPARE(view->currentIndex(), index0); + + if (doubleClick) { + // press on same item within the double click interval + QTest::mouseDClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, + view->visualRect(index0).center()); + } else { + // or on different item with a slow second press + QTest::mousePress(view->viewport(), Qt::LeftButton, Qt::NoModifier, + view->visualRect(index1).center()); + } + // then drag far enough with left button held + const QPoint dragTo = view->visualRect(index1).center() + + QPoint(2 * QApplication::startDragDistance(), + 2 * QApplication::startDragDistance()); + QMouseEvent mouseMoveEvent(QEvent::MouseMove, dragTo, + Qt::NoButton, Qt::LeftButton, Qt::NoModifier); + QVERIFY(QApplication::sendEvent(view->viewport(), &mouseMoveEvent)); + // twice since the view will first enter dragging state, then start the drag + // (not necessary to actually move the mouse) + QVERIFY(QApplication::sendEvent(view->viewport(), &mouseMoveEvent)); + QVERIFY(dragRecorder->dragStarted); + QTest::mouseRelease(view->viewport(), Qt::LeftButton, Qt::NoModifier, dragTo); +} + void tst_QAbstractItemView::selectionCommand_data() { QTest::addColumn<QAbstractItemView::SelectionMode>("selectionMode"); |