// #define KFILEITEMMODEL_DEBUG
KFileItemModel::KFileItemModel(QObject *parent)
- : KItemModelBase("text", parent)
+ : KItemModelBase("text", "text", parent)
, m_dirLister(nullptr)
, m_sortDirsFirst(true)
, m_sortHiddenLast(false)
QElapsedTimer timer;
timer.start();
#endif
- switch (typeForRole(sortRole())) {
+ switch (typeForRole(groupRole())) {
+ case NoRole:
+ m_groups.clear();
+ break;
case NameRole:
m_groups = nameRoleGroups();
break;
m_groups = ratingRoleGroups();
break;
default:
- m_groups = genericStringRoleGroups(sortRole());
+ m_groups = genericStringRoleGroups(groupRole());
break;
}
}
}
+KFileItemModel::RoleInfo KFileItemModel::roleInformation(const QByteArray &role)
+{
+ static QHash<QByteArray, RoleInfo> information;
+ if (information.isEmpty()) {
+ int count = 0;
+ const RoleInfoMap *map = rolesInfoMap(count);
+ for (int i = 0; i < count; ++i) {
+ RoleInfo info;
+ info.role = map[i].role;
+ info.translation = map[i].roleTranslation.toString();
+ if (!map[i].groupTranslation.isEmpty()) {
+ info.group = map[i].groupTranslation.toString();
+ } else {
+ // For top level roles, groupTranslation is 0. We must make sure that
+ // info.group is an empty string then because the code that generates
+ // menus tries to put the actions into sub menus otherwise.
+ info.group = QString();
+ }
+ info.requiresBaloo = map[i].requiresBaloo;
+ info.requiresIndexer = map[i].requiresIndexer;
+ if (!map[i].tooltipTranslation.isEmpty()) {
+ info.tooltip = map[i].tooltipTranslation.toString();
+ } else {
+ info.tooltip = QString();
+ }
+
+ information.insert(map[i].role, info);
+ }
+ }
+
+ return information.value(role);
+}
+
QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation()
{
static QList<RoleInfo> rolesInfo;
const RoleInfoMap *map = rolesInfoMap(count);
for (int i = 0; i < count; ++i) {
if (map[i].roleType != NoRole) {
- RoleInfo info;
- info.role = map[i].role;
- info.translation = map[i].roleTranslation.toString();
- if (!map[i].groupTranslation.isEmpty()) {
- info.group = map[i].groupTranslation.toString();
- } else {
- // For top level roles, groupTranslation is 0. We must make sure that
- // info.group is an empty string then because the code that generates
- // menus tries to put the actions into sub menus otherwise.
- info.group = QString();
- }
- info.requiresBaloo = map[i].requiresBaloo;
- info.requiresIndexer = map[i].requiresIndexer;
- if (!map[i].tooltipTranslation.isEmpty()) {
- info.tooltip = map[i].tooltipTranslation.toString();
- } else {
- info.tooltip = QString();
- }
+ RoleInfo info = roleInformation(map[i].role);
rolesInfo.append(info);
}
}
}
}
-void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
+void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous, bool resortItems)
{
Q_UNUSED(current)
Q_UNUSED(previous)
- resortAllItems();
+
+ if (resortItems) {
+ resortAllItems();
+ }
+}
+
+void KFileItemModel::onGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems)
+{
+ Q_UNUSED(previous)
+ m_groupRole = typeForRole(current);
+
+ if (!m_requestRole[m_sortRole]) {
+ QSet<QByteArray> newRoles = m_roles;
+ newRoles << current;
+ setRoles(newRoles);
+ }
+
+ if (resortItems) {
+ resortAllItems();
+ }
+}
+
+void KFileItemModel::onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous, bool resortItems)
+{
+ Q_UNUSED(current)
+ Q_UNUSED(previous)
+
+ if (resortItems) {
+ resortAllItems();
+ }
}
void KFileItemModel::loadSortingSettings()
m_items.clear();
m_items.reserve(itemCount);
- // Resort the items
- sort(m_itemData.begin(), m_itemData.end());
+ const QList<QPair<int, QVariant>> oldGroups = m_groups;
+
+ if (groupedSorting() && m_groupRole) {
+ // Hacky way to implement grouped sorting without rewriting more code.
+ // 1. Sort all items by grouping criteria. "Folders first" priority to be ignored.
+ // 2. Generate groups, which will stay usable after in-group sorting.
+ // 3. Perform sorts by the original sorting criteria inside groups.
+
+ RoleType originalSortRole = m_sortRole;
+ Qt::SortOrder originalSortOrder = sortOrder();
+ bool originalSortDirsFirst = m_sortDirsFirst;
+ m_sortRole = m_groupRole;
+ setSortOrder(groupOrder(), false);
+ m_sortDirsFirst = false;
+
+ sort(m_itemData.begin(), m_itemData.end());
+ m_groups.clear();
+ groups();
+
+ m_sortRole = originalSortRole;
+ setSortOrder(originalSortOrder, false);
+ m_sortDirsFirst = originalSortDirsFirst;
+
+ int lastIndex = 0, newIndex = 0;
+ for (int i = 0; i < m_groups.count() - 1; ++i) {
+ qCritical() << m_groups[i];
+ fflush(stderr);
+ newIndex = m_groups[i + 1].first;
+ sort(m_itemData.begin() + lastIndex, m_itemData.begin() + newIndex);
+ lastIndex = newIndex;
+ }
+ } else {
+ if (!m_groups.isEmpty()) {
+ m_groups.clear();
+ }
+ sort(m_itemData.begin(), m_itemData.end());
+ }
+
for (int i = 0; i < itemCount; ++i) {
m_items.insert(m_itemData.at(i)->item.url(), i);
}
Q_EMIT itemsMoved(KItemRange(firstMovedIndex, movedItemsCount), movedToIndexes);
} else if (groupedSorting()) {
- // The groups might have changed even if the order of the items has not.
- const QList<QPair<int, QVariant>> oldGroups = m_groups;
- m_groups.clear();
- if (groups() != oldGroups) {
+ if (m_groups != oldGroups) {
Q_EMIT groupsChanged();
}
}
-#ifdef KFILEITEMMODEL_DEBUG
+#ifdef KFILEITEMMODEL_DEBUGf
qCDebug(DolphinDebug) << "[TIME] Resorting of" << itemCount << "items:" << timer.elapsed();
#endif
}
std::reverse(itemRanges.begin(), itemRanges.end());
}
+ // N
+ //resortAllItems();
// The indexes in m_items are not correct anymore. Therefore, we clear m_items.
// It will be re-populated with the updated indices if index(const QUrl&) is called.
m_items.clear();
static const RoleInfoMap rolesInfoMap[] = {
// clang-format off
// | role | roleType | role translation | group translation | requires Baloo | requires indexer
- { nullptr, NoRole, KLazyLocalizedString(), KLazyLocalizedString(), KLazyLocalizedString(), false, false },
+ { nullptr, NoRole, kli18nc("@label", "None"), KLazyLocalizedString(), KLazyLocalizedString(), false, false },
{ "text", NameRole, kli18nc("@label", "Name"), KLazyLocalizedString(), KLazyLocalizedString(), false, false },
{ "size", SizeRole, kli18nc("@label", "Size"), KLazyLocalizedString(), KLazyLocalizedString(), false, false },
{ "modificationtime", ModificationTimeRole, kli18nc("@label", "Modified"), KLazyLocalizedString(), kli18nc("@tooltip", "The date format can be selected in settings."), false, false },