X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/6db0bec32548fd6c1d742defba5dbf958e61f45c..ec628cfa09ea3c33ef34607d5e91a23dcabd3106:/src/tests/kitemlistcontrollertest.cpp diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp index 443faa35f..8044f9ac9 100644 --- a/src/tests/kitemlistcontrollertest.cpp +++ b/src/tests/kitemlistcontrollertest.cpp @@ -21,22 +21,27 @@ #include #include -#include #include "kitemviews/kitemlistcontainer.h" #include "kitemviews/kfileitemlistview.h" #include "kitemviews/kfileitemmodel.h" #include "kitemviews/kitemlistcontroller.h" #include "kitemviews/kitemlistselectionmanager.h" -#include "kitemviews/kitemlistviewlayouter_p.h" +#include "kitemviews/private/kitemlistviewlayouter.h" #include "testdir.h" +#include +#include + +#include + namespace { const int DefaultTimeout = 2000; }; -Q_DECLARE_METATYPE(KFileItemListView::Layout); +Q_DECLARE_METATYPE(KFileItemListView::ItemLayout); Q_DECLARE_METATYPE(Qt::Orientation); Q_DECLARE_METATYPE(KItemListController::SelectionBehavior); +Q_DECLARE_METATYPE(QSet); class KItemListControllerTest : public QObject { @@ -51,6 +56,7 @@ private slots: void testKeyboardNavigation_data(); void testKeyboardNavigation(); + void testMouseClickActivation(); private: /** @@ -64,7 +70,6 @@ private: KItemListController* m_controller; KItemListSelectionManager* m_selectionManager; KFileItemModel* m_model; - KDirLister* m_dirLister; TestDir* m_testDir; KItemListContainer* m_container; }; @@ -76,18 +81,17 @@ private: */ void KItemListControllerTest::initTestCase() { + qRegisterMetaType >("QSet"); + m_testDir = new TestDir(); - m_dirLister = new KDirLister(); - m_model = new KFileItemModel(m_dirLister); - m_container = new KItemListContainer(); + m_model = new KFileItemModel(); + m_view = new KFileItemListView(); + m_controller = new KItemListController(m_model, m_view, this); + m_container = new KItemListContainer(m_controller); m_controller = m_container->controller(); m_controller->setSelectionBehavior(KItemListController::MultiSelection); m_selectionManager = m_controller->selectionManager(); - m_view = new KFileItemListView(); - m_controller->setView(m_view); - m_controller->setModel(m_model); - QStringList files; files << "a1" << "a2" << "a3" @@ -97,8 +101,8 @@ void KItemListControllerTest::initTestCase() << "e1" << "e2" << "e3" << "e4" << "e5" << "e6" << "e7"; m_testDir->createFiles(files); - m_dirLister->openUrl(m_testDir->url()); - QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(loadingCompleted()), DefaultTimeout)); + m_model->loadDirectory(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout)); m_container->show(); QTest::qWaitForWindowShown(m_container); @@ -106,18 +110,8 @@ void KItemListControllerTest::initTestCase() void KItemListControllerTest::cleanupTestCase() { - delete m_view; - m_view = 0; - delete m_container; m_container = 0; - m_controller = 0; - - delete m_model; - m_model = 0; - - delete m_dirLister; - m_dirLister = 0; delete m_testDir; m_testDir = 0; @@ -158,17 +152,22 @@ struct KeyPress { /** * \class ViewState is a small helper struct that represents a certain state - * of the view, including the current item and the selected items. + * of the view, including the current item, the selected items in MultiSelection + * mode (in the other modes, the selection is either empty or equal to the + * current item), and the information whether items were activated by the last + * key press. */ struct ViewState { - ViewState(int current, QSet selection) : + ViewState(int current, const QSet selection, bool activated = false) : m_current(current), - m_selection(selection) + m_selection(selection), + m_activated(activated) {} int m_current; QSet m_selection; + bool m_activated; }; // We have to define a typedef for the pair in order to make the test compile. @@ -185,50 +184,39 @@ Q_DECLARE_METATYPE(QList); */ void KItemListControllerTest::testKeyboardNavigation_data() { - QTest::addColumn("layout"); + QTest::addColumn("layout"); QTest::addColumn("scrollOrientation"); QTest::addColumn("columnCount"); QTest::addColumn("selectionBehavior"); QTest::addColumn("groupingEnabled"); QTest::addColumn > >("testList"); - static QList layoutList; - static QHash layoutNames; - if (layoutList.isEmpty()) { - layoutList.append(KFileItemListView::IconsLayout); - layoutNames[KFileItemListView::IconsLayout] = "Icons"; - - layoutList.append(KFileItemListView::CompactLayout); - layoutNames[KFileItemListView::CompactLayout] = "Compact"; - - layoutList.append(KFileItemListView::DetailsLayout); - layoutNames[KFileItemListView::DetailsLayout] = "Details"; - } - - static QList selectionBehaviorList; - static QHash selectionBehaviorNames; - if (selectionBehaviorList.isEmpty()) { - selectionBehaviorList.append(KItemListController::NoSelection); - selectionBehaviorNames[KItemListController::NoSelection] = "NoSelection"; - - selectionBehaviorList.append(KItemListController::SingleSelection); - selectionBehaviorNames[KItemListController::SingleSelection] = "SingleSelection"; - - selectionBehaviorList.append(KItemListController::MultiSelection); - selectionBehaviorNames[KItemListController::MultiSelection] = "MultiSelection"; - } - - static QList groupingEnabledList; - static QHash groupingEnabledNames; - if (groupingEnabledList.isEmpty()) { - groupingEnabledList.append(false); - groupingEnabledNames[false] = "ungrouped"; - - groupingEnabledList.append(true); - groupingEnabledNames[true] = "grouping enabled"; - } - - foreach (KFileItemListView::Layout layout, layoutList) { + QList layoutList; + QHash 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 selectionBehaviorList; + QHash selectionBehaviorNames; + selectionBehaviorList.append(KItemListController::NoSelection); + selectionBehaviorNames[KItemListController::NoSelection] = "NoSelection"; + selectionBehaviorList.append(KItemListController::SingleSelection); + selectionBehaviorNames[KItemListController::SingleSelection] = "SingleSelection"; + selectionBehaviorList.append(KItemListController::MultiSelection); + selectionBehaviorNames[KItemListController::MultiSelection] = "MultiSelection"; + + QList groupingEnabledList; + QHash groupingEnabledNames; + groupingEnabledList.append(false); + groupingEnabledNames[false] = "ungrouped"; + groupingEnabledList.append(true); + groupingEnabledNames[true] = "grouping enabled"; + + foreach (const KFileItemListView::ItemLayout& layout, layoutList) { // The following settings depend on the layout. // Note that 'columns' are actually 'rows' in // Compact layout. @@ -267,19 +255,23 @@ void KItemListControllerTest::testKeyboardNavigation_data() } foreach (int columnCount, columnCountList) { - foreach (KItemListController::SelectionBehavior selectionBehavior, selectionBehaviorList) { - foreach (bool groupingEnabled, groupingEnabledList) { + 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, QSet() << 1)) + << qMakePair(KeyPress(Qt::Key_Return), ViewState(1, QSet() << 1, true)) + << qMakePair(KeyPress(Qt::Key_Enter), ViewState(1, QSet() << 1, true)) << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet() << 2)) << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Return), ViewState(3, QSet() << 2 << 3, true)) << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, QSet() << 2)) << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet() << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Return), ViewState(4, QSet() << 2 << 3, true)) << qMakePair(KeyPress(previousItemKey), ViewState(3, QSet() << 3)) << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, QSet() << 0 << 1 << 2 << 3)) << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) @@ -287,7 +279,10 @@ void KItemListControllerTest::testKeyboardNavigation_data() << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet() << 19)) << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, QSet() << 18 << 19)) - << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, QSet())) + << qMakePair(KeyPress(Qt::Key_Enter), ViewState(0, QSet(), true)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, QSet() << 0)); // Next, we test combinations of key presses which only work for a // particular number of columns and either enabled or disabled grouping. @@ -445,7 +440,7 @@ void KItemListControllerTest::testKeyboardNavigation_data() */ void KItemListControllerTest::testKeyboardNavigation() { - QFETCH(KFileItemListView::Layout, layout); + QFETCH(KFileItemListView::ItemLayout, layout); QFETCH(Qt::Orientation, scrollOrientation); QFETCH(int, columnCount); QFETCH(KItemListController::SelectionBehavior, selectionBehavior); @@ -458,29 +453,164 @@ void KItemListControllerTest::testKeyboardNavigation() m_view->setScrollOrientation(scrollOrientation); QCOMPARE(m_view->scrollOrientation(), scrollOrientation); - adjustGeometryForColumnCount(columnCount); - QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); - m_controller->setSelectionBehavior(selectionBehavior); QCOMPARE(m_controller->selectionBehavior(), selectionBehavior); m_model->setGroupedSorting(groupingEnabled); QCOMPARE(m_model->groupedSorting(), groupingEnabled); + adjustGeometryForColumnCount(columnCount); + QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); + + QSignalSpy spySingleItemActivated(m_controller, SIGNAL(itemActivated(int))); + QSignalSpy spyMultipleItemsActivated(m_controller, SIGNAL(itemsActivated(QSet))); + while (!testList.isEmpty()) { const QPair 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 QSet selection = test.second.m_selection; + const bool activated = test.second.m_activated; QTest::keyClick(m_container, key, modifier); + QCOMPARE(m_selectionManager->currentItem(), current); switch (selectionBehavior) { case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); break; case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), QSet() << current); break; case KItemListController::MultiSelection: QCOMPARE(m_selectionManager->selectedItems(), selection); break; } + + 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(spySingleItemActivated.takeFirst().at(0)), selection.toList().at(0)); + QVERIFY(spyMultipleItemsActivated.isEmpty()); + } else { + QVERIFY(spySingleItemActivated.isEmpty()); + QVERIFY(!spyMultipleItemsActivated.isEmpty()); + QCOMPARE(qvariant_cast >(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. + case KItemListController::NoSelection: + case KItemListController::SingleSelection: + // In NoSelection and SingleSelection mode, the current item should be activated. + QVERIFY(!spySingleItemActivated.isEmpty()); + QCOMPARE(qvariant_cast(spySingleItemActivated.takeFirst().at(0)), current); + QVERIFY(spyMultipleItemsActivated.isEmpty()); + break; + } + } + } +} + +void KItemListControllerTest::testMouseClickActivation() +{ + m_view->setItemLayout(KFileItemListView::IconsLayout); + + // Make sure that we have a large window, such that + // the items are visible and clickable. + adjustGeometryForColumnCount(5); + + // Make sure that the first item is visible in the view. + QTest::keyClick(m_container, Qt::Key_End, Qt::NoModifier); + QTest::keyClick(m_container, Qt::Key_Home, Qt::NoModifier); + while (m_view->firstVisibleIndex() > 0) { + QTest::qWait(50); + } + + const QPointF pos = m_view->itemContextRect(0).center(); + + // Save the "single click" setting. + const bool restoreKGlobalSettingsSingleClick = KGlobalSettings::singleClick(); + + KConfig config("kcminputrc"); + KConfigGroup group = config.group("KDE"); + + QGraphicsSceneMouseEvent mousePressEvent(QEvent::GraphicsSceneMousePress); + mousePressEvent.setPos(pos); + mousePressEvent.setButton(Qt::LeftButton); + mousePressEvent.setButtons(Qt::LeftButton); + + QGraphicsSceneMouseEvent mouseReleaseEvent(QEvent::GraphicsSceneMouseRelease); + mouseReleaseEvent.setPos(pos); + mouseReleaseEvent.setButton(Qt::LeftButton); + mouseReleaseEvent.setButtons(Qt::NoButton); + + QSignalSpy spyItemActivated(m_controller, SIGNAL(itemActivated(int))); + + // Default setting: single click activation. + group.writeEntry("SingleClick", true, KConfig::Persistent|KConfig::Global); + config.sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); + while (!KGlobalSettings::singleClick()) { + QTest::qWait(50); + } + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 1); + spyItemActivated.clear(); + + // Set the global setting to "double click activation". + group.writeEntry("SingleClick", false, KConfig::Persistent|KConfig::Global); + config.sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); + while (KGlobalSettings::singleClick()) { + QTest::qWait(50); + } + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 0); + spyItemActivated.clear(); + + // Enforce single click activation in the controller. + m_controller->setSingleClickActivationEnforced(true); + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 1); + spyItemActivated.clear(); + + // Do not enforce single click activation in the controller. + m_controller->setSingleClickActivationEnforced(false); + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 0); + spyItemActivated.clear(); + + // Set the global setting back to "single click activation". + group.writeEntry("SingleClick", true, KConfig::Persistent|KConfig::Global); + config.sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); + while (!KGlobalSettings::singleClick()) { + QTest::qWait(50); + } + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 1); + spyItemActivated.clear(); + + // Enforce single click activation in the controller. + m_controller->setSingleClickActivationEnforced(true); + m_view->event(&mousePressEvent); + m_view->event(&mouseReleaseEvent); + QCOMPARE(spyItemActivated.count(), 1); + spyItemActivated.clear(); + + // Restore previous settings. + m_controller->setSingleClickActivationEnforced(true); + group.writeEntry("SingleClick", restoreKGlobalSettingsSingleClick, KConfig::Persistent|KConfig::Global); + config.sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); + while (KGlobalSettings::singleClick() != restoreKGlobalSettingsSingleClick) { + QTest::qWait(50); } }