From 695cfead163aec39f5299d7e1c6773cb12ca7bf5 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 26 Jun 2020 18:31:42 +0200 Subject: [PATCH] patch_manager: add option to only show owned games and remove the app version level from the gui --- rpcs3/rpcs3qt/game_list_frame.cpp | 5 ++ rpcs3/rpcs3qt/game_list_frame.h | 2 + rpcs3/rpcs3qt/main_window.cpp | 13 ++- rpcs3/rpcs3qt/patch_manager_dialog.cpp | 117 +++++++++++++++---------- rpcs3/rpcs3qt/patch_manager_dialog.h | 6 +- rpcs3/rpcs3qt/patch_manager_dialog.ui | 21 ++--- 6 files changed, 101 insertions(+), 63 deletions(-) diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index a76467d983..e6605ba176 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -2230,3 +2230,8 @@ void game_list_frame::SetShowCompatibilityInGrid(bool show) RepaintIcons(); m_gui_settings->SetValue(gui::gl_draw_compat, show); } + +QList game_list_frame::GetGameInfo() const +{ + return m_game_data; +} diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index 3c9c6803f0..4a8ba07426 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -69,6 +69,8 @@ public: void SetShowHidden(bool show); + QList GetGameInfo() const; + public Q_SLOTS: void BatchCreatePPUCaches(); void BatchRemovePPUCaches(); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 9f5ab975e8..fd7fdadb5f 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -1535,7 +1535,18 @@ void main_window::CreateConnects() connect(ui->actionManage_Game_Patches, &QAction::triggered, [this] { - patch_manager_dialog patch_manager(m_gui_settings, this); + std::unordered_map> games; + if (m_game_list_frame) + { + for (const auto game : m_game_list_frame->GetGameInfo()) + { + if (game) + { + games[game->info.serial].insert(game->info.app_ver); + } + } + } + patch_manager_dialog patch_manager(m_gui_settings, games, this); patch_manager.exec(); }); diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.cpp b/rpcs3/rpcs3qt/patch_manager_dialog.cpp index 77c980c72a..08e6e13892 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/patch_manager_dialog.cpp @@ -45,13 +45,13 @@ enum node_level : int { title_level, serial_level, - app_version_level, patch_level }; -patch_manager_dialog::patch_manager_dialog(std::shared_ptr gui_settings, QWidget* parent) +patch_manager_dialog::patch_manager_dialog(std::shared_ptr gui_settings, std::unordered_map> games, QWidget* parent) : QDialog(parent) , m_gui_settings(gui_settings) + , m_owned_games(std::move(games)) , ui(new Ui::patch_manager_dialog) { ui->setupUi(this); @@ -65,9 +65,8 @@ patch_manager_dialog::patch_manager_dialog(std::shared_ptr gui_set connect(ui->patch_tree, &QTreeWidget::currentItemChanged, this, &patch_manager_dialog::on_item_selected); connect(ui->patch_tree, &QTreeWidget::itemChanged, this, &patch_manager_dialog::on_item_changed); connect(ui->patch_tree, &QTreeWidget::customContextMenuRequested, this, &patch_manager_dialog::on_custom_context_menu_requested); - connect(ui->pb_expand_all, &QAbstractButton::clicked, ui->patch_tree, &QTreeWidget::expandAll); - connect(ui->pb_collapse_all, &QAbstractButton::clicked, ui->patch_tree, &QTreeWidget::collapseAll); connect(ui->cb_enable_legacy_patches, &QCheckBox::stateChanged, this, &patch_manager_dialog::on_legacy_patches_enabled); + connect(ui->cb_owned_games_only, &QCheckBox::stateChanged, this, &patch_manager_dialog::on_show_owned_games_only); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close); connect(ui->buttonBox, &QDialogButtonBox::clicked, [this](QAbstractButton* button) { @@ -103,6 +102,7 @@ void patch_manager_dialog::refresh(bool restore_layout) { load_patches(); populate_tree(); + filter_patches(ui->patch_filter->text()); if (restore_layout) { @@ -212,44 +212,28 @@ void patch_manager_dialog::populate_tree() const QString q_serial = QString::fromStdString(serial); - // Find out if there is a node item for this serial - QTreeWidgetItem* serial_level_item = gui::utils::find_child(title_level_item, q_serial); - - // Add a node item for this serial if it doesn't exist yet - if (!serial_level_item) - { - serial_level_item = new QTreeWidgetItem(); - serial_level_item->setText(0, q_serial); - serial_level_item->setData(0, title_role, q_title); - serial_level_item->setData(0, serial_role, q_serial); - serial_level_item->setData(0, node_level_role, node_level::serial_level); - serial_level_item->setData(0, persistance_role, true); - - title_level_item->addChild(serial_level_item); - } - assert(serial_level_item); - for (const auto& [app_version, enabled] : app_versions) { const QString q_app_version = QString::fromStdString(app_version); + const QString q_serial_and_version = q_serial + QStringLiteral(" v.") + q_app_version; - // Find out if there is a node item for this app version - QTreeWidgetItem* app_version_level_item = gui::utils::find_child(serial_level_item, q_app_version); + // Find out if there is a node item for this serial + QTreeWidgetItem* serial_level_item = gui::utils::find_child(title_level_item, q_serial_and_version); - // Add a node item for this app version if it doesn't exist yet - if (!app_version_level_item) + // Add a node item for this serial if it doesn't exist yet + if (!serial_level_item) { - app_version_level_item = new QTreeWidgetItem(); - app_version_level_item->setText(0, q_app_version); - app_version_level_item->setData(0, title_role, q_title); - app_version_level_item->setData(0, serial_role, q_serial); - app_version_level_item->setData(0, app_version_role, q_app_version); - app_version_level_item->setData(0, node_level_role, node_level::app_version_level); - app_version_level_item->setData(0, persistance_role, true); + serial_level_item = new QTreeWidgetItem(); + serial_level_item->setText(0, q_serial_and_version); + serial_level_item->setData(0, title_role, q_title); + serial_level_item->setData(0, serial_role, q_serial); + serial_level_item->setData(0, app_version_role, q_app_version); + serial_level_item->setData(0, node_level_role, node_level::serial_level); + serial_level_item->setData(0, persistance_role, true); - serial_level_item->addChild(app_version_level_item); + title_level_item->addChild(serial_level_item); } - assert(app_version_level_item); + assert(serial_level_item); // Add a checkable leaf item for this patch const QString q_description = QString::fromStdString(description); @@ -258,7 +242,7 @@ void patch_manager_dialog::populate_tree() const auto match_criteria = QList>() << QPair(description_role, q_description) << QPair(persistance_role, true); // Add counter to leafs if the name already exists due to different hashes of the same game (PPU, SPU, PRX, OVL) - if (const auto matches = gui::utils::find_children_by_data(app_version_level_item, match_criteria, false); matches.count() > 0) + if (const auto matches = gui::utils::find_children_by_data(serial_level_item, match_criteria, false); matches.count() > 0) { if (auto only_match = matches.count() == 1 ? matches[0] : nullptr) { @@ -279,7 +263,7 @@ void patch_manager_dialog::populate_tree() patch_level_item->setData(0, node_level_role, node_level::patch_level); patch_level_item->setData(0, persistance_role, true); - app_version_level_item->addChild(patch_level_item); + serial_level_item->addChild(patch_level_item); } } } @@ -315,13 +299,31 @@ void patch_manager_dialog::filter_patches(const QString& term) // Recursive function to show all matching items and their children. // @return number of visible children of item, including item std::function show_matches; - show_matches = [&show_matches, search_text = term.toLower()](QTreeWidgetItem* item, bool parent_visible) -> int + show_matches = [this, &show_matches, search_text = term.toLower()](QTreeWidgetItem* item, bool parent_visible) -> int { if (!item) return 0; + const node_level level = static_cast(item->data(0, node_level_role).toInt()); + + // Hide nodes that aren't in the game list + if (m_show_owned_games_only) + { + if (level == node_level::serial_level) + { + const std::string serial = item->data(0, serial_role).toString().toStdString(); + const std::string app_version = item->data(0, app_version_role).toString().toStdString(); + + if (m_owned_games.find(serial) == m_owned_games.end() || !m_owned_games.at(serial).contains(app_version)) + { + item->setHidden(true); + return 0; + } + } + } + // Only try to match if the parent is not visible parent_visible = parent_visible || item->text(0).toLower().contains(search_text); - int visible_items = parent_visible ? 1 : 0; + int visible_items = 0; // Get the number of visible children recursively for (int i = 0; i < item->childCount(); i++) @@ -329,6 +331,15 @@ void patch_manager_dialog::filter_patches(const QString& term) visible_items += show_matches(item->child(i), parent_visible); } + if (parent_visible) + { + // Only show the title node if it has visible children when filtering for game list entries + if (!m_show_owned_games_only || level != node_level::title_level || visible_items > 0) + { + visible_items++; + } + } + // Only show item if itself or any of its children is visible item->setHidden(visible_items <= 0); return visible_items; @@ -391,14 +402,10 @@ void patch_manager_dialog::on_item_selected(QTreeWidgetItem *current, QTreeWidge } [[fallthrough]]; } - case node_level::app_version_level: - { - info.app_version = current->data(0, app_version_role).toString(); - [[fallthrough]]; - } case node_level::serial_level: { info.serial = current->data(0, serial_role).toString(); + info.app_version = current->data(0, app_version_role).toString(); [[fallthrough]]; } case node_level::title_level: @@ -473,9 +480,19 @@ void patch_manager_dialog::on_custom_context_menu_requested(const QPoint &pos) QMenu* menu = new QMenu(this); + QAction* collapse_all = new QAction(tr("Collapse All")); + menu->addAction(collapse_all); + connect(collapse_all, &QAction::triggered, ui->patch_tree, &QTreeWidget::collapseAll); + + QAction* expand_all = new QAction(tr("Expand All")); + menu->addAction(expand_all); + connect(expand_all, &QAction::triggered, ui->patch_tree, &QTreeWidget::expandAll); + + menu->addSeparator(); + if (item->childCount() > 0) { - QAction* collapse_children = new QAction("Collapse Children"); + QAction* collapse_children = new QAction(tr("Collapse Children")); menu->addAction(collapse_children); connect(collapse_children, &QAction::triggered, this, [&item](bool) { @@ -485,7 +502,7 @@ void patch_manager_dialog::on_custom_context_menu_requested(const QPoint &pos) } }); - QAction* expand_children = new QAction("Expand Children"); + QAction* expand_children = new QAction(tr("Expand Children")); menu->addAction(expand_children); connect(expand_children, &QAction::triggered, this, [&item](bool) { @@ -509,7 +526,7 @@ void patch_manager_dialog::on_custom_context_menu_requested(const QPoint &pos) { const auto info = container.patch_info_map.at(description); - QAction* open_filepath = new QAction("Show Patch File"); + QAction* open_filepath = new QAction(tr("Show Patch File")); menu->addAction(open_filepath); connect(open_filepath, &QAction::triggered, this, [info](bool) { @@ -520,7 +537,7 @@ void patch_manager_dialog::on_custom_context_menu_requested(const QPoint &pos) { menu->addSeparator(); - QAction* remove_patch = new QAction("Remove Patch"); + QAction* remove_patch = new QAction(tr("Remove Patch")); menu->addAction(remove_patch); connect(remove_patch, &QAction::triggered, this, [info, this](bool) { @@ -661,6 +678,12 @@ void patch_manager_dialog::on_legacy_patches_enabled(int state) m_legacy_patches_enabled = state == Qt::CheckState::Checked; } +void patch_manager_dialog::on_show_owned_games_only(int state) +{ + m_show_owned_games_only = state == Qt::CheckState::Checked; + filter_patches(ui->patch_filter->text()); +} + void patch_manager_dialog::dragEnterEvent(QDragEnterEvent* event) { if (is_valid_file(*event->mimeData())) diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.h b/rpcs3/rpcs3qt/patch_manager_dialog.h index 8120dddd3e..10265d8bb7 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.h +++ b/rpcs3/rpcs3qt/patch_manager_dialog.h @@ -31,7 +31,7 @@ class patch_manager_dialog : public QDialog }; public: - explicit patch_manager_dialog(std::shared_ptr gui_settings, QWidget* parent = nullptr); + explicit patch_manager_dialog(std::shared_ptr gui_settings, std::unordered_map> games, QWidget* parent = nullptr); ~patch_manager_dialog(); int exec() override; @@ -42,6 +42,7 @@ private Q_SLOTS: void on_item_changed(QTreeWidgetItem *item, int column); void on_custom_context_menu_requested(const QPoint& pos); void on_legacy_patches_enabled(int state); + void on_show_owned_games_only(int state); private: void refresh(bool restore_layout = false); @@ -53,6 +54,9 @@ private: std::shared_ptr m_gui_settings; + std::unordered_map> m_owned_games; + bool m_show_owned_games_only = false; + patch_engine::patch_map m_map; bool m_legacy_patches_enabled = false; diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.ui b/rpcs3/rpcs3qt/patch_manager_dialog.ui index 700eb2b406..618e487350 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.ui +++ b/rpcs3/rpcs3qt/patch_manager_dialog.ui @@ -39,6 +39,13 @@ + + + + Only show owned games + + + @@ -46,20 +53,6 @@ - - - - Collapse All - - - - - - - Expand All - - -