From 1e4b2daedb7ca56cecb187f40a8c4a4e3fb43b94 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 19 Oct 2021 14:39:32 -0700 Subject: [PATCH] GameList: Fix duplicate selections with ctrl+a in grid view Make grid view use selectedRow() instead of selectedIndexes() to ensure one selection per game. --- Source/Core/DolphinQt/GameList/GameList.cpp | 58 +++++++++++---------- Source/Core/DolphinQt/GameList/GameList.h | 3 ++ 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index cd6ea5e2b2..d74088afce 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -286,6 +286,16 @@ void GameList::MakeGridView() m_grid = new QListView(this); m_grid->setModel(m_grid_proxy); m_grid->setSelectionMode(QAbstractItemView::ExtendedSelection); + + // Row in this context refers to the full set of columns (banner, title, region, etc.) associated + // with a single game rather than multiple games presented visually on the same row. Even though + // most of these elements are hidden in grid view selecting all of them allows us to use + // selectedRow() which only returns rows where all elements are selected. In addition to improving + // consistency with list view this avoids an edge case where clicking a game in grid mode selected + // only the first element of the row but ctrl+a selected every element of the row, making a bunch + // of duplicate selections for each game. + m_grid->setSelectionBehavior(QAbstractItemView::SelectRows); + m_grid->setViewMode(QListView::IconMode); m_grid->setResizeMode(QListView::Adjust); m_grid->setUniformItemSizes(true); @@ -790,23 +800,30 @@ void GameList::ChangeDisc() Core::RunAsCPUThread([file_path = game->GetFilePath()] { DVDInterface::ChangeDisc(file_path); }); } -std::shared_ptr GameList::GetSelectedGame() const +QAbstractItemView* GameList::GetActiveView() const { - QAbstractItemView* view; - QSortFilterProxyModel* proxy; if (currentWidget() == m_list) { - view = m_list; - proxy = m_list_proxy; + return m_list; } - else + return m_grid; +} + +QSortFilterProxyModel* GameList::GetActiveProxyModel() const +{ + if (currentWidget() == m_list) { - view = m_grid; - proxy = m_grid_proxy; + return m_list_proxy; } - QItemSelectionModel* sel_model = view->selectionModel(); + return m_grid_proxy; +} + +std::shared_ptr GameList::GetSelectedGame() const +{ + QItemSelectionModel* const sel_model = GetActiveView()->selectionModel(); if (sel_model->hasSelection()) { + QSortFilterProxyModel* const proxy = GetActiveProxyModel(); QModelIndex model_index = proxy->mapToSource(sel_model->selectedIndexes()[0]); return m_model.GetGameFile(model_index.row()); } @@ -815,27 +832,15 @@ std::shared_ptr GameList::GetSelectedGame() const QList> GameList::GetSelectedGames() const { - QAbstractItemView* view; - QSortFilterProxyModel* proxy; - if (currentWidget() == m_list) - { - view = m_list; - proxy = m_list_proxy; - } - else - { - view = m_grid; - proxy = m_grid_proxy; - } QList> selected_list; - QItemSelectionModel* sel_model = view->selectionModel(); + QItemSelectionModel* const sel_model = GetActiveView()->selectionModel(); + if (sel_model->hasSelection()) { - QModelIndexList index_list = - currentWidget() == m_list ? sel_model->selectedRows() : sel_model->selectedIndexes(); + const QModelIndexList index_list = sel_model->selectedRows(); for (const auto& index : index_list) { - QModelIndex model_index = proxy->mapToSource(index); + const QModelIndex model_index = GetActiveProxyModel()->mapToSource(index); selected_list.push_back(m_model.GetGameFile(model_index.row())); } } @@ -844,8 +849,7 @@ QList> GameList::GetSelectedGames() co bool GameList::HasMultipleSelected() const { - return currentWidget() == m_list ? m_list->selectionModel()->selectedRows().size() > 1 : - m_grid->selectionModel()->selectedIndexes().size() > 1; + return GetActiveView()->selectionModel()->selectedRows().size() > 1; } std::shared_ptr GameList::FindGame(const std::string& path) const diff --git a/Source/Core/DolphinQt/GameList/GameList.h b/Source/Core/DolphinQt/GameList/GameList.h index 4c96464cf8..5bdbebe339 100644 --- a/Source/Core/DolphinQt/GameList/GameList.h +++ b/Source/Core/DolphinQt/GameList/GameList.h @@ -9,6 +9,7 @@ #include "DolphinQt/GameList/GameListModel.h" +class QAbstractItemView; class QLabel; class QListView; class QSortFilterProxyModel; @@ -87,6 +88,8 @@ private: void MakeEmptyView(); // We only have two views, just use a bool to distinguish. void SetPreferredView(bool list); + QAbstractItemView* GetActiveView() const; + QSortFilterProxyModel* GetActiveProxyModel() const; void ConsiderViewChange(); void UpdateFont();