From: Frank Reininghaus Date: Mon, 30 Sep 2013 22:15:04 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/KDE/4.11' X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/926782d3be2502c6d3e87ef992aa371c081d72b4?hp=-c Merge remote-tracking branch 'origin/KDE/4.11' --- 926782d3be2502c6d3e87ef992aa371c081d72b4 diff --combined src/kitemviews/kfileitemmodel.cpp index c06f87e06,7b7c39ad7..bd905bf07 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@@ -468,7 -468,10 +468,7 @@@ bool KFileItemModel::isExpandable(int i int KFileItemModel::expandedParentsCount(int index) const { if (index >= 0 && index < count()) { - const int parentsCount = m_itemData.at(index)->values.value("expandedParentsCount").toInt(); - if (parentsCount > 0) { - return parentsCount; - } + return expandedParentsCount(m_itemData.at(index)); } return 0; } @@@ -682,6 -685,7 +682,6 @@@ void KFileItemModel::resortAllItems( oldUrls.append(itemData->item.url()); } - m_groups.clear(); m_items.clear(); // Resort the items @@@ -690,45 -694,20 +690,45 @@@ m_items.insert(m_itemData.at(i)->item.url(), i); } - // Determine the indexes that have been moved - QList movedToIndexes; - movedToIndexes.reserve(itemCount); - for (int i = 0; i < itemCount; i++) { - const int newIndex = m_items.value(oldUrls.at(i)); - movedToIndexes.append(newIndex); + // Determine the first index that has been moved. + int firstMovedIndex = 0; + while (firstMovedIndex < itemCount + && firstMovedIndex == m_items.value(oldUrls.at(firstMovedIndex))) { + ++firstMovedIndex; } - // Don't check whether items have really been moved and always emit a - // itemsMoved() signal after resorting: In case of grouped items - // the groups might change even if the items themselves don't change their - // position. Let the receiver of the signal decide whether a check for moved - // items makes sense. - emit itemsMoved(KItemRange(0, itemCount), movedToIndexes); + const bool itemsHaveMoved = firstMovedIndex < itemCount; + if (itemsHaveMoved) { + m_groups.clear(); + + int lastMovedIndex = itemCount - 1; + while (lastMovedIndex > firstMovedIndex + && lastMovedIndex == m_items.value(oldUrls.at(lastMovedIndex))) { + --lastMovedIndex; + } + + Q_ASSERT(firstMovedIndex <= lastMovedIndex); + + // Create a list movedToIndexes, which has the property that + // movedToIndexes[i] is the new index of the item with the old index + // firstMovedIndex + i. + const int movedItemsCount = lastMovedIndex - firstMovedIndex + 1; + QList movedToIndexes; + movedToIndexes.reserve(movedItemsCount); + for (int i = firstMovedIndex; i <= lastMovedIndex; ++i) { + const int newIndex = m_items.value(oldUrls.at(i)); + movedToIndexes.append(newIndex); + } + + emit itemsMoved(KItemRange(firstMovedIndex, movedItemsCount), movedToIndexes); + } else if (groupedSorting()) { + // The groups might have changed even if the order of the items has not. + const QList > oldGroups = m_groups; + m_groups.clear(); + if (groups() != oldGroups) { + emit groupsChanged(); + } + } #ifdef KFILEITEMMODEL_DEBUG kDebug() << "[TIME] Resorting of" << itemCount << "items:" << timer.elapsed(); @@@ -916,7 -895,30 +916,7 @@@ void KFileItemModel::slotRefreshItems(c // Extract the item-ranges out of the changed indexes qSort(indexes); - - KItemRangeList itemRangeList; - int previousIndex = indexes.at(0); - int rangeIndex = previousIndex; - int rangeCount = 1; - - const int maxIndex = indexes.count() - 1; - for (int i = 1; i <= maxIndex; ++i) { - const int currentIndex = indexes.at(i); - if (currentIndex == previousIndex + 1) { - ++rangeCount; - } else { - itemRangeList.append(KItemRange(rangeIndex, rangeCount)); - - rangeIndex = currentIndex; - rangeCount = 1; - } - previousIndex = currentIndex; - } - - if (rangeCount > 0) { - itemRangeList.append(KItemRange(rangeIndex, rangeCount)); - } - + const KItemRangeList itemRangeList = KItemRangeList::fromSortedContainer(indexes); emitItemsChangedAndTriggerResorting(itemRangeList, changedRoles); } @@@ -1054,6 -1056,36 +1054,6 @@@ void KFileItemModel::insertItems(QList< #endif } -static KItemRangeList sortedIndexesToKItemRangeList(const QList& sortedNumbers) -{ - if (sortedNumbers.empty()) { - return KItemRangeList(); - } - - KItemRangeList result; - - QList::const_iterator it = sortedNumbers.begin(); - int index = *it; - int count = 1; - - ++it; - - QList::const_iterator end = sortedNumbers.end(); - while (it != end) { - if (*it == index + count) { - ++count; - } else { - result << KItemRange(index, count); - index = *it; - count = 1; - } - ++it; - } - - result << KItemRange(index, count); - return result; -} - void KFileItemModel::removeItems(const KFileItemList& items, RemoveItemsBehavior behavior) { #ifdef KFILEITEMMODEL_DEBUG @@@ -1092,7 -1124,7 +1092,7 @@@ std::sort(indexesToRemove.begin(), indexesToRemove.end()); // Step 2: Remove the ItemData pointers from the list m_itemData. - const KItemRangeList itemRanges = sortedIndexesToKItemRangeList(indexesToRemove); + const KItemRangeList itemRanges = KItemRangeList::fromSortedContainer(indexesToRemove); int target = itemRanges.at(0).index; int source = itemRanges.at(0).index + itemRanges.at(0).count; int nextRange = 1; @@@ -1148,23 -1180,6 +1148,23 @@@ QList KFileI return itemDataList; } +int KFileItemModel::expandedParentsCount(const ItemData* data) +{ + // The hash 'values' is only guaranteed to contain the key "expandedParentsCount" + // if the corresponding item is expanded, and it is not a top-level item. + const ItemData* parent = data->parent; + if (parent) { + if (parent->parent) { + Q_ASSERT(parent->values.contains("expandedParentsCount")); + return parent->values.value("expandedParentsCount").toInt() + 1; + } else { + return 1; + } + } else { + return 0; + } +} + void KFileItemModel::removeExpandedItems() { KFileItemList expandedItems; @@@ -1172,13 -1187,29 +1172,26 @@@ const int maxIndex = m_itemData.count() - 1; for (int i = 0; i <= maxIndex; ++i) { const ItemData* itemData = m_itemData.at(i); - if (itemData->values.value("expandedParentsCount").toInt() > 0) { + if (itemData->parent) { expandedItems.append(itemData->item); } } - // The m_expandedParentsCountRoot may not get reset before all items with - // a bigger count have been removed. removeItems(expandedItems, DeleteItemData); - m_expandedDirs.clear(); + + // Also remove all filtered items which have a parent. + QHash::iterator it = m_filteredItems.begin(); + const QHash::iterator end = m_filteredItems.end(); + + while (it != end) { + if (it.value()->parent) { + delete it.value(); + it = m_filteredItems.erase(it); + } else { + ++it; + } + } } void KFileItemModel::emitItemsChangedAndTriggerResorting(const KItemRangeList& itemRanges, const QSet& changedRoles) @@@ -1374,7 -1405,7 +1387,7 @@@ QHash KFileItemMo if (m_requestRole[ExpandedParentsCountRole]) { if (parent) { - const int level = parent->values["expandedParentsCount"].toInt() + 1; + const int level = expandedParentsCount(parent) + 1; data.insert(sharedValue("expandedParentsCount"), level); } } @@@ -1398,8 -1429,8 +1411,8 @@@ bool KFileItemModel::lessThan(const Ite int result = 0; if (a->parent != b->parent) { - const int expansionLevelA = a->values.value("expandedParentsCount").toInt(); - const int expansionLevelB = b->values.value("expandedParentsCount").toInt(); + const int expansionLevelA = expandedParentsCount(a); + const int expansionLevelB = expandedParentsCount(b); // If b has a higher expansion level than a, check if a is a parent // of b, and make sure that both expansion levels are equal otherwise. @@@ -1419,7 -1450,7 +1432,7 @@@ a = a->parent; } - Q_ASSERT(a->values.value("expandedParentsCount").toInt() == b->values.value("expandedParentsCount").toInt()); + Q_ASSERT(expandedParentsCount(a) == expandedParentsCount(b)); // Compare the last parents of a and b which are different. while (a->parent != b->parent) { @@@ -1918,9 -1949,9 +1931,9 @@@ KFileItemList KFileItemModel::childItem int index = m_items.value(item.url(), -1); if (index >= 0) { - const int parentLevel = m_itemData.at(index)->values.value("expandedParentsCount").toInt(); + const int parentLevel = expandedParentsCount(index); ++index; - while (index < m_itemData.count() && m_itemData.at(index)->values.value("expandedParentsCount").toInt() > parentLevel) { + while (index < m_itemData.count() && expandedParentsCount(index) > parentLevel) { items.append(m_itemData.at(index)->item); ++index; } @@@ -2055,7 -2086,7 +2068,7 @@@ bool KFileItemModel::isConsistent() con const ItemData* data = m_itemData.at(i); const ItemData* parent = data->parent; if (parent) { - if (data->values.value("expandedParentsCount").toInt() != parent->values.value("expandedParentsCount").toInt() + 1) { + if (expandedParentsCount(data) != expandedParentsCount(parent) + 1) { qWarning() << "expandedParentsCount is inconsistent for parent" << parent->item << "and child" << data->item; return false; } diff --combined src/tests/kfileitemmodeltest.cpp index ff8dcd268,5dd3417fc..299ca6f92 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@@ -49,7 -49,6 +49,7 @@@ namespace const int DefaultTimeout = 5000; }; +Q_DECLARE_METATYPE(KItemRange) Q_DECLARE_METATYPE(KItemRangeList) Q_DECLARE_METATYPE(QList) @@@ -77,6 -76,7 +77,7 @@@ private slots void testExpandItems(); void testExpandParentItems(); void testMakeExpandedItemHidden(); + void testRemoveFilteredExpandedItems(); void testSorting(); void testIndexForKeyboardSearch(); void testNameFilter(); @@@ -87,6 -87,7 +88,7 @@@ void removeParentOfHiddenItems(); void testGeneralParentChildRelationships(); void testNameRoleGroups(); + void testNameRoleGroupsWithExpandedItems(); private: QStringList itemsInModel() const; @@@ -498,8 -499,7 +500,8 @@@ void KFileItemModelTest::testExpandItem // KFileItemModel::expansionLevelsCompare(const KFileItem& a, const KFileItem& b) // yields the correct result for "a/a/1" and "a/a-1/", whis is non-trivial because they share the // first three characters. - QSet modelRoles = m_model->roles(); + QSet originalModelRoles = m_model->roles(); + QSet modelRoles = originalModelRoles; modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; m_model->setRoles(modelRoles); @@@ -606,18 -606,6 +608,18 @@@ QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout)); QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" QCOMPARE(m_model->expandedDirectories(), allFolders); + + // Remove all expanded items by changing the roles + spyRemoved.clear(); + m_model->setRoles(originalModelRoles); + QVERIFY(!m_model->isExpanded(0)); + QCOMPARE(m_model->count(), 1); + QVERIFY(!m_model->expandedDirectories().contains(KUrl(m_testDir->name() + 'a'))); + + QCOMPARE(spyRemoved.count(), 1); + itemRangeList = spyRemoved.takeFirst().at(0).value(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 4)); // 4 items removed + QVERIFY(m_model->isConsistent()); } void KFileItemModelTest::testExpandParentItems() @@@ -670,28 -658,6 +672,28 @@@ QVERIFY(m_model->isExpanded(3)); QVERIFY(!m_model->isExpanded(4)); QVERIFY(m_model->isConsistent()); + + // Expand "a 1/b1/". + m_model->setExpanded(1, true); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout)); + QCOMPARE(m_model->count(), 6); + QVERIFY(m_model->isExpanded(0)); + QVERIFY(m_model->isExpanded(1)); + QVERIFY(!m_model->isExpanded(2)); + QVERIFY(m_model->isExpanded(3)); + QVERIFY(m_model->isExpanded(4)); + QVERIFY(!m_model->isExpanded(5)); + QVERIFY(m_model->isConsistent()); + + // Collapse "a 1/b1/" again, and verify that the previous state is restored. + m_model->setExpanded(1, false); + QCOMPARE(m_model->count(), 5); + QVERIFY(m_model->isExpanded(0)); + QVERIFY(!m_model->isExpanded(1)); + QVERIFY(m_model->isExpanded(2)); + QVERIFY(m_model->isExpanded(3)); + QVERIFY(!m_model->isExpanded(4)); + QVERIFY(m_model->isConsistent()); } /** @@@ -743,6 -709,51 +745,51 @@@ void KFileItemModelTest::testMakeExpand } + void KFileItemModelTest::testRemoveFilteredExpandedItems() + { + QSet originalModelRoles = m_model->roles(); + QSet modelRoles = originalModelRoles; + modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + m_model->setRoles(modelRoles); + + QStringList files; + files << "folder/child" << "file"; // missing folders are created automatically + m_testDir->createFiles(files); + + m_model->loadDirectory(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + + // So far, the model contains only "folder/" and "file". + QCOMPARE(m_model->count(), 2); + QVERIFY(m_model->isExpandable(0)); + QVERIFY(!m_model->isExpandable(1)); + QVERIFY(!m_model->isExpanded(0)); + QVERIFY(!m_model->isExpanded(1)); + QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + + // Expand "folder" -> "folder/child" becomes visible. + m_model->setExpanded(0, true); + QVERIFY(m_model->isExpanded(0)); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + QCOMPARE(itemsInModel(), QStringList() << "folder" << "child" << "file"); + + // Add a name filter. + m_model->setNameFilter("f"); + QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + + m_model->setNameFilter("fo"); + QCOMPARE(itemsInModel(), QStringList() << "folder"); + + // Remove all expanded items by changing the roles + m_model->setRoles(originalModelRoles); + QVERIFY(!m_model->isExpanded(0)); + QCOMPARE(itemsInModel(), QStringList() << "folder"); + + // Remove the name filter and verify that "folder/child" does not reappear. + m_model->setNameFilter(QString()); + QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + } + void KFileItemModelTest::testSorting() { // Create some files with different sizes and modification times to check the different sorting options @@@ -792,8 -803,7 +839,8 @@@ QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e"); QCOMPARE(spyItemsMoved.count(), 1); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(0, 6)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1); // Sort by Name, descending m_model->setSortDirectoriesFirst(true); @@@ -802,10 -812,8 +849,10 @@@ QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a"); QCOMPARE(spyItemsMoved.count(), 2); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 4 << 5 << 0 << 3 << 1 << 2 << 6 << 7); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 1 << 2 << 3 << 7 << 6 << 5 << 4); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(0, 6)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 4 << 5 << 0 << 3 << 1 << 2); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(4, 4)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); // Sort by Date, descending m_model->setSortDirectoriesFirst(true); @@@ -814,8 -822,7 +861,8 @@@ QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "b" << "d" << "a" << "e"); QCOMPARE(spyItemsMoved.count(), 1); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 1 << 2 << 3 << 7 << 5 << 4 << 6); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(4, 4)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 7 << 5 << 4 << 6); // Sort by Date, ascending m_model->setSortOrder(Qt::AscendingOrder); @@@ -823,8 -830,7 +870,8 @@@ QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "a" << "d" << "b"); QCOMPARE(spyItemsMoved.count(), 1); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 1 << 2 << 3 << 7 << 6 << 5 << 4); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(4, 4)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); // Sort by Date, ascending, 'Sort Folders First' disabled m_model->setSortDirectoriesFirst(false); @@@ -833,8 -839,7 +880,8 @@@ QVERIFY(!m_model->sortDirectoriesFirst()); QCOMPARE(itemsInModel(), QStringList() << "e" << "a" << "c" << "c-1" << "c-2" << "c-3" << "d" << "b"); QCOMPARE(spyItemsMoved.count(), 1); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(0, 6)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1); // Sort by Name, ascending, 'Sort Folders First' disabled m_model->setSortRole("text"); @@@ -842,7 -847,6 +889,7 @@@ QVERIFY(!m_model->sortDirectoriesFirst()); QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e"); QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(0, 8)); QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 7 << 0 << 2 << 3 << 4 << 5 << 6 << 1); // Sort by Size, ascending, 'Sort Folders First' disabled @@@ -852,15 -856,19 +899,15 @@@ QVERIFY(!m_model->sortDirectoriesFirst()); QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "e" << "d"); QCOMPARE(spyItemsMoved.count(), 1); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(0, 8)); QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 4 << 5 << 0 << 3 << 1 << 2 << 7 << 6); - QSKIP("2 tests of testSorting() are temporary deactivated as in KFileItemModel resortAllItems() " - "always emits a itemsMoved() signal. Before adjusting the tests think about probably introducing " - "another signal", SkipSingle); - // Internal note: Check comment in KFileItemModel::resortAllItems() for details. - // In 'Sort by Size' mode, folders are always first -> changing 'Sort Folders First' does not resort the model m_model->setSortDirectoriesFirst(true); QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "a" << "b" << "e" << "d"); + QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "e" << "d"); QCOMPARE(spyItemsMoved.count(), 0); // Sort by Size, descending, 'Sort Folders First' enabled @@@ -868,10 -876,9 +915,10 @@@ QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QVERIFY(m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "d" << "e" << "b" << "a"); + QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "d" << "e" << "b" << "a"); QCOMPARE(spyItemsMoved.count(), 1); - QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 0 << 4 << 3 << 2 << 1); + QCOMPARE(spyItemsMoved.first().at(0).value(), KItemRange(4, 4)); + QCOMPARE(spyItemsMoved.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); // TODO: Sort by other roles; show/hide hidden files } @@@ -1289,7 -1296,7 +1336,7 @@@ void KFileItemModelTest::testNameRoleGr // Rename c.txt to d.txt. data.insert("text", "d.txt"); m_model->setData(2, data); - QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsMoved(KItemRange,QList)), DefaultTimeout)); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(groupsChanged()), DefaultTimeout)); QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "d.txt" << "e.txt"); expectedGroups.clear(); @@@ -1307,7 -1314,7 +1354,7 @@@ fileItemC.setUrl(urlC); m_model->slotRefreshItems(QList >() << qMakePair(fileItemD, fileItemC)); - QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsMoved(KItemRange,QList)), DefaultTimeout)); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(groupsChanged()), DefaultTimeout)); QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "e.txt"); expectedGroups.clear(); @@@ -1318,11 -1325,50 +1365,50 @@@ QCOMPARE(m_model->groups(), expectedGroups); } + void KFileItemModelTest::testNameRoleGroupsWithExpandedItems() + { + QSet modelRoles = m_model->roles(); + modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + m_model->setRoles(modelRoles); + + QStringList files; + files << "a/b.txt" << "a/c.txt" << "d/e.txt" << "d/f.txt"; + + m_testDir->createFiles(files); + + m_model->setGroupedSorting(true); + m_model->loadDirectory(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + QCOMPARE(itemsInModel(), QStringList() << "a" << "d"); + + QList > expectedGroups; + expectedGroups << QPair(0, QLatin1String("A")); + expectedGroups << QPair(1, QLatin1String("D")); + QCOMPARE(m_model->groups(), expectedGroups); + + // Verify that expanding "a" and "d" will not change the groups (except for the index of "D"). + expectedGroups.clear(); + expectedGroups << QPair(0, QLatin1String("A")); + expectedGroups << QPair(3, QLatin1String("D")); + + m_model->setExpanded(0, true); + QVERIFY(m_model->isExpanded(0)); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + QCOMPARE(itemsInModel(), QStringList() << "a" << "b.txt" << "c.txt" << "d"); + QCOMPARE(m_model->groups(), expectedGroups); + + m_model->setExpanded(3, true); + QVERIFY(m_model->isExpanded(3)); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + QCOMPARE(itemsInModel(), QStringList() << "a" << "b.txt" << "c.txt" << "d" << "e.txt" << "f.txt"); + QCOMPARE(m_model->groups(), expectedGroups); + } + QStringList KFileItemModelTest::itemsInModel() const { QStringList items; for (int i = 0; i < m_model->count(); i++) { - items << m_model->data(i).value("text").toString(); + items << m_model->fileItem(i).text(); } return items; }