]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Port away from deprecated QFontMetrics::width()
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index 60983aa7bc3b6276ddabb553bf54b38dfdcb96e1..ac3c33e22e44af1a0680c1684c50dfd0139c084b 100644 (file)
@@ -22,6 +22,7 @@
 #include "kfileitemmodel.h"
 
 #include "dolphin_generalsettings.h"
+#include "dolphin_detailsmodesettings.h"
 #include "dolphindebug.h"
 #include "private/kfileitemmodeldirlister.h"
 #include "private/kfileitemmodelsortalgorithm.h"
@@ -33,6 +34,9 @@
 #include <QMimeData>
 #include <QTimer>
 #include <QWidget>
+#include <QMutex>
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, s_collatorMutex, (QMutex::Recursive))
 
 // #define KFILEITEMMODEL_DEBUG
 
@@ -267,7 +271,7 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
             urls << item.url();
 
             bool isLocal;
-            mostLocalUrls << item.mostLocalUrl(isLocal);
+            mostLocalUrls << item.mostLocalUrl(&isLocal);
         }
     }
 
@@ -1187,12 +1191,20 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
     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());
+    // 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 using QString::operator<(), which is quite fast.
+    if (m_naturalSorting) {
+        if (m_sortRole == NameRole) {
+            parallelMergeSort(newItems.begin(), newItems.end(), nameLessThan, QThread::idealThreadCount());
+        } else if (isRoleValueNatural(m_sortRole)) {
+            auto lambdaLessThan = [&] (const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b)
+            {
+                const QByteArray role = roleForType(m_sortRole);
+                return a->values.value(role).toString() < b->values.value(role).toString();
+            };
+            parallelMergeSort(newItems.begin(), newItems.end(), lambdaLessThan, QThread::idealThreadCount());
+        }
     }
 
     sort(newItems.begin(), newItems.end());
@@ -1726,8 +1738,8 @@ void KFileItemModel::sort(const QList<KFileItemModel::ItemData*>::iterator &begi
         return lessThan(a, b, m_collator);
     };
 
-    if (m_sortRole == NameRole) {
-        // Sorting by name can be expensive, in particular if natural sorting is
+    if (m_sortRole == NameRole || isRoleValueNatural(m_sortRole)) {
+        // Sorting by string can be expensive, in particular if natural sorting is
         // enabled. Use all CPU cores to speed up the sorting process.
         static const int numberOfThreads = QThread::idealThreadCount();
         parallelMergeSort(begin, end, lambdaLessThan, numberOfThreads);
@@ -1756,8 +1768,15 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
             // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
             Q_ASSERT(itemB.isDir());
 
-            const QVariant valueA = a->values.value("size");
-            const QVariant valueB = b->values.value("size");
+            QVariant valueA, valueB;
+            if (DetailsModeSettings::directorySizeCount()) {
+                valueA = a->values.value("count");
+                valueB = b->values.value("count");
+            } else {
+                // use dir size then
+                valueA = a->values.value("size");
+                valueB = b->values.value("size");
+            }
             if (valueA.isNull() && valueB.isNull()) {
                 result = 0;
             } else if (valueA.isNull()) {
@@ -1765,7 +1784,11 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
             } else if (valueB.isNull()) {
                 result = +1;
             } else {
-                result = valueA.toInt() - valueB.toInt();
+                if (valueA < valueB) {
+                    return -1;
+                } else {
+                    return +1;
+                }
             }
         } else {
             // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
@@ -1835,6 +1858,8 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
             result = -1;
         } else if (roleValueA.isEmpty() && !roleValueB.isEmpty()) {
             result = +1;
+        } else if (isRoleValueNatural(m_sortRole)) {
+            result = stringCompare(roleValueA, roleValueB, collator);
         } else {
             result = QString::compare(roleValueA, roleValueB);
         }
@@ -1868,6 +1893,8 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
 
 int KFileItemModel::stringCompare(const QString& a, const QString& b, const QCollator& collator) const
 {
+    QMutexLocker collatorLock(s_collatorMutex());
+
     if (m_naturalSorting) {
         return collator.compare(a, b);
     }