1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-06-30 15:36:30 +00:00

Implemented ItemGroupInfo in place of QVariant in roleRoleGroup functions

This commit is contained in:
Zakhar Afonin 2024-06-16 13:02:24 +03:00
parent 3e4392bed8
commit 38d293ae41
3 changed files with 283 additions and 279 deletions

View 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) {
result = -1;
} else if (groupA > groupB) {
result = 1;
}
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 groupA = getGenericStringRoleGroup(groupRole(), a);
QString groupB = getGenericStringRoleGroup(groupRole(), b);
QString strGroupA = genericStringRoleGroup(groupRole(), a);
QString strGroupB = genericStringRoleGroup(groupRole(), b);
if (strGroupA < strGroupB) {
result = -1;
} else if (strGroupA > strGroupB) {
result = 1;
}
break;
}
}
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;
// 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();
}
static ItemGroupInfo oldGroupInfo, groupInfo;
static QChar oldFirstChar, firstChar;
if (newFirstChar.isLetter()) {
if (m_collator.compare(newFirstChar, QChar(QLatin1Char('A'))) >= 0 && m_collator.compare(newFirstChar, QChar(QLatin1Char('Z'))) <= 0) {
const QString name = itemData->item.text();
// Use the first character of the name as group indication
firstChar = name.at(0).toUpper();
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
{
const KFileItem item = itemData->item;
static ItemGroupInfo oldGroupInfo, groupInfo;
static KIO::filesize_t oldFileSize, fileSize;
KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
int newGroupValue = -1; // None
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) {
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;
int intGroupInfo;
QString strGroupInfo;
if (!asString) {
// Simplified grouping algorithm, preserving dates
// but not taking "pretty printing" into account
if (currentDate.year() == fileDate.year() && currentDate.month() == fileDate.month()) {
// 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;
ItemGroupInfo newGroupInfo = timeRoleGroup(fileTimeCb, m_itemData.at(i));
QString newGroupValue = getTimeRoleGroup(fileTimeCb, m_itemData.at(i)).toString();
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;
}

View 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

View 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);
}