From b776f98df8200e9ae05b1d00515a5a6d6ce16bdd Mon Sep 17 00:00:00 2001 From: jagannatharjun Date: Thu, 18 Feb 2021 14:32:36 +0530 Subject: [PATCH] Support sub-sorting in Transferlist --- src/gui/transferlistsortmodel.cpp | 59 ++++++++++++++++++++++--------- src/gui/transferlistsortmodel.h | 4 +++ 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp index e38f0f992..2e804887c 100644 --- a/src/gui/transferlistsortmodel.cpp +++ b/src/gui/transferlistsortmodel.cpp @@ -40,7 +40,15 @@ namespace { template - bool customLessThan(const T left, const T right) + int threeWayCompare(const T &left, const T &right) + { + if (left == right) + return 0; + return (left < right) ? -1 : 1; + } + + template + int customCompare(const T left, const T right) { static_assert(std::is_arithmetic_v); @@ -48,8 +56,10 @@ namespace const bool isRightValid = (right >= 0); if (isLeftValid && isRightValid) - return left < right; - return isLeftValid; + return threeWayCompare(left, right); + if (!isLeftValid && !isRightValid) + return 0; + return isLeftValid ? -1 : 1; } } @@ -101,22 +111,20 @@ void TransferListSortModel::disableTrackerFilter() invalidateFilter(); } -bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &right) const { - Q_ASSERT(left.column() == right.column()); - - const int sortColumn = left.column(); + const int compareColumn = left.column(); const QVariant leftValue = left.data(TransferListModel::UnderlyingDataRole); const QVariant rightValue = right.data(TransferListModel::UnderlyingDataRole); - switch (sortColumn) + switch (compareColumn) { case TransferListModel::TR_CATEGORY: case TransferListModel::TR_NAME: case TransferListModel::TR_SAVE_PATH: case TransferListModel::TR_TAGS: case TransferListModel::TR_TRACKER: - return Utils::String::naturalCompare(leftValue.toString(), rightValue.toString(), Qt::CaseInsensitive) < 0; + return Utils::String::naturalCompare(leftValue.toString(), rightValue.toString(), Qt::CaseInsensitive); case TransferListModel::TR_AMOUNT_DOWNLOADED: case TransferListModel::TR_AMOUNT_DOWNLOADED_SESSION: @@ -129,28 +137,28 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex case TransferListModel::TR_SIZE: case TransferListModel::TR_TIME_ELAPSED: case TransferListModel::TR_TOTAL_SIZE: - return customLessThan(leftValue.toLongLong(), rightValue.toLongLong()); + return customCompare(leftValue.toLongLong(), rightValue.toLongLong()); case TransferListModel::TR_AVAILABILITY: case TransferListModel::TR_PROGRESS: case TransferListModel::TR_RATIO: case TransferListModel::TR_RATIO_LIMIT: - return customLessThan(leftValue.toReal(), rightValue.toReal()); + return customCompare(leftValue.toReal(), rightValue.toReal()); case TransferListModel::TR_STATUS: - return leftValue.value() < rightValue.value(); + return threeWayCompare(leftValue.toInt(), rightValue.toInt()); case TransferListModel::TR_ADD_DATE: case TransferListModel::TR_SEED_DATE: case TransferListModel::TR_SEEN_COMPLETE_DATE: - return leftValue.toDateTime() < rightValue.toDateTime(); + return threeWayCompare(leftValue.toDateTime(), rightValue.toDateTime()); case TransferListModel::TR_DLLIMIT: case TransferListModel::TR_DLSPEED: case TransferListModel::TR_QUEUE_POSITION: case TransferListModel::TR_UPLIMIT: case TransferListModel::TR_UPSPEED: - return customLessThan(leftValue.toInt(), rightValue.toInt()); + return customCompare(leftValue.toInt(), rightValue.toInt()); case TransferListModel::TR_PEERS: case TransferListModel::TR_SEEDS: @@ -159,11 +167,11 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex const auto activeL = leftValue.toInt(); const auto activeR = rightValue.toInt(); if (activeL != activeR) - return activeL < activeR; + return threeWayCompare(activeL, activeR); const auto totalL = left.data(TransferListModel::AdditionalUnderlyingDataRole).toInt(); const auto totalR = right.data(TransferListModel::AdditionalUnderlyingDataRole).toInt(); - return totalL < totalR; + return threeWayCompare(totalL, totalR); } default: @@ -171,7 +179,24 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex break; } - return false; + return 0; +} + +bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + Q_ASSERT(left.column() == right.column()); + + if (m_sortColumn != left.column()) + { + m_subSortColumn = m_sortColumn; + m_sortColumn = left.column(); + } + + const int result = compare(left, right); + if ((result == 0) && (m_subSortColumn != -1)) + return compare(left.sibling(left.row(), m_subSortColumn), right.sibling(right.row(), m_subSortColumn)) < 0; + + return result < 0; } bool TransferListSortModel::filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const diff --git a/src/gui/transferlistsortmodel.h b/src/gui/transferlistsortmodel.h index fef2aba83..95df8426a 100644 --- a/src/gui/transferlistsortmodel.h +++ b/src/gui/transferlistsortmodel.h @@ -53,9 +53,13 @@ public: void disableTrackerFilter(); private: + int compare(const QModelIndex &left, const QModelIndex &right) const; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool matchFilter(int sourceRow, const QModelIndex &sourceParent) const; TorrentFilter m_filter; + mutable int m_subSortColumn = -1; + mutable int m_sortColumn = -1; };