]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
kfileitemmodel: allow more than 2 single quotes in translated strings
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index 3a60834af32b222ec6f2c6aad5c3b9ca3466248d..4386bca16b6ada60a808a9764ff83ed8d74826ed 100644 (file)
@@ -20,6 +20,9 @@
 #include <KLocalizedString>
 #include <KUrlMimeData>
 
+#ifndef QT_NO_ACCESSIBILITY
+#include <QAccessible>
+#endif
 #include <QElapsedTimer>
 #include <QIcon>
 #include <QMimeData>
@@ -332,16 +335,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;
         }
     }
@@ -2246,7 +2265,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());
@@ -2450,7 +2486,7 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
                         "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 "
@@ -2482,7 +2518,7 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
                         "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 "
@@ -2503,7 +2539,7 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
                         "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 "
@@ -2524,7 +2560,7 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
                         "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 "
@@ -2545,7 +2581,7 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
                         "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 "