diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 1ab9cd0e41..5620460591 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -2366,16 +2366,18 @@ int KFileItemModel::groupRoleCompare(const ItemData *a, const ItemData *b, const false) .comparable; break; - // case PermissionsRole: - // case RatingRole: + case PermissionsRole: + groupA = permissionRoleGroup(a, false).comparable; + groupB = permissionRoleGroup(b, false).comparable; + break; + case RatingRole: + groupA = ratingRoleGroup(a, false).comparable; + groupB = ratingRoleGroup(b, false).comparable; + break; default: { QString strGroupA = genericStringRoleGroup(groupRole(), a); QString strGroupB = genericStringRoleGroup(groupRole(), b); - if (strGroupA < strGroupB) { - result = -1; - } else if (strGroupA > strGroupB) { - result = 1; - } + result = stringCompare(strGroupA, strGroupB, collator); break; } } @@ -2410,8 +2412,10 @@ int KFileItemModel::stringCompare(const QString &a, const QString &b, const QCol KFileItemModel::ItemGroupInfo KFileItemModel::nameRoleGroup(const ItemData *itemData, bool withString) const { - static ItemGroupInfo oldGroupInfo, groupInfo; - static QChar oldFirstChar, firstChar; + static ItemGroupInfo oldGroupInfo; + static QChar oldFirstChar; + ItemGroupInfo groupInfo; + QChar firstChar; const QString name = itemData->item.text(); @@ -2480,15 +2484,14 @@ KFileItemModel::ItemGroupInfo KFileItemModel::nameRoleGroup(const ItemData *item KFileItemModel::ItemGroupInfo KFileItemModel::sizeRoleGroup(const ItemData *itemData, bool withString) const { - static ItemGroupInfo oldGroupInfo, groupInfo; - static KIO::filesize_t oldFileSize, fileSize; + static ItemGroupInfo oldGroupInfo; + static KIO::filesize_t oldFileSize; + ItemGroupInfo groupInfo; + KIO::filesize_t fileSize; const KFileItem item = itemData->item; fileSize = !item.isNull() ? item.size() : ~0U; - // 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) { @@ -2498,7 +2501,7 @@ KFileItemModel::ItemGroupInfo KFileItemModel::sizeRoleGroup(const ItemData *item } } if (fileSize == oldFileSize) { - groupInfo = oldGroupInfo; + return oldGroupInfo; } if (groupInfo.comparable < 0) { if (fileSize < 5 * 1024 * 1024) { // < 5 MB @@ -2522,17 +2525,15 @@ KFileItemModel::ItemGroupInfo KFileItemModel::sizeRoleGroup(const ItemData *item KFileItemModel::ItemGroupInfo KFileItemModel::timeRoleGroup(const std::function &fileTimeCb, const ItemData *itemData, bool withString) const { - static ItemGroupInfo oldGroupInfo, groupInfo; + static ItemGroupInfo oldGroupInfo; static QDate oldFileDate; + ItemGroupInfo groupInfo; const QDate currentDate = QDate::currentDate(); const QDateTime fileTime = fileTimeCb(itemData); const QDate fileDate = fileTime.date(); const int daysDistance = fileDate.daysTo(currentDate); - 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()) { @@ -2553,13 +2554,13 @@ KFileItemModel::timeRoleGroup(const std::function & if (daysDistance < 7) { groupInfo.comparable = daysDistance; // Today, Yesterday and week days (Month, Year) } else if (daysDistance < 14) { - groupInfo.comparable = 9; // One Week Ago (Month, Year) + groupInfo.comparable = 11; // One Week Ago (Month, Year) } else if (daysDistance < 21) { - groupInfo.comparable = 19; // Two Weeks Ago (Month, Year) + groupInfo.comparable = 21; // Two Weeks Ago (Month, Year) } else if (daysDistance < 28) { - groupInfo.comparable = 29; // Three Weeks Ago (Month, Year) + groupInfo.comparable = 31; // Three Weeks Ago (Month, Year) } else { - groupInfo.comparable = 39; // Earlier on Month, Year + groupInfo.comparable = 41; // Earlier on Month, Year } } else { // The trick will fail for dates past April, 178956967 or before 1 AD. @@ -2626,7 +2627,7 @@ KFileItemModel::timeRoleGroup(const std::function & const QString untranslatedFormat = format.toString({QLatin1String("en_US")}); groupInfo.text = fileTime.toString(untranslatedFormat); } - } else if (daysDistance <= 7) { + } else if (daysDistance < 7) { groupInfo.text = fileTime.toString(i18nc("@title:group Date: " "The week day name: dddd, MMMM is full month name " @@ -2637,7 +2638,7 @@ KFileItemModel::timeRoleGroup(const std::function & "\"dddd (MMMM, yyyy)\" with context @title:group Date", "%1", groupInfo.text); - } else if (daysDistance <= 7 * 2) { + } else if (daysDistance < 7 * 2) { const KLocalizedString format = ki18nc( "@title:group Date: " "MMMM is full month name in current locale, and yyyy is " @@ -2658,7 +2659,7 @@ KFileItemModel::timeRoleGroup(const std::function & const QString untranslatedFormat = format.toString({QLatin1String("en_US")}); groupInfo.text = fileTime.toString(untranslatedFormat); } - } else if (daysDistance <= 7 * 3) { + } else if (daysDistance < 7 * 3) { const KLocalizedString format = ki18nc( "@title:group Date: " "MMMM is full month name in current locale, and yyyy is " @@ -2679,7 +2680,7 @@ KFileItemModel::timeRoleGroup(const std::function & const QString untranslatedFormat = format.toString({QLatin1String("en_US")}); groupInfo.text = fileTime.toString(untranslatedFormat); } - } else if (daysDistance <= 7 * 4) { + } else if (daysDistance < 7 * 4) { const KLocalizedString format = ki18nc( "@title:group Date: " "MMMM is full month name in current locale, and yyyy is " @@ -2741,6 +2742,77 @@ KFileItemModel::timeRoleGroup(const std::function & return groupInfo; } +KFileItemModel::ItemGroupInfo KFileItemModel::permissionRoleGroup(const ItemData *itemData, bool withString) const +{ + static ItemGroupInfo oldGroupInfo; + static QFileDevice::Permissions oldPermissions; + ItemGroupInfo groupInfo; + + const QFileInfo info(itemData->item.url().toLocalFile()); + const QFileDevice::Permissions permissions = info.permissions(); + if (permissions == oldPermissions) { + return oldGroupInfo; + } + groupInfo.comparable = (int)permissions; + + if (withString) { + // Set user string + QString user; + if (permissions & QFile::ReadUser) { + user = i18nc("@item:intext Access permission, concatenated", "Read, "); + } + if (permissions & QFile::WriteUser) { + user += i18nc("@item:intext Access permission, concatenated", "Write, "); + } + if (permissions & QFile::ExeUser) { + user += i18nc("@item:intext Access permission, concatenated", "Execute, "); + } + user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.length() - 2); + + // Set group string + QString group; + if (permissions & QFile::ReadGroup) { + group = i18nc("@item:intext Access permission, concatenated", "Read, "); + } + if (permissions & QFile::WriteGroup) { + group += i18nc("@item:intext Access permission, concatenated", "Write, "); + } + if (permissions & QFile::ExeGroup) { + group += i18nc("@item:intext Access permission, concatenated", "Execute, "); + } + group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.length() - 2); + + // Set others string + QString others; + if (permissions & QFile::ReadOther) { + others = i18nc("@item:intext Access permission, concatenated", "Read, "); + } + if (permissions & QFile::WriteOther) { + others += i18nc("@item:intext Access permission, concatenated", "Write, "); + } + if (permissions & QFile::ExeOther) { + others += i18nc("@item:intext Access permission, concatenated", "Execute, "); + } + others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.length() - 2); + groupInfo.text = i18nc("@title:group Files and folders by permissions", "User: %1 | Group: %2 | Others: %3", user, group, others); + } + oldPermissions = permissions; + oldGroupInfo = groupInfo; + return groupInfo; +} + +KFileItemModel::ItemGroupInfo KFileItemModel::ratingRoleGroup(const ItemData *itemData, bool withString) const +{ + ItemGroupInfo groupInfo; + groupInfo.comparable = itemData->values.value("rating", 0).toInt(); + if (withString) { + // Dolphin does not currently use string representation of star rating + // as stars are rendered as graphics in group headers. + groupInfo.text = i18nc("@item:intext Rated N (stars)", "Rated ") + QString::number(groupInfo.comparable); + } + return groupInfo; +} + QString KFileItemModel::genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const { return itemData->values.value(role).toString(); @@ -2822,69 +2894,19 @@ QList> KFileItemModel::permissionRoleGroups() const const int maxIndex = count() - 1; QList> groups; - /*QString permissionsString; ItemGroupInfo groupInfo; for (int i = 0; i <= maxIndex; ++i) { if (isChildItem(i)) { continue; } - const ItemData *itemData = m_itemData.at(i); - const QString newPermissionsString = itemData->values.value("permissions").toString(); - if (newPermissionsString == permissionsString) { - continue; - } - permissionsString = newPermissionsString; + ItemGroupInfo newGroupInfo = permissionRoleGroup(m_itemData.at(i)); - const QFileInfo info(itemData->item.url().toLocalFile()); - - // Set user string - QString user; - if (info.permission(QFile::ReadUser)) { - user = i18nc("@item:intext Access permission, concatenated", "Read, "); - } - if (info.permission(QFile::WriteUser)) { - user += i18nc("@item:intext Access permission, concatenated", "Write, "); - } - if (info.permission(QFile::ExeUser)) { - user += i18nc("@item:intext Access permission, concatenated", "Execute, "); - } - user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.length() - 2); - - // Set group string - QString group; - if (info.permission(QFile::ReadGroup)) { - group = i18nc("@item:intext Access permission, concatenated", "Read, "); - } - if (info.permission(QFile::WriteGroup)) { - group += i18nc("@item:intext Access permission, concatenated", "Write, "); - } - if (info.permission(QFile::ExeGroup)) { - group += i18nc("@item:intext Access permission, concatenated", "Execute, "); - } - group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.length() - 2); - - // Set others string - QString others; - if (info.permission(QFile::ReadOther)) { - others = i18nc("@item:intext Access permission, concatenated", "Read, "); - } - if (info.permission(QFile::WriteOther)) { - others += i18nc("@item:intext Access permission, concatenated", "Write, "); - } - if (info.permission(QFile::ExeOther)) { - others += i18nc("@item:intext Access permission, concatenated", "Execute, "); - } - others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.length() - 2); - - 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(i, newGroupInfo)); + groups.append(QPair(i, newGroupInfo.text)); } - }*/ - + } return groups; } @@ -2895,19 +2917,21 @@ QList> KFileItemModel::ratingRoleGroups() const const int maxIndex = count() - 1; QList> groups; - /*ItemGroupInfo groupInfo; + ItemGroupInfo groupInfo; for (int i = 0; i <= maxIndex; ++i) { if (isChildItem(i)) { continue; } - ItemGroupInfo newGroupInfo = nameRoleGroup(fileTimeCb, m_itemData.at(i)).toString(); + ItemGroupInfo newGroupInfo = ratingRoleGroup(m_itemData.at(i)); if (newGroupInfo != groupInfo) { groupInfo = newGroupInfo; - groups.append(QPair(i, newGroupInfo)); + // Using the numeric representation because Dolphin has a special + // case for drawing stars. + groups.append(QPair(i, newGroupInfo.comparable)); } - }*/ + } return groups; } diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 152321f94f..9001e7bd56 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -113,6 +113,8 @@ public: QString roleDescription(const QByteArray &role) const override; + QList> 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 @@ -209,8 +211,6 @@ public: */ static QList rolesInformation(); - QList> groups() const override; - /** set to true to hide application/x-trash files */ void setShowTrashMime(bool show);