mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-17 15:31:20 +00:00
Merge remote-tracking branch 'origin/KDE/4.11'
This commit is contained in:
commit
926782d3be
|
@ -1179,6 +1179,19 @@ void KFileItemModel::removeExpandedItems()
|
||||||
|
|
||||||
removeItems(expandedItems, DeleteItemData);
|
removeItems(expandedItems, DeleteItemData);
|
||||||
m_expandedDirs.clear();
|
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)
|
void KFileItemModel::emitItemsChangedAndTriggerResorting(const KItemRangeList& itemRanges, const QSet<QByteArray>& changedRoles)
|
||||||
|
|
|
@ -77,6 +77,7 @@ private slots:
|
||||||
void testExpandItems();
|
void testExpandItems();
|
||||||
void testExpandParentItems();
|
void testExpandParentItems();
|
||||||
void testMakeExpandedItemHidden();
|
void testMakeExpandedItemHidden();
|
||||||
|
void testRemoveFilteredExpandedItems();
|
||||||
void testSorting();
|
void testSorting();
|
||||||
void testIndexForKeyboardSearch();
|
void testIndexForKeyboardSearch();
|
||||||
void testNameFilter();
|
void testNameFilter();
|
||||||
|
@ -87,6 +88,7 @@ private slots:
|
||||||
void removeParentOfHiddenItems();
|
void removeParentOfHiddenItems();
|
||||||
void testGeneralParentChildRelationships();
|
void testGeneralParentChildRelationships();
|
||||||
void testNameRoleGroups();
|
void testNameRoleGroups();
|
||||||
|
void testNameRoleGroupsWithExpandedItems();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList itemsInModel() const;
|
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()
|
void KFileItemModelTest::testSorting()
|
||||||
{
|
{
|
||||||
// Create some files with different sizes and modification times to check the different sorting options
|
// 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);
|
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 KFileItemModelTest::itemsInModel() const
|
||||||
{
|
{
|
||||||
QStringList items;
|
QStringList items;
|
||||||
for (int i = 0; i < m_model->count(); i++) {
|
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;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
|
|
||||||
UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin,
|
UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin,
|
||||||
const QList<VersionControlObserver::ItemState>& itemStates) :
|
const QMap<QString, QVector<VersionControlObserver::ItemState> >& itemStates) :
|
||||||
QThread(),
|
QThread(),
|
||||||
m_globalPluginMutex(0),
|
m_globalPluginMutex(0),
|
||||||
m_plugin(plugin),
|
m_plugin(plugin),
|
||||||
|
@ -47,27 +47,29 @@ void UpdateItemStatesThread::run()
|
||||||
Q_ASSERT(!m_itemStates.isEmpty());
|
Q_ASSERT(!m_itemStates.isEmpty());
|
||||||
Q_ASSERT(m_plugin);
|
Q_ASSERT(m_plugin);
|
||||||
|
|
||||||
const QString directory = m_itemStates.first().item.url().directory(KUrl::AppendTrailingSlash);
|
|
||||||
m_retrievedItems = false;
|
m_retrievedItems = false;
|
||||||
|
|
||||||
QMutexLocker pluginLocker(m_globalPluginMutex);
|
QMutexLocker pluginLocker(m_globalPluginMutex);
|
||||||
if (m_plugin->beginRetrieval(directory)) {
|
foreach (const QString& directory, m_itemStates.keys()) {
|
||||||
const int count = m_itemStates.count();
|
if (m_plugin->beginRetrieval(directory)) {
|
||||||
|
QVector<VersionControlObserver::ItemState>& items = m_itemStates[directory];
|
||||||
|
const int count = items.count();
|
||||||
|
|
||||||
KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
|
KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
|
||||||
if (pluginV2) {
|
if (pluginV2) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
m_itemStates[i].version = pluginV2->itemVersion(m_itemStates[i].item);
|
items[i].version = pluginV2->itemVersion(items[i].item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
const KVersionControlPlugin::VersionState state = m_plugin->versionState(m_itemStates[i].item);
|
const KVersionControlPlugin::VersionState state = m_plugin->versionState(items[i].item);
|
||||||
m_itemStates[i].version = static_cast<KVersionControlPlugin2::ItemVersion>(state);
|
items[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();
|
m_globalPluginMutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<VersionControlObserver::ItemState> UpdateItemStatesThread::itemStates() const
|
QMap<QString, QVector<VersionControlObserver::ItemState> > UpdateItemStatesThread::itemStates() const
|
||||||
{
|
{
|
||||||
return m_itemStates;
|
return m_itemStates;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
* @param itemStates List of items, where the states get updated.
|
* @param itemStates List of items, where the states get updated.
|
||||||
*/
|
*/
|
||||||
UpdateItemStatesThread(KVersionControlPlugin* plugin,
|
UpdateItemStatesThread(KVersionControlPlugin* plugin,
|
||||||
const QList<VersionControlObserver::ItemState>& itemStates);
|
const QMap<QString, QVector<VersionControlObserver::ItemState> >& itemStates);
|
||||||
virtual ~UpdateItemStatesThread();
|
virtual ~UpdateItemStatesThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void unlockPlugin();
|
void unlockPlugin();
|
||||||
|
|
||||||
QList<VersionControlObserver::ItemState> itemStates() const;
|
QMap<QString, QVector<VersionControlObserver::ItemState> > itemStates() const;
|
||||||
|
|
||||||
bool retrievedItems() const;
|
bool retrievedItems() const;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ private:
|
||||||
KVersionControlPlugin* m_plugin;
|
KVersionControlPlugin* m_plugin;
|
||||||
|
|
||||||
bool m_retrievedItems;
|
bool m_retrievedItems;
|
||||||
QList<VersionControlObserver::ItemState> m_itemStates;
|
QMap<QString, QVector<VersionControlObserver::ItemState> > m_itemStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UPDATEITEMSTATESTHREAD_H
|
#endif // UPDATEITEMSTATESTHREAD_H
|
||||||
|
|
|
@ -204,11 +204,15 @@ void VersionControlObserver::slotThreadFinished()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<ItemState> itemStates = thread->itemStates();
|
const QMap<QString, QVector<ItemState> >& itemStates = thread->itemStates();
|
||||||
foreach (const ItemState& itemState, itemStates) {
|
foreach (const QString& directory, itemStates.keys()) {
|
||||||
QHash<QByteArray, QVariant> values;
|
const QVector<ItemState>& items = itemStates.value(directory);
|
||||||
values.insert("version", QVariant(itemState.version));
|
|
||||||
m_model->setData(itemState.index, values);
|
foreach (const ItemState& item, items) {
|
||||||
|
QHash<QByteArray, QVariant> values;
|
||||||
|
values.insert("version", QVariant(item.version));
|
||||||
|
m_model->setData(item.index, values);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_silentUpdate) {
|
if (!m_silentUpdate) {
|
||||||
|
@ -233,18 +237,9 @@ void VersionControlObserver::updateItemStates()
|
||||||
m_pendingItemStatesUpdate = true;
|
m_pendingItemStatesUpdate = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QList<ItemState> itemStates;
|
|
||||||
const int itemCount = m_model->count();
|
|
||||||
itemStates.reserve(itemCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < itemCount; ++i) {
|
QMap<QString, QVector<ItemState> > itemStates;
|
||||||
ItemState itemState;
|
createItemStatesList(itemStates);
|
||||||
itemState.index = i;
|
|
||||||
itemState.item = m_model->fileItem(i);
|
|
||||||
itemState.version = KVersionControlPlugin2::UnversionedVersion;
|
|
||||||
|
|
||||||
itemStates.append(itemState);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itemStates.isEmpty()) {
|
if (!itemStates.isEmpty()) {
|
||||||
if (!m_silentUpdate) {
|
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
|
KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& directory) const
|
||||||
{
|
{
|
||||||
static bool pluginsAvailable = true;
|
static bool pluginsAvailable = true;
|
||||||
|
|
|
@ -109,6 +109,22 @@ private:
|
||||||
|
|
||||||
void updateItemStates();
|
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.
|
* Returns a matching plugin for the given directory.
|
||||||
* 0 is returned, if no matching plugin has been found.
|
* 0 is returned, if no matching plugin has been found.
|
||||||
|
|
Loading…
Reference in a new issue