diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kitemviews/kfileitemmodel.cpp | 13 | ||||
| -rw-r--r-- | src/tests/kfileitemmodeltest.cpp | 88 | ||||
| -rw-r--r-- | src/views/versioncontrol/updateitemstatesthread.cpp | 36 | ||||
| -rw-r--r-- | src/views/versioncontrol/updateitemstatesthread.h | 6 | ||||
| -rw-r--r-- | src/views/versioncontrol/versioncontrolobserver.cpp | 63 | ||||
| -rw-r--r-- | src/views/versioncontrol/versioncontrolobserver.h | 16 |
6 files changed, 185 insertions, 37 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index c06f87e06..bd905bf07 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -1179,6 +1179,19 @@ void KFileItemModel::removeExpandedItems() removeItems(expandedItems, DeleteItemData); m_expandedDirs.clear(); + + // Also remove all filtered items which have a parent. + QHash<KFileItem, ItemData*>::iterator it = m_filteredItems.begin(); + const QHash<KFileItem, ItemData*>::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<QByteArray>& changedRoles) diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index ff8dcd268..299ca6f92 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -77,6 +77,7 @@ private slots: void testExpandItems(); void testExpandParentItems(); void testMakeExpandedItemHidden(); + void testRemoveFilteredExpandedItems(); void testSorting(); void testIndexForKeyboardSearch(); void testNameFilter(); @@ -87,6 +88,7 @@ private slots: void removeParentOfHiddenItems(); void testGeneralParentChildRelationships(); void testNameRoleGroups(); + void testNameRoleGroupsWithExpandedItems(); private: QStringList itemsInModel() const; @@ -743,6 +745,51 @@ void KFileItemModelTest::testMakeExpandedItemHidden() } +void KFileItemModelTest::testRemoveFilteredExpandedItems() +{ + QSet<QByteArray> originalModelRoles = m_model->roles(); + QSet<QByteArray> 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 @@ -1318,11 +1365,50 @@ void KFileItemModelTest::testNameRoleGroups() QCOMPARE(m_model->groups(), expectedGroups); } +void KFileItemModelTest::testNameRoleGroupsWithExpandedItems() +{ + QSet<QByteArray> 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<QPair<int, QVariant> > expectedGroups; + expectedGroups << QPair<int, QVariant>(0, QLatin1String("A")); + expectedGroups << QPair<int, QVariant>(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<int, QVariant>(0, QLatin1String("A")); + expectedGroups << QPair<int, QVariant>(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; } diff --git a/src/views/versioncontrol/updateitemstatesthread.cpp b/src/views/versioncontrol/updateitemstatesthread.cpp index fa005f8f1..6be07d361 100644 --- a/src/views/versioncontrol/updateitemstatesthread.cpp +++ b/src/views/versioncontrol/updateitemstatesthread.cpp @@ -24,7 +24,7 @@ #include <QMutexLocker> UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin, - const QList<VersionControlObserver::ItemState>& itemStates) : + const QMap<QString, QVector<VersionControlObserver::ItemState> >& itemStates) : QThread(), m_globalPluginMutex(0), m_plugin(plugin), @@ -47,27 +47,29 @@ void UpdateItemStatesThread::run() Q_ASSERT(!m_itemStates.isEmpty()); Q_ASSERT(m_plugin); - const QString directory = m_itemStates.first().item.url().directory(KUrl::AppendTrailingSlash); m_retrievedItems = false; QMutexLocker pluginLocker(m_globalPluginMutex); - if (m_plugin->beginRetrieval(directory)) { - const int count = m_itemStates.count(); + foreach (const QString& directory, m_itemStates.keys()) { + if (m_plugin->beginRetrieval(directory)) { + QVector<VersionControlObserver::ItemState>& items = m_itemStates[directory]; + const int count = items.count(); - KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin); - if (pluginV2) { - for (int i = 0; i < count; ++i) { - m_itemStates[i].version = pluginV2->itemVersion(m_itemStates[i].item); + KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin); + if (pluginV2) { + for (int i = 0; i < count; ++i) { + items[i].version = pluginV2->itemVersion(items[i].item); + } + } else { + for (int i = 0; i < count; ++i) { + const KVersionControlPlugin::VersionState state = m_plugin->versionState(items[i].item); + items[i].version = static_cast<KVersionControlPlugin2::ItemVersion>(state); + } } - } else { - for (int i = 0; i < count; ++i) { - const KVersionControlPlugin::VersionState state = m_plugin->versionState(m_itemStates[i].item); - m_itemStates[i].version = static_cast<KVersionControlPlugin2::ItemVersion>(state); - } - } - m_plugin->endRetrieval(); - m_retrievedItems = true; + m_plugin->endRetrieval(); + m_retrievedItems = true; + } } } @@ -81,7 +83,7 @@ void UpdateItemStatesThread::unlockPlugin() m_globalPluginMutex->unlock(); } -QList<VersionControlObserver::ItemState> UpdateItemStatesThread::itemStates() const +QMap<QString, QVector<VersionControlObserver::ItemState> > UpdateItemStatesThread::itemStates() const { return m_itemStates; } diff --git a/src/views/versioncontrol/updateitemstatesthread.h b/src/views/versioncontrol/updateitemstatesthread.h index a28169755..2914bc2b7 100644 --- a/src/views/versioncontrol/updateitemstatesthread.h +++ b/src/views/versioncontrol/updateitemstatesthread.h @@ -47,7 +47,7 @@ public: * @param itemStates List of items, where the states get updated. */ UpdateItemStatesThread(KVersionControlPlugin* plugin, - const QList<VersionControlObserver::ItemState>& itemStates); + const QMap<QString, QVector<VersionControlObserver::ItemState> >& itemStates); virtual ~UpdateItemStatesThread(); /** @@ -63,7 +63,7 @@ public: */ void unlockPlugin(); - QList<VersionControlObserver::ItemState> itemStates() const; + QMap<QString, QVector<VersionControlObserver::ItemState> > itemStates() const; bool retrievedItems() const; @@ -75,7 +75,7 @@ private: KVersionControlPlugin* m_plugin; bool m_retrievedItems; - QList<VersionControlObserver::ItemState> m_itemStates; + QMap<QString, QVector<VersionControlObserver::ItemState> > m_itemStates; }; #endif // UPDATEITEMSTATESTHREAD_H diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index 402a2de54..4d939ee0d 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -204,11 +204,15 @@ void VersionControlObserver::slotThreadFinished() return; } - const QList<ItemState> itemStates = thread->itemStates(); - foreach (const ItemState& itemState, itemStates) { - QHash<QByteArray, QVariant> values; - values.insert("version", QVariant(itemState.version)); - m_model->setData(itemState.index, values); + const QMap<QString, QVector<ItemState> >& itemStates = thread->itemStates(); + foreach (const QString& directory, itemStates.keys()) { + const QVector<ItemState>& items = itemStates.value(directory); + + foreach (const ItemState& item, items) { + QHash<QByteArray, QVariant> values; + values.insert("version", QVariant(item.version)); + m_model->setData(item.index, values); + } } if (!m_silentUpdate) { @@ -233,18 +237,9 @@ void VersionControlObserver::updateItemStates() m_pendingItemStatesUpdate = true; return; } - QList<ItemState> itemStates; - const int itemCount = m_model->count(); - itemStates.reserve(itemCount); - for (int i = 0; i < itemCount; ++i) { - ItemState itemState; - itemState.index = i; - itemState.item = m_model->fileItem(i); - itemState.version = KVersionControlPlugin2::UnversionedVersion; - - itemStates.append(itemState); - } + QMap<QString, QVector<ItemState> > itemStates; + createItemStatesList(itemStates); if (!itemStates.isEmpty()) { if (!m_silentUpdate) { @@ -260,6 +255,42 @@ void VersionControlObserver::updateItemStates() } } +int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState> >& itemStates, + const int firstIndex) +{ + const int itemCount = m_model->count(); + const int currentExpansionLevel = m_model->expandedParentsCount(firstIndex); + + QVector<ItemState> items; + items.reserve(itemCount - firstIndex); + + int index; + for (index = firstIndex; index < itemCount; ++index) { + const int expansionLevel = m_model->expandedParentsCount(index); + + if (expansionLevel == currentExpansionLevel) { + ItemState itemState; + itemState.index = index; + itemState.item = m_model->fileItem(index); + itemState.version = KVersionControlPlugin2::UnversionedVersion; + + items.append(itemState); + } else if (expansionLevel > currentExpansionLevel) { + // Sub folder + index += createItemStatesList(itemStates, index) - 1; + } else { + break; + } + } + + if (items.count() > 0) { + const KUrl& url = items.first().item.url(); + itemStates.insert(url.directory(KUrl::AppendTrailingSlash), items); + } + + return index - firstIndex; // number of processed items +} + KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& directory) const { static bool pluginsAvailable = true; diff --git a/src/views/versioncontrol/versioncontrolobserver.h b/src/views/versioncontrol/versioncontrolobserver.h index 501af7d6f..980374af9 100644 --- a/src/views/versioncontrol/versioncontrolobserver.h +++ b/src/views/versioncontrol/versioncontrolobserver.h @@ -110,6 +110,22 @@ private: void updateItemStates(); /** + * It creates a item state list for every expanded directory and stores + * this list together with the directory url in the \a itemStates map. + * + * @itemStates A map of item state lists for every expanded directory + * and its items, where the "key" is the directory url and + * the "value" is a list of ItemStates for every item + * within this directory. + * @firstIndex The index to start the processing from, this is needed + * because this function is recursively called. + * + * @return The number of (recursive) processed items. + */ + int createItemStatesList(QMap<QString, QVector<ItemState> >& itemStates, + const int firstIndex = 0); + + /** * Returns a matching plugin for the given directory. * 0 is returned, if no matching plugin has been found. */ |
