X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/240d33ce17fc531e8bc6638af8f71454fe7c05e6..f1a5aaa183e4e917a6d1b19fa328fca0a38df479:/src/tests/kitemlistcontrollertest.cpp diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp index 40b2cecaa..a882accaa 100644 --- a/src/tests/kitemlistcontrollertest.cpp +++ b/src/tests/kitemlistcontrollertest.cpp @@ -174,6 +174,7 @@ void KItemListControllerTest::init() void KItemListControllerTest::cleanup() { + m_controller->setSelectionModeEnabled(false); } /** @@ -228,9 +229,11 @@ void KItemListControllerTest::testKeyboardNavigation_data() QTest::addColumn("layout"); QTest::addColumn("scrollOrientation"); QTest::addColumn("columnCount"); - QTest::addColumn("selectionBehavior"); + QTest::addColumn("selectionBehavior"); // Defines how many items can be selected at the same time. QTest::addColumn("groupingEnabled"); QTest::addColumn("layoutDirection"); + QTest::addColumn( + "selectionModeEnabled"); // Don't confuse this with "selectionBehaviour". This is about changing controls for users to help multi-selecting. QTest::addColumn>>("testList"); QList layoutList; @@ -265,6 +268,9 @@ void KItemListControllerTest::testKeyboardNavigation_data() layoutDirectionList.append(Qt::RightToLeft); layoutDirectionNames[Qt::RightToLeft] = "Right-to-Left LayoutDirection"; + bool selectionModeEnabled = false; // For most tests this is kept disabled because it is not really affected by all the other test conditions. + // We only enable it for a few separate tests at the end. + for (const KFileItemListView::ItemLayout &layout : layoutList) { // The following settings depend on the layout. // Note that 'columns' are actually 'rows' in @@ -478,19 +484,98 @@ void KItemListControllerTest::testKeyboardNavigation_data() << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0)); } - const QString testName = layoutNames[layout] + ", " + QString("%1 columns, ").arg(columnCount) + const QString testName = layoutNames[layout] + ", " + QStringLiteral("%1 columns, ").arg(columnCount) + selectionBehaviorNames[selectionBehavior] + ", " + groupingEnabledNames[groupingEnabled] + ", " + layoutDirectionNames[layoutDirection]; const QByteArray testNameAscii = testName.toLatin1(); - QTest::newRow(testNameAscii.data()) - << layout << scrollOrientation << columnCount << selectionBehavior << groupingEnabled << layoutDirection << testList; + QTest::newRow(testNameAscii.data()) << layout << scrollOrientation << columnCount << selectionBehavior << groupingEnabled + << layoutDirection << selectionModeEnabled << testList; } } } } } + + /** + * Selection mode tests + * We only test for the default icon view mode with typical scrollOrientation, selectionBehaviour, no grouping, left-to-right layoutDirection because none + * of this should affect selection mode and special-casing selection mode within the above test would make the above code even more complex than it already + * is. + */ + selectionModeEnabled = true; + const KFileItemListView::ItemLayout layout = KFileItemListView::IconsLayout; + const Qt::Orientation scrollOrientation = Qt::Vertical; + const int columnCount = 3; + const Qt::Key nextItemKey = Qt::Key_Right; + const Qt::Key previousItemKey = Qt::Key_Left; + const Qt::Key nextRowKey = Qt::Key_Down; + const Qt::Key previousRowKey = Qt::Key_Up; + + const Qt::LayoutDirection layoutDirection = Qt::LeftToRight; + const KItemListController::SelectionBehavior &selectionBehavior = KItemListController::MultiSelection; + const bool groupingEnabled = false; + + QList> testList; + + testList << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet())) // In selection mode nothing is selected simply by moving with arrow keys. + << qMakePair(KeyPress(Qt::Key_Return), ViewState(1, KItemSet() << 1)) // Pressing Return toggles the selection but does not activate. + << qMakePair(KeyPress(Qt::Key_Enter), ViewState(1, KItemSet())) // Pressing Enter toggles the selection but does not activate. + << qMakePair(KeyPress(nextItemKey), ViewState(2, KItemSet())) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3)) // Shift+Arrow key still selects in selection mode. + << qMakePair(KeyPress(Qt::Key_Return), ViewState(3, KItemSet() << 2)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, KItemSet() << 2 << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2)) // Shift+Left and then Shift+Right cancel each other out. + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 2)) + << qMakePair(KeyPress(Qt::Key_Return), ViewState(4, KItemSet() << 2 << 4)) + << qMakePair(KeyPress(previousItemKey), ViewState(3, KItemSet() << 2 << 4)) + << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, KItemSet() << 0 << 1 << 2 << 3 << 4)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3 << 4)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 2 << 3 << 4)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3 << 4)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 0 << 1 << 2 << 3 << 4)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, KItemSet() << 0 << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0 << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet() << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Enter), ViewState(0, KItemSet() << 0 << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet() << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet() << 0 << 1 << 2 << 3 << 4 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Space), ViewState(0, KItemSet() << 1 << 2 << 3 << 4 << 18 << 19)) // Space toggles selection in selection mode. + << qMakePair(KeyPress(Qt::Key_D), ViewState(9, KItemSet() << 1 << 2 << 3 << 4 << 18 << 19)) // No selection change by type-ahead. + << qMakePair(KeyPress(Qt::Key_Space), ViewState(9, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) // Space is not added to type-ahead. + << qMakePair(KeyPress(Qt::Key_4), ViewState(12, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) // No selection change by type-ahead. + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + + // The following tests assume a columnCount of three and no grouping enabled. + << qMakePair(KeyPress(nextRowKey), ViewState(3, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextRowKey), ViewState(7, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 1 << 2 << 3 << 4 << 7 << 8 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, KItemSet() << 1 << 2 << 3 << 4 << 7 << 8 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 1 << 2 << 3 << 4 << 7 << 8 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 1 << 2 << 3 << 4 << 6 << 7 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, KItemSet() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 1 << 2 << 3 << 4 << 6 << 7 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextRowKey), ViewState(10, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextItemKey), ViewState(11, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextRowKey), ViewState(14, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextRowKey), ViewState(17, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(16, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 1 << 2 << 3 << 4 << 9 << 18 << 19)); + + const QString testName = "Selection Mode: " + layoutNames[layout] + ", " + QStringLiteral("%1 columns, ").arg(columnCount) + + selectionBehaviorNames[selectionBehavior] + ", " + groupingEnabledNames[groupingEnabled] + ", " + layoutDirectionNames[layoutDirection]; + + const QByteArray testNameAscii = testName.toLatin1(); + + QTest::newRow(testNameAscii.data()) << layout << scrollOrientation << columnCount << selectionBehavior << groupingEnabled << layoutDirection + << selectionModeEnabled << testList; } /** @@ -508,6 +593,7 @@ void KItemListControllerTest::testKeyboardNavigation() QFETCH(KItemListController::SelectionBehavior, selectionBehavior); QFETCH(bool, groupingEnabled); QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(bool, selectionModeEnabled); QFETCH(QList, testList); QApplication::setLayoutDirection(layoutDirection); @@ -525,6 +611,9 @@ void KItemListControllerTest::testKeyboardNavigation() m_model->setGroupedSorting(groupingEnabled); QCOMPARE(m_model->groupedSorting(), groupingEnabled); + m_controller->setSelectionModeEnabled(selectionModeEnabled); + QCOMPARE(m_controller->selectionMode(), selectionModeEnabled); + adjustGeometryForColumnCount(columnCount); QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); @@ -543,13 +632,14 @@ void KItemListControllerTest::testKeyboardNavigation() QTest::keyClick(m_container, key, modifier); - QVERIFY2(m_selectionManager->currentItem() == current, - qPrintable(QString("currentItem() returns index %1 but %2 would be expected. Before this, key \"%3\" was pressed. This test case is defined " - "in row %4 of the testList from KItemListControllerTest::testKeyboardNavigation_data().") - .arg(m_selectionManager->currentItem()) - .arg(current) - .arg(QKeySequence(key).toString()) - .arg(rowCount))); + QVERIFY2( + m_selectionManager->currentItem() == current, + qPrintable(QStringLiteral("currentItem() returns index %1 but %2 would be expected. Before this, key \"%3\" was pressed. This test case is defined " + "in row %4 of the testList from KItemListControllerTest::testKeyboardNavigation_data().") + .arg(m_selectionManager->currentItem()) + .arg(current) + .arg(QKeySequence(key).toString()) + .arg(rowCount))); switch (selectionBehavior) { case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); @@ -620,6 +710,41 @@ void KItemListControllerTest::testMouseClickActivation() mouseReleaseEvent.setButton(Qt::LeftButton); mouseReleaseEvent.setButtons(Qt::NoButton); + QGraphicsSceneMouseEvent mouseDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick); + mouseDoubleClickEvent.setPos(pos); + mouseDoubleClickEvent.setButton(Qt::LeftButton); + mouseDoubleClickEvent.setButtons(Qt::LeftButton); + + QGraphicsSceneMouseEvent mouseRightPressEvent(QEvent::GraphicsSceneMousePress); + mouseRightPressEvent.setPos(pos); + mouseRightPressEvent.setButton(Qt::RightButton); + mouseRightPressEvent.setButtons(Qt::RightButton); + + QGraphicsSceneMouseEvent mouseRightReleaseEvent(QEvent::GraphicsSceneMouseRelease); + mouseRightReleaseEvent.setPos(pos); + mouseRightReleaseEvent.setButton(Qt::RightButton); + mouseRightReleaseEvent.setButtons(Qt::NoButton); + + QGraphicsSceneMouseEvent mouseRightDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick); + mouseRightDoubleClickEvent.setPos(pos); + mouseRightDoubleClickEvent.setButton(Qt::RightButton); + mouseRightDoubleClickEvent.setButtons(Qt::RightButton); + + QGraphicsSceneMouseEvent mouseBackPressEvent(QEvent::GraphicsSceneMousePress); + mouseBackPressEvent.setPos(pos); + mouseBackPressEvent.setButton(Qt::BackButton); + mouseBackPressEvent.setButtons(Qt::BackButton); + + QGraphicsSceneMouseEvent mouseBackReleaseEvent(QEvent::GraphicsSceneMouseRelease); + mouseBackReleaseEvent.setPos(pos); + mouseBackReleaseEvent.setButton(Qt::BackButton); + mouseBackReleaseEvent.setButtons(Qt::NoButton); + + QGraphicsSceneMouseEvent mouseBackDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick); + mouseBackDoubleClickEvent.setPos(pos); + mouseBackDoubleClickEvent.setButton(Qt::BackButton); + mouseBackDoubleClickEvent.setButtons(Qt::BackButton); + QSignalSpy spyItemActivated(m_controller, &KItemListController::itemActivated); // Default setting: single click activation. @@ -628,6 +753,7 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 1); spyItemActivated.clear(); + QVERIFY2(!m_view->controller()->selectionManager()->hasSelection(), "An item should not be implicitly selected during activation. @see bug 424723"); // Set the global setting to "double click activation". m_testStyle->setActivateItemOnSingleClick(false); @@ -635,6 +761,30 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 0); spyItemActivated.clear(); + QVERIFY(m_view->controller()->selectionManager()->hasSelection()); + + // emulation of double click according to https://doc.qt.io/qt-6/qgraphicsscene.html#mouseDoubleClickEvent + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + m_view->event(&mouseDoubleClickEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 1); + spyItemActivated.clear(); + QVERIFY2(!m_view->controller()->selectionManager()->hasSelection(), "An item should not be implicitly selected during activation. @see bug 424723"); + + // right mouse button should not trigger activation + m_view->event(&mouseRightPressEvent); + m_view->event(&mouseRightReleaseEvent); + m_view->event(&mouseRightDoubleClickEvent); + m_view->event(&mouseRightReleaseEvent); + QCOMPARE(spyItemActivated.count(), 0); + + // back mouse button should not trigger activation + m_view->event(&mouseBackPressEvent); + m_view->event(&mouseBackReleaseEvent); + m_view->event(&mouseBackDoubleClickEvent); + m_view->event(&mouseBackReleaseEvent); + QCOMPARE(spyItemActivated.count(), 0); // Enforce single click activation in the controller. m_controller->setSingleClickActivationEnforced(true); @@ -642,6 +792,8 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 1); spyItemActivated.clear(); + constexpr const char *reasonWhySelectionShouldPersist = "An item was selected before this mouse click. The click should not have cleared this selection."; + QVERIFY2(m_view->controller()->selectionManager()->hasSelection(), reasonWhySelectionShouldPersist); // Do not enforce single click activation in the controller. m_controller->setSingleClickActivationEnforced(false); @@ -649,6 +801,7 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 0); spyItemActivated.clear(); + QVERIFY2(m_view->controller()->selectionManager()->hasSelection(), reasonWhySelectionShouldPersist); // Set the global setting back to "single click activation". m_testStyle->setActivateItemOnSingleClick(true); @@ -656,6 +809,7 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 1); spyItemActivated.clear(); + QVERIFY2(m_view->controller()->selectionManager()->hasSelection(), reasonWhySelectionShouldPersist); // Enforce single click activation in the controller. m_controller->setSingleClickActivationEnforced(true); @@ -663,6 +817,7 @@ void KItemListControllerTest::testMouseClickActivation() m_view->event(&mouseReleaseEvent); QCOMPARE(spyItemActivated.count(), 1); spyItemActivated.clear(); + QVERIFY2(m_view->controller()->selectionManager()->hasSelection(), reasonWhySelectionShouldPersist); // Restore previous settings. m_controller->setSingleClickActivationEnforced(true);