From 7424fcc3314a63d0716cb428a8b8de24b23e0279 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Thu, 29 Sep 2011 20:50:00 +0200 Subject: Keep current item and selection when resorting, part 1 KFileItemModel now emits the itemsMoved signal when the model is resorted, and KItemListSelectionManager has a new function itemsMoved() which will be called indirectly when this signal is emitted. Unit tests for the new functionality are included. The following things are still needed to make the feature work: 1. KFileItemMdel::resortAllItems() should not emit itemsAdded/itemsRemoved any more. 2. KItemListView::itemsMoved() must update the view according to the changes in the model, and it must call KItemListSelectionManager::itemsMoved(). --- src/tests/kfileitemmodeltest.cpp | 33 +++++++++-- src/tests/kitemlistselectionmanagertest.cpp | 91 ++++++++++++++++++++++++----- 2 files changed, 103 insertions(+), 21 deletions(-) (limited to 'src/tests') diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index ea8c19c05..f56ef9033 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -29,6 +29,7 @@ namespace { }; Q_DECLARE_METATYPE(KItemRangeList) +Q_DECLARE_METATYPE(QList) class KFileItemModelTest : public QObject { @@ -65,6 +66,7 @@ private: void KFileItemModelTest::init() { + qRegisterMetaType("KItemRange"); qRegisterMetaType("KItemRangeList"); qRegisterMetaType("KFileItemList"); @@ -355,23 +357,31 @@ void KFileItemModelTest::testSorting() //QVERIFY(!m_model->showHiddenFiles()); QCOMPARE(itemsInModel(), QStringList() << "c" << "a" << "b" << "d" << "e"); + QSignalSpy spyItemsMoved(m_model, SIGNAL(itemsMoved(KItemRange,QList))); + // Sort by Name, descending m_model->setSortOrder(Qt::DescendingOrder); QCOMPARE(m_model->sortRole(), QByteArray("name")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "e" << "d" << "b" << "a"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 4 << 3 << 2 << 1); - // Sort by Date, decending + // Sort by Date, descending m_model->setSortRole("date"); QCOMPARE(m_model->sortRole(), QByteArray("date")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "b" << "d" << "a" << "e"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 4 << 2 << 1 << 3); // Sort by Date, ascending m_model->setSortOrder(Qt::AscendingOrder); QCOMPARE(m_model->sortRole(), QByteArray("date")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "e" << "a" << "d" << "b"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 4 << 3 << 2 << 1); // Sort by Date, ascending, 'Sort Folders First' disabled m_model->setSortFoldersFirst(false); @@ -379,20 +389,33 @@ void KFileItemModelTest::testSorting() QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(!m_model->sortFoldersFirst()); QCOMPARE(itemsInModel(), QStringList() << "e" << "a" << "c" << "d" << "b"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 2 << 0 << 1 << 3 << 4); - // Default: Sort by Name, ascending, 'Sort Folders First' disabled + // Sort by Name, ascending, 'Sort Folders First' disabled m_model->setSortRole("name"); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(!m_model->sortFoldersFirst()); QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "d" << "e"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 4 << 0 << 2 << 3 << 1); - // Sort by Size, ascending, 'Sort Folders First' enabled + // Sort by Size, ascending, 'Sort Folders First' disabled m_model->setSortRole("size"); + QCOMPARE(m_model->sortRole(), QByteArray("size")); + QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); + QVERIFY(!m_model->sortFoldersFirst()); + QCOMPARE(itemsInModel(), QStringList() << "c" << "a" << "b" << "e" << "d"); + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 1 << 2 << 0 << 4 << 3); + + // In 'Sort by Size' mode, folders are always first -> changing 'Sort Folders First' does not resort the model m_model->setSortFoldersFirst(true); QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(m_model->sortFoldersFirst()); QCOMPARE(itemsInModel(), QStringList() << "c" << "a" << "b" << "e" << "d"); + QCOMPARE(spyItemsMoved.count(), 0); // Sort by Size, descending, 'Sort Folders First' enabled m_model->setSortOrder(Qt::DescendingOrder); @@ -400,8 +423,8 @@ void KFileItemModelTest::testSorting() QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QVERIFY(m_model->sortFoldersFirst()); QCOMPARE(itemsInModel(), QStringList() << "c" << "d" << "e" << "b" << "a"); - - // TODO: How shall the sorting by size be done if 'Sort Folders First' is disabled? + QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 4 << 3 << 2 << 1); // TODO: Sort by other roles; show/hide hidden files } diff --git a/src/tests/kitemlistselectionmanagertest.cpp b/src/tests/kitemlistselectionmanagertest.cpp index c27096177..2a3601bb0 100644 --- a/src/tests/kitemlistselectionmanagertest.cpp +++ b/src/tests/kitemlistselectionmanagertest.cpp @@ -297,14 +297,44 @@ namespace { NoChange, InsertItems, RemoveItems, + MoveItems, EndAnchoredSelection, - ToggleSelected + SetSelected }; } Q_DECLARE_METATYPE(QSet); Q_DECLARE_METATYPE(ChangeType); +Q_DECLARE_METATYPE(KItemRange); Q_DECLARE_METATYPE(KItemRangeList); +Q_DECLARE_METATYPE(KItemListSelectionManager::SelectionMode); +Q_DECLARE_METATYPE(QList); + +/** + * The following function provides a generic way to test the selection functionality. + * + * The test is data-driven and takes the following arguments: + * + * \param initialSelection The selection at the beginning. + * \param anchor This item will be the anchor item. + * \param current This item will be the current item. + * \param expectedSelection Expected selection after anchor and current are set. + * \param changeType Type of the change that is done then: + * - NoChange + * - InsertItems -> data.at(0) provides the KItemRangeList. \sa KItemListSelectionManager::itemsInserted() + * - RemoveItems -> data.at(0) provides the KItemRangeList. \sa KItemListSelectionManager::itemsRemoved() + * - MoveItems -> data.at(0) provides the KItemRange containing the original indices, + * data.at(1) provides the list containing the new indices + * \sa KItemListSelectionManager::itemsMoved(), KItemModelBase::itemsMoved() + * - EndAnchoredSelection + * - SetSelected -> data.at(0) provides the index where the selection process starts, + * data.at(1) provides the number of indices to be selected, + * data.at(2) provides the selection mode. + * \sa KItemListSelectionManager::setSelected() + * \param data A list of QVariants which will be cast to the arguments needed for the chosen ChangeType (see above). + * \param finalSelection The expected final selection. + * + */ void KItemListSelectionManagerTest::testChangeSelection_data() { @@ -313,43 +343,68 @@ void KItemListSelectionManagerTest::testChangeSelection_data() QTest::addColumn("current"); QTest::addColumn >("expectedSelection"); QTest::addColumn("changeType"); - QTest::addColumn("changedItems"); + QTest::addColumn >("data"); QTest::addColumn >("finalSelection"); QTest::newRow("No change") << (QSet() << 5 << 6) << 2 << 3 << (QSet() << 2 << 3 << 5 << 6) - << NoChange << KItemRangeList() + << NoChange + << QList() << (QSet() << 2 << 3 << 5 << 6); QTest::newRow("Insert Items") << (QSet() << 5 << 6) << 2 << 3 << (QSet() << 2 << 3 << 5 << 6) - << InsertItems << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 2) << KItemRange(10, 5)) + << InsertItems + << (QList() << QVariant::fromValue(KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 2) << KItemRange(10, 5))) << (QSet() << 3 << 4 << 8 << 9); QTest::newRow("Remove Items") << (QSet() << 5 << 6) << 2 << 3 << (QSet() << 2 << 3 << 5 << 6) - << RemoveItems << (KItemRangeList() << KItemRange(1, 1) << KItemRange(3, 1) << KItemRange(10, 5)) + << RemoveItems + << (QList() << QVariant::fromValue(KItemRangeList() << KItemRange(1, 1) << KItemRange(3, 1) << KItemRange(10, 5))) << (QSet() << 1 << 2 << 3 << 4); QTest::newRow("Empty Anchored Selection") << QSet() << 2 << 2 << QSet() - << EndAnchoredSelection << KItemRangeList() + << EndAnchoredSelection + << QList() << QSet(); QTest::newRow("Toggle selection") << (QSet() << 1 << 3 << 4) << 6 << 8 << (QSet() << 1 << 3 << 4 << 6 << 7 << 8) - << ToggleSelected << (KItemRangeList() << KItemRange(0, 10)) + << SetSelected + << (QList() << 0 << 10 << QVariant::fromValue(KItemListSelectionManager::Toggle)) << (QSet() << 0 << 2 << 5 << 9); + + // Swap items 2, 3 and 4, 5 + QTest::newRow("Move items") + << (QSet() << 0 << 1 << 2 << 3) + << -1 << -1 + << (QSet() << 0 << 1 << 2 << 3) + << MoveItems + << (QList() << QVariant::fromValue(KItemRange(2, 4)) + << QVariant::fromValue(QList() << 4 << 5 << 2 << 3)) + << (QSet() << 0 << 1 << 4 << 5); + + // Revert sort order + QTest::newRow("Revert sort order") + << (QSet() << 0 << 1) + << 3 << 4 + << (QSet() << 0 << 1 << 3 << 4) + << MoveItems + << (QList() << QVariant::fromValue(KItemRange(0, 10)) + << QVariant::fromValue(QList() << 9 << 8 << 7 << 6 << 5 << 4 << 3 << 2 << 1 << 0)) + << (QSet() << 5 << 6 << 8 << 9); } void KItemListSelectionManagerTest::testChangeSelection() @@ -357,10 +412,10 @@ void KItemListSelectionManagerTest::testChangeSelection() QFETCH(QSet, initialSelection); QFETCH(int, anchor); QFETCH(int, current); - QFETCH(QSet , expectedSelection); + QFETCH(QSet, expectedSelection); QFETCH(ChangeType, changeType); - QFETCH(KItemRangeList, changedItems); - QFETCH(QSet , finalSelection); + QFETCH(QList, data); + QFETCH(QSet, finalSelection); QSignalSpy spySelectionChanged(m_selectionManager, SIGNAL(selectionChanged(QSet,QSet))); @@ -406,19 +461,23 @@ void KItemListSelectionManagerTest::testChangeSelection() // Change the model by inserting or removing items. switch (changeType) { case InsertItems: - m_selectionManager->itemsInserted(changedItems); + m_selectionManager->itemsInserted(data.at(0).value()); break; case RemoveItems: - m_selectionManager->itemsRemoved(changedItems); + m_selectionManager->itemsRemoved(data.at(0).value()); + break; + case MoveItems: + m_selectionManager->itemsMoved(data.at(0).value(), + data.at(1).value >()); break; case EndAnchoredSelection: m_selectionManager->endAnchoredSelection(); QVERIFY(!m_selectionManager->isAnchoredSelectionActive()); break; - case ToggleSelected: - foreach(const KItemRange& range, changedItems) { - m_selectionManager->setSelected(range.index, range.count, KItemListSelectionManager::Toggle); - } + case SetSelected: + m_selectionManager->setSelected(data.at(0).value(), // index + data.at(1).value(), // count + data.at(2).value()); break; case NoChange: break; -- cgit v1.3