]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Add natural sorting and case-insensitive sorting for all role-types
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index 091044c06c4e00480db701157891d3dbd49a525f..4b35a0248a5e07f976451fc2b5f80792bc64d5d5 100644 (file)
@@ -267,7 +267,7 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
             urls << item.url();
 
             bool isLocal;
-            mostLocalUrls << item.mostLocalUrl(isLocal);
+            mostLocalUrls << item.mostLocalUrl(&isLocal);
         }
     }
 
@@ -785,13 +785,13 @@ QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation()
 
 void KFileItemModel::onGroupedSortingChanged(bool current)
 {
-    Q_UNUSED(current);
+    Q_UNUSED(current)
     m_groups.clear();
 }
 
 void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems)
 {
-    Q_UNUSED(previous);
+    Q_UNUSED(previous)
     m_sortRole = typeForRole(current);
 
     if (!m_requestRole[m_sortRole]) {
@@ -807,8 +807,8 @@ void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArr
 
 void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
+    Q_UNUSED(current)
+    Q_UNUSED(previous)
     resortAllItems();
 }
 
@@ -1187,12 +1187,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());
@@ -1607,7 +1615,7 @@ QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item,
     if (m_requestRole[DestinationRole]) {
         QString destination = item.linkDest();
         if (destination.isEmpty()) {
-            destination = QStringLiteral("-");
+            destination = QLatin1Char('-');
         }
         data.insert(sharedValue("destination"), destination);
     }
@@ -1726,8 +1734,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);
@@ -1835,6 +1843,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);
         }
@@ -2309,38 +2319,38 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
     static const RoleInfoMap rolesInfoMap[] = {
     //  |         role           |        roleType        |                role translation                     |            group translation               | requires Baloo | requires indexer
         { nullptr,               NoRole,                  nullptr, nullptr,                                     nullptr, nullptr,                            false,           false },
-        { "text",                NameRole,                I18N_NOOP2_NOSTRIP("@label", "Name"),                 nullptr, nullptr,                            false,           false },
-        { "size",                SizeRole,                I18N_NOOP2_NOSTRIP("@label", "Size"),                 nullptr, nullptr,                            false,           false },
-        { "modificationtime",    ModificationTimeRole,    I18N_NOOP2_NOSTRIP("@label", "Modified"),             nullptr, nullptr,                            false,           false },
-        { "creationtime",        CreationTimeRole,        I18N_NOOP2_NOSTRIP("@label", "Created"),              nullptr, nullptr,                            false,           false },
-        { "accesstime",          AccessTimeRole,          I18N_NOOP2_NOSTRIP("@label", "Accessed"),             nullptr, nullptr,                            false,           false },
-        { "type",                TypeRole,                I18N_NOOP2_NOSTRIP("@label", "Type"),                 nullptr, nullptr,                            false,           false },
-        { "rating",              RatingRole,              I18N_NOOP2_NOSTRIP("@label", "Rating"),               nullptr, nullptr,                            true,            false },
-        { "tags",                TagsRole,                I18N_NOOP2_NOSTRIP("@label", "Tags"),                 nullptr, nullptr,                            true,            false },
-        { "comment",             CommentRole,             I18N_NOOP2_NOSTRIP("@label", "Comment"),              nullptr, nullptr,                            true,            false },
-        { "title",               TitleRole,               I18N_NOOP2_NOSTRIP("@label", "Title"),                I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "wordCount",           WordCountRole,           I18N_NOOP2_NOSTRIP("@label", "Word Count"),           I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "lineCount",           LineCountRole,           I18N_NOOP2_NOSTRIP("@label", "Line Count"),           I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "imageDateTime",       ImageDateTimeRole,       I18N_NOOP2_NOSTRIP("@label", "Date Photographed"),    I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "width",               WidthRole,               I18N_NOOP2_NOSTRIP("@label", "Width"),                I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "height",              HeightRole,              I18N_NOOP2_NOSTRIP("@label", "Height"),               I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "orientation",         OrientationRole,         I18N_NOOP2_NOSTRIP("@label", "Orientation"),          I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "artist",              ArtistRole,              I18N_NOOP2_NOSTRIP("@label", "Artist"),               I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "genre",               GenreRole,               I18N_NOOP2_NOSTRIP("@label", "Genre"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "album",               AlbumRole,               I18N_NOOP2_NOSTRIP("@label", "Album"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "duration",            DurationRole,            I18N_NOOP2_NOSTRIP("@label", "Duration"),             I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "bitrate",             BitrateRole,             I18N_NOOP2_NOSTRIP("@label", "Bitrate"),              I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "track",               TrackRole,               I18N_NOOP2_NOSTRIP("@label", "Track"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "releaseYear",         ReleaseYearRole,         I18N_NOOP2_NOSTRIP("@label", "Release Year"),         I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "aspectRatio",         AspectRatioRole,         I18N_NOOP2_NOSTRIP("@label", "Aspect Ratio"),         I18N_NOOP2_NOSTRIP("@label", "Video"),       true,            true  },
-        { "frameRate",           FrameRateRole,           I18N_NOOP2_NOSTRIP("@label", "Frame Rate"),           I18N_NOOP2_NOSTRIP("@label", "Video"),       true,            true  },
-        { "path",                PathRole,                I18N_NOOP2_NOSTRIP("@label", "Path"),                 I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "deletiontime",        DeletionTimeRole,        I18N_NOOP2_NOSTRIP("@label", "Deletion Time"),        I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "destination",         DestinationRole,         I18N_NOOP2_NOSTRIP("@label", "Link Destination"),     I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "originUrl",           OriginUrlRole,           I18N_NOOP2_NOSTRIP("@label", "Downloaded From"),      I18N_NOOP2_NOSTRIP("@label", "Other"),       true,            false },
-        { "permissions",         PermissionsRole,         I18N_NOOP2_NOSTRIP("@label", "Permissions"),          I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "owner",               OwnerRole,               I18N_NOOP2_NOSTRIP("@label", "Owner"),                I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "group",               GroupRole,               I18N_NOOP2_NOSTRIP("@label", "User Group"),           I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
+        { "text",                NameRole,                I18NC_NOOP("@label", "Name"),                 nullptr, nullptr,                            false,           false },
+        { "size",                SizeRole,                I18NC_NOOP("@label", "Size"),                 nullptr, nullptr,                            false,           false },
+        { "modificationtime",    ModificationTimeRole,    I18NC_NOOP("@label", "Modified"),             nullptr, nullptr,                            false,           false },
+        { "creationtime",        CreationTimeRole,        I18NC_NOOP("@label", "Created"),              nullptr, nullptr,                            false,           false },
+        { "accesstime",          AccessTimeRole,          I18NC_NOOP("@label", "Accessed"),             nullptr, nullptr,                            false,           false },
+        { "type",                TypeRole,                I18NC_NOOP("@label", "Type"),                 nullptr, nullptr,                            false,           false },
+        { "rating",              RatingRole,              I18NC_NOOP("@label", "Rating"),               nullptr, nullptr,                            true,            false },
+        { "tags",                TagsRole,                I18NC_NOOP("@label", "Tags"),                 nullptr, nullptr,                            true,            false },
+        { "comment",             CommentRole,             I18NC_NOOP("@label", "Comment"),              nullptr, nullptr,                            true,            false },
+        { "title",               TitleRole,               I18NC_NOOP("@label", "Title"),                I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "wordCount",           WordCountRole,           I18NC_NOOP("@label", "Word Count"),           I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "lineCount",           LineCountRole,           I18NC_NOOP("@label", "Line Count"),           I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "imageDateTime",       ImageDateTimeRole,       I18NC_NOOP("@label", "Date Photographed"),    I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "width",               WidthRole,               I18NC_NOOP("@label", "Width"),                I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "height",              HeightRole,              I18NC_NOOP("@label", "Height"),               I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "orientation",         OrientationRole,         I18NC_NOOP("@label", "Orientation"),          I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "artist",              ArtistRole,              I18NC_NOOP("@label", "Artist"),               I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "genre",               GenreRole,               I18NC_NOOP("@label", "Genre"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "album",               AlbumRole,               I18NC_NOOP("@label", "Album"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "duration",            DurationRole,            I18NC_NOOP("@label", "Duration"),             I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "bitrate",             BitrateRole,             I18NC_NOOP("@label", "Bitrate"),              I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "track",               TrackRole,               I18NC_NOOP("@label", "Track"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "releaseYear",         ReleaseYearRole,         I18NC_NOOP("@label", "Release Year"),         I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "aspectRatio",         AspectRatioRole,         I18NC_NOOP("@label", "Aspect Ratio"),         I18NC_NOOP("@label", "Video"),       true,            true  },
+        { "frameRate",           FrameRateRole,           I18NC_NOOP("@label", "Frame Rate"),           I18NC_NOOP("@label", "Video"),       true,            true  },
+        { "path",                PathRole,                I18NC_NOOP("@label", "Path"),                 I18NC_NOOP("@label", "Other"),       false,           false },
+        { "deletiontime",        DeletionTimeRole,        I18NC_NOOP("@label", "Deletion Time"),        I18NC_NOOP("@label", "Other"),       false,           false },
+        { "destination",         DestinationRole,         I18NC_NOOP("@label", "Link Destination"),     I18NC_NOOP("@label", "Other"),       false,           false },
+        { "originUrl",           OriginUrlRole,           I18NC_NOOP("@label", "Downloaded From"),      I18NC_NOOP("@label", "Other"),       true,            false },
+        { "permissions",         PermissionsRole,         I18NC_NOOP("@label", "Permissions"),          I18NC_NOOP("@label", "Other"),       false,           false },
+        { "owner",               OwnerRole,               I18NC_NOOP("@label", "Owner"),                I18NC_NOOP("@label", "Other"),       false,           false },
+        { "group",               GroupRole,               I18NC_NOOP("@label", "User Group"),           I18NC_NOOP("@label", "Other"),       false,           false },
     };
 
     count = sizeof(rolesInfoMap) / sizeof(RoleInfoMap);