GameList: Fix duplicate selections with ctrl+a in grid view

Make grid view use selectedRow() instead of selectedIndexes() to ensure
one selection per game.
This commit is contained in:
Dentomologist 2021-10-19 14:39:32 -07:00
parent 13985b774e
commit 1e4b2daedb
2 changed files with 34 additions and 27 deletions

View File

@ -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<const UICommon::GameFile> 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<const UICommon::GameFile> 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<const UICommon::GameFile> GameList::GetSelectedGame() const
QList<std::shared_ptr<const UICommon::GameFile>> 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<std::shared_ptr<const UICommon::GameFile>> 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<std::shared_ptr<const UICommon::GameFile>> 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<const UICommon::GameFile> GameList::FindGame(const std::string& path) const

View File

@ -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();