X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/ecbab34510f6f925ec4b03e02d24b1ceff4d2744..4bca03532bcf7d1a1d66df7a8102e98b4cf3354a:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 8c736ccfe..b14647b42 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -22,23 +22,18 @@ #include "kfileitemmodel.h" #include "dolphin_generalsettings.h" +#include "dolphindebug.h" +#include "private/kfileitemmodeldirlister.h" +#include "private/kfileitemmodelsortalgorithm.h" #include #include -#include "dolphindebug.h" - -#include "private/kfileitemmodelsortalgorithm.h" -#include "private/kfileitemmodeldirlister.h" - #include #include #include #include -#include -#include - // #define KFILEITEMMODEL_DEBUG KFileItemModel::KFileItemModel(QObject* parent) : @@ -251,7 +246,6 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const // Copyright (C) 2006 David Faure QList urls; QList mostLocalUrls; - bool canUseMostLocalUrls = true; const ItemData* lastAddedItem = nullptr; for (int index : indexes) { @@ -274,9 +268,6 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const bool isLocal; mostLocalUrls << item.mostLocalUrl(isLocal); - if (!isLocal) { - canUseMostLocalUrls = false; - } } } @@ -313,6 +304,9 @@ QString KFileItemModel::roleDescription(const QByteArray& role) const int count = 0; const RoleInfoMap* map = rolesInfoMap(count); for (int i = 0; i < count; ++i) { + if (!map[i].roleTranslation) { + continue; + } description.insert(map[i].role, i18nc(map[i].roleTranslationContext, map[i].roleTranslation)); } } @@ -795,7 +789,7 @@ void KFileItemModel::onGroupedSortingChanged(bool current) m_groups.clear(); } -void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous) +void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems) { Q_UNUSED(previous); m_sortRole = typeForRole(current); @@ -806,7 +800,9 @@ void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArr setRoles(newRoles); } - resortAllItems(); + if (resortItems) { + resortAllItems(); + } } void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) @@ -835,6 +831,9 @@ void KFileItemModel::loadSortingSettings() default: Q_UNREACHABLE(); } + // 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()); } void KFileItemModel::resortAllItems() @@ -1125,7 +1124,7 @@ void KFileItemModel::slotRefreshItems(const QList >& } // Extract the item-ranges out of the changed indexes - qSort(indexes); + std::sort(indexes.begin(), indexes.end()); const KItemRangeList itemRangeList = KItemRangeList::fromSortedContainer(indexes); emitItemsChangedAndTriggerResorting(itemRangeList, changedRoles); } @@ -1214,7 +1213,7 @@ void KFileItemModel::insertItems(QList& newItems) } else { m_itemData.reserve(totalItemCount); for (int i = existingItemCount; i < totalItemCount; ++i) { - m_itemData.append(0); + m_itemData.append(nullptr); } // We build the new list m_itemData in reverse order to minimize @@ -1284,7 +1283,7 @@ void KFileItemModel::removeItems(const KItemRangeList& itemRanges, RemoveItemsBe delete m_itemData.at(index); } - m_itemData[index] = 0; + m_itemData[index] = nullptr; } } @@ -1325,7 +1324,7 @@ QList KFileItemModel::createItemDataList(const QUrl& } const int parentIndex = index(parentUrl); - ItemData* parentItem = parentIndex < 0 ? 0 : m_itemData.at(parentIndex); + ItemData* parentItem = parentIndex < 0 ? nullptr : m_itemData.at(parentIndex); QList itemDataList; itemDataList.reserve(items.count()); @@ -1556,8 +1555,8 @@ QHash KFileItemModel::retrieveData(const KFileItem& item, data.insert(sharedValue("isLink"), true); } - if (m_requestRole[IsHiddenRole] && item.isHidden()) { - data.insert(sharedValue("isHidden"), true); + if (m_requestRole[IsHiddenRole]) { + data.insert(sharedValue("isHidden"), item.isHidden()); } if (m_requestRole[NameRole]) { @@ -1569,26 +1568,26 @@ QHash KFileItemModel::retrieveData(const KFileItem& item, } if (m_requestRole[ModificationTimeRole]) { - // Don't use KFileItem::timeString() as this is too expensive when - // having several thousands of items. Instead the formatting of the - // date-time will be done on-demand by the view when the date will be shown. - const QDateTime dateTime = item.time(KFileItem::ModificationTime); + // Don't use KFileItem::timeString() or KFileItem::time() as this is too expensive when + // having several thousands of items. Instead read the raw number from UDSEntry directly + // and the formatting of the date-time will be done on-demand by the view when the date will be shown. + const long long dateTime = item.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1); data.insert(sharedValue("modificationtime"), dateTime); } if (m_requestRole[CreationTimeRole]) { - // Don't use KFileItem::timeString() as this is too expensive when - // having several thousands of items. Instead the formatting of the - // date-time will be done on-demand by the view when the date will be shown. - const QDateTime dateTime = item.time(KFileItem::CreationTime); + // Don't use KFileItem::timeString() or KFileItem::time() as this is too expensive when + // having several thousands of items. Instead read the raw number from UDSEntry directly + // and the formatting of the date-time will be done on-demand by the view when the date will be shown. + const long long dateTime = item.entry().numberValue(KIO::UDSEntry::UDS_CREATION_TIME, -1); data.insert(sharedValue("creationtime"), dateTime); } if (m_requestRole[AccessTimeRole]) { - // Don't use KFileItem::timeString() as this is too expensive when - // having several thousands of items. Instead the formatting of the - // date-time will be done on-demand by the view when the date will be shown. - const QDateTime dateTime = item.time(KFileItem::AccessTime); + // Don't use KFileItem::timeString() or KFileItem::time() as this is too expensive when + // having several thousands of items. Instead read the raw number from UDSEntry directly + // and the formatting of the date-time will be done on-demand by the view when the date will be shown. + const long long dateTime = item.entry().numberValue(KIO::UDSEntry::UDS_ACCESS_TIME, -1); data.insert(sharedValue("accesstime"), dateTime); } @@ -1718,63 +1717,24 @@ bool KFileItemModel::lessThan(const ItemData* a, const ItemData* b, const QColla return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0; } -/** - * Helper class for KFileItemModel::sort(). - */ -class KFileItemModelLessThan +void KFileItemModel::sort(const QList::iterator &begin, + const QList::iterator &end) const { -public: - KFileItemModelLessThan(const KFileItemModel* model, const QCollator& collator) : - m_model(model), - m_collator(collator) + auto lambdaLessThan = [&] (const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b) { - } - - KFileItemModelLessThan(const KFileItemModelLessThan& other) : - m_model(other.m_model), - m_collator() - { - m_collator.setCaseSensitivity(other.m_collator.caseSensitivity()); - m_collator.setIgnorePunctuation(other.m_collator.ignorePunctuation()); - m_collator.setLocale(other.m_collator.locale()); - m_collator.setNumericMode(other.m_collator.numericMode()); - } - - ~KFileItemModelLessThan() = default; - //We do not delete m_model as the pointer was passed from outside ant it will be deleted elsewhere. - - KFileItemModelLessThan& operator=(const KFileItemModelLessThan& other) - { - m_model = other.m_model; - m_collator = other.m_collator; - return *this; - } - - bool operator()(const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b) const - { - return m_model->lessThan(a, b, m_collator); - } - -private: - const KFileItemModel* m_model; - QCollator m_collator; -}; - -void KFileItemModel::sort(QList::iterator begin, - QList::iterator end) const -{ - KFileItemModelLessThan lessThan(this, m_collator); + return lessThan(a, b, m_collator); + }; if (m_sortRole == NameRole) { // Sorting by name 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, lessThan, numberOfThreads); + parallelMergeSort(begin, end, lambdaLessThan, numberOfThreads); } else { // Sorting by other roles is quite fast. Use only one thread to prevent // problems caused by non-reentrant comparison functions, see // https://bugs.kde.org/show_bug.cgi?id=312679 - mergeSort(begin, end, lessThan); + mergeSort(begin, end, lambdaLessThan); } } @@ -1823,8 +1783,8 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const } case ModificationTimeRole: { - const QDateTime dateTimeA = itemA.time(KFileItem::ModificationTime); - const QDateTime dateTimeB = itemB.time(KFileItem::ModificationTime); + const long long dateTimeA = itemA.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1); + const long long dateTimeB = itemB.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1); if (dateTimeA < dateTimeB) { result = -1; } else if (dateTimeA > dateTimeB) { @@ -1834,8 +1794,8 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const } case CreationTimeRole: { - const QDateTime dateTimeA = itemA.time(KFileItem::CreationTime); - const QDateTime dateTimeB = itemB.time(KFileItem::CreationTime); + const long long dateTimeA = itemA.entry().numberValue(KIO::UDSEntry::UDS_CREATION_TIME, -1); + const long long dateTimeB = itemB.entry().numberValue(KIO::UDSEntry::UDS_CREATION_TIME, -1); if (dateTimeA < dateTimeB) { result = -1; } else if (dateTimeA > dateTimeB) { @@ -1855,16 +1815,14 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const break; } - case RatingRole: { - result = a->values.value("rating").toInt() - b->values.value("rating").toInt(); - break; - } - - case ImageSizeRole: { - // Alway use a natural comparing to interpret the numbers of a string like - // "1600 x 1200" for having a correct sorting. - result = collator.compare(a->values.value("imageSize").toString(), - b->values.value("imageSize").toString()); + case RatingRole: + case WidthRole: + case HeightRole: + case WordCountRole: + case LineCountRole: + case TrackRole: + case ReleaseYearRole: { + result = a->values.value(roleForType(m_sortRole)).toInt() - b->values.value(roleForType(m_sortRole)).toInt(); break; } @@ -2024,7 +1982,7 @@ QList > KFileItemModel::sizeRoleGroups() const return groups; } -QList > KFileItemModel::timeRoleGroups(std::function fileTimeCb) const +QList > KFileItemModel::timeRoleGroups(const std::function &fileTimeCb) const { Q_ASSERT(!m_itemData.isEmpty()); @@ -2088,12 +2046,20 @@ QList > KFileItemModel::timeRoleGroups(std::function > KFileItemModel::timeRoleGroups(std::function