X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/91273c8b03dbf184d7a9043d4f5ffe5b45c87b71..9aaf3054106311d8ef49174e32f0ad03dcbe3fca:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index a2e7c0075..9464c7e09 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -975,14 +975,10 @@ void KFileItemModel::onSortRoleChanged(const QByteArray ¤t, const QByteArr } } -void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous, bool resortItems) +void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) { Q_UNUSED(current) Q_UNUSED(previous) - - if (resortItems) { - resortAllItems(); - } } void KFileItemModel::onGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems) @@ -1008,14 +1004,10 @@ void KFileItemModel::onGroupRoleChanged(const QByteArray ¤t, const QByteAr } } -void KFileItemModel::onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous, bool resortItems) +void KFileItemModel::onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) { Q_UNUSED(current) Q_UNUSED(previous) - - if (resortItems) { - resortAllItems(); - } } void KFileItemModel::loadSortingSettings() @@ -1040,6 +1032,7 @@ void KFileItemModel::loadSortingSettings() // Workaround for bug https://bugreports.qt.io/browse/QTBUG-69361 // Force the clean state of QCollator in single thread to avoid thread safety problems in sort m_collator.compare(QString(), QString()); + m_dirSizeMode = ContentDisplaySettings::directorySizeMode(); } void KFileItemModel::resortAllItems() @@ -1105,7 +1098,8 @@ void KFileItemModel::resortAllItems() } Q_EMIT itemsMoved(KItemRange(firstMovedIndex, movedItemsCount), movedToIndexes); - } else if (groupedSorting()) { + } + if (groupedSorting()) { // The groups might have changed even if the order of the items has not. const QList> oldGroups = m_groups; m_groups.clear(); @@ -1690,7 +1684,7 @@ void KFileItemModel::removeItems(const KItemRangeList &itemRanges, RemoveItemsBe QList KFileItemModel::createItemDataList(const QUrl &parentUrl, const KFileItemList &items) const { - if (m_sortRole == TypeRole) { + if (m_sortRole == TypeRole || m_groupRole == TypeRole) { // Try to resolve the MIME-types synchronously to prevent a reordering of // the items when sorting by type (per default MIME-types are resolved // asynchronously by KFileItemModelRolesUpdater). @@ -1714,9 +1708,9 @@ QList KFileItemModel::createItemDataList(const QUrl return itemDataList; } -void KFileItemModel::prepareItemsForSorting(QList &itemDataList) +void KFileItemModel::prepareItemsWithRole(QList &itemDataList, RoleType roleType) { - switch (m_sortRole) { + switch (roleType) { case ExtensionRole: case PermissionsRole: case OwnerRole: @@ -1755,6 +1749,12 @@ void KFileItemModel::prepareItemsForSorting(QList &itemDataList) } } +void KFileItemModel::prepareItemsForSorting(QList &itemDataList) +{ + prepareItemsWithRole(itemDataList, m_sortRole); + prepareItemsWithRole(itemDataList, m_groupRole); +} + int KFileItemModel::expandedParentsCount(const ItemData *data) { // The hash 'values' is only guaranteed to contain the key "expandedParentsCount" @@ -2100,8 +2100,7 @@ bool KFileItemModel::lessThan(const ItemData *a, const ItemData *b, const QColla return true; } } - if (m_sortDirsFirst - || (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount && m_sortRole == SizeRole)) { + if (m_sortDirsFirst || (m_dirSizeMode == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount && m_sortRole == SizeRole)) { const bool isDirA = a->item.isDir(); const bool isDirB = b->item.isDir(); if (isDirA && !isDirB) { @@ -2155,7 +2154,7 @@ int KFileItemModel::sortRoleCompare(const ItemData *a, const ItemData *b, const break; case SizeRole: { - if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount && itemA.isDir()) { + if (m_dirSizeMode == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount && itemA.isDir()) { // folders first then // items A and B are folders thanks to lessThan checks auto valueA = a->values.value("count"); @@ -2311,104 +2310,99 @@ int KFileItemModel::groupRoleCompare(const ItemData *a, const ItemData *b, const // Unlike sortRoleCompare, this function can and often will return 0. int result = 0; - int groupA, groupB; + ItemGroupInfo groupA, groupB; switch (m_groupRole) { case NoRole: // Non-trivial grouping behavior might be handled there in the future. return 0; case NameRole: - groupA = nameRoleGroup(a, false).comparable; - groupB = nameRoleGroup(b, false).comparable; + groupA = nameRoleGroup(a, false); + groupB = nameRoleGroup(b, false); break; case SizeRole: - groupA = sizeRoleGroup(a, false).comparable; - groupB = sizeRoleGroup(b, false).comparable; + groupA = sizeRoleGroup(a, false); + groupB = sizeRoleGroup(b, false); break; case ModificationTimeRole: groupA = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::ModificationTime); - }, - a, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::ModificationTime); + }, + a, + false); groupB = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::ModificationTime); - }, - b, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::ModificationTime); + }, + b, + false); break; case CreationTimeRole: groupA = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::CreationTime); - }, - a, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::CreationTime); + }, + a, + false); groupB = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::CreationTime); - }, - b, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::CreationTime); + }, + b, + false); break; case AccessTimeRole: groupA = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::AccessTime); - }, - a, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::AccessTime); + }, + a, + false); groupB = timeRoleGroup( - [](const ItemData *item) { - return item->item.time(KFileItem::AccessTime); - }, - b, - false) - .comparable; + [](const ItemData *item) { + return item->item.time(KFileItem::AccessTime); + }, + b, + false); break; case DeletionTimeRole: groupA = timeRoleGroup( - [](const ItemData *item) { - return item->values.value("deletiontime").toDateTime(); - }, - a, - false) - .comparable; + [](const ItemData *item) { + return item->values.value("deletiontime").toDateTime(); + }, + a, + false); groupB = timeRoleGroup( - [](const ItemData *item) { - return item->values.value("deletiontime").toDateTime(); - }, - b, - false) - .comparable; + [](const ItemData *item) { + return item->values.value("deletiontime").toDateTime(); + }, + b, + false); break; case PermissionsRole: - groupA = permissionRoleGroup(a, false).comparable; - groupB = permissionRoleGroup(b, false).comparable; + groupA = permissionRoleGroup(a, false); + groupB = permissionRoleGroup(b, false); break; case RatingRole: - groupA = ratingRoleGroup(a, false).comparable; - groupB = ratingRoleGroup(b, false).comparable; + groupA = ratingRoleGroup(a, false); + groupB = ratingRoleGroup(b, false); + break; + case TypeRole: + groupA = typeRoleGroup(a); + groupB = typeRoleGroup(b); break; default: { - QString strGroupA = genericStringRoleGroup(groupRole(), a); - QString strGroupB = genericStringRoleGroup(groupRole(), b); - result = stringCompare(strGroupA, strGroupB, collator); + groupA = genericStringRoleGroup(groupRole(), a); + groupB = genericStringRoleGroup(groupRole(), b); break; } } - if (result == 0) { - if (groupA < groupB) { - result = -1; - } else if (groupA > groupB) { - result = 1; - } + if (groupA.comparable < groupB.comparable) { + result = -1; + } else if (groupA.comparable > groupB.comparable) { + result = 1; + } else { + result = stringCompare(groupA.text, groupB.text, collator); } return result; } @@ -2441,6 +2435,8 @@ KFileItemModel::ItemGroupInfo KFileItemModel::nameRoleGroup(const ItemData *item const QString name = itemData->item.text(); + QMutexLocker collatorLock(s_collatorMutex()); + // Use the first character of the name as group indication firstChar = name.at(0).toUpper(); @@ -2516,7 +2512,7 @@ KFileItemModel::ItemGroupInfo KFileItemModel::sizeRoleGroup(const ItemData *item groupInfo.comparable = -1; // None if (!item.isNull() && item.isDir()) { - if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount || m_sortDirsFirst) { + if (m_dirSizeMode != ContentDisplaySettings::EnumDirectorySizeMode::ContentSize) { groupInfo.comparable = 0; // Folders } else { fileSize = itemData->values.value("size").toULongLong(); @@ -2835,9 +2831,9 @@ KFileItemModel::ItemGroupInfo KFileItemModel::ratingRoleGroup(const ItemData *it return groupInfo; } -QString KFileItemModel::genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const +KFileItemModel::ItemGroupInfo KFileItemModel::genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const { - return itemData->values.value(role).toString(); + return {0, itemData->values.value(role).toString()}; } QList> KFileItemModel::nameRoleGroups() const @@ -2886,6 +2882,20 @@ QList> KFileItemModel::sizeRoleGroups() const return groups; } +KFileItemModel::ItemGroupInfo KFileItemModel::typeRoleGroup(const ItemData *itemData) const +{ + int priority = 0; + if (itemData->item.isDir() && m_sortDirsFirst) { + // Ensure folders stay first regardless of grouping order + if (groupOrder() == Qt::AscendingOrder) { + priority = -1; + } else { + priority = 1; + } + } + return {priority, itemData->values.value("type").toString()}; +} + QList> KFileItemModel::timeRoleGroups(const std::function &fileTimeCb) const { Q_ASSERT(!m_itemData.isEmpty()); @@ -2964,17 +2974,17 @@ QList> KFileItemModel::genericStringRoleGroups(const QByteA const int maxIndex = count() - 1; QList> groups; - QString groupText; + ItemGroupInfo groupInfo; for (int i = 0; i <= maxIndex; ++i) { if (isChildItem(i)) { continue; } - QString newGroupText = genericStringRoleGroup(role, m_itemData.at(i)); + ItemGroupInfo newGroupInfo = genericStringRoleGroup(role, m_itemData.at(i)); - if (newGroupText != groupText) { - groupText = newGroupText; - groups.append(QPair(i, newGroupText)); + if (newGroupInfo != groupInfo) { + groupInfo = newGroupInfo; + groups.append(QPair(i, newGroupInfo.text)); } } return groups;