]> cloud.milkyroute.net Git - dolphin.git/commitdiff
kitemlistkeyboardsearchmanager: smarter search start position
authorYifan Zhu <fanzhuyifan@gmail.com>
Thu, 20 Feb 2025 18:35:06 +0000 (10:35 -0800)
committerYifan Zhu <fanzhuyifan@gmail.com>
Sat, 22 Feb 2025 22:26:57 +0000 (14:26 -0800)
Search from the next position for new search and special repeated key search.
Otherwise search from the current position, which is current selected item if
something is selected or in selection mode, and 0 (the beginning) otherwise.

Test plan:
- create directory with files ab1, ab2, and ab3
- click ab2, and press escape to deselect
- type ab; verify that ab1 is selected
- wait a while, type ab again, verify that ab2 is selected
- wait a while, type ab again, verify that ab3 is selected
- click ab1, type ab, verify that ab2 is selected

BUG: 422951

src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp
src/kitemviews/private/kitemlistkeyboardsearchmanager.h
src/tests/kitemlistcontrollertest.cpp
src/tests/kitemlistkeyboardsearchmanagertest.cpp

index 5a396de61fd48f83be3144a771a36eea19fce194..2f1bdc551df3bc071094e415eed870b805d4123a 100644 (file)
@@ -521,9 +521,9 @@ void KItemListController::slotChangeCurrentItem(const QString &text, bool search
         return;
     }
     int index;
-    if (searchFromNextItem) {
-        const int currentIndex = m_selectionManager->currentItem();
-        index = m_model->indexForKeyboardSearch(text, (currentIndex + 1) % m_model->count());
+    // In selection mode, always use the current (underlined) item, or the next item, for search start position.
+    if (m_selectionBehavior == NoSelection || m_selectionMode || m_selectionManager->hasSelection()) {
+        index = m_model->indexForKeyboardSearch(text, searchFromNextItem ? m_selectionManager->currentItem() + 1 : m_selectionManager->currentItem());
     } else {
         index = m_model->indexForKeyboardSearch(text, 0);
     }
index c18f87b7d280e872b4accae4b6dd4f3d78d32540..afc3bb0713e7f0e6a3f1ac73ee09b6fbae00d2f1 100644 (file)
@@ -10,7 +10,6 @@
 
 KItemListKeyboardSearchManager::KItemListKeyboardSearchManager(QObject *parent)
     : QObject(parent)
-    , m_isSearchRestarted(false)
     , m_timeout(1000)
 {
     m_keyboardInputTime.invalidate();
@@ -55,13 +54,9 @@ void KItemListKeyboardSearchManager::addKeys(const QString &keys)
         const bool sameKey = m_searchedString.length() > 1 && m_searchedString.count(firstKey) == m_searchedString.length();
 
         // Searching for a matching item should start from the next item if either
-        // 1. a new search is started and a search has not been restarted or
+        // 1. a new search is started, or
         // 2. a 'repeated key' search is done.
-        const bool searchFromNextItem = (!m_isSearchRestarted && newSearch) || sameKey;
-
-        // to remember not to searchFromNextItem if selection was deselected
-        // losing keyboard search context basically
-        m_isSearchRestarted = false;
+        const bool searchFromNextItem = newSearch || sameKey;
 
         Q_EMIT changeCurrentItem(sameKey ? firstKey : m_searchedString, searchFromNextItem);
     }
@@ -80,7 +75,6 @@ qint64 KItemListKeyboardSearchManager::timeout() const
 
 void KItemListKeyboardSearchManager::cancelSearch()
 {
-    m_isSearchRestarted = true;
     m_searchedString.clear();
 }
 
index 981d98cd3c2ed0d840beb8bc21fc8a58c2216488..5cb8effbf52b996ffbc34e80c0259d5fb92ba7c2 100644 (file)
@@ -72,7 +72,6 @@ private:
     bool shouldClearSearchIfInputTimeReached();
 
     QString m_searchedString;
-    bool m_isSearchRestarted;
     /** Measures the time since the last key press. */
     QElapsedTimer m_keyboardInputTime;
     /** Time in milliseconds in which a key press is considered as a continuation of the previous search input. */
index 4cb999f06f2aca02865e02c0544f06d1059d878b..b05f4b23d755eae06a716f86591f24672a6137c2 100644 (file)
@@ -73,8 +73,10 @@ private Q_SLOTS:
     void init();
     void cleanup();
 
-    void testKeyboardNavigation_data();
-    void testKeyboardNavigation();
+    void testKeyboardNavigationMultiSelection_data();
+    void testKeyboardNavigationMultiSelection();
+    void testKeyboardNavigationSingleSelectionNoSelection_data();
+    void testKeyboardNavigationSingleSelectionNoSelection();
     void testMouseClickActivation();
 
 private:
@@ -170,6 +172,9 @@ void KItemListControllerTest::init()
     const QSizeF itemSize(50, 50);
     m_view->setItemSize(itemSize);
     QCOMPARE(m_view->itemSize(), itemSize);
+
+    m_controller->setSelectionBehavior(KItemListController::MultiSelection);
+    QCOMPARE(m_controller->selectionBehavior(), KItemListController::MultiSelection);
 }
 
 void KItemListControllerTest::cleanup()
@@ -217,14 +222,442 @@ typedef QPair<KeyPress, ViewState> keyPressViewStatePair;
 Q_DECLARE_METATYPE(QList<keyPressViewStatePair>)
 
 /**
- * This function provides the data for the actual test function
- * KItemListControllerTest::testKeyboardNavigation().
- * It tests all possible combinations of view layouts, selection behaviors,
+ * This function tests all possible combinations of view layouts, layout direction,
  * and enabled/disabled groupings for different column counts, and
  * provides a list of key presses and the states that the view should be in
  * after the key press event.
  */
-void KItemListControllerTest::testKeyboardNavigation_data()
+void KItemListControllerTest::testKeyboardNavigationMultiSelection_data()
+{
+    QTest::addColumn<KFileItemListView::ItemLayout>("layout");
+    QTest::addColumn<Qt::Orientation>("scrollOrientation");
+    QTest::addColumn<int>("columnCount");
+    QTest::addColumn<bool>("groupingEnabled");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<bool>(
+        "selectionModeEnabled"); // Don't confuse this with "selectionBehaviour". This is about changing controls for users to help multi-selecting.
+    QTest::addColumn<QList<QPair<KeyPress, ViewState>>>("testList");
+
+    QList<KFileItemListView::ItemLayout> layoutList;
+    QHash<KFileItemListView::ItemLayout, QString> layoutNames;
+    layoutList.append(KFileItemListView::IconsLayout);
+    layoutNames[KFileItemListView::IconsLayout] = "Icons";
+    layoutList.append(KFileItemListView::CompactLayout);
+    layoutNames[KFileItemListView::CompactLayout] = "Compact";
+    layoutList.append(KFileItemListView::DetailsLayout);
+    layoutNames[KFileItemListView::DetailsLayout] = "Details";
+
+    QList<bool> groupingEnabledList;
+    QHash<bool, QString> groupingEnabledNames;
+    groupingEnabledList.append(false);
+    groupingEnabledNames[false] = "ungrouped";
+    groupingEnabledList.append(true);
+    groupingEnabledNames[true] = "grouping enabled";
+
+    QList<Qt::LayoutDirection> layoutDirectionList;
+    QHash<Qt::LayoutDirection, QString> layoutDirectionNames;
+    layoutDirectionList.append(Qt::LeftToRight);
+    layoutDirectionNames[Qt::LeftToRight] = "Left-to-Right LayoutDirection";
+    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
+        // Compact layout.
+        Qt::Orientation scrollOrientation;
+        QList<int> columnCountList;
+        Qt::Key nextItemKey = Qt::Key_Right;
+        Qt::Key previousItemKey = Qt::Key_Right;
+        Qt::Key nextRowKey = Qt::Key_Right;
+        Qt::Key previousRowKey = Qt::Key_Right;
+
+        switch (layout) {
+        case KFileItemListView::IconsLayout:
+            scrollOrientation = Qt::Vertical;
+            columnCountList << 1 << 3 << 5;
+            nextItemKey = Qt::Key_Right;
+            previousItemKey = Qt::Key_Left;
+            nextRowKey = Qt::Key_Down;
+            previousRowKey = Qt::Key_Up;
+            break;
+        case KFileItemListView::CompactLayout:
+            scrollOrientation = Qt::Horizontal;
+            columnCountList << 1 << 3 << 5;
+            nextItemKey = Qt::Key_Down;
+            previousItemKey = Qt::Key_Up;
+            nextRowKey = Qt::Key_Right;
+            previousRowKey = Qt::Key_Left;
+            break;
+        case KFileItemListView::DetailsLayout:
+            scrollOrientation = Qt::Vertical;
+            columnCountList << 1;
+            nextItemKey = Qt::Key_Down;
+            previousItemKey = Qt::Key_Up;
+            nextRowKey = Qt::Key_Down;
+            previousRowKey = Qt::Key_Up;
+            break;
+        }
+        for (auto layoutDirection : std::as_const(layoutDirectionList)) {
+            if (layoutDirection == Qt::RightToLeft) {
+                switch (layout) {
+                case KFileItemListView::IconsLayout:
+                    std::swap(nextItemKey, previousItemKey);
+                    break;
+                case KFileItemListView::CompactLayout:
+                    std::swap(nextRowKey, previousRowKey);
+                    break;
+                default:
+                    break;
+                }
+            }
+            for (int columnCount : std::as_const(columnCountList)) {
+                for (bool groupingEnabled : std::as_const(groupingEnabledList)) {
+                    QList<QPair<KeyPress, ViewState>> testList;
+
+                    // First, key presses which should have the same effect
+                    // for any layout and any number of columns.
+                    testList << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                             << qMakePair(KeyPress(Qt::Key_Return), ViewState(1, KItemSet() << 1, true))
+                             << qMakePair(KeyPress(Qt::Key_Enter), ViewState(1, KItemSet() << 1, true))
+                             << qMakePair(KeyPress(nextItemKey), ViewState(2, KItemSet() << 2))
+                             << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                             << qMakePair(KeyPress(Qt::Key_Return), ViewState(3, KItemSet() << 2 << 3, true))
+                             << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, KItemSet() << 2))
+                             << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                             << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 2 << 3))
+                             << qMakePair(KeyPress(Qt::Key_Return), ViewState(4, KItemSet() << 2 << 3, true))
+                             << qMakePair(KeyPress(previousItemKey), ViewState(3, KItemSet() << 3))
+                             << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, KItemSet() << 0 << 1 << 2 << 3))
+                             << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3))
+                             << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 2 << 3))
+                             << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3))
+                             << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 19))
+                             << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, KItemSet() << 18 << 19))
+                             << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0))
+                             << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet()))
+                             << qMakePair(KeyPress(Qt::Key_Enter), ViewState(0, KItemSet(), true))
+                             << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet() << 0))
+                             << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet()))
+                             << qMakePair(KeyPress(Qt::Key_Space), ViewState(0, KItemSet() << 0))
+                             << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
+                             << qMakePair(KeyPress(Qt::Key_Space), ViewState(14, KItemSet() << 14))
+                             << qMakePair(KeyPress(Qt::Key_3), ViewState(15, KItemSet() << 15))
+                             << qMakePair(KeyPress(Qt::Key_Escape), ViewState(15, KItemSet()))
+                             << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
+                             << qMakePair(KeyPress(Qt::Key_E), ViewState(14, KItemSet() << 14))
+                             << qMakePair(KeyPress(previousItemKey), ViewState(13, KItemSet() << 13))
+                             << qMakePair(KeyPress(Qt::Key_E), ViewState(14, KItemSet() << 14))
+                             << qMakePair(KeyPress(Qt::Key_Escape), ViewState(14, KItemSet()))
+                             << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
+                             << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0))
+                             << qMakePair(KeyPress(Qt::Key_Escape), ViewState(0, KItemSet()));
+
+                    // Next, we test combinations of key presses which only work for a
+                    // particular number of columns and either enabled or disabled grouping.
+
+                    // One column.
+                    if (columnCount == 1) {
+                        testList << qMakePair(KeyPress(nextRowKey), ViewState(1, KItemSet() << 1))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(2, KItemSet() << 1 << 2))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ControlModifier), ViewState(3, KItemSet() << 1 << 2))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(2, KItemSet() << 2))
+                                 << qMakePair(KeyPress(previousItemKey), ViewState(1, KItemSet() << 1))
+                                 << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
+                    }
+
+                    // Multiple columns: we test both 3 and 5 columns with grouping
+                    // enabled or disabled. For each case, the layout of the items
+                    // in the view is shown (both using file names and indices) to
+                    // make it easier to understand what the tests do.
+
+                    if (columnCount == 3 && !groupingEnabled) {
+                        // 3 columns, no grouping:
+                        //
+                        // a1 a2 a3 |  0  1  2
+                        // b1 c1 c2 |  3  4  5
+                        // c3 c4 c5 |  6  7  8
+                        // d1 d2 d3 |  9 10 11
+                        // d4 e1 e2 | 12 13 14
+                        // e3 e4 e5 | 15 16 17
+                        // e6 e7    | 18 19
+                        testList << qMakePair(KeyPress(nextRowKey), ViewState(3, KItemSet() << 3))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 3))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(7, KItemSet() << 7))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 7 << 8))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, KItemSet() << 7 << 8 << 9))
+                                 << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 7 << 8))
+                                 << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7))
+                                 << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 6 << 7))
+                                 << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, KItemSet() << 5 << 6 << 7))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 6 << 7))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(10, KItemSet() << 10))
+                                 << qMakePair(KeyPress(nextItemKey), ViewState(11, KItemSet() << 11))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(14, KItemSet() << 14))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 19))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(16, KItemSet() << 16))
+                                 << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
+                    }
+
+                    if (columnCount == 5 && !groupingEnabled) {
+                        // 5 columns, no grouping:
+                        //
+                        // a1 a2 a3 b1 c1 |  0  1  2  3  4
+                        // c2 c3 c4 c5 d1 |  5  6  7  8  9
+                        // d2 d3 d4 e1 e2 | 10 11 12 13 14
+                        // e3 e4 e5 e6 e7 | 15 16 17 18 19
+                        testList << qMakePair(KeyPress(nextRowKey), ViewState(5, KItemSet() << 5))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(6, KItemSet() << 5))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(11, KItemSet() << 11))
+                                 << qMakePair(KeyPress(nextItemKey), ViewState(12, KItemSet() << 12))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(17, KItemSet() << 12 << 13 << 14 << 15 << 16 << 17))
+                                 << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(12, KItemSet() << 12))
+                                 << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7 << 8 << 9 << 10 << 11 << 12))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(12, KItemSet() << 12))
+                                 << qMakePair(KeyPress(Qt::Key_End, Qt::ControlModifier), ViewState(19, KItemSet() << 12))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(14, KItemSet() << 14))
+                                 << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
+                    }
+
+                    if (columnCount == 3 && groupingEnabled) {
+                        // 3 columns, with grouping:
+                        //
+                        // a1 a2 a3 |  0  1  2
+                        // b1       |  3
+                        // c1 c2 c3 |  4  5  6
+                        // c4 c5    |  7  8
+                        // d1 d2 d3 |  9 10 11
+                        // d4       | 12
+                        // e1 e2 e3 | 13 14 15
+                        // e4 e5 e6 | 16 17 18
+                        // e7       | 19
+                        testList << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                                 << qMakePair(KeyPress(nextItemKey), ViewState(2, KItemSet() << 2))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 2 << 3 << 4 << 5 << 6))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(8, KItemSet() << 8))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(11, KItemSet() << 11))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(12, KItemSet() << 11))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(13, KItemSet() << 13))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(16, KItemSet() << 16))
+                                 << qMakePair(KeyPress(nextItemKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
+                    }
+
+                    if (columnCount == 5 && groupingEnabled) {
+                        // 5 columns, with grouping:
+                        //
+                        // a1 a2 a3       |  0  1  2
+                        // b1             |  3
+                        // c1 c2 c3 c4 c5 |  4  5  6  7  8
+                        // d1 d2 d3 d4    |  9 10 11 12
+                        // e1 e2 e3 e4 e5 | 13 14 15 16 17
+                        // e6 e7          | 18 19
+                        testList << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 1 << 2 << 3))
+                                 << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(5, KItemSet() << 1 << 2 << 3 << 4 << 5))
+                                 << qMakePair(KeyPress(nextItemKey), ViewState(6, KItemSet() << 6))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(7, KItemSet() << 6))
+                                 << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(8, KItemSet() << 6))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(12, KItemSet() << 12))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                                 << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(Qt::Key_End, Qt::ShiftModifier), ViewState(19, KItemSet() << 17 << 18 << 19))
+                                 << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(14, KItemSet() << 14 << 15 << 16 << 17))
+                                 << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
+                    }
+
+                    const QString testName = layoutNames[layout] + ", " + QStringLiteral("%1 columns, ").arg(columnCount)
+                        + groupingEnabledNames[groupingEnabled] + ", " + layoutDirectionNames[layoutDirection];
+
+                    const QByteArray testNameAscii = testName.toLatin1();
+
+                    QTest::newRow(testNameAscii.data())
+                        << layout << scrollOrientation << columnCount << 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<QPair<KeyPress, ViewState>> 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)
+        + groupingEnabledNames[groupingEnabled] + ", " + layoutDirectionNames[layoutDirection];
+
+    const QByteArray testNameAscii = testName.toLatin1();
+
+    QTest::newRow(testNameAscii.data()) << layout << scrollOrientation << columnCount << groupingEnabled << layoutDirection << selectionModeEnabled << testList;
+}
+
+/**
+ * This function sets the view's properties according to the data provided.
+ *
+ * The list \a testList contains pairs of key presses, which are sent to the
+ * container, and expected view states, which are verified then.
+ */
+void KItemListControllerTest::testKeyboardNavigationMultiSelection()
+{
+    QFETCH(KFileItemListView::ItemLayout, layout);
+    QFETCH(Qt::Orientation, scrollOrientation);
+    QFETCH(int, columnCount);
+    QFETCH(bool, groupingEnabled);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(bool, selectionModeEnabled);
+    QFETCH(QList<keyPressViewStatePair>, testList);
+
+    QApplication::setLayoutDirection(layoutDirection);
+    m_view->setLayoutDirection(layoutDirection);
+
+    m_view->setItemLayout(layout);
+    QCOMPARE(m_view->itemLayout(), layout);
+
+    m_view->setScrollOrientation(scrollOrientation);
+    QCOMPARE(m_view->scrollOrientation(), scrollOrientation);
+
+    m_controller->setSelectionBehavior(KItemListController::MultiSelection);
+    QCOMPARE(m_controller->selectionBehavior(), KItemListController::MultiSelection);
+
+    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);
+
+    QSignalSpy spySingleItemActivated(m_controller, &KItemListController::itemActivated);
+    QSignalSpy spyMultipleItemsActivated(m_controller, &KItemListController::itemsActivated);
+
+    int rowCount = 0;
+    while (!testList.isEmpty()) {
+        ++rowCount;
+        const QPair<KeyPress, ViewState> test = testList.takeFirst();
+        const Qt::Key key = test.first.m_key;
+        const Qt::KeyboardModifiers modifier = test.first.m_modifier;
+        const int current = test.second.m_current;
+        const KItemSet selection = test.second.m_selection;
+        const bool activated = test.second.m_activated;
+
+        QTest::keyClick(m_container, key, modifier);
+
+        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::testKeyboardNavigationMultiSelection_data().")
+                           .arg(m_selectionManager->currentItem())
+                           .arg(current)
+                           .arg(QKeySequence(key).toString())
+                           .arg(rowCount)));
+        QCOMPARE(m_selectionManager->selectedItems(), selection);
+
+        if (activated) {
+            if (!selection.isEmpty()) {
+                // The selected items should be activated.
+                if (selection.count() == 1) {
+                    QVERIFY(!spySingleItemActivated.isEmpty());
+                    QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), selection.first());
+                    QVERIFY(spyMultipleItemsActivated.isEmpty());
+                } else {
+                    QVERIFY(spySingleItemActivated.isEmpty());
+                    QVERIFY(!spyMultipleItemsActivated.isEmpty());
+                    QCOMPARE(qvariant_cast<KItemSet>(spyMultipleItemsActivated.takeFirst().at(0)), selection);
+                }
+            } else {
+                QVERIFY(!spySingleItemActivated.isEmpty());
+                QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), current);
+                QVERIFY(spyMultipleItemsActivated.isEmpty());
+            }
+        }
+    }
+}
+
+/**
+ * This function tests all possible combinations of view layouts, layout direction,
+ * and enabled/disabled groupings for different column counts, and
+ * provides a list of key presses and the states that the view should be in
+ * after the key press event.
+ */
+void KItemListControllerTest::testKeyboardNavigationSingleSelectionNoSelection_data()
 {
     QTest::addColumn<KFileItemListView::ItemLayout>("layout");
     QTest::addColumn<Qt::Orientation>("scrollOrientation");
@@ -251,8 +684,6 @@ void KItemListControllerTest::testKeyboardNavigation_data()
     selectionBehaviorNames[KItemListController::NoSelection] = "NoSelection";
     selectionBehaviorList.append(KItemListController::SingleSelection);
     selectionBehaviorNames[KItemListController::SingleSelection] = "SingleSelection";
-    selectionBehaviorList.append(KItemListController::MultiSelection);
-    selectionBehaviorNames[KItemListController::MultiSelection] = "MultiSelection";
 
     QList<bool> groupingEnabledList;
     QHash<bool, QString> groupingEnabledNames;
@@ -355,11 +786,12 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                                  << qMakePair(KeyPress(Qt::Key_Space), ViewState(14, KItemSet() << 14))
                                  << qMakePair(KeyPress(Qt::Key_3), ViewState(15, KItemSet() << 15))
                                  << qMakePair(KeyPress(Qt::Key_Escape), ViewState(15, KItemSet()))
-                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
-                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(14, KItemSet() << 14))
-                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(15, KItemSet() << 15))
-                                 << qMakePair(KeyPress(Qt::Key_Escape), ViewState(15, KItemSet()))
-                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
+                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(16, KItemSet() << 16))
+                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(previousItemKey), ViewState(16, KItemSet() << 16))
+                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(17, KItemSet() << 17))
+                                 << qMakePair(KeyPress(Qt::Key_Escape), ViewState(17, KItemSet()))
+                                 << qMakePair(KeyPress(Qt::Key_E), ViewState(18, KItemSet() << 18))
                                  << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0))
                                  << qMakePair(KeyPress(Qt::Key_Escape), ViewState(0, KItemSet()));
 
@@ -497,95 +929,15 @@ void KItemListControllerTest::testKeyboardNavigation_data()
             }
         }
     }
-
-    /**
-     * 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<QPair<KeyPress, ViewState>> 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;
 }
 
 /**
- * This function sets the view's properties according to the data provided by
- * KItemListControllerTest::testKeyboardNavigation_data().
+ * This function sets the view's properties according to the data provided.
  *
  * The list \a testList contains pairs of key presses, which are sent to the
  * container, and expected view states, which are verified then.
  */
-void KItemListControllerTest::testKeyboardNavigation()
+void KItemListControllerTest::testKeyboardNavigationSingleSelectionNoSelection()
 {
     QFETCH(KFileItemListView::ItemLayout, layout);
     QFETCH(Qt::Orientation, scrollOrientation);
@@ -635,7 +987,7 @@ void KItemListControllerTest::testKeyboardNavigation()
         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().")
+                                      "in row %4 of the testList from KItemListControllerTest::testKeyboardNavigationSingleSelectionNoSelection_data().")
                            .arg(m_selectionManager->currentItem())
                            .arg(current)
                            .arg(QKeySequence(key).toString())
@@ -647,30 +999,12 @@ void KItemListControllerTest::testKeyboardNavigation()
         case KItemListController::SingleSelection:
             QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << current);
             break;
-        case KItemListController::MultiSelection:
-            QCOMPARE(m_selectionManager->selectedItems(), selection);
-            break;
+        default:
+            Q_UNREACHABLE();
         }
 
         if (activated) {
             switch (selectionBehavior) {
-            case KItemListController::MultiSelection:
-                if (!selection.isEmpty()) {
-                    // The selected items should be activated.
-                    if (selection.count() == 1) {
-                        QVERIFY(!spySingleItemActivated.isEmpty());
-                        QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), selection.first());
-                        QVERIFY(spyMultipleItemsActivated.isEmpty());
-                    } else {
-                        QVERIFY(spySingleItemActivated.isEmpty());
-                        QVERIFY(!spyMultipleItemsActivated.isEmpty());
-                        QCOMPARE(qvariant_cast<KItemSet>(spyMultipleItemsActivated.takeFirst().at(0)), selection);
-                    }
-                    break;
-                }
-                // No items are selected. Therefore, the current item should be activated.
-                // This is handled by falling through to the NoSelection/SingleSelection case.
-                Q_FALLTHROUGH();
             case KItemListController::NoSelection:
             case KItemListController::SingleSelection:
                 // In NoSelection and SingleSelection mode, the current item should be activated.
@@ -678,6 +1012,8 @@ void KItemListControllerTest::testKeyboardNavigation()
                 QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), current);
                 QVERIFY(spyMultipleItemsActivated.isEmpty());
                 break;
+            default:
+                Q_UNREACHABLE();
             }
         }
     }
index 17424c801109ac62e2588549a6bc059f4ca75a55..bbdb9c397f491ea0b1c5fe44a365f5444dc1ba0b 100644 (file)
@@ -45,7 +45,7 @@ void KItemListKeyboardSearchManagerTest::testBasicKeyboardSearch()
 
     m_keyboardSearchManager.addKeys("f");
     QCOMPARE(spy.count(), 1);
-    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "f" << false);
+    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "f" << true);
 
     m_keyboardSearchManager.addKeys("i");
     QCOMPARE(spy.count(), 1);
@@ -71,7 +71,7 @@ void KItemListKeyboardSearchManagerTest::testAbortedKeyboardSearch()
 
     m_keyboardSearchManager.addKeys("f");
     QCOMPARE(spy.count(), 1);
-    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "f" << false);
+    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "f" << true);
 
     m_keyboardSearchManager.addKeys("i");
     QCOMPARE(spy.count(), 1);
@@ -94,7 +94,7 @@ void KItemListKeyboardSearchManagerTest::testAbortedKeyboardSearch()
 
     m_keyboardSearchManager.addKeys("a");
     QCOMPARE(spy.count(), 1);
-    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "a" << false);
+    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "a" << true);
 }
 
 void KItemListKeyboardSearchManagerTest::testRepeatedKeyPress()
@@ -110,7 +110,7 @@ void KItemListKeyboardSearchManagerTest::testRepeatedKeyPress()
 
     m_keyboardSearchManager.addKeys("p");
     QCOMPARE(spy.count(), 1);
-    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "p" << false);
+    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "p" << true);
 
     m_keyboardSearchManager.addKeys("p");
     QCOMPARE(spy.count(), 1);
@@ -139,7 +139,7 @@ void KItemListKeyboardSearchManagerTest::testPressShift()
     // Simulate that the user enters "a_b".
     m_keyboardSearchManager.addKeys("a");
     QCOMPARE(spy.count(), 1);
-    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "a" << false);
+    QCOMPARE(spy.takeFirst(), QList<QVariant>() << "a" << true);
 
     m_keyboardSearchManager.addKeys("");
     QCOMPARE(spy.count(), 0);