]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Update the roles for filtered items if necessary
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index ea7ac2fc1bdf166a922de70f70c18b718d344c1d..739384bf9f0431c8e6b6cd3f1f900247811746c8 100644 (file)
@@ -237,7 +237,7 @@ bool KFileItemModel::showDirectoriesOnly() const
     return m_dirLister->dirOnlyMode();
 }
 
-QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
+QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
 {
     QMimeData* data = new QMimeData();
 
@@ -248,9 +248,7 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
     KUrl::List mostLocalUrls;
     bool canUseMostLocalUrls = true;
 
-    QSetIterator<int> it(indexes);
-    while (it.hasNext()) {
-        const int index = it.next();
+    foreach (int index, indexes) {
         const KFileItem item = fileItem(index);
         if (!item.isNull()) {
             urls << item.targetUrl();
@@ -415,6 +413,15 @@ void KFileItemModel::setRoles(const QSet<QByteArray>& roles)
         kWarning() << "TODO: Emitting itemsChanged() with no information what has changed!";
         emit itemsChanged(KItemRangeList() << KItemRange(0, count()), QSet<QByteArray>());
     }
+
+    // Clear the 'values' of all filtered items. They will be re-populated with the
+    // correct roles the next time 'values' will be accessed via data(int).
+    QHash<KFileItem, ItemData*>::iterator filteredIt = m_filteredItems.begin();
+    const QHash<KFileItem, ItemData*>::iterator filteredEnd = m_filteredItems.end();
+    while (filteredIt != filteredEnd) {
+        (*filteredIt)->values.clear();
+        ++filteredIt;
+    }
 }
 
 QSet<QByteArray> KFileItemModel::roles() const
@@ -440,6 +447,11 @@ bool KFileItemModel::setExpanded(int index, bool expanded)
     if (expanded) {
         m_expandedDirs.insert(targetUrl, url);
         m_dirLister->openUrl(url, KDirLister::Keep);
+
+        const KUrl::List previouslyExpandedChildren = m_itemData.at(index)->values.value("previouslyExpandedChildren").value<KUrl::List>();
+        foreach (const KUrl& url, previouslyExpandedChildren) {
+            m_urlsToExpand.insert(url);
+        }
     } else {
         m_expandedDirs.remove(targetUrl);
         m_dirLister->stop(url);
@@ -448,14 +460,24 @@ bool KFileItemModel::setExpanded(int index, bool expanded)
         const int itemCount = m_itemData.count();
         const int firstChildIndex = index + 1;
 
+        KUrl::List expandedChildren;
+
         int childIndex = firstChildIndex;
         while (childIndex < itemCount && expandedParentsCount(childIndex) > parentLevel) {
+            ItemData* itemData = m_itemData.at(childIndex);
+            if (itemData->values.value("isExpanded").toBool()) {
+                const KUrl targetUrl = itemData->item.targetUrl();
+                m_expandedDirs.remove(targetUrl);
+                expandedChildren.append(targetUrl);
+            }
             ++childIndex;
         }
         const int childrenCount = childIndex - firstChildIndex;
 
         removeFilteredChildren(KItemRangeList() << KItemRange(index, 1 + childrenCount));
         removeItems(KItemRangeList() << KItemRange(firstChildIndex, childrenCount), DeleteItemData);
+
+        m_itemData.at(index)->values.insert("previouslyExpandedChildren", expandedChildren);
     }
 
     return true;
@@ -1020,6 +1042,15 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
 #endif
 
     m_groups.clear();
+    prepareItemsForSorting(newItems);
+
+    if (m_sortRole == NameRole && m_naturalSorting) {
+        // Natural sorting of items can be very slow. However, it becomes much
+        // faster if the input sequence is already mostly sorted. Therefore, we
+        // first sort 'newItems' according to the QStrings returned by
+        // KFileItem::text() using QString::operator<(), which is quite fast.
+        parallelMergeSort(newItems.begin(), newItems.end(), nameLessThan, QThread::idealThreadCount());
+    }
 
     sort(newItems.begin(), newItems.end());
 
@@ -1175,6 +1206,11 @@ QList<KFileItemModel::ItemData*> KFileItemModel::createItemDataList(const KUrl&
         itemDataList.append(itemData);
     }
 
+    return itemDataList;
+}
+
+void KFileItemModel::prepareItemsForSorting(QList<ItemData*>& itemDataList)
+{
     switch (m_sortRole) {
     case PermissionsRole:
     case OwnerRole:
@@ -1184,16 +1220,20 @@ QList<KFileItemModel::ItemData*> KFileItemModel::createItemDataList(const KUrl&
         // These roles can be determined with retrieveData, and they have to be stored
         // in the QHash "values" for the sorting.
         foreach (ItemData* itemData, itemDataList) {
-            itemData->values = retrieveData(itemData->item, parentItem);
+            if (itemData->values.isEmpty()) {
+                itemData->values = retrieveData(itemData->item, itemData->parent);
+            }
         }
         break;
 
     case TypeRole:
         // At least store the data including the file type for items with known MIME type.
         foreach (ItemData* itemData, itemDataList) {
-            const KFileItem item = itemData->item;
-            if (item.isDir() || item.isMimeTypeKnown()) {
-                itemData->values = retrieveData(itemData->item, parentItem);
+            if (itemData->values.isEmpty()) {
+                const KFileItem item = itemData->item;
+                if (item.isDir() || item.isMimeTypeKnown()) {
+                    itemData->values = retrieveData(itemData->item, itemData->parent);
+                }
             }
         }
         break;
@@ -1202,12 +1242,10 @@ QList<KFileItemModel::ItemData*> KFileItemModel::createItemDataList(const KUrl&
         // The other roles are either resolved by KFileItemModelRolesUpdater
         // (this includes the SizeRole for directories), or they do not need
         // to be stored in the QHash "values" for sorting because the data can
-        // be retrieved directly from the KFileItem (NameRole, SiezRole for files,
+        // be retrieved directly from the KFileItem (NameRole, SizeRole for files,
         // DateRole).
         break;
     }
-
-    return itemDataList;
 }
 
 int KFileItemModel::expandedParentsCount(const ItemData* data)