diff options
| author | Ahmad Samir <a.samirh78@gmail.com> | 2022-10-01 02:11:24 +0200 |
|---|---|---|
| committer | Ahmad Samir <a.samirh78@gmail.com> | 2023-02-10 01:19:21 +0200 |
| commit | b5a54d488cfc94a3cefc5690c7717404ba03feb9 (patch) | |
| tree | 693e7a78fb5e0f3792895d08840beda73b84df2a /src/corelib/io/qdir.cpp | |
| parent | eb60e940202857dc155f1a0e499364962faad7f6 (diff) | |
QDir: use QCollator when doing locale-aware sorting
And don't use toLower() as QString::compare() and QCollator::compare()
can compare case-insensitively.
Change-Id: I999d787cb77e10a101da75d1bf0a5baf096a5c9b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qdir.cpp')
| -rw-r--r-- | src/corelib/io/qdir.cpp | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index b08595bf14c..f5c27e74723 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -22,6 +22,7 @@ #include <qstringbuilder.h> #ifndef QT_BOOTSTRAPPED +# include <qcollator.h> # include "qreadwritelock.h" # include "qmutex.h" #endif @@ -199,10 +200,8 @@ struct QDirSortItem // A dir e.g. "dirA.bar" doesn't have actually have an extension/suffix, when // sorting by type such "suffix" should be ignored but that would complicate // the code and uses can change the behavior by setting DirsFirst/DirsLast - if (sort.testAnyFlag(QDir::Type)) { - const bool ic = sort.testAnyFlag(QDir::IgnoreCase); - suffix_cache = ic ? item.suffix().toLower() : item.suffix(); - } + if (sort.testAnyFlag(QDir::Type)) + suffix_cache = item.suffix(); } mutable QString filename_cache; @@ -210,13 +209,39 @@ struct QDirSortItem QFileInfo item; }; - class QDirSortItemComparator { QDir::SortFlags qt_cmp_si_sort_flags; + +#ifndef QT_BOOTSTRAPPED + QCollator *collator = nullptr; +#endif public: - QDirSortItemComparator(QDir::SortFlags flags) : qt_cmp_si_sort_flags(flags) {} +#ifndef QT_BOOTSTRAPPED + QDirSortItemComparator(QDir::SortFlags flags, QCollator *coll = nullptr) + : qt_cmp_si_sort_flags(flags), collator(coll) + { + Q_ASSERT(!qt_cmp_si_sort_flags.testAnyFlag(QDir::LocaleAware) || collator); + + if (collator && qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase)) + collator->setCaseSensitivity(Qt::CaseInsensitive); + } +#else + QDirSortItemComparator(QDir::SortFlags flags) + : qt_cmp_si_sort_flags(flags) + { + } +#endif bool operator()(const QDirSortItem &, const QDirSortItem &) const; + + int compareStrings(const QString &a, const QString &b, Qt::CaseSensitivity cs) const + { +#ifndef QT_BOOTSTRAPPED + if (collator) + return collator->compare(a, b); +#endif + return a.compare(b, cs); + } }; bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortItem &n2) const @@ -229,6 +254,9 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir())) return !f1->item.isDir(); + const bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase); + const auto qtcase = ic ? Qt::CaseInsensitive : Qt::CaseSensitive; + qint64 r = 0; int sortBy = ((qt_cmp_si_sort_flags & QDir::SortByMask) | (qt_cmp_si_sort_flags & QDir::Type)).toInt(); @@ -243,11 +271,8 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt case QDir::Size: r = f2->item.size() - f1->item.size(); break; - case QDir::Type: { - r = qt_cmp_si_sort_flags & QDir::LocaleAware - ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache) - : f1->suffix_cache.compare(f2->suffix_cache); - } + case QDir::Type: + r = compareStrings(f1->suffix_cache, f2->suffix_cache, qtcase); break; default: ; @@ -255,18 +280,13 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt if (r == 0 && sortBy != QDir::Unsorted) { // Still not sorted - sort by name - bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase); if (f1->filename_cache.isNull()) - f1->filename_cache = ic ? f1->item.fileName().toLower() - : f1->item.fileName(); + f1->filename_cache = f1->item.fileName(); if (f2->filename_cache.isNull()) - f2->filename_cache = ic ? f2->item.fileName().toLower() - : f2->item.fileName(); + f2->filename_cache = f2->item.fileName(); - r = qt_cmp_si_sort_flags & QDir::LocaleAware - ? f1->filename_cache.localeAwareCompare(f2->filename_cache) - : f1->filename_cache.compare(f2->filename_cache); + r = compareStrings(f1->filename_cache, f2->filename_cache, qtcase); } if (qt_cmp_si_sort_flags & QDir::Reversed) return r > 0; @@ -297,7 +317,17 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, const QFileInfoList for (qsizetype i = 0; i < n; ++i) si[i] = QDirSortItem{l.at(i), sort}; +#ifndef QT_BOOTSTRAPPED + if (sort.testAnyFlag(QDir::LocaleAware)) { + QCollator coll; + std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort, &coll)); + } else { + std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort)); + } +#else std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort)); +#endif // QT_BOOTSTRAPPED + // put them back in the list(s) for (qsizetype i = 0; i < n; ++i) { if (infos) |
