┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemmodel.cpp13
-rw-r--r--src/tests/kfileitemmodeltest.cpp88
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.cpp36
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.h6
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.cpp63
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.h16
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.
*/