X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/6e752f507a1dd82a40d4bd140457203842fc0c80..refs/heads/master:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index a6f90b9f5..603c16e0d 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -20,6 +20,9 @@ #include #include +#ifndef QT_NO_ACCESSIBILITY +#include +#endif #include #include #include @@ -203,13 +206,20 @@ bool KFileItemModel::setData(int index, const QHash &value return false; } - m_itemData[index]->values = currentValues; if (changedRoles.contains("text")) { QUrl url = m_itemData[index]->item.url(); + m_items.remove(url); url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + currentValues["text"].toString()); m_itemData[index]->item.setUrl(url); + m_items.insert(url, index); + + if (!changedRoles.contains("url")) { + changedRoles.insert("url"); + currentValues["url"] = url; + } } + m_itemData[index]->values = currentValues; emitItemsChangedAndTriggerResorting(KItemRangeList() << KItemRange(index, 1), changedRoles); @@ -326,16 +336,32 @@ QMimeData *KFileItemModel::createMimeData(const KItemSet &indexes) const return data; } +namespace +{ +QString removeMarks(const QString &original) +{ + const auto normalized = original.normalized(QString::NormalizationForm_D); + QString res; + for (auto ch : normalized) { + if (!ch.isMark()) { + res.append(ch); + } + } + return res; +} +} + int KFileItemModel::indexForKeyboardSearch(const QString &text, int startFromIndex) const { + const auto noMarkText = removeMarks(text); startFromIndex = qMax(0, startFromIndex); for (int i = startFromIndex; i < count(); ++i) { - if (fileItem(i).text().startsWith(text, Qt::CaseInsensitive)) { + if (removeMarks(fileItem(i).text()).startsWith(noMarkText, Qt::CaseInsensitive)) { return i; } } for (int i = 0; i < startFromIndex; ++i) { - if (fileItem(i).text().startsWith(text, Qt::CaseInsensitive)) { + if (removeMarks(fileItem(i).text()).startsWith(noMarkText, Qt::CaseInsensitive)) { return i; } } @@ -2424,7 +2450,24 @@ int KFileItemModel::stringCompare(const QString &a, const QString &b, const QCol QMutexLocker collatorLock(s_collatorMutex()); if (m_naturalSorting) { - return collator.compare(a, b); + // Split extension, taking into account it can be empty + constexpr QString::SectionFlags flags = QString::SectionSkipEmpty | QString::SectionIncludeLeadingSep; + + // Sort by baseName first + const QString aBaseName = a.section('.', 0, 0, flags); + const QString bBaseName = b.section('.', 0, 0, flags); + + const int res = collator.compare(aBaseName, bBaseName); + if (res != 0 || (aBaseName.length() == a.length() && bBaseName.length() == b.length())) { + return res; + } + + // sliced() has undefined behavior when pos < 0 or pos > size(). + Q_ASSERT(aBaseName.length() <= a.length() && aBaseName.length() >= 0); + Q_ASSERT(bBaseName.length() <= b.length() && bBaseName.length() >= 0); + + // baseNames were equal, sort by extension + return collator.compare(a.sliced(aBaseName.length()), b.sliced(bBaseName.length())); } const int result = QString::compare(a, b, collator.caseSensitivity()); @@ -2658,7 +2701,7 @@ KFileItemModel::timeRoleGroup(const std::function & "part of the text that should not be formatted as a date", "'Yesterday' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); - if (translatedFormat.count(QLatin1Char('\'')) == 2) { + if (const int count = translatedFormat.count(QLatin1Char('\'')); count >= 2 && count % 2 == 0) { newGroupValue = locale.toString(fileTime, translatedFormat); newGroupValue = i18nc( "Can be used to script translation of " @@ -2690,7 +2733,7 @@ KFileItemModel::timeRoleGroup(const std::function & "part of the text that should not be formatted as a date", "'One Week Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); - if (translatedFormat.count(QLatin1Char('\'')) == 2) { + if (const int count = translatedFormat.count(QLatin1Char('\'')); count >= 2 && count % 2 == 0) { newGroupValue = locale.toString(fileTime, translatedFormat); newGroupValue = i18nc( "Can be used to script translation of " @@ -2711,7 +2754,7 @@ KFileItemModel::timeRoleGroup(const std::function & "part of the text that should not be formatted as a date", "'Two Weeks Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); - if (translatedFormat.count(QLatin1Char('\'')) == 2) { + if (const int count = translatedFormat.count(QLatin1Char('\'')); count >= 2 && count % 2 == 0) { newGroupValue = locale.toString(fileTime, translatedFormat); newGroupValue = i18nc( "Can be used to script translation of " @@ -2732,7 +2775,7 @@ KFileItemModel::timeRoleGroup(const std::function & "part of the text that should not be formatted as a date", "'Three Weeks Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); - if (translatedFormat.count(QLatin1Char('\'')) == 2) { + if (const int count = translatedFormat.count(QLatin1Char('\'')); count >= 2 && count % 2 == 0) { newGroupValue = locale.toString(fileTime, translatedFormat); newGroupValue = i18nc( "Can be used to script translation of " @@ -2753,7 +2796,7 @@ KFileItemModel::timeRoleGroup(const std::function & "part of the text that should not be formatted as a date", "'Earlier on' MMMM, yyyy"); const QString translatedFormat = format.toString(); - if (translatedFormat.count(QLatin1Char('\'')) == 2) { + if (const int count = translatedFormat.count(QLatin1Char('\'')); count >= 2 && count % 2 == 0) { newGroupValue = locale.toString(fileTime, translatedFormat); newGroupValue = i18nc( "Can be used to script translation of " @@ -3082,6 +3125,7 @@ const KFileItemModel::RoleInfoMap *KFileItemModel::rolesInfoMap(int &count) { "releaseYear", ReleaseYearRole, kli18nc("@label", "Release Year"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, { "aspectRatio", AspectRatioRole, kli18nc("@label", "Aspect Ratio"), kli18nc("@label", "Video"), KLazyLocalizedString(), true, true }, { "frameRate", FrameRateRole, kli18nc("@label", "Frame Rate"), kli18nc("@label", "Video"), KLazyLocalizedString(), true, true }, + { "duration", DurationRole, kli18nc("@label", "Duration"), kli18nc("@label", "Video"), KLazyLocalizedString(), true, true }, { "path", PathRole, kli18nc("@label", "Path"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, { "extension", ExtensionRole, kli18nc("@label", "File Extension"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, { "deletiontime", DeletionTimeRole, kli18nc("@label", "Deletion Time"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false },