From 2611e6445904b7b7767c4cfe182b7fc26624cffe Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 8 Jan 2020 15:01:04 +1000 Subject: [PATCH] Qt: Implement game list sorting --- src/duckstation-qt/gamelistwidget.cpp | 72 ++++++++++++++++++++++++++- src/duckstation-qt/gamelistwidget.h | 2 + 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/duckstation-qt/gamelistwidget.cpp b/src/duckstation-qt/gamelistwidget.cpp index 28ea7f7ab..9dfed3bb5 100644 --- a/src/duckstation-qt/gamelistwidget.cpp +++ b/src/duckstation-qt/gamelistwidget.cpp @@ -2,10 +2,11 @@ #include "core/settings.h" #include "qthostinterface.h" #include "qtutils.h" +#include #include #include -class GameListModel : public QAbstractTableModel +class GameListModel final : public QAbstractTableModel { public: enum Column : int @@ -73,6 +74,30 @@ public: } } + case Qt::InitialSortOrderRole: + { + switch (index.column()) + { + case Column_Type: + return static_cast(ge.type); + + case Column_Code: + return QString::fromStdString(ge.code); + + case Column_Title: + return QString::fromStdString(ge.title); + + case Column_Region: + return static_cast(ge.region); + + case Column_Size: + return ge.total_size; + + default: + return {}; + } + } + case Qt::DecorationRole: { switch (index.column()) @@ -153,6 +178,19 @@ public: endInsertRows(); } + bool titlesLessThan(int left_row, int right_row, bool ascending) const + { + if (left_row < 0 || left_row >= static_cast(m_game_list->GetEntryCount()) || right_row < 0 || + right_row >= static_cast(m_game_list->GetEntryCount())) + { + return false; + } + + const GameList::GameListEntry& left = m_game_list->GetEntries().at(left_row); + const GameList::GameListEntry& right = m_game_list->GetEntries().at(right_row); + return ascending ? (left.title < right.title) : (right.title < left.title); + } + private: void loadCommonImages() { @@ -176,6 +214,33 @@ private: QPixmap m_region_us_pixmap; }; +class GameListSortModel final : public QSortFilterProxyModel +{ +public: + GameListSortModel(GameListModel* parent) : QSortFilterProxyModel(parent), m_model(parent) {} + + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override + { + // TODO: Search + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } + + bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override + { + const bool ascending = sortOrder() == Qt::AscendingOrder; + const QVariant left = source_left.data(Qt::InitialSortOrderRole); + const QVariant right = source_right.data(Qt::InitialSortOrderRole); + if (left != right) + return ascending ? (left < right) : (right < left); + + // fallback to sorting by title for equal items + return m_model->titlesLessThan(source_left.row(), source_right.row(), ascending); + } + +private: + GameListModel* m_model; +}; + GameListWidget::GameListWidget(QWidget* parent /* = nullptr */) : QStackedWidget(parent) {} GameListWidget::~GameListWidget() = default; @@ -188,8 +253,11 @@ void GameListWidget::initialize(QtHostInterface* host_interface) connect(m_host_interface, &QtHostInterface::gameListRefreshed, this, &GameListWidget::onGameListRefreshed); m_table_model = new GameListModel(m_game_list, this); + m_table_sort_model = new GameListSortModel(m_table_model); + m_table_sort_model->setSourceModel(m_table_model); m_table_view = new QTableView(this); - m_table_view->setModel(m_table_model); + m_table_view->setModel(m_table_sort_model); + m_table_view->setSortingEnabled(true); m_table_view->setSelectionMode(QAbstractItemView::SingleSelection); m_table_view->setSelectionBehavior(QAbstractItemView::SelectRows); m_table_view->setAlternatingRowColors(true); diff --git a/src/duckstation-qt/gamelistwidget.h b/src/duckstation-qt/gamelistwidget.h index 864643a44..ebe9ec720 100644 --- a/src/duckstation-qt/gamelistwidget.h +++ b/src/duckstation-qt/gamelistwidget.h @@ -4,6 +4,7 @@ #include class GameListModel; +class GameListSortModel; class QtHostInterface; @@ -32,5 +33,6 @@ private: GameList* m_game_list = nullptr; GameListModel* m_table_model = nullptr; + GameListSortModel* m_table_sort_model = nullptr; QTableView* m_table_view = nullptr; };