]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Implemented ItemGroupInfo in place of QVariant in roleRoleGroup functions
authorZakhar Afonin <aza22u419@student.bmstu.ru>
Sun, 16 Jun 2024 10:02:24 +0000 (13:02 +0300)
committerZakhar Afonin <aza22u419@student.bmstu.ru>
Sun, 16 Jun 2024 10:02:24 +0000 (13:02 +0300)
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/views/dolphinviewactionhandler.cpp

index 564ac42ea15a4228e42f6c108bf00cb76dff2c7a..1ab9cd0e41cfe147af9b6f9c8ff7d642e1f72944 100644 (file)
@@ -2288,134 +2288,103 @@ int KFileItemModel::sortRoleCompare(const ItemData *a, const ItemData *b, const
 int KFileItemModel::groupRoleCompare(const ItemData *a, const ItemData *b, const QCollator &collator) const
 {
     // Unlike sortRoleCompare, this function can and often will return 0.
-    const KFileItem &itemA = a->item;
-    const KFileItem &itemB = b->item;
-
     int result = 0;
 
+    int groupA, groupB;
     switch (m_groupRole) {
     case NoRole:
         break;
-    case NameRole: {
-        QChar groupA = getNameRoleGroup(a, false).toChar();
-        QChar groupB = getNameRoleGroup(b, false).toChar();
-        if (groupA < groupB) {
-            result = -1;
-        } else if (groupA > groupB) {
-            result = 1;
-        }
+    case NameRole:
+        groupA = nameRoleGroup(a, false).comparable;
+        groupB = nameRoleGroup(b, false).comparable;
         break;
-    }
-    case SizeRole: {
-        int groupA = getSizeRoleGroup(a, false).toInt();
-        int groupB = getSizeRoleGroup(b, false).toInt();
-        if (groupA < groupB) {
-            result = -1;
-        } else if (groupA > groupB) {
-            result = 1;
-        }
+    case SizeRole:
+        groupA = sizeRoleGroup(a, false).comparable;
+        groupB = sizeRoleGroup(b, false).comparable;
         break;
-    }
-    case ModificationTimeRole: {
-        int groupA = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::ModificationTime);
-                         },
-                         a,
-                         false)
-                         .toInt();
-        int groupB = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::ModificationTime);
-                         },
-                         b,
-                         false)
-                         .toInt();
-        if (groupA < groupB) {
-            result = -1;
-        } else if (groupA > groupB) {
-            result = 1;
-        }
+    case ModificationTimeRole:
+        groupA = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::ModificationTime);
+                     },
+                     a,
+                     false)
+                     .comparable;
+        groupB = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::ModificationTime);
+                     },
+                     b,
+                     false)
+                     .comparable;
         break;
-    }
-    case CreationTimeRole: {
-        int groupA = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::CreationTime);
-                         },
-                         a,
-                         false)
-                         .toInt();
-        int groupB = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::CreationTime);
-                         },
-                         b,
-                         false)
-                         .toInt();
-        if (groupA < groupB) {
-            result = -1;
-        } else if (groupA > groupB) {
-            result = 1;
-        }
+    case CreationTimeRole:
+        groupA = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::CreationTime);
+                     },
+                     a,
+                     false)
+                     .comparable;
+        groupB = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::CreationTime);
+                     },
+                     b,
+                     false)
+                     .comparable;
         break;
-    }
-    case AccessTimeRole: {
-        int groupA = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::AccessTime);
-                         },
-                         a,
-                         false)
-                         .toInt();
-        int groupB = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->item.time(KFileItem::AccessTime);
-                         },
-                         b,
-                         false)
-                         .toInt();
-        if (groupA < groupB) {
-            result = -1;
-        } else if (groupA > groupB) {
-            result = 1;
-        }
+    case AccessTimeRole:
+        groupA = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::AccessTime);
+                     },
+                     a,
+                     false)
+                     .comparable;
+        groupB = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->item.time(KFileItem::AccessTime);
+                     },
+                     b,
+                     false)
+                     .comparable;
         break;
-    }
-    case DeletionTimeRole: {
-        int groupA = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->values.value("deletiontime").toDateTime();
-                         },
-                         a,
-                         false)
-                         .toInt();
-        int groupB = getTimeRoleGroup(
-                         [](const ItemData *item) {
-                             return item->values.value("deletiontime").toDateTime();
-                         },
-                         b,
-                         false)
-                         .toInt();
-        if (groupA < groupB) {
+    case DeletionTimeRole:
+        groupA = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->values.value("deletiontime").toDateTime();
+                     },
+                     a,
+                     false)
+                     .comparable;
+        groupB = timeRoleGroup(
+                     [](const ItemData *item) {
+                         return item->values.value("deletiontime").toDateTime();
+                     },
+                     b,
+                     false)
+                     .comparable;
+        break;
+    // case PermissionsRole:
+    //  case RatingRole:
+    default: {
+        QString strGroupA = genericStringRoleGroup(groupRole(), a);
+        QString strGroupB = genericStringRoleGroup(groupRole(), b);
+        if (strGroupA < strGroupB) {
             result = -1;
-        } else if (groupA > groupB) {
+        } else if (strGroupA > strGroupB) {
             result = 1;
         }
         break;
     }
-    // case PermissionsRole:
-    //  case RatingRole:
-    default: {
-        QString groupA = getGenericStringRoleGroup(groupRole(), a);
-        QString groupB = getGenericStringRoleGroup(groupRole(), b);
+    }
+    if (result == 0) {
         if (groupA < groupB) {
             result = -1;
         } else if (groupA > groupB) {
             result = 1;
         }
-        break;
-    }
     }
     return result;
 }
@@ -2439,19 +2408,24 @@ int KFileItemModel::stringCompare(const QString &a, const QString &b, const QCol
     return QString::compare(a, b, Qt::CaseSensitive);
 }
 
-QVariant KFileItemModel::getNameRoleGroup(const ItemData *itemData, bool asString) const
+KFileItemModel::ItemGroupInfo KFileItemModel::nameRoleGroup(const ItemData *itemData, bool withString) const
 {
-    const KFileItem item = itemData->item;
-    const QString name = item.text();
-    QVariant newGroupValue;
+    static ItemGroupInfo oldGroupInfo, groupInfo;
+    static QChar oldFirstChar, firstChar;
+
+    const QString name = itemData->item.text();
+
     // Use the first character of the name as group indication
-    QChar newFirstChar = name.at(0).toUpper();
-    if (newFirstChar == QLatin1Char('~') && name.length() > 1) {
-        newFirstChar = name.at(1).toUpper();
-    }
+    firstChar = name.at(0).toUpper();
 
-    if (newFirstChar.isLetter()) {
-        if (m_collator.compare(newFirstChar, QChar(QLatin1Char('A'))) >= 0 && m_collator.compare(newFirstChar, QChar(QLatin1Char('Z'))) <= 0) {
+    if (firstChar == oldFirstChar) {
+        return oldGroupInfo;
+    }
+    if (firstChar == QLatin1Char('~') && name.length() > 1) {
+        firstChar = name.at(1).toUpper();
+    }
+    if (firstChar.isLetter()) {
+        if (m_collator.compare(firstChar, QChar(QLatin1Char('A'))) >= 0 && m_collator.compare(firstChar, QChar(QLatin1Char('Z'))) <= 0) {
             // WARNING! Symbols based on latin 'Z' like 'Z' with acute are treated wrong as non Latin and put in a new group.
 
             // Try to find a matching group in the range 'A' to 'Z'.
@@ -2467,146 +2441,163 @@ QVariant KFileItemModel::getNameRoleGroup(const ItemData *itemData, bool asStrin
                 return m_collator.compare(c1, c2) < 0;
             };
 
-            std::vector<QChar>::iterator it = std::lower_bound(lettersAtoZ.begin(), lettersAtoZ.end(), newFirstChar, localeAwareLessThan);
+            std::vector<QChar>::iterator it = std::lower_bound(lettersAtoZ.begin(), lettersAtoZ.end(), firstChar, localeAwareLessThan);
             if (it != lettersAtoZ.end()) {
-                if (localeAwareLessThan(newFirstChar, *it)) {
+                if (localeAwareLessThan(firstChar, *it)) {
                     // newFirstChar belongs to the group preceding *it.
                     // Example: for an umlaut 'A' in the German locale, *it would be 'B' now.
                     --it;
                 }
-                newGroupValue = *it;
+                if (withString) {
+                    groupInfo.text = *it;
+                }
+                groupInfo.comparable = (*it).unicode();
             }
 
         } else {
             // Symbols from non Latin-based scripts
-            newGroupValue = newFirstChar;
+            if (withString) {
+                groupInfo.text = firstChar;
+            }
+            groupInfo.comparable = firstChar.unicode();
         }
-    } else if (newFirstChar >= QLatin1Char('0') && newFirstChar <= QLatin1Char('9')) {
+    } else if (firstChar >= QLatin1Char('0') && firstChar <= QLatin1Char('9')) {
         // Apply group '0 - 9' for any name that starts with a digit
-        if (asString) {
-            newGroupValue = i18nc("@title:group Groups that start with a digit", "0 - 9");
-        } else {
-            newGroupValue = QChar('0');
+        if (withString) {
+            groupInfo.text = i18nc("@title:group Groups that start with a digit", "0 - 9");
         }
+        groupInfo.comparable = (int)'0';
     } else {
-        if (asString) {
-            newGroupValue = i18nc("@title:group", "Others");
-        } else {
-            newGroupValue = QChar('.');
+        if (withString) {
+            groupInfo.text = i18nc("@title:group", "Others");
         }
+        groupInfo.comparable = (int)'.';
     }
-    return newGroupValue;
+    oldFirstChar = firstChar;
+    oldGroupInfo = groupInfo;
+    return groupInfo;
 }
 
-QVariant KFileItemModel::getSizeRoleGroup(const ItemData *itemData, bool asString) const
+KFileItemModel::ItemGroupInfo KFileItemModel::sizeRoleGroup(const ItemData *itemData, bool withString) const
 {
+    static ItemGroupInfo oldGroupInfo, groupInfo;
+    static KIO::filesize_t oldFileSize, fileSize;
+
     const KFileItem item = itemData->item;
+    fileSize = !item.isNull() ? item.size() : ~0U;
 
-    KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
-    int newGroupValue = -1; // None
+    // Use the first character of the name as group indication
+    fileSize = item.size();
+
+    groupInfo.comparable = -1; // None
     if (!item.isNull() && item.isDir()) {
         if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount || m_sortDirsFirst) {
-            newGroupValue = 0; // Folders
+            groupInfo.comparable = 0; // Folders
         } else {
             fileSize = itemData->values.value("size").toULongLong();
         }
     }
-
-    if (newGroupValue < 0) {
+    if (fileSize == oldFileSize) {
+        groupInfo = oldGroupInfo;
+    }
+    if (groupInfo.comparable < 0) {
         if (fileSize < 5 * 1024 * 1024) { // < 5 MB
-            newGroupValue = 1; // Small
+            groupInfo.comparable = 1; // Small
         } else if (fileSize < 10 * 1024 * 1024) { // < 10 MB
-            newGroupValue = 2; // Medium
+            groupInfo.comparable = 2; // Medium
         } else {
-            newGroupValue = 3; // Big
+            groupInfo.comparable = 3; // Big
         }
     }
 
-    if (asString) {
+    if (withString) {
         char const *groupNames[] = {"Folders", "Small", "Medium", "Big"};
-        return i18nc("@title:group Size", groupNames[newGroupValue]);
-    } else {
-        return newGroupValue;
+        groupInfo.text = i18nc("@title:group Size", groupNames[groupInfo.comparable]);
     }
+    oldFileSize = fileSize;
+    oldGroupInfo = groupInfo;
+    return groupInfo;
 }
 
-QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const ItemData *)> &fileTimeCb, const ItemData *itemData, bool asString) const
+KFileItemModel::ItemGroupInfo
+KFileItemModel::timeRoleGroup(const std::function<QDateTime(const ItemData *)> &fileTimeCb, const ItemData *itemData, bool withString) const
 {
+    static ItemGroupInfo oldGroupInfo, groupInfo;
+    static QDate oldFileDate;
+
     const QDate currentDate = QDate::currentDate();
     const QDateTime fileTime = fileTimeCb(itemData);
     const QDate fileDate = fileTime.date();
     const int daysDistance = fileDate.daysTo(currentDate);
 
-    int intGroupValue;
-    QString strGroupValue;
-
-    if (!asString) {
-        // Simplified grouping algorithm, preserving dates
-        // but not taking "pretty printing" into account
-        if (currentDate.year() == fileDate.year() && currentDate.month() == fileDate.month()) {
+    int intGroupInfo;
+    QString strGroupInfo;
+
+    // Simplified grouping algorithm, preserving dates
+    // but not taking "pretty printing" into account
+    if (currentDate.year() == fileDate.year() && currentDate.month() == fileDate.month()) {
+        if (daysDistance < 7) {
+            groupInfo.comparable = daysDistance; // Today, Yesterday and week days
+        } else if (daysDistance < 14) {
+            groupInfo.comparable = 10; // One Week Ago
+        } else if (daysDistance < 21) {
+            groupInfo.comparable = 20; // Two Weeks Ago
+        } else if (daysDistance < 28) {
+            groupInfo.comparable = 30; // Three Weeks Ago
+        } else {
+            groupInfo.comparable = 40; // Earlier This Month
+        }
+    } else {
+        const QDate lastMonthDate = currentDate.addMonths(-1);
+        if (lastMonthDate.year() == fileDate.year() && lastMonthDate.month() == fileDate.month()) {
             if (daysDistance < 7) {
-                intGroupValue = daysDistance; // Today, Yesterday and week days
+                groupInfo.comparable = daysDistance; // Today, Yesterday and week days (Month, Year)
             } else if (daysDistance < 14) {
-                intGroupValue = 10; // One Week Ago
+                groupInfo.comparable = 9; // One Week Ago (Month, Year)
             } else if (daysDistance < 21) {
-                intGroupValue = 20; // Two Weeks Ago
+                groupInfo.comparable = 19; // Two Weeks Ago (Month, Year)
             } else if (daysDistance < 28) {
-                intGroupValue = 30; // Three Weeks Ago
+                groupInfo.comparable = 29; // Three Weeks Ago (Month, Year)
             } else {
-                intGroupValue = 40; // Earlier This Month
+                groupInfo.comparable = 39; // Earlier on Month, Year
             }
         } else {
-            const QDate lastMonthDate = currentDate.addMonths(-1);
-            if (lastMonthDate.year() == fileDate.year() && lastMonthDate.month() == fileDate.month()) {
-                if (daysDistance < 7) {
-                    intGroupValue = daysDistance; // Today, Yesterday and week days (Month, Year)
-                } else if (daysDistance < 14) {
-                    intGroupValue = 9; // One Week Ago (Month, Year)
-                } else if (daysDistance < 21) {
-                    intGroupValue = 19; // Two Weeks Ago (Month, Year)
-                } else if (daysDistance < 28) {
-                    intGroupValue = 29; // Three Weeks Ago (Month, Year)
-                } else {
-                    intGroupValue = 39; // Earlier on Month, Year
-                }
-            } else {
-                // The trick will fail for dates past April, 178956967 or before 1 AD.
-                intGroupValue = 2147483647 - (fileDate.year() * 12 + fileDate.month() - 1); // Month, Year; newer < older
-            }
+            // The trick will fail for dates past April, 178956967 or before 1 AD.
+            groupInfo.comparable = 2147483647 - (fileDate.year() * 12 + fileDate.month() - 1); // Month, Year; newer < older
         }
-        return QVariant(intGroupValue);
-    } else {
+    }
+    if (withString) {
         if (currentDate.year() == fileDate.year() && currentDate.month() == fileDate.month()) {
             switch (daysDistance / 7) {
             case 0:
                 switch (daysDistance) {
                 case 0:
-                    strGroupValue = i18nc("@title:group Date", "Today");
+                    groupInfo.text = i18nc("@title:group Date", "Today");
                     break;
                 case 1:
-                    strGroupValue = i18nc("@title:group Date", "Yesterday");
+                    groupInfo.text = i18nc("@title:group Date", "Yesterday");
                     break;
                 default:
-                    strGroupValue = fileTime.toString(i18nc("@title:group Date: The week day name: dddd", "dddd"));
-                    strGroupValue = i18nc(
+                    groupInfo.text = fileTime.toString(i18nc("@title:group Date: The week day name: dddd", "dddd"));
+                    groupInfo.text = i18nc(
                         "Can be used to script translation of \"dddd\""
                         "with context @title:group Date",
                         "%1",
-                        strGroupValue);
+                        groupInfo.text);
                 }
                 break;
             case 1:
-                strGroupValue = i18nc("@title:group Date", "One Week Ago");
+                groupInfo.text = i18nc("@title:group Date", "One Week Ago");
                 break;
             case 2:
-                strGroupValue = i18nc("@title:group Date", "Two Weeks Ago");
+                groupInfo.text = i18nc("@title:group Date", "Two Weeks Ago");
                 break;
             case 3:
-                strGroupValue = i18nc("@title:group Date", "Three Weeks Ago");
+                groupInfo.text = i18nc("@title:group Date", "Three Weeks Ago");
                 break;
             case 4:
             case 5:
-                strGroupValue = i18nc("@title:group Date", "Earlier this Month");
+                groupInfo.text = i18nc("@title:group Date", "Earlier this Month");
                 break;
             default:
                 Q_ASSERT(false);
@@ -2623,29 +2614,29 @@ QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const It
                         "'Yesterday' (MMMM, yyyy)");
                     const QString translatedFormat = format.toString();
                     if (translatedFormat.count(QLatin1Char('\'')) == 2) {
-                        strGroupValue = fileTime.toString(translatedFormat);
-                        strGroupValue = i18nc(
+                        groupInfo.text = fileTime.toString(translatedFormat);
+                        groupInfo.text = i18nc(
                             "Can be used to script translation of "
                             "\"'Yesterday' (MMMM, yyyy)\" with context @title:group Date",
                             "%1",
-                            strGroupValue);
+                            groupInfo.text);
                     } else {
                         qCWarning(DolphinDebug).nospace()
                             << "A wrong translation was found: " << translatedFormat << ". Please file a bug report at bugs.kde.org";
                         const QString untranslatedFormat = format.toString({QLatin1String("en_US")});
-                        strGroupValue = fileTime.toString(untranslatedFormat);
+                        groupInfo.text = fileTime.toString(untranslatedFormat);
                     }
                 } else if (daysDistance <= 7) {
-                    strGroupValue =
+                    groupInfo.text =
                         fileTime.toString(i18nc("@title:group Date: "
                                                 "The week day name: dddd, MMMM is full month name "
                                                 "in current locale, and yyyy is full year number.",
                                                 "dddd (MMMM, yyyy)"));
-                    strGroupValue = i18nc(
+                    groupInfo.text = i18nc(
                         "Can be used to script translation of "
                         "\"dddd (MMMM, yyyy)\" with context @title:group Date",
                         "%1",
-                        strGroupValue);
+                        groupInfo.text);
                 } else if (daysDistance <= 7 * 2) {
                     const KLocalizedString format = ki18nc(
                         "@title:group Date: "
@@ -2655,17 +2646,17 @@ QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const It
                         "'One Week Ago' (MMMM, yyyy)");
                     const QString translatedFormat = format.toString();
                     if (translatedFormat.count(QLatin1Char('\'')) == 2) {
-                        strGroupValue = fileTime.toString(translatedFormat);
-                        strGroupValue = i18nc(
+                        groupInfo.text = fileTime.toString(translatedFormat);
+                        groupInfo.text = i18nc(
                             "Can be used to script translation of "
                             "\"'One Week Ago' (MMMM, yyyy)\" with context @title:group Date",
                             "%1",
-                            strGroupValue);
+                            groupInfo.text);
                     } else {
                         qCWarning(DolphinDebug).nospace()
                             << "A wrong translation was found: " << translatedFormat << ". Please file a bug report at bugs.kde.org";
                         const QString untranslatedFormat = format.toString({QLatin1String("en_US")});
-                        strGroupValue = fileTime.toString(untranslatedFormat);
+                        groupInfo.text = fileTime.toString(untranslatedFormat);
                     }
                 } else if (daysDistance <= 7 * 3) {
                     const KLocalizedString format = ki18nc(
@@ -2676,17 +2667,17 @@ QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const It
                         "'Two Weeks Ago' (MMMM, yyyy)");
                     const QString translatedFormat = format.toString();
                     if (translatedFormat.count(QLatin1Char('\'')) == 2) {
-                        strGroupValue = fileTime.toString(translatedFormat);
-                        strGroupValue = i18nc(
+                        groupInfo.text = fileTime.toString(translatedFormat);
+                        groupInfo.text = i18nc(
                             "Can be used to script translation of "
                             "\"'Two Weeks Ago' (MMMM, yyyy)\" with context @title:group Date",
                             "%1",
-                            strGroupValue);
+                            groupInfo.text);
                     } else {
                         qCWarning(DolphinDebug).nospace()
                             << "A wrong translation was found: " << translatedFormat << ". Please file a bug report at bugs.kde.org";
                         const QString untranslatedFormat = format.toString({QLatin1String("en_US")});
-                        strGroupValue = fileTime.toString(untranslatedFormat);
+                        groupInfo.text = fileTime.toString(untranslatedFormat);
                     }
                 } else if (daysDistance <= 7 * 4) {
                     const KLocalizedString format = ki18nc(
@@ -2697,17 +2688,17 @@ QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const It
                         "'Three Weeks Ago' (MMMM, yyyy)");
                     const QString translatedFormat = format.toString();
                     if (translatedFormat.count(QLatin1Char('\'')) == 2) {
-                        strGroupValue = fileTime.toString(translatedFormat);
-                        strGroupValue = i18nc(
+                        groupInfo.text = fileTime.toString(translatedFormat);
+                        groupInfo.text = i18nc(
                             "Can be used to script translation of "
                             "\"'Three Weeks Ago' (MMMM, yyyy)\" with context @title:group Date",
                             "%1",
-                            strGroupValue);
+                            groupInfo.text);
                     } else {
                         qCWarning(DolphinDebug).nospace()
                             << "A wrong translation was found: " << translatedFormat << ". Please file a bug report at bugs.kde.org";
                         const QString untranslatedFormat = format.toString({QLatin1String("en_US")});
-                        strGroupValue = fileTime.toString(untranslatedFormat);
+                        groupInfo.text = fileTime.toString(untranslatedFormat);
                     }
                 } else {
                     const KLocalizedString format = ki18nc(
@@ -2718,37 +2709,39 @@ QVariant KFileItemModel::getTimeRoleGroup(const std::function<QDateTime(const It
                         "'Earlier on' MMMM, yyyy");
                     const QString translatedFormat = format.toString();
                     if (translatedFormat.count(QLatin1Char('\'')) == 2) {
-                        strGroupValue = fileTime.toString(translatedFormat);
-                        strGroupValue = i18nc(
+                        groupInfo.text = fileTime.toString(translatedFormat);
+                        groupInfo.text = i18nc(
                             "Can be used to script translation of "
                             "\"'Earlier on' MMMM, yyyy\" with context @title:group Date",
                             "%1",
-                            strGroupValue);
+                            groupInfo.text);
                     } else {
                         qCWarning(DolphinDebug).nospace()
                             << "A wrong translation was found: " << translatedFormat << ". Please file a bug report at bugs.kde.org";
                         const QString untranslatedFormat = format.toString({QLatin1String("en_US")});
-                        strGroupValue = fileTime.toString(untranslatedFormat);
+                        groupInfo.text = fileTime.toString(untranslatedFormat);
                     }
                 }
             } else {
-                strGroupValue =
+                groupInfo.text =
                     fileTime.toString(i18nc("@title:group "
                                             "The month and year: MMMM is full month name in current locale, "
                                             "and yyyy is full year number",
                                             "MMMM, yyyy"));
-                strGroupValue = i18nc(
+                groupInfo.text = i18nc(
                     "Can be used to script translation of "
                     "\"MMMM, yyyy\" with context @title:group Date",
                     "%1",
-                    strGroupValue);
+                    groupInfo.text);
             }
         }
-        return QVariant(strGroupValue);
     }
+    oldFileDate = fileDate;
+    oldGroupInfo = groupInfo;
+    return groupInfo;
 }
 
-QString KFileItemModel::getGenericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const
+QString KFileItemModel::genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const
 {
     return itemData->values.value(role).toString();
 }
@@ -2760,21 +2753,18 @@ QList<QPair<int, QVariant>> KFileItemModel::nameRoleGroups() const
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    QString groupValue;
-    QChar firstChar;
+    ItemGroupInfo groupInfo;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
         }
 
-        QString newGroupValue = getNameRoleGroup(m_itemData.at(i)).toString();
+        ItemGroupInfo newGroupInfo = nameRoleGroup(m_itemData.at(i));
 
-        if (newGroupValue != groupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
+        if (newGroupInfo != groupInfo) {
+            groupInfo = newGroupInfo;
+            groups.append(QPair<int, QVariant>(i, newGroupInfo.text));
         }
-
-        // firstChar = newFirstChar;
     }
     return groups;
 }
@@ -2786,20 +2776,19 @@ QList<QPair<int, QVariant>> KFileItemModel::sizeRoleGroups() const
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    QString groupValue;
+    ItemGroupInfo groupInfo;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
         }
 
-        QString newGroupValue = getSizeRoleGroup(m_itemData.at(i)).toString();
+        ItemGroupInfo newGroupInfo = sizeRoleGroup(m_itemData.at(i));
 
-        if (newGroupValue != groupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
+        if (newGroupInfo != groupInfo) {
+            groupInfo = newGroupInfo;
+            groups.append(QPair<int, QVariant>(i, newGroupInfo.text));
         }
     }
-
     return groups;
 }
 
@@ -2810,31 +2799,19 @@ QList<QPair<int, QVariant>> KFileItemModel::timeRoleGroups(const std::function<Q
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    const QDate currentDate = QDate::currentDate();
-
-    QDate previousFileDate;
-    QString groupValue;
+    ItemGroupInfo groupInfo;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
         }
 
-        const QDateTime fileTime = fileTimeCb(m_itemData.at(i));
-        const QDate fileDate = fileTime.date();
-        if (fileDate == previousFileDate) {
-            // The current item is in the same group as the previous item
-            continue;
-        }
-        previousFileDate = fileDate;
-
-        QString newGroupValue = getTimeRoleGroup(fileTimeCb, m_itemData.at(i)).toString();
+        ItemGroupInfo newGroupInfo = timeRoleGroup(fileTimeCb, m_itemData.at(i));
 
-        if (newGroupValue != groupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
+        if (newGroupInfo != groupInfo) {
+            groupInfo = newGroupInfo;
+            groups.append(QPair<int, QVariant>(i, newGroupInfo.text));
         }
     }
-
     return groups;
 }
 
@@ -2845,8 +2822,8 @@ QList<QPair<int, QVariant>> KFileItemModel::permissionRoleGroups() const
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    QString permissionsString;
-    QString groupValue;
+    /*QString permissionsString;
+    ItemGroupInfo groupInfo;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
@@ -2900,12 +2877,13 @@ QList<QPair<int, QVariant>> KFileItemModel::permissionRoleGroups() const
         }
         others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.length() - 2);
 
-        const QString newGroupValue = i18nc("@title:group Files and folders by permissions", "User: %1 | Group: %2 | Others: %3", user, group, others);
-        if (newGroupValue != groupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
+        const ItemListGroup newGroupInfo = {0,
+                                            i18nc("@title:group Files and folders by permissions", "User: %1 | Group: %2 | Others: %3", user, group, others)};
+        if (newGroupInfo != groupInfo) {
+            groupInfo = newGroupInfo;
+            groups.append(QPair<int, QVariant>(i, newGroupInfo));
         }
-    }
+    }*/
 
     return groups;
 }
@@ -2917,19 +2895,19 @@ QList<QPair<int, QVariant>> KFileItemModel::ratingRoleGroups() const
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    int groupValue = -1;
+    /*ItemGroupInfo groupInfo;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
         }
 
-        const int newGroupValue = m_itemData.at(i)->values.value("rating", 0).toInt();
-        if (newGroupValue != groupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
-        }
-    }
+        ItemGroupInfo newGroupInfo = nameRoleGroup(fileTimeCb, m_itemData.at(i)).toString();
 
+        if (newGroupInfo != groupInfo) {
+            groupInfo = newGroupInfo;
+            groups.append(QPair<int, QVariant>(i, newGroupInfo));
+        }
+    }*/
     return groups;
 }
 
@@ -2940,21 +2918,19 @@ QList<QPair<int, QVariant>> KFileItemModel::genericStringRoleGroups(const QByteA
     const int maxIndex = count() - 1;
     QList<QPair<int, QVariant>> groups;
 
-    bool isFirstGroupValue = true;
-    QString groupValue;
+    QString groupText;
     for (int i = 0; i <= maxIndex; ++i) {
         if (isChildItem(i)) {
             continue;
         }
 
-        const QString newGroupValue = getGenericStringRoleGroup(role, m_itemData.at(i));
-        if (newGroupValue != groupValue || isFirstGroupValue) {
-            groupValue = newGroupValue;
-            groups.append(QPair<int, QVariant>(i, newGroupValue));
-            isFirstGroupValue = false;
+        QString newGroupText = genericStringRoleGroup(role, m_itemData.at(i));
+
+        if (newGroupText != groupText) {
+            groupText = newGroupText;
+            groups.append(QPair<int, QVariant>(i, newGroupText));
         }
     }
-
     return groups;
 }
 
index 725ba71bdbe503593db89d9f724ba8a2cbcafa98..152321f94f3e87459d3cccb7961bedc80eb98659 100644 (file)
@@ -113,8 +113,6 @@ public:
 
     QString roleDescription(const QByteArray &role) const override;
 
-    QList<QPair<int, QVariant>> groups() const override;
-
     /**
      * @return The file-item for the index \a index. If the index is in a valid
      *         range it is assured that the file-item is not null. The runtime
@@ -198,7 +196,7 @@ public:
 
     /**
      * @return Provides static information for a role that is supported
-     *         by KFileItemModel. Some roles can only be determined if 
+     *         by KFileItemModel. Some roles can only be determined if
      *         Baloo is enabled and/or the Baloo indexing is enabled.
      */
     static RoleInfo roleInformation(const QByteArray &role);
@@ -211,6 +209,8 @@ public:
      */
     static QList<RoleInfo> rolesInformation();
 
+    QList<QPair<int, QVariant>> groups() const override;
+
     /** set to true to hide application/x-trash files */
     void setShowTrashMime(bool show);
 
@@ -374,6 +374,15 @@ private:
         ItemData *parent;
     };
 
+    struct ItemGroupInfo {
+        int comparable;
+        QString text;
+
+        bool operator==(const ItemGroupInfo &other) const;
+        bool operator!=(const ItemGroupInfo &other) const;
+        bool operator<(const ItemGroupInfo &other) const;
+    };
+
     enum RemoveItemsBehavior { KeepItemData, DeleteItemData, DeleteItemDataIfUnfiltered };
 
     void insertItems(QList<ItemData *> &items);
@@ -463,12 +472,12 @@ private:
 
     int stringCompare(const QString &a, const QString &b, const QCollator &collator) const;
 
-    QVariant getNameRoleGroup(const ItemData *itemData, bool asString = true) const;
-    QVariant getSizeRoleGroup(const ItemData *itemData, bool asString = true) const;
-    QVariant getTimeRoleGroup(const std::function<QDateTime(const ItemData *)> &fileTimeCb, const ItemData *itemData, bool asString = true) const;
-    QVariant getPermissionRoleGroup(const ItemData *itemData, bool asString = true) const;
-    QVariant getRatingRoleGroup(const ItemData *itemData, bool asString = true) const;
-    QString getGenericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const;
+    ItemGroupInfo nameRoleGroup(const ItemData *itemData, bool withString = true) const;
+    ItemGroupInfo sizeRoleGroup(const ItemData *itemData, bool withString = true) const;
+    ItemGroupInfo timeRoleGroup(const std::function<QDateTime(const ItemData *)> &fileTimeCb, const ItemData *itemData, bool withString = true) const;
+    ItemGroupInfo permissionRoleGroup(const ItemData *itemData, bool withString = true) const;
+    ItemGroupInfo ratingRoleGroup(const ItemData *itemData, bool withString = true) const;
+    QString genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const;
 
     QList<QPair<int, QVariant>> nameRoleGroups() const;
     QList<QPair<int, QVariant>> sizeRoleGroups() const;
@@ -624,4 +633,23 @@ inline bool KFileItemModel::isChildItem(int index) const
     }
 }
 
+inline bool KFileItemModel::ItemGroupInfo::operator==(const ItemGroupInfo &other) const
+{
+    return comparable == other.comparable && text == other.text;
+}
+
+inline bool KFileItemModel::ItemGroupInfo::operator!=(const ItemGroupInfo &other) const
+{
+    return comparable != other.comparable || text != other.text;
+}
+
+inline bool KFileItemModel::ItemGroupInfo::operator<(const ItemGroupInfo &other) const
+{
+    if (comparable == other.comparable) {
+        return text < other.text;
+    } else {
+        return comparable < other.comparable;
+    }
+}
+
 #endif
index fadd2b334681832f0843d602d6d721b398f66e00..7454ed0b947f2979483d052da5a7a4a122c1ae08 100644 (file)
@@ -308,7 +308,7 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
     groupByActionMenu->setPopupMode(QToolButton::InstantPopup);
 
     const auto groupByActionGroupActions = groupByActionGroup->actions();
-    for (const QAction *action : groupByActionGroupActions) {
+    for (QAction *action : groupByActionGroupActions) {
         groupByActionMenu->addAction(action);
     }