1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

Qt: Use pointer to game info instead of index in game list

this should fix differences between model and view
This commit is contained in:
Megamouse 2018-05-02 21:58:03 +02:00 committed by Ivan
parent cafcac9ccd
commit ff2c05da50
5 changed files with 121 additions and 80 deletions

View File

@ -115,7 +115,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
// Events
connect(m_gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
connect(m_gameList, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_gameList, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
connect(m_gameList->horizontalHeader(), &QHeaderView::customContextMenuRequested, [=](const QPoint& pos)
@ -125,30 +125,30 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
configure->exec(mapToGlobal(pos));
});
connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
connect(m_game_compat.get(), &game_compatibility::DownloadStarted, [=]()
{
for (auto& game : m_game_data)
for (const auto& game : m_game_data)
{
game.compat = m_game_compat->GetStatusData("Download");
game->compat = m_game_compat->GetStatusData("Download");
}
Refresh();
});
connect(m_game_compat.get(), &game_compatibility::DownloadFinished, [=]()
{
for (auto& game : m_game_data)
for (const auto& game : m_game_data)
{
game.compat = m_game_compat->GetCompatibility(game.info.serial);
game->compat = m_game_compat->GetCompatibility(game->info.serial);
}
Refresh();
});
connect(m_game_compat.get(), &game_compatibility::DownloadError, [=](const QString& error)
{
for (auto& game : m_game_data)
for (const auto& game : m_game_data)
{
game.compat = m_game_compat->GetCompatibility(game.info.serial);
game->compat = m_game_compat->GetCompatibility(game->info.serial);
}
Refresh();
QMessageBox::warning(this, tr("Warning!"), tr("Failed to retrieve the online compatibility database!\nFalling back to local database.\n\n") + tr(qPrintable(error)));
@ -249,16 +249,19 @@ void game_list_frame::OnColClicked(int col)
}
// Get visibility of entries
bool game_list_frame::IsEntryVisible(const GUI_GameInfo& game)
bool game_list_frame::IsEntryVisible(const game_info& game)
{
auto matches_category = [&]()
{
if (m_isListLayout)
return m_categoryFilters.contains(qstr(game.info.category));
return category::CategoryInMap(game.info.category, category::cat_boot);
{
return m_categoryFilters.contains(qstr(game->info.category));
}
return category::CategoryInMap(game->info.category, category::cat_boot);
};
bool is_visible = m_show_hidden || !m_hidden_list.contains(qstr(game.info.serial));
return is_visible && matches_category() && SearchMatchesApp(game.info.name, game.info.serial);
bool is_visible = m_show_hidden || !m_hidden_list.contains(qstr(game->info.serial));
return is_visible && matches_category() && SearchMatchesApp(game->info.name, game->info.serial);
}
void game_list_frame::SortGameList()
@ -382,7 +385,7 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
QPixmap pxmap = PaintedPixmap(img, hasCustomConfig);
m_game_data.push_back({ game, m_game_compat->GetCompatibility(game.serial), img, pxmap, hasCustomConfig });
m_game_data.push_back(game_info(new gui_game_info{ game, m_game_compat->GetCompatibility(game.serial), img, pxmap, hasCustomConfig }));
}
catch (const std::exception& e)
{
@ -391,9 +394,9 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
// Blame MSVC for double }}
}}
auto op = [](const GUI_GameInfo& game1, const GUI_GameInfo& game2)
auto op = [](const game_info& game1, const game_info& game2)
{
return qstr(game1.info.name).toLower() < qstr(game2.info.name).toLower();
return qstr(game1->info.name).toLower() < qstr(game2->info.name).toLower();
};
// Sort by name at the very least.
@ -433,7 +436,7 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
int scroll_position = m_xgrid->verticalScrollBar()->value();
PopulateGameGrid(games_per_row, m_Icon_Size, m_Icon_Color);
connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
m_Central_Widget->addWidget(m_xgrid);
m_Central_Widget->setCurrentWidget(m_xgrid);
@ -477,21 +480,31 @@ static void open_dir(const std::string& spath)
QDesktopServices::openUrl(QUrl("file:///" + path));
}
void game_list_frame::doubleClickedSlot(const QModelIndex& index)
void game_list_frame::doubleClickedSlot(QTableWidgetItem *item)
{
int i;
if (item == nullptr)
{
return;
}
game_info game;
if (m_isListLayout)
{
i = m_gameList->item(index.row(), gui::column_icon)->data(Qt::UserRole).toInt();
game = GetGameInfoFromItem(m_gameList->item(item->row(), gui::column_icon));
}
else
{
i = m_xgrid->item(index.row(), index.column())->data(Qt::ItemDataRole::UserRole).toInt();
game = GetGameInfoFromItem(item);
}
if (game.get() == nullptr)
{
return;
}
LOG_NOTICE(LOADER, "Booting from gamelist per doubleclick...");
Q_EMIT RequestBoot(m_game_data[i].info.path);
Q_EMIT RequestBoot(game->info.path);
}
void game_list_frame::ShowContextMenu(const QPoint &pos)
@ -511,18 +524,13 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
globalPos = m_xgrid->mapToGlobal(pos);
}
if (item == nullptr)
game_info gameinfo = GetGameInfoFromItem(item);
if (gameinfo.get() == nullptr)
{
return; // null happens if you are double clicking in dockwidget area on nothing.
return;
}
int index = item->data(Qt::UserRole).toInt();
if (index == -1)
{
return; // invalid
}
GameInfo currGame = m_game_data[index].info;
GameInfo currGame = gameinfo->info;
const QString serial = qstr(currGame.serial);
// Make Actions
@ -549,7 +557,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
QAction* checkCompat = myMenu.addAction(tr("&Check Game Compatibility"));
QAction* downloadCompat = myMenu.addAction(tr("&Download Compatibility Database"));
const std::string config_base_dir = fs::get_config_dir() + "data/" + m_game_data[index].info.serial;
const std::string config_base_dir = fs::get_config_dir() + "data/" + currGame.serial;
connect(boot, &QAction::triggered, [=]
{
@ -559,7 +567,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
connect(configure, &QAction::triggered, [=]
{
settings_dialog dlg(xgui_settings, xemu_settings, 0, this, &currGame);
if (dlg.exec() == QDialog::Accepted && !m_game_data[index].hasCustomConfig)
if (dlg.exec() == QDialog::Accepted && !gameinfo->hasCustomConfig)
{
ShowCustomConfigIcon(item, true);
}
@ -595,7 +603,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
RemoveCustomConfiguration(config_base_dir);
}
fs::remove_all(currGame.path);
m_game_data.erase(m_game_data.begin() + index);
m_game_data.erase(std::remove(m_game_data.begin(), m_game_data.end(), gameinfo), m_game_data.end());
if (m_isListLayout)
{
m_gameList->removeRow(m_gameList->currentItem()->row());
@ -661,7 +669,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
}
// Disable removeconfig if no config exists.
removeConfig->setEnabled(m_game_data[index].hasCustomConfig);
removeConfig->setEnabled(gameinfo->hasCustomConfig);
// remove delete options if necessary
if (!fs::is_dir(config_base_dir))
@ -773,19 +781,20 @@ QPixmap game_list_frame::PaintedPixmap(const QImage& img, bool paintConfigIcon)
void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled)
{
if (item == nullptr)
auto game = GetGameInfoFromItem(item);
if (game == nullptr)
{
return;
}
int index = item->data(Qt::UserRole).toInt();
auto& game = m_game_data[index];
game.hasCustomConfig = enabled;
game.pxmap = PaintedPixmap(game.icon, enabled);
game->hasCustomConfig = enabled;
game->pxmap = PaintedPixmap(game->icon, enabled);
if (!m_isListLayout)
{
m_xgrid->addItem(game.pxmap, qstr(game.info.name).simplified(), index, m_xgrid->currentItem()->row(), m_xgrid->currentItem()->column());
int r = m_xgrid->currentItem()->row(), c = m_xgrid->currentItem()->column();
m_xgrid->addItem(game->pxmap, qstr(game->info.name).simplified(), r, c);
m_xgrid->item(r, c)->setData(gui::game_role, QVariant::fromValue(game));
}
else if (enabled)
{
@ -793,7 +802,7 @@ void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled)
}
else
{
m_gameList->setItem(item->row(), gui::column_name, new custom_table_widget_item(game.info.name));
m_gameList->setItem(item->row(), gui::column_name, new custom_table_widget_item(game->info.name));
}
}
@ -821,7 +830,7 @@ void game_list_frame::RepaintIcons(const bool& fromSettings)
for (auto& game : m_game_data)
{
game.pxmap = PaintedPixmap(game.icon, game.hasCustomConfig);
game->pxmap = PaintedPixmap(game->icon, game->hasCustomConfig);
}
Refresh();
@ -923,43 +932,44 @@ int game_list_frame::PopulateGameList()
// Icon
custom_table_widget_item* icon_item = new custom_table_widget_item;
icon_item->setData(Qt::DecorationRole, game.pxmap);
icon_item->setData(Qt::DecorationRole, game->pxmap);
icon_item->setData(Qt::UserRole, index, true);
icon_item->setData(gui::game_role, QVariant::fromValue(game));
// Title
custom_table_widget_item* title_item = new custom_table_widget_item(game.info.name);
if (game.hasCustomConfig)
custom_table_widget_item* title_item = new custom_table_widget_item(game->info.name);
if (game->hasCustomConfig)
{
title_item->setIcon(QIcon(":/Icons/cog_black.png"));
}
// Move Support (http://www.psdevwiki.com/ps3/PARAM.SFO#ATTRIBUTE)
bool supports_move = game.info.attr & 0x800000;
bool supports_move = game->info.attr & 0x800000;
// Compatibility
custom_table_widget_item* compat_item = new custom_table_widget_item;
compat_item->setText(game.compat.text + (game.compat.date.isEmpty() ? "" : " (" + game.compat.date + ")"));
compat_item->setData(Qt::UserRole, game.compat.index, true);
compat_item->setToolTip(game.compat.tooltip);
if (!game.compat.color.isEmpty())
compat_item->setText(game->compat.text + (game->compat.date.isEmpty() ? "" : " (" + game->compat.date + ")"));
compat_item->setData(Qt::UserRole, game->compat.index, true);
compat_item->setToolTip(game->compat.tooltip);
if (!game->compat.color.isEmpty())
{
compat_item->setData(Qt::DecorationRole, compat_pixmap(game.compat.color));
compat_item->setData(Qt::DecorationRole, compat_pixmap(game->compat.color));
}
m_gameList->setItem(row, gui::column_icon, icon_item);
m_gameList->setItem(row, gui::column_name, title_item);
m_gameList->setItem(row, gui::column_serial, new custom_table_widget_item(game.info.serial));
m_gameList->setItem(row, gui::column_firmware, new custom_table_widget_item(game.info.fw));
m_gameList->setItem(row, gui::column_version, new custom_table_widget_item(game.info.app_ver));
m_gameList->setItem(row, gui::column_category, new custom_table_widget_item(game.info.category));
m_gameList->setItem(row, gui::column_path, new custom_table_widget_item(game.info.path));
m_gameList->setItem(row, gui::column_serial, new custom_table_widget_item(game->info.serial));
m_gameList->setItem(row, gui::column_firmware, new custom_table_widget_item(game->info.fw));
m_gameList->setItem(row, gui::column_version, new custom_table_widget_item(game->info.app_ver));
m_gameList->setItem(row, gui::column_category, new custom_table_widget_item(game->info.category));
m_gameList->setItem(row, gui::column_path, new custom_table_widget_item(game->info.path));
m_gameList->setItem(row, gui::column_move, new custom_table_widget_item(sstr(supports_move ? tr("Supported") : tr("Not Supported")), Qt::UserRole, !supports_move));
m_gameList->setItem(row, gui::column_resolution, new custom_table_widget_item(GetStringFromU32(game.info.resolution, resolution::mode, true)));
m_gameList->setItem(row, gui::column_sound, new custom_table_widget_item(GetStringFromU32(game.info.sound_format, sound::format, true)));
m_gameList->setItem(row, gui::column_parental, new custom_table_widget_item(GetStringFromU32(game.info.parental_lvl, parental::level), Qt::UserRole, game.info.parental_lvl));
m_gameList->setItem(row, gui::column_resolution, new custom_table_widget_item(GetStringFromU32(game->info.resolution, resolution::mode, true)));
m_gameList->setItem(row, gui::column_sound, new custom_table_widget_item(GetStringFromU32(game->info.sound_format, sound::format, true)));
m_gameList->setItem(row, gui::column_parental, new custom_table_widget_item(GetStringFromU32(game->info.parental_lvl, parental::level), Qt::UserRole, game->info.parental_lvl));
m_gameList->setItem(row, gui::column_compat, compat_item);
if (selected_item == game.info.icon_path)
if (selected_item == game->info.icon_path)
{
result = row;
}
@ -992,14 +1002,14 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
m_xgrid = new game_list_grid(image_size, image_color, m_Margin_Factor, m_Text_Factor, showText);
}
// Get list of matching apps and their index
QList<QPair<GUI_GameInfo*, int>> matching_apps;
// Get list of matching apps
QList<game_info> matching_apps;
for (uint i = 0; i < m_game_data.size(); i++)
for (const auto& app : m_game_data)
{
if (IsEntryVisible(m_game_data[i]))
if (IsEntryVisible(app))
{
matching_apps.append(QPair<GUI_GameInfo*, int>(&m_game_data[i], i));
matching_apps.push_back(app);
}
}
@ -1026,11 +1036,12 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
for (const auto& app : matching_apps)
{
const QString title = qstr(app.first->info.name).simplified(); // simplified() forces single line text
const QString title = qstr(app->info.name).simplified(); // simplified() forces single line text
m_xgrid->addItem(app.first->pxmap, title, app.second, r, c);
m_xgrid->addItem(app->pxmap, title, r, c);
m_xgrid->item(r, c)->setData(gui::game_role, QVariant::fromValue(app));
if (selected_item == app.first->info.icon_path)
if (selected_item == app->info.icon_path)
{
m_xgrid->setCurrentItem(m_xgrid->item(r, c));
}
@ -1048,7 +1059,6 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
{
QTableWidgetItem* emptyItem = new QTableWidgetItem();
emptyItem->setFlags(Qt::NoItemFlags);
emptyItem->setData(Qt::UserRole, -1);
m_xgrid->setItem(r, col, emptyItem);
}
}
@ -1079,10 +1089,16 @@ std::string game_list_frame::CurrentSelectionIconPath()
if (m_gameList->selectedItems().count())
{
QTableWidgetItem* item = m_oldLayoutIsList ? m_gameList->item(m_gameList->currentRow(), 0) : m_xgrid->currentItem();
int ind = item->data(Qt::UserRole).toInt();
QVariant var = item->data(gui::game_role);
if (ind < m_game_data.size())
selection = m_game_data.at(ind).info.icon_path;
if (var.canConvert<game_info>())
{
auto game = var.value<game_info>();
if (game)
{
selection = game->info.icon_path;
}
}
}
m_oldLayoutIsList = m_isListLayout;
@ -1119,3 +1135,19 @@ std::string game_list_frame::GetStringFromU32(const u32& key, const std::map<u32
return sstr(string.join(", "));
}
game_info game_list_frame::GetGameInfoFromItem(QTableWidgetItem* item)
{
if (item == nullptr)
{
return nullptr;
}
QVariant var = item->data(gui::game_role);
if (!var.canConvert<game_info>())
{
return nullptr;
}
return var.value<game_info>();
}

View File

@ -160,7 +160,7 @@ namespace sound
}
/* Having the icons associated with the game info simplifies logic internally */
struct GUI_GameInfo
struct gui_game_info
{
GameInfo info;
compat_status compat;
@ -169,6 +169,9 @@ struct GUI_GameInfo
bool hasCustomConfig;
};
typedef std::shared_ptr<gui_game_info> game_info;
Q_DECLARE_METATYPE(game_info)
class game_list_frame : public custom_dock_widget
{
Q_OBJECT
@ -207,7 +210,7 @@ private Q_SLOTS:
bool DeleteLLVMCache(const std::string& base_dir, bool is_interactive = false);
void OnColClicked(int col);
void ShowContextMenu(const QPoint &pos);
void doubleClickedSlot(const QModelIndex& index);
void doubleClickedSlot(QTableWidgetItem *item);
Q_SIGNALS:
void GameListFrameClosed();
void RequestBoot(const std::string& path);
@ -221,7 +224,7 @@ private:
QPixmap PaintedPixmap(const QImage& img, bool paintConfigIcon = false);
void ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled);
void PopulateGameGrid(int maxCols, const QSize& image_size, const QColor& image_color);
bool IsEntryVisible(const GUI_GameInfo& game);
bool IsEntryVisible(const game_info& game);
void SortGameList();
int PopulateGameList();
@ -230,6 +233,8 @@ private:
std::string CurrentSelectionIconPath();
std::string GetStringFromU32(const u32& key, const std::map<u32, QString>& map, bool combined = false);
game_info GetGameInfoFromItem(QTableWidgetItem* item);
// Which widget we are displaying depends on if we are in grid or list mode.
QMainWindow* m_Game_Dock;
QStackedWidget* m_Central_Widget;
@ -254,7 +259,7 @@ private:
// Data
std::shared_ptr<gui_settings> xgui_settings;
std::shared_ptr<emu_settings> xemu_settings;
std::vector<GUI_GameInfo> m_game_data;
QList<game_info> m_game_data;
QSet<QString> m_hidden_list;
bool m_show_hidden{false};

View File

@ -58,7 +58,7 @@ void game_list_grid::setIconSize(const QSize& size)
}
}
void game_list_grid::addItem(const QPixmap& img, const QString& name, const int& idx, const int& row, const int& col)
void game_list_grid::addItem(const QPixmap& img, const QString& name, const int& row, const int& col)
{
// define size of expanded image, which is raw image size + margins
QSize exp_size;
@ -91,7 +91,6 @@ void game_list_grid::addItem(const QPixmap& img, const QString& name, const int&
// create item with expanded image, title and position
QTableWidgetItem* item = new QTableWidgetItem();
item->setData(Qt::ItemDataRole::DecorationRole, QPixmap::fromImage(exp_img));
item->setData(Qt::ItemDataRole::UserRole, idx);
item->setData(Qt::ItemDataRole::ToolTipRole, name);
if (m_text_enabled)

View File

@ -22,7 +22,7 @@ public:
void enableText(const bool& enabled);
void setIconSize(const QSize& size);
void addItem(const QPixmap& img, const QString& name, const int& idx, const int& row, const int& col);
void addItem(const QPixmap& img, const QString& name, const int& row, const int& col);
qreal getMarginFactor();

View File

@ -39,6 +39,11 @@ namespace gui
{
static QString stylesheet;
enum custom_roles
{
game_role = Qt::UserRole + 1337,
};
enum game_list_columns
{
column_icon,