From ad6ccf2b86b3e97138d13518bd6ea8fd670d3530 Mon Sep 17 00:00:00 2001 From: Nathan Williams Date: Thu, 11 Sep 2025 02:28:16 +0000 Subject: dolphinview: add preferred sort order for roles BUG: 425457 This commit ensures that both the menu and column headers in table view will have the same default sorting (ascending/descending) for each role. It also saves the user's preferences for each role throughout the session. Previously, sorting by "Modified" would always sort by "Oldest First." If the user then changed to "Newest First" and sorted again by "Name," files would be sorted in reverse alphabetical order (Z-A). Now, sorting by "Modified" defaults to "Newest First." If a user switches between multiple roles, the default for each role will be used unless the user changes to a non-default sort order. In that case, the user's preference will be applied. Defaults: **Descending Order:** Time-based roles - modificationtime - creationtime - accesstime - deletiontime - imageDateTime - releaseYear Size/dimension roles - size - width - height - pageCount - wordCount - lineCount Quality/Quantity roles - rating - duration - bitrate - frameRate **Ascending order:** - Text based roles (A-Z) - All other roles --- src/kitemviews/private/kitemlistheaderwidget.cpp | 10 +---- src/views/dolphinview.cpp | 56 ++++++++++++++++++++++++ src/views/dolphinview.h | 22 ++++++++++ src/views/dolphinviewactionhandler.cpp | 8 ++-- 4 files changed, 85 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/kitemviews/private/kitemlistheaderwidget.cpp b/src/kitemviews/private/kitemlistheaderwidget.cpp index 378dd1d5d..08afdc5cf 100644 --- a/src/kitemviews/private/kitemlistheaderwidget.cpp +++ b/src/kitemviews/private/kitemlistheaderwidget.cpp @@ -261,17 +261,11 @@ void KItemListHeaderWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) m_model->setSortOrder(current); Q_EMIT sortOrderChanged(current, previous); } else { - // Change the sort role and reset to the ascending order + // Change the sort role and use the appropriate default sort order const QByteArray previous = m_model->sortRole(); const QByteArray current = m_columns[m_pressedRoleIndex]; - const bool resetSortOrder = m_model->sortOrder() == Qt::DescendingOrder; - m_model->setSortRole(current, !resetSortOrder); + m_model->setSortRole(current, true); Q_EMIT sortRoleChanged(current, previous); - - if (resetSortOrder) { - m_model->setSortOrder(Qt::AscendingOrder); - Q_EMIT sortOrderChanged(Qt::AscendingOrder, Qt::DescendingOrder); - } } } diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 6bd2ad0c1..d147a87f6 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -487,6 +487,13 @@ void DolphinView::setSortRole(const QByteArray &role) ViewProperties props(viewPropertiesUrl()); props.setSortRole(role); + const Qt::SortOrder preferredOrder = preferredSortOrder(role); + if (sortOrder() != preferredOrder) { + props.setSortOrder(preferredOrder); + KItemModelBase *model = m_container->controller()->model(); + model->setSortOrder(preferredOrder); + } + KItemModelBase *model = m_container->controller()->model(); model->setSortRole(role); @@ -1734,6 +1741,31 @@ QUrl DolphinView::openItemAsFolderUrl(const KFileItem &item, const bool browseTh return QUrl(); } +Qt::SortOrder DolphinView::defaultSortOrderForRole(const QByteArray &role) +{ + static const QSet descendingRoles = {// Time-based roles + "modificationtime", + "creationtime", + "accesstime", + "deletiontime", + "imageDateTime", + "releaseYear", + // Size/dimension roles + "size", + "width", + "height", + "pageCount", + "wordCount", + "lineCount", + // Quality/Quantity roles + "rating", + "duration", + "bitrate", + "frameRate"}; + + return descendingRoles.contains(role) ? Qt::DescendingOrder : Qt::AscendingOrder; +} + void DolphinView::resetZoomLevel() { ViewModeSettings settings{m_mode}; @@ -1984,6 +2016,9 @@ void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOr Q_UNUSED(previous) Q_ASSERT(m_model->sortOrder() == current); + const QByteArray currentRole = m_model->sortRole(); + m_rolesSortOrder[currentRole] = current; + ViewProperties props(viewPropertiesUrl()); props.setSortOrder(current); @@ -1998,6 +2033,13 @@ void DolphinView::slotSortRoleChangedByHeader(const QByteArray ¤t, const Q ViewProperties props(viewPropertiesUrl()); props.setSortRole(current); + const Qt::SortOrder preferredOrder = preferredSortOrder(current); + if (m_model->sortOrder() != preferredOrder) { + props.setSortOrder(preferredOrder); + m_model->setSortOrder(preferredOrder); + Q_EMIT sortOrderChanged(preferredOrder); + } + Q_EMIT sortRoleChanged(current); } @@ -2561,4 +2603,18 @@ bool DolphinView::tryShowNameToolTip(QHelpEvent *event) return false; } +Qt::SortOrder DolphinView::preferredSortOrder(const QByteArray &role) const +{ + if (m_rolesSortOrder.contains(role)) { + return m_rolesSortOrder.value(role); + } else { + return defaultSortOrderForRole(role); + } +} + +void DolphinView::setPreferredSortOrder(const QByteArray &role, Qt::SortOrder order) +{ + m_rolesSortOrder[role] = order; +} + #include "moc_dolphinview.cpp" diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index f491b6dd5..7c077d292 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -233,6 +233,18 @@ public: /** Returns the additional information which should be shown for the items. */ QList visibleRoles() const; + /** + * Returns the preferred sort order for a given role, taking into account + * user preferences and default sort orders. + */ + Qt::SortOrder preferredSortOrder(const QByteArray &role) const; + + /** + * Sets the preferred sort order for a given role. This remembers user + * preferences when switching between different sort roles. + */ + void setPreferredSortOrder(const QByteArray &role, Qt::SortOrder order); + /** * Refreshes the view to get synchronized with the settings (e.g. icons size, * font, ...). @@ -336,6 +348,13 @@ public: */ static QUrl openItemAsFolderUrl(const KFileItem &item, const bool browseThroughArchives = true); + /** + * Set the default order for a given sort role. + * Time-based roles, size/dimension roles, and quality/quantity roles + * default to descending order. All other roles default to ascending order. + */ + static Qt::SortOrder defaultSortOrderForRole(const QByteArray &role); + /** * Hides tooltip displayed over element. */ @@ -988,6 +1007,9 @@ private: /// Used for selection mode. @see setSelectionMode() std::unique_ptr m_proxyStyle; + /// Hash table of user-preferred sort orders for each role + QHash m_rolesSortOrder; + // For unit tests friend class TestBase; friend class DolphinDetailsViewTest; diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index e504fd831..de3facd14 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -594,6 +594,8 @@ void DolphinViewActionHandler::slotSortOrderChanged(Qt::SortOrder order) const bool sortDescending = (order == Qt::DescendingOrder); descending->setChecked(sortDescending); ascending->setChecked(!sortDescending); + const QByteArray currentRole = m_currentView->sortRole(); + m_currentView->setPreferredSortOrder(currentRole, order); } void DolphinViewActionHandler::slotSortFoldersFirstChanged(bool foldersFirst) @@ -723,13 +725,13 @@ void DolphinViewActionHandler::slotSortRoleChanged(const QByteArray &role) if (role == "text" || role == "type" || role == "extension" || role == "tags" || role == "comment") { descending->setText(i18nc("Sort descending", "Z-A")); ascending->setText(i18nc("Sort ascending", "A-Z")); - } else if (role == "size") { + } else if (role == "size" || role == "width" || role == "height" || role == "pageCount" || role == "wordCount" || role == "lineCount") { descending->setText(i18nc("Sort descending", "Largest First")); ascending->setText(i18nc("Sort ascending", "Smallest First")); - } else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") { + } else if (role == "modificationtime" || role == "creationtime" || role == "accesstime" || role == "imageDateTime" || role == "releaseYear") { descending->setText(i18nc("Sort descending", "Newest First")); ascending->setText(i18nc("Sort ascending", "Oldest First")); - } else if (role == "rating") { + } else if (role == "rating" || role == "bitrate" || role == "frameRate") { descending->setText(i18nc("Sort descending", "Highest First")); ascending->setText(i18nc("Sort ascending", "Lowest First")); } else { -- cgit v1.3