X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/9aee5d22513f0367febab54b38b3a7dc58d120bb..131c889b0c050592809035242db6200482e0edde:/src/tests/kitemlistcontrollertest.cpp diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp index e34731fa4..18ad1186d 100644 --- a/src/tests/kitemlistcontrollertest.cpp +++ b/src/tests/kitemlistcontrollertest.cpp @@ -1,34 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2012 by Frank Reininghaus * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Frank Reininghaus + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ -#include "kitemviews/kitemlistcontainer.h" +#include "kitemviews/kitemlistcontroller.h" #include "kitemviews/kfileitemlistview.h" #include "kitemviews/kfileitemmodel.h" -#include "kitemviews/kitemlistcontroller.h" +#include "kitemviews/kitemlistcontainer.h" #include "kitemviews/kitemlistselectionmanager.h" #include "kitemviews/private/kitemlistviewlayouter.h" #include "testdir.h" -#include #include -#include #include +#include +#include +#include /** * \class KItemListControllerTestStyle is a proxy style for testing the @@ -37,10 +25,11 @@ */ class KItemListControllerTestStyle : public QProxyStyle { + Q_OBJECT public: - KItemListControllerTestStyle(QStyle* style) : - QProxyStyle(style), - m_activateItemOnSingleClick((bool)style->styleHint(SH_ItemView_ActivateItemOnSingleClick)) + KItemListControllerTestStyle(QStyle *style) + : QProxyStyle(style) + , m_activateItemOnSingleClick((bool)style->styleHint(SH_ItemView_ActivateItemOnSingleClick)) { } @@ -54,10 +43,7 @@ public: return m_activateItemOnSingleClick; } - int styleHint(StyleHint hint, - const QStyleOption* option = nullptr, - const QWidget* widget = nullptr, - QStyleHintReturn* returnData = nullptr) const Q_DECL_OVERRIDE + int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override { switch (hint) { case QStyle::SH_ItemView_ActivateItemOnSingleClick: @@ -71,16 +57,16 @@ private: bool m_activateItemOnSingleClick; }; -Q_DECLARE_METATYPE(KFileItemListView::ItemLayout); -Q_DECLARE_METATYPE(Qt::Orientation); -Q_DECLARE_METATYPE(KItemListController::SelectionBehavior); -Q_DECLARE_METATYPE(KItemSet); +Q_DECLARE_METATYPE(KFileItemListView::ItemLayout) +Q_DECLARE_METATYPE(Qt::Orientation) +Q_DECLARE_METATYPE(KItemListController::SelectionBehavior) +Q_DECLARE_METATYPE(KItemSet) class KItemListControllerTest : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void initTestCase(); void cleanupTestCase(); @@ -99,13 +85,13 @@ private: void adjustGeometryForColumnCount(int count); private: - KFileItemListView* m_view; - KItemListController* m_controller; - KItemListSelectionManager* m_selectionManager; - KFileItemModel* m_model; - TestDir* m_testDir; - KItemListContainer* m_container; - KItemListControllerTestStyle* m_testStyle; + KFileItemListView *m_view; + KItemListController *m_controller; + KItemListSelectionManager *m_selectionManager; + KFileItemModel *m_model; + TestDir *m_testDir; + KItemListContainer *m_container; + KItemListControllerTestStyle *m_testStyle; }; /** @@ -115,6 +101,7 @@ private: */ void KItemListControllerTest::initTestCase() { + QStandardPaths::setTestModeEnabled(true); qRegisterMetaType("KItemSet"); m_testDir = new TestDir(); @@ -122,6 +109,9 @@ void KItemListControllerTest::initTestCase() m_view = new KFileItemListView(); m_controller = new KItemListController(m_model, m_view, this); m_container = new KItemListContainer(m_controller); +#ifndef QT_NO_ACCESSIBILITY + m_view->setAccessibleParentsObject(m_container); +#endif m_controller = m_container->controller(); m_controller->setSelectionBehavior(KItemListController::MultiSelection); m_selectionManager = m_controller->selectionManager(); @@ -129,29 +119,43 @@ void KItemListControllerTest::initTestCase() m_view->setStyle(m_testStyle); QStringList files; - files - << "a1" << "a2" << "a3" - << "b1" - << "c1" << "c2" << "c3" << "c4" << "c5" - << "d1" << "d2" << "d3" << "d4" - << "e" << "e 2" << "e 3" << "e 4" << "e 5" << "e 6" << "e 7"; + files << "a1" + << "a2" + << "a3" + << "b1" + << "c1" + << "c2" + << "c3" + << "c4" + << "c5" + << "d1" + << "d2" + << "d3" + << "d4" + << "e" + << "e 2" + << "e 3" + << "e 4" + << "e 5" + << "e 6" + << "e 7"; m_testDir->createFiles(files); m_model->loadDirectory(m_testDir->url()); - QSignalSpy spyDirectoryLoadingCompleted(m_model, SIGNAL(directoryLoadingCompleted())); + QSignalSpy spyDirectoryLoadingCompleted(m_model, &KFileItemModel::directoryLoadingCompleted); QVERIFY(spyDirectoryLoadingCompleted.wait()); m_container->show(); - QTest::qWaitForWindowExposed(m_container); + QVERIFY(QTest::qWaitForWindowExposed(m_container)); } void KItemListControllerTest::cleanupTestCase() { delete m_container; - m_container = 0; + m_container = nullptr; delete m_testDir; - m_testDir = 0; + m_testDir = nullptr; } /** Before each test, the current item, selection, and item size are reset to the defaults. */ @@ -177,11 +181,11 @@ void KItemListControllerTest::cleanup() * including the key and the keyboard modifiers. */ struct KeyPress { - - KeyPress(Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier) : - m_key(key), - m_modifier(modifier) - {} + KeyPress(Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier) + : m_key(key) + , m_modifier(modifier) + { + } Qt::Key m_key; Qt::KeyboardModifiers m_modifier; @@ -195,12 +199,12 @@ struct KeyPress { * key press. */ struct ViewState { - - ViewState(int current, const KItemSet selection, bool activated = false) : - m_current(current), - m_selection(selection), - m_activated(activated) - {} + ViewState(int current, const KItemSet &selection, bool activated = false) + : m_current(current) + , m_selection(selection) + , m_activated(activated) + { + } int m_current; KItemSet m_selection; @@ -209,7 +213,7 @@ struct ViewState { // We have to define a typedef for the pair in order to make the test compile. typedef QPair keyPressViewStatePair; -Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QList) /** * This function provides the data for the actual test function @@ -226,7 +230,8 @@ void KItemListControllerTest::testKeyboardNavigation_data() QTest::addColumn("columnCount"); QTest::addColumn("selectionBehavior"); QTest::addColumn("groupingEnabled"); - QTest::addColumn > >("testList"); + QTest::addColumn("layoutDirection"); + QTest::addColumn>>("testList"); QList layoutList; QHash layoutNames; @@ -253,7 +258,14 @@ void KItemListControllerTest::testKeyboardNavigation_data() groupingEnabledList.append(true); groupingEnabledNames[true] = "grouping enabled"; - foreach (const KFileItemListView::ItemLayout& layout, layoutList) { + QList layoutDirectionList; + QHash layoutDirectionNames; + layoutDirectionList.append(Qt::LeftToRight); + layoutDirectionNames[Qt::LeftToRight] = "Left-to-Right LayoutDirection"; + layoutDirectionList.append(Qt::RightToLeft); + layoutDirectionNames[Qt::RightToLeft] = "Right-to-Left LayoutDirection"; + + for (const KFileItemListView::ItemLayout &layout : layoutList) { // The following settings depend on the layout. // Note that 'columns' are actually 'rows' in // Compact layout. @@ -290,185 +302,191 @@ void KItemListControllerTest::testKeyboardNavigation_data() previousRowKey = Qt::Key_Up; break; } - - foreach (int columnCount, columnCountList) { - foreach (const KItemListController::SelectionBehavior& selectionBehavior, selectionBehaviorList) { - foreach (bool groupingEnabled, groupingEnabledList) { // krazy:exclude=foreach - QList > 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_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)); + 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 (const KItemListController::SelectionBehavior &selectionBehavior : std::as_const(selectionBehaviorList)) { + for (bool groupingEnabled : std::as_const(groupingEnabledList)) { + QList> 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(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_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] + ", " + QString("%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; } - - const QString testName = - layoutNames[layout] + ", " + - QString("%1 columns, ").arg(columnCount) + - selectionBehaviorNames[selectionBehavior] + ", " + - groupingEnabledNames[groupingEnabled]; - - const QByteArray testNameAscii = testName.toLatin1(); - - QTest::newRow(testNameAscii.data()) - << layout - << scrollOrientation - << columnCount - << selectionBehavior - << groupingEnabled - << testList; } } } @@ -489,8 +507,12 @@ void KItemListControllerTest::testKeyboardNavigation() QFETCH(int, columnCount); QFETCH(KItemListController::SelectionBehavior, selectionBehavior); QFETCH(bool, groupingEnabled); + QFETCH(Qt::LayoutDirection, layoutDirection); QFETCH(QList, testList); + QApplication::setLayoutDirection(layoutDirection); + m_view->setLayoutDirection(layoutDirection); + m_view->setItemLayout(layout); QCOMPARE(m_view->itemLayout(), layout); @@ -506,10 +528,12 @@ void KItemListControllerTest::testKeyboardNavigation() adjustGeometryForColumnCount(columnCount); QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); - QSignalSpy spySingleItemActivated(m_controller, SIGNAL(itemActivated(int))); - QSignalSpy spyMultipleItemsActivated(m_controller, SIGNAL(itemsActivated(KItemSet))); + QSignalSpy spySingleItemActivated(m_controller, &KItemListController::itemActivated); + QSignalSpy spyMultipleItemsActivated(m_controller, &KItemListController::itemsActivated); + int rowCount = 0; while (!testList.isEmpty()) { + ++rowCount; const QPair test = testList.takeFirst(); const Qt::Key key = test.first.m_key; const Qt::KeyboardModifiers modifier = test.first.m_modifier; @@ -519,11 +543,23 @@ void KItemListControllerTest::testKeyboardNavigation() QTest::keyClick(m_container, key, modifier); - QCOMPARE(m_selectionManager->currentItem(), current); + 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))); switch (selectionBehavior) { - case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); break; - case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << current); break; - case KItemListController::MultiSelection: QCOMPARE(m_selectionManager->selectedItems(), selection); break; + case KItemListController::NoSelection: + QVERIFY(m_selectionManager->selectedItems().isEmpty()); + break; + case KItemListController::SingleSelection: + QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << current); + break; + case KItemListController::MultiSelection: + QCOMPARE(m_selectionManager->selectedItems(), selection); + break; } if (activated) { @@ -544,6 +580,7 @@ void KItemListControllerTest::testKeyboardNavigation() } // 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. @@ -583,7 +620,42 @@ void KItemListControllerTest::testMouseClickActivation() mouseReleaseEvent.setButton(Qt::LeftButton); mouseReleaseEvent.setButtons(Qt::NoButton); - QSignalSpy spyItemActivated(m_controller, SIGNAL(itemActivated(int))); + 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. m_testStyle->setActivateItemOnSingleClick(true); @@ -591,6 +663,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); @@ -598,6 +671,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); @@ -605,6 +702,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); @@ -612,6 +711,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); @@ -619,6 +719,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); @@ -626,6 +727,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);