diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp index 4721c7e00f55..bc66e3dfe715 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp @@ -14,6 +14,8 @@ #include "Emu/system_utils.hpp" #include "Emu/Cell/Modules/sceNpTrophy.h" +#include +#include #include #include #include @@ -90,6 +92,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_game_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); m_game_table->horizontalHeader()->setStretchLastSection(true); m_game_table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); + m_game_table->setContextMenuPolicy(Qt::CustomContextMenu); m_game_table->verticalHeader()->setVisible(false); m_game_table->setAlternatingRowColors(true); m_game_table->installEventFilter(this); @@ -316,7 +319,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_gui_settings->SetValue(gui::tr_show_platinum, checked); }); - connect(m_trophy_table, &QTableWidget::customContextMenuRequested, this, &trophy_manager_dialog::ShowContextMenu); + connect(m_trophy_table, &QTableWidget::customContextMenuRequested, this, &trophy_manager_dialog::ShowTrophyTableContextMenu); connect(m_game_combo, &QComboBox::currentTextChanged, this, [this] { @@ -324,6 +327,8 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s ApplyFilter(); }); + connect(m_game_table, &QTableWidget::customContextMenuRequested, this, &trophy_manager_dialog::ShowGameTableContextMenu); + connect(m_game_table, &QTableWidget::itemSelectionChanged, this, [this] { if (m_game_table->selectedItems().isEmpty()) @@ -712,16 +717,17 @@ void trophy_manager_dialog::ApplyFilter() ReadjustTrophyTable(); } -void trophy_manager_dialog::ShowContextMenu(const QPoint& pos) +void trophy_manager_dialog::ShowTrophyTableContextMenu(const QPoint& pos) { - QTableWidgetItem* item = m_trophy_table->item(m_trophy_table->currentRow(), TrophyColumns::Icon); - if (!item) + const int row = m_trophy_table->currentRow(); + + if (!m_trophy_table->item(row, TrophyColumns::Icon)) { return; } QMenu* menu = new QMenu(); - QAction* show_trophy_dir = new QAction(tr("Open Trophy Directory"), menu); + QAction* show_trophy_dir = new QAction(tr("&Open Trophy Directory"), menu); const int db_ind = m_game_combo->currentData().toInt(); @@ -732,9 +738,91 @@ void trophy_manager_dialog::ShowContextMenu(const QPoint& pos) }); menu->addAction(show_trophy_dir); + + const QTableWidgetItem* name_item = m_trophy_table->item(row, TrophyColumns::Name); + const QTableWidgetItem* desc_item = m_trophy_table->item(row, TrophyColumns::Description); + + const QString name = name_item ? name_item->text() : ""; + const QString desc = desc_item ? desc_item->text() : ""; + + if (!name.isEmpty() || !desc.isEmpty()) + { + QMenu* copy_menu = new QMenu(tr("&Copy Info"), menu); + + if (!name.isEmpty() && !desc.isEmpty()) + { + QAction* copy_both = new QAction(tr("&Copy Name + Description"), copy_menu); + connect(copy_both, &QAction::triggered, this, [this, name, desc]() + { + QApplication::clipboard()->setText(name % QStringLiteral("\n\n") % desc); + }); + copy_menu->addAction(copy_both); + } + + if (!name.isEmpty()) + { + QAction* copy_name = new QAction(tr("&Copy Name"), copy_menu); + connect(copy_name, &QAction::triggered, this, [this, name]() + { + QApplication::clipboard()->setText(name); + }); + copy_menu->addAction(copy_name); + } + + if (!desc.isEmpty()) + { + QAction* copy_desc = new QAction(tr("&Copy Description"), copy_menu); + connect(copy_desc, &QAction::triggered, this, [this, desc]() + { + QApplication::clipboard()->setText(desc); + }); + copy_menu->addAction(copy_desc); + } + + menu->addMenu(copy_menu); + } + menu->exec(m_trophy_table->viewport()->mapToGlobal(pos)); } +void trophy_manager_dialog::ShowGameTableContextMenu(const QPoint& pos) +{ + const int row = m_game_table->currentRow(); + + if (!m_game_table->item(row, GameColumns::GameIcon)) + { + return; + } + + QMenu* menu = new QMenu(); + QAction* show_trophy_dir = new QAction(tr("&Open Trophy Directory"), menu); + + const int db_ind = m_game_combo->currentData().toInt(); + + connect(show_trophy_dir, &QAction::triggered, this, [this, db_ind]() + { + const QString path = qstr(m_trophies_db[db_ind]->path); + QDesktopServices::openUrl(QUrl::fromLocalFile(path)); + }); + + menu->addAction(show_trophy_dir); + + const QTableWidgetItem* name_item = m_game_table->item(row, GameColumns::GameName); + const QString name = name_item ? name_item->text() : ""; + + if (!name.isEmpty()) + { + QAction* copy_name = new QAction(tr("&Copy Name"), menu); + connect(copy_name, &QAction::triggered, this, [this, name]() + { + QApplication::clipboard()->setText(name); + }); + menu->addAction(copy_name); + } + + menu->exec(m_game_table->viewport()->mapToGlobal(pos)); +} + void trophy_manager_dialog::StartTrophyLoadThreads() { if (m_game_repaint_watcher.isRunning()) diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.h b/rpcs3/rpcs3qt/trophy_manager_dialog.h index c709a9ab3c61..210cb738f809 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.h +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.h @@ -75,10 +75,11 @@ private Q_SLOTS: void ResizeGameIcons(); void ResizeTrophyIcons(); void ApplyFilter(); - void ShowContextMenu(const QPoint& pos); + void ShowTrophyTableContextMenu(const QPoint& pos); + void ShowGameTableContextMenu(const QPoint& pos); private: - /** Loads a trophy folder. + /** Loads a trophy folder. Returns true if successful. Does not attempt to install if failure occurs, like sceNpTrophy. */ bool LoadTrophyFolderToDB(const std::string& trop_name);