┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Vogiatzis <[email protected]>2020-01-28 08:50:06 -0700
committerNate Graham <[email protected]>2020-01-28 08:52:58 -0700
commit9e3418bd558293a92b2e8bcba55f5a3f5d3cc5a4 (patch)
treeecfa3ffd734901b396fe4d723116561484aeca65
parentc2fa8ae9ab0df08781b7d032e99d7b8f220c10e0 (diff)
Add natural sorting and case-insensitive sorting for all role-types
Summary: Add natural sorting and case-insensitive sorting, for all role-types that benefit from. BUG: 406296 FIXED-IN: 19.12.2 Test Plan: Sort by any role type specified in `isRoleValueNatural()` Before: Sorting is always case sensitive After: Sorting according to 'Sorting mode' in configuration. Reviewers: #dolphin, nicolasfella, meven, elvisangelaccio, ngraham Reviewed By: #dolphin, meven, elvisangelaccio, ngraham Subscribers: cfeck, meven, kfm-devel Tags: #dolphin Differential Revision: https://phabricator.kde.org/D25741
-rw-r--r--src/kitemviews/kfileitemmodel.cpp26
-rw-r--r--src/kitemviews/kfileitemmodel.h22
2 files changed, 39 insertions, 9 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp
index ad996a59e..4b35a0248 100644
--- a/src/kitemviews/kfileitemmodel.cpp
+++ b/src/kitemviews/kfileitemmodel.cpp
@@ -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());
@@ -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);
}
diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h
index c2dfd0167..132a76e46 100644
--- a/src/kitemviews/kfileitemmodel.h
+++ b/src/kitemviews/kfileitemmodel.h
@@ -356,6 +356,11 @@ private:
QHash<QByteArray, QVariant> retrieveData(const KFileItem& item, const ItemData* parent) const;
/**
+ * @return True if role values benefit from natural or case insensitive sorting.
+ */
+ static bool isRoleValueNatural(const RoleType roleType);
+
+ /**
* @return True if \a a has a KFileItem whose text is 'less than' the one
* of \a b according to QString::operator<(const QString&).
*/
@@ -504,12 +509,27 @@ private:
friend class DolphinPart; // Accesses m_dirLister
};
+inline bool KFileItemModel::isRoleValueNatural(RoleType roleType)
+{
+ return (roleType == TypeRole ||
+ roleType == TagsRole ||
+ roleType == CommentRole ||
+ roleType == TitleRole ||
+ roleType == ArtistRole ||
+ roleType == GenreRole ||
+ roleType == AlbumRole ||
+ roleType == PathRole ||
+ roleType == DestinationRole ||
+ roleType == OriginUrlRole ||
+ roleType == OwnerRole ||
+ roleType == GroupRole);
+}
+
inline bool KFileItemModel::nameLessThan(const ItemData* a, const ItemData* b)
{
return a->item.text() < b->item.text();
}
-
inline bool KFileItemModel::isChildItem(int index) const
{
if (m_itemData.at(index)->parent) {