X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/615838083dfe7ff6845069cc18a88d38be56a478..89158c6b3d29b9c01fe9dcc4c2b477dbc80abbdb:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 2a9e2ea41..7c7abe9a7 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -304,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)); } } @@ -786,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); @@ -797,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) @@ -826,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() @@ -1205,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 @@ -1275,7 +1283,7 @@ void KFileItemModel::removeItems(const KItemRangeList& itemRanges, RemoveItemsBe delete m_itemData.at(index); } - m_itemData[index] = 0; + m_itemData[index] = nullptr; } } @@ -1316,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()); @@ -1547,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]) { @@ -1560,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); } @@ -1709,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 -{ -public: - KFileItemModelLessThan(const KFileItemModel* model, const QCollator& collator) : - m_model(model), - m_collator(collator) - { - } - - 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); + auto lambdaLessThan = [&] (const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b) + { + 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); } } @@ -1814,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) { @@ -1825,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) {